On Dec 1, 2008, at 2:32 PM, Allen Wirfs-Brock wrote:
{|a,b,c| ...} or
\(a,b,c) {...} or
{\(a,b,c) ...}
I could be happy with any of them and can find pros and cons with
each. I think the high order bit should be that a concise closure
syntax is possible and desirable. If we agree on that then we just
need to pick one.
The use of \ slightly bothers me because it is takes a character
that now is exclusively used in the lexical (token) grammar
( Unicode escapes, string escapes, line continuations) and gives it
syntactic significance. This is probably not a fatal flaw but it
would mean that the lexical uses of \ become less visually
distinctive.
Whether someone prefers the parameters inside or outside the braces
may be another symptom of whether they are focusing on control
abstraction or functional abstraction. With control abstraction you
use closures as "blocks" of code that form pieces of the abstraction
so it may seems natural from that perspective for the braces to
surround the entire "block". This is closer to the syntactic feel of
the built-in control statements. If you are building functional
abstractions then you are probably thinking about the closures as
functions so placing the formals before the body seems natural.
Can you give an example? Since ECMAScript's built-in control
structures already have special syntax, it's hard to make anything
look *exactly* like them.
Here's my best shot at an example. Let's pretend you have a
withOpenFile function that opens a file, does some work using the
resulting file handle (assuming there were such things in some host
extension), and guarantees the file handle will be closed whether on
normal exit or exception, but passing exceptions through. How would a
site of use look?
withOpenFile(fileName, { |handle|
doSomething(handle);
doSomethingElse(handle);
});
withOpenFile(fileName, \(handle) {
doSomething(handle);
doSomethingElse(handle);
});
Both look a little odd but I'd say the latter resembles built-in
constructs like for..in a tiny bit more.
It's fairly common with control abstractions to use 0 argument
closures so the readability of {||...}, \(){...}, and {\()...} are
probably also worth considering. Ideally a 0 argument closure would
be written as {...} but resolution of the syntactic ambiguities
between object literal and such closures (particularly in the
presence of statement labels) seems too difficult to contend with.
Perhaps with the backslash idea, a 0-argument lambda could have a
short form of just \ {...}. I'm trying to think of a useful control
construct that takes thunks. Maybe implementing memoized lazy lists, a
la scheme, so you can do stuff like:
lazyPair(val1, \ { computeRestOfList(); } );
var fibonacciNumbers = \ {
let fib = \(a, b) { lazyPair(b, \ { fib(b, a + b) }) };
lazyPair(0, fib(0, 1));
}();
(I'm skipping the definition of lazyPair and the lazyCar / lazyCdr
you'd need to walk the stream).
Seems adequately readable.
For comparison:
lazyPair(val1, { || computeRestOfList(); } );
var fibonacciNumbers = { ||
let fib = { |a, b| lazyPair(b, { || fib(b, a + b) }) };
lazyPair(0, fib(0, 1));
}();
Maybe it's just lack of familiarity but the second version seems less
readable and natural to me.
My focus on supporting control abstraction may be mute. While
Smalltalk and Ruby show that power of such abstraction mechanisms it
takes more than just a concise block-like closure notation to
achieve it. The complexity of the BGGA Java closure proposal (and
the associated controversy) shows how hard it can be to fully
support control abstraction using C syntax (and, of course, Java
semantics).
I think it's possible to build useful control abstractions with a
concise block-like syntax. But an important factor here is making
these look natural in the context of the language as well as concise.
Ruby and Smalltalk have overall designs that make them friendly to a
smalltalkish block syntax, so your custom control constructs look just
like the built-in ones (or conversely you could claim none are built
in). In ECMAScript you can't have them look exactly the same, but I
think the Haskellish backslash style fits in a little better.
Regards,
Maciej
Allen
-----Original Message-----
From: [EMAIL PROTECTED] [mailto:es-discuss-
[EMAIL PROTECTED] On Behalf Of Maciej Stachowiak
Sent: Monday, December 01, 2008 12:59 PM
To: Brendan Eich
Cc: [email protected]
Subject: Re: Allen's lambda syntax proposal
On Nov 29, 2008, at 10:30 PM, Brendan Eich wrote:
At the TC39 meeting two weeks ago in Kona, we had a brief
bikeshedding discussion about lambda syntax and why it matters.
Observation: blocks in Smalltalk being lightweight means users don't
mind writing them for control abstractions, compared to JS functions
in ES3. In Smalltalk, ignoring JS, it's hard to beat [ and ] as
overhead, although one must count the message selector and its
punctuation too.
Allen Wirfs-Brock put his proposal, which will not shock you who
know Smalltalk or Allen, on the whiteboard:
// Instead of lambda (a, b, c) { ... }, why not:
{ |a, b, c| ... } ?
I like the brevity, but having the formals inside the block and in ||
delimiters seems like it will look weird in an ECMAScript program.
For
function declarations the parameters go in parentheses, and for calls
(presumably also for lambda calls), the arguments go in parens. If
brevity is important, why not lift the lambda syntax from modern pure
functional languages:
\(a, b, c) { ... }
That's backslash as a lambda operator. This has one more character
than your version, but will make formals and parameters look the same
for functions, lambdas, and calls, and will avoid putting the formals
inside the body which I think is confusing and visually hard to scan.
Regards,
Maciej
_______________________________________________
Es-discuss mailing list
[email protected]
https://mail.mozilla.org/listinfo/es-discuss
_______________________________________________
Es-discuss mailing list
[email protected]
https://mail.mozilla.org/listinfo/es-discuss