January 15, 2012 12:15 PM


-----Pôvodná správa----- From: Brendan Eich
Sent: Sunday, January 15, 2012 8:56 PM
To: Grant Husbands
Cc: [email protected]
Subject: Re: Block Lambdas: break and continue

...

block-Other ideas?

/be
===

I sent an _expression_-less continue and break elaboration today. at 11:something CET.
I would like to hear what is wrong with that, if something.

Your earlier message was way (way!) too long to get through today, and I stopped reading it when it proposed an ambiguous extension to continue, namely continue <_expression_>. The language already supports continue <label> where label is an identifier, which is also a valid _expression_.

Let's back up from trying to do something involving passing an _expression_ via continue, since that is not needed for what Grant showed: a desugaring from for-prefix block-lambda to label-based block-lambda code.

It also seems to me, after some more thoughts, that block-lambdas with strict TCP and break/continue are mutually exclusive

Not so. The strawman requires and starts to specify TCP conformance for break, continue, return, and |this|.

and you must select one of them (if TCP is primary goal, break and continue must work the same independently of whether block-lambda is present or not

That's what the strawman proposes.

- it is what TCP is about, so even the idea of lambda-block-specific break/continue is breaking TCP). So what are we really looking for?

You haven't said what is mutually exclusive, and the proposal preserves TCP while supporting break and continue in block lambdas to outer loops/switches/labeled-statements, just as if the block-lambda were replaced by a block statement with the appropriate changes to surrounding code (TCP conformance).

Please try to show proof (a convincing argument) for claims like "mutually exclusive".

/be

Herby
_______________________________________________
es-discuss mailing list
[email protected]
https://mail.mozilla.org/listinfo/es-discuss
January 15, 2012 11:56 AM
January 15, 2012 8:00 AM

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
January 15, 2012 8:00 AM

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.

January 15, 2012 7:36 AM


January 15, 2012 3:51 AM
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
January 15, 2012 3:51 AM
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.

_______________________________________________
es-discuss mailing list
[email protected]
https://mail.mozilla.org/listinfo/es-discuss

Reply via email to