Re: GoTo in Java




In article <1138322336.610097.254790@xxxxxxxxxxxxxxxxxxxxxxxxxxxx>, "Richard" <riplin@xxxxxxxxxxxx> writes:
> [I wrote:]
> > Yes, but I'm afraid I don't see the relevance of that to my point. I
> > mentioned the proliferation of X11 APIs for C only as an example of
> > the proliferation of reinvention.
>
> And why isn't the proliferation of sets of C++ GUI classes an example
> of proliferation of reinvention ?

It is. I'll see your antistrephon and raise you a concessio: GUI
libraries were a poor example. Container libraries are better, since
C++ does provide those as part of the language, and C does not.
Hence my point: C's popularity does not depend on the availability of
software components for use in new applications.

> In actual fact "Xlib, Xtk, Xaw, Motif..." is more an example of
> building on existing code. Xtk is built on top of Xlib, Xaw is a set of
> widget, Motif is a full GUI that relies on Xlib and Xtk.

By "Motif" I meant specifically the Motif widget set, not mwm and
the rest of CDE. If I were going to continue this line of argument
I might instead contrast the Xtk basic widget set with Xaw, Xm, the
Motif set, and (most tellingly) one-off sets like the one used in
xrn; but I'm not.

> > Swing was invented by Sun as a successor to AWT. wx4j is a port of a
> > preexisting API to Java. BambooKit isn't an API; it's an XML-based
> > GUI scripting language. None of them represent reinvention as such.
>
> Why is Swing not a 'reinvention' of AWT, or SWT not a reinvention of
> Swing ?

Swing isn't a reinvention of AWT because it was developed specifically
as a successor to AWT. Nothing makes Xaw particularly better than Xm
or vice versa; neither was developed as an improvement on the other;
they were just developed because someone felt like writing them.

> > Of those, only Ruby and Python even approach OCaml's expressiveness.
>
> Can you give an example showing OCaml to be more expressive.

(Obviously it's no more expressive in terms of Kolmogorov
complexity; I hope that goes without saying.)

Neither Ruby nor Python really support pure functional (non-destructive)
programming in any convenient fashion; at least that's the conclusion
I've seen from people who have spent more time investigating the
question than I have.

Ruby doesn't quite have first-class functions, because it doesn't
have functions. It has methods, which are always encapsulated in
objects; and blocks, which are anonymous closures; and Procs, which
are blocks bound to some state. The result is that higher-order
functions in Ruby are a bit awkward; there's a syntactic leap from
method definition, which is what Ruby programmers typically use for
defining code, to creating function-type objects for HOFs.

Here's an example I found online for a curried function in Ruby:

f = lambda { |x, y| x + y }
curry = lambda { |f, n| lambda { |x| f.call(n, x) } }
g = curry.call(f, 2)
g.call(3) #=> 5

Here's the same thing in OCaml:

let f(x,y) = x + y;;
let g(x) = f(2, x);;
g(3);; [displays "- : int = 5"]

OCaml has first-class functions as its basic function form, so
there's no special syntax required for them. Nor does it require the
special "curry" class to curry a function; f takes two parameters,
so if only one is supplied, the result is a function taking the
remaining parameter.

On the other hand, Ruby does make *every* method and closure a HOF,
in effect, by always allowing a block to be attached to it (and
invoked via the yield operator or processed in fancier ways by
treating it as a named Proc). That's quite clever, and I suppose
it'd be fair to say that Ruby is really quite close to the expres-
siveness of OCaml. The yield operator also is a nifty way of
implementing a sort of coroutine, though you need to use Ruby's
continuations for general coroutines.

In Python, functional programming is given even less attention. It's
not unworkable, because objects can capture state, which makes it
possible (and even reasonable) to build closures and continuations
from them, and HOFs in turn from that, but functional programming was
not a major goal for van Rossum, as far as I can tell.

There's that koan-style bit someone wrote about objects being the
poor man's closure and closures being the poor man's object, and it's
true that one will substitute for t'other. But OCaml fully supports
both, as part of its basic syntax, which is what makes it a genuinely
multiparadigm language.

