Herby
_______________________________________________
es-discuss mailing list
[email protected]
https://mail.mozilla.org/listinfo/es-discuss
The
above would desugar to:
label1:
arr.forEach { |o|
if (...) break label1;
}
If it had continue instead of
break, it would desugar to:
arr.forEach
{ |o|
label2: {
if (...) break label2;
}
}
It wouldn't need to be described as a
desugaring in a strawman, given
the similarity to typical
break/continue handling, but I think that
makes the meaning clear.
No, this is a special form and if it can be specified by desugaring,
that is better in principle than extending the spec's kernel semantics.
Whether it actually pays to gensym a label and translate in the spec is
TBD.
Thanks for writing this down. You're right, I was wrong: a new
for arr.forEach { |o|
if (...) break;
}
special form would not require exception-reified break and continue
given the desugaring you show.
Let's talk about syntax, though. This use of for makes something that
looks like a paren-free for loop, but there's no body. Note that (as
Francois pointed out earlier) block-lambdas cannot start statements, and
the block-lambda above is an argument to arr.forEach.
(The "for" repeating after the keyword in the "forEach" name is
unfortunate, but let's say we can migrate to a JQuery-like "each" name
to resolve this glitch.)
Even with paren-free moving toward more significant newlines, the
newline in the example does not terminate the loop "head", it is part of
the block-lambda in the head. So this is future-hostile to paren-free.
I wonder whether we need this use of "for". It's not clear the continue
case arises enough with forEach to be worth it. The break case is
already satisfied by some/every. If we can defer this sugar until it's
clear we know the need for it is strong enough to measure, we ought to
-- esp. given the paren-free conflict.
We could try for other syntax, but it too would have the body-less
problem. Unless we use a new keyword:
loop arr.forEach { |o|
if (...) break;
}
We could contextually reserve loop. But statements are part of JS, and
so I suspect people would want this to do what Doug Crockford has
suggested it to: indefinitely
iterate its body (here the arr.forEach call _expression_ statement, which
would have a semicolon inserted automatically after). This is a
conflict, since forEach does its own looping.
Other ideas?
/be
The above would
desugar to:
label1: arr.ForEach { |o|
if (...) break label1;
}
If
it had continue instead of break, it would desugar to:
arr.ForEach {
|o|
label2: {
if (...) break label2;
}
}
It
wouldn't need to be described as a desugaring in a strawman, given
the
similarity to typical break/continue handling, but I think that
makes
the meaning clear.
Regards,
Grant Husbands.
Brendan Eich wrote:
More when I reply to Axel in a bit.
I think there may have been a misunderstanding. My proposed solution
amounts to syntactic sugar over the existing strawman and makes
break/continue work intuitively with loopy block lambdas, and your
reply to Axel appears to be against an exception-based version, but
you seem to have (implicitly) tied them together.
That's right, because I don't see how your proposal can work without
exceptions. You write that it is yntactic sugar. Ok, what is the
desugaring? How does
for arr.ForEach { |o|
if (...) break;
}
And it still works, without needing to throw exceptions or alter the
existing library code.
translate into JS without a throw that the implementation of
arr.forEach, which is not modfiied by this for-prefixed invocation, can
catch?
/be
Brendan Eich wrote:
More when I reply to Axel in a bit.
I think there may have been a misunderstanding. My proposed solution
amounts to syntactic sugar over the existing strawman and makes
break/continue work intuitively with loopy block lambdas, and your
reply to Axel appears to be against an exception-based version, but
you seem to have (implicitly) tied them together.
Of course we want to uphold TCP, which constrains the design. What works
here must work in a regular block statement as body of such a loopish
structure.
Well, the LCP (Loop Correspondence Principle :) is maintained. So, you
can change your loop construct from:
for (var i=0; i<arr.length; ++i) {
var o = arr[i];
if (...) break;
}
To this:
for arr.ForEach { |o|
if (...) break;
}
And it still works, without needing to throw exceptions or alter the
existing library code. I believe TCP to be maintained everywhere it
might apply, not least because there's a syntactic opt-in, but I may
have missed what you're pointing out.
If the syntax conflicts disastrously with paren-free, then a suitable
nearby syntax could be chosen. I'm not attached to the syntax; I'm
simply offering an implementation strategy that's minimal, matches
most requirements and doesn't appear to break any of the imposed
rules; I don't know the other strawman proposals well enough to avoid
conflicting syntax. It's a boolean toggle, though, so it should be
easy to find a suitable syntax.
Regards,
Grant Husbands.