Short Functions

Brendan Eich brendan at mozilla.com
Sun May 22 17:30:37 PDT 2011


On May 22, 2011, at 5:21 PM, Isaac Schlueter wrote:

> That was the point I was trying to make.  Having block-lambdas behave
> like functions is not a hazard.  "||" is enough of a differentiator,
> just like "function ()" is, only with a little less to look at.

Ok, thanks.


> On Sun, May 22, 2011 at 16:36, Brendan Eich <brendan at mozilla.com> wrote:
>> To reverse the argument you made: if function body looking like a block
>> were a source of confusion, we'd already have trouble:
> 
> I'm not saying it's a source of confusion.  I'm saying "this callable
> thing is dramatically different than that other callable thing" is a
> bigger hazard than "this curly-brace is dramatically different from
> that other curly-brace".

Yet callables can do all sorts of things in JS today, via host objects. Rhino long ago, via the Cocoon project, gained a Continuation object, object-oriented call/cc!

Calling block-lambda expressions with the paren-free form is pretty tame and well-behaved so long as the downward block-lambda funargs don't escape to outlive the call. That's not the case you are worried about, from what you write above.

The case where a block is passed down less literally, via a local variable, and that block can force a return, is new if you're not using Rhino with Continuations. But it's strictly less powerful than call/cc. You can only return from the function containing the block-lambda expression. You can't force some other function to return.


> Here's the sort of thing that I'm driving at:
> 
> function abc (cb) {
>  if (Math.random() < 0.5) cb(100)
> }
> function xyz () {
>  abc( {|x| return x } )
>  return 10
> }
> var p = xyz()
> 
> The fact that a conditional in abc() can trigger a return in xyz,
> without transferring control back to the calling function first, seems
> surprising to me.

You should try call/cc in full in languages that support it :-P.

Yes, it's a novelty to some (many, most? could be) JS hackers. It's not as wild as full call/cc. It is a bigger shift than generators, where the yield operator must be used to make a preemption point (this came up on twitter the other week -- some confusion about generators, but there's no way for any function call f() to suspend the calling code -- you would need yield f()).

So agreed, new semantics. The people who support this acknowledge the new + bigger aspects here and argue that giving users the ability to build control abstractions, using lighter syntax than function, with full Tennent correspondence, is worth it.

I hope we won't have to thumb-wrestle this week to settle this.

Hate to say it, but I wrote it already in reply to Bob Nystrom: arrow function syntax is not going to thumb- or arm-wrestle its way to victory given the GLR parsing requirement. IMHO, sad to say. I'll give it my best shot.

/be
/be
> 
> The situation is further complicated when dealing with asynchronous
> code.  If I'm not mistaken, the following will throw if readyToGo()
> returns false, yes?
> 
> function abc (cb) {
>  if (readyToGo()) cb()
>  else setTimeout(cb, 100)
> }
> function xyz () {
>  abc( {|x| return x } )
>  return 10
> }
> var p = xyz()
> 
> Changes to flow control semantics have subtle implications.  Perhaps
> user-testing will bear out that my taste is in the minority, and that
> the abuses are lesser or no worse than what we already deal with, I
> don't know.



More information about the es-discuss mailing list