(On the other hand, the syntax of the ML family isn't exactly lovely,
and I do like Ruby very much, and Python's not bad. If I had a fast,
portable native-code compiler for Ruby, I might make it my target
rather than OCaml. The yield operation is very nice for pipelined
data flow, which is great for a lot of comms applications.)

Perhaps the ML family's most famous bit of expressive power, though,
is its pattern-matching function bodies, which are a very basic
language feature (they're typically one of the first things students
are introduced to) and very powerful. What's more, the language
imposes some rather strong constraints on the implementation of
pattern-matching that make it very practical. (The implementation
checks during interpretation or compilation that cases are exhaustive
and unambiguous, for example, and there are optimization requirements
as well.)

OCaml's pattern matching includes parallel patterns, partial variable
binding, and guarded patterns (patterns that match only when an
expression is true). And they're particularly well-suited for the
kind of recursive function that's popular in functional programming
(and is practical in OCaml because, like Scheme, it features tail-call
optimization).

Here's an example of simple pattern matching with recursion, in a
function to sum a list:

let rec sum list = match list with
| [] -> 0
| head::rest -> head + sum rest;;

(You'd invoke this in the interpreter with eg "sum [1; 2; 3];;",
which would display "- : int = 6".)

That says "sum" is a function that takes a list and matches it against
two possibilities. If the list is empty, it returns 0; if it's not
empty, it assigns the first value to "head" and the rest of the list
to "rest", then returns head plus the sum of rest.

It's just syntactic sugar, but it's a very handy construct in practice.
You can see its use in some of the programs on Jon Harrop's site.[1]

So the real answer to your question is a combination of multiparadigm
elements with equal support for (pure and impure) functional and OO
programming, some unusual syntactic sugar, and a syntax which is
terse without being quite the line noise that's typical of, say, Perl
or APL (much as I enjoy the latter).

On the whole, I'd call Python more expressive than Javascript, Ruby
more than Python, and OCaml more than Ruby. But they're all in a
class above older procedural languages, and even older functional
ones like Scheme or LISP (at least without its OO bolt-on).

Anyway, that's how I see it. Of course you or others might make a
different case. Also, I'm by no means an expert on any of those
languages, and I may be missing out on equally compeling points in
favor of some of the others.


1. http://www.ffconsultancy.com/free/index.html

--
Michael Wojcik michael.wojcik@xxxxxxxxxxxxxx

Pogo: The dogs *scarcely* ever catches the rabbit.
Bun: "Scarcely" got a very unpleasant ring of frequency to it.
-- Walt Kelly
.



Relevant Pages

  • Re: Probably an FAQ, but...
    ... You referred to 'dedicated' Ruby coders, ... Another person on this list that's been programming a "longish" ... time and is in the intersection of language lawyers (aka people who ... innovations have *led* the formal specifications, ...
    (comp.lang.ruby)
  • Re: Ideas on "Why Living Dangerous can be A Good Thing" in Ruby?
    ... The fear in part has to do with type checking. ... essential to 'safe' programming. ... I personally have never crashed my computer using Ruby. ... just removing the type checking and other 'security' measures. ...
    (comp.lang.ruby)
  • Re: [ANN] rocaml: Ruby extensions in Objective Caml
    ... you define the interface in Ruby, and also define what should be ... Couldn't you, say, just define it in OCaml (where the ... type sigantures will be know completely, I guess?), and have the Ruby ... specifying it all in extconf.rb and ...
    (comp.lang.ruby)
  • Re: Threads and Ruby
    ... you must either synchronize or avoid access to shared resources. ... standard implementation of Ruby doesn't do it well. ... a message passing fashion and even more often use those threads to ...
    (comp.lang.ruby)
  • Re: teaching ruby as cs intro?
    ... Learning about Ruby has been a way nicer ... > language at an introductory level. ... > students too quickly; nonetheless there's enough documentation on the ... rich std lib and wide range of programming paradigms covered as ...
    (comp.lang.ruby)