Re: return when desugaring to closures

2008-10-09 Thread Brendan Eich
On Oct 9, 2008, at 8:57 PM, Peter Michaux wrote:

> This keyword/scoping problem must already have appeared for functions
> as function declarations have "var" scoping and obtaining "let"
> scoping requires using something like "let a = function(){}". This is
> pretty ugly for functions to have "let" scoping

An agreement from TC39 this past sprint was that function definitions  
directly nested in blocks, not specified by ES3, defined block-local  
(let) bindings.

There was general aversion to 'let function f() ...', an earlier ES4  
idea already on the ropes. Separating binding forms from function  
definition and other options (such as const) avoids too many binding  
forms ('let const', 'let function', etc.). But too many binding forms  
is just too many, and the committee strongly favored using grammatical  
placement to avoid adding more syntactic complexity.


> but the good news is
> the door has been left open for real lambdas to snatch up the
> available "var a(){}" and "let a(){}" syntaxes.

There's no reason to add var a() {} given function a() {} as a direct  
child of a program or function body. It seems to me let a(){} is  
Dave's define. So we're back to function vs. define/lambda.

The idea of a desugaring let statement and let expression require  
lambda, the reformed function (whether define wins or not). But let  
declarations as "the new var" do not desugar to lambdas. They hoist,  
even if forward references (use before set) are errors.

We haven't found a reformed var; I don't think there is one. This does  
not mean let declarations are somehow not worth adding. They're a big  
improvement on var declarations in our experience with let in JS1.7  
and up.

/be

___
Es-discuss mailing list
Es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: return when desugaring to closures

2008-10-09 Thread Peter Michaux
On Thu, Oct 9, 2008 at 4:28 PM, David Herman <[EMAIL PROTECTED]> wrote:

[snip]

> How would people feel about the declaration form being 'define'
> instead of lambda? As in:
>
>define const(x) {
>lambda(y) x
>}
>
> Maybe I'm just accustomed to Scheme, but it looks awkward to me
> for the declaration form to be called lambda. Dylan also used 'define'.

I think there is a good reason for concern that may be intuitively
behind your "looks awkward". (That little voice in my head saying
"eww" is usually correct.)

>From Scheme's r5rs specification, two of the three declaration forms are

(define  )
(define ( ) )

The second form for declaring lambdas is just shorthand for

(define 
(lambda () ))

So there is a reason the declaration form for lambdas uses "define":
it desugars to the first form which also uses "define". It gives a
tidy parallel syntax for both kinds of declarations.

If we try to make the same parallelism in JavaScript with "var" we would have

var  = 
var () 

or if we use "let" we have the following parallelism

let  = 
let () 

So in your suggestion for using "define", does "define" mean "var" or
"let" scoping of the declaration? Since it should probably mean one or
the other, it might be better to allow the declaration forms for
lambdas to just use either "var" or "let" depending how the programmer
wants the declaration scoped. If new scoping keywords appear in the
language (e.g. "our", "my") then new lambda declaration forms can use
the new keywords and scoping of various declaration forms will be
naturally parallel.

This keyword/scoping problem must already have appeared for functions
as function declarations have "var" scoping and obtaining "let"
scoping requires using something like "let a = function(){}". This is
pretty ugly for functions to have "let" scoping but the good news is
the door has been left open for real lambdas to snatch up the
available "var a(){}" and "let a(){}" syntaxes.

Peter
___
Es-discuss mailing list
Es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: return when desugaring to closures

2008-10-09 Thread Brendan Eich
On Oct 9, 2008, at 6:44 PM, David Herman wrote:

> Sorry, I was unclear.

No, my fault for missing "declaration form".


> I meant 'lambda' for the expression form and 'define' for the  
> definition form.

Do keywords cost more than concepts?

If people think define name(x) x and lambda (x) x are different  
beasts, then different names win.

If people think of lambdas (what else to call them? not "functions")  
as being named or not when used as expressions, and named when  
declarations (parallel to the existing function forms are in ES3), but  
being different (albeit similar; cleaned-up) function-like beasts,  
then one name for the three forms that parallel the ES3 function forms  
seems better.

It's hard to argue about from first principles outside of the  
specifics of ES3 and modern JS implementations and teaching. The  
specific JS books I know talk about functions having several forms, so  
it seems better to me to keep lambda parallel. I see the appeal of  
define for the declaration (definition, rather) form, though.

/be

___
Es-discuss mailing list
Es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: return when desugaring to closures

2008-10-09 Thread David Herman
Sorry, I was unclear. I meant 'lambda' for the expression form and 'define' for 
the definition form.

Dave

- Original Message -
From: "Brendan Eich" <[EMAIL PROTECTED]>
To: "David Herman" <[EMAIL PROTECTED]>
Cc: "Peter Michaux" <[EMAIL PROTECTED]>, "es3 x-discuss" <[EMAIL PROTECTED]>, 
es-discuss@mozilla.org
Sent: Thursday, October 9, 2008 9:12:26 PM GMT -05:00 US/Canada Eastern
Subject: Re: return when desugaring to closures

On Oct 9, 2008, at 4:28 PM, David Herman wrote:

> How would people feel about the declaration form being 'define'  
> instead of lambda? As in:
>
>define const(x) {
>lambda(y) x
>}
>
> Maybe I'm just accustomed to Scheme, but it looks awkward to me for  
> the declaration form to be called lambda. Dylan also used 'define'.

For named functions, it's less cryptic, it has clearer connotations.  
For anonymous functions, e.g.:

   (define (x) {...})(x)

or

   return foo(define (y) {...}, z);

your mileage *will* vary, but it seems worse by a hair to me. But I'm  
used to "lambda" as a term of art.

The obscurity of "lambda" helps it avoid collisions (we have ways of  
unreserving keywords in property-name contexts, but these do not work  
for formal parameters and variables named "define", which seem  
likelier at a guess than "lambda" -- spidering the web could help  
confirm this guess).

The obscurity also arguably partners "lambda" better with "function".  
Setting up "define" as a cleaner "function" seems to switch domains of  
discourse. Concretely, we have in ES3.1 Object.defineProperty and  
similarly named functions. These "define" APIs were prefigured by  
Object.prototype._defineGetter__, etc.. This sense of "define" has  
meant "bind property name to value or getter/setter".

On the other side, Python, E, etc. use "def". But we would be verbose  
like Scheme and Dylan. So "define" vs. "lambda".

End of my bike-shedding ruminations.

/be
___
Es-discuss mailing list
Es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: return when desugaring to closures

2008-10-09 Thread Brendan Eich
On Oct 9, 2008, at 4:28 PM, David Herman wrote:

> How would people feel about the declaration form being 'define'  
> instead of lambda? As in:
>
>define const(x) {
>lambda(y) x
>}
>
> Maybe I'm just accustomed to Scheme, but it looks awkward to me for  
> the declaration form to be called lambda. Dylan also used 'define'.

For named functions, it's less cryptic, it has clearer connotations.  
For anonymous functions, e.g.:

   (define (x) {...})(x)

or

   return foo(define (y) {...}, z);

your mileage *will* vary, but it seems worse by a hair to me. But I'm  
used to "lambda" as a term of art.

The obscurity of "lambda" helps it avoid collisions (we have ways of  
unreserving keywords in property-name contexts, but these do not work  
for formal parameters and variables named "define", which seem  
likelier at a guess than "lambda" -- spidering the web could help  
confirm this guess).

The obscurity also arguably partners "lambda" better with "function".  
Setting up "define" as a cleaner "function" seems to switch domains of  
discourse. Concretely, we have in ES3.1 Object.defineProperty and  
similarly named functions. These "define" APIs were prefigured by  
Object.prototype._defineGetter__, etc.. This sense of "define" has  
meant "bind property name to value or getter/setter".

On the other side, Python, E, etc. use "def". But we would be verbose  
like Scheme and Dylan. So "define" vs. "lambda".

End of my bike-shedding ruminations.

/be
___
Es-discuss mailing list
Es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: [Caja] GC of name objects in ES3.1

2008-10-09 Thread Brendan Eich
On Oct 9, 2008, at 6:04 PM, David-Sarah Hopwood wrote:

> Mike Samuel wrote:
>> Mark,
>>
>> Do you know if the ES3.1 spec specifies GC behavior around Name  
>> objects that

No Name objects in ES3.1.

/be

___
Es-discuss mailing list
Es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: [Caja] GC of name objects in ES3.1

2008-10-09 Thread David-Sarah Hopwood
Mike Samuel wrote:
> Mark,
> 
> Do you know if the ES3.1 spec specifies GC behavior around Name objects that
> are not referenced from any reachable or executing functions' scope chains,
> and are not a key for any enumerable property?

Typically language specs don't normatively specify GC behaviour, because
it isn't observable except for the effect on memory usage, and they
don't specify memory usage. But it does deserve a footnote, IMHO.

In Erlang, atoms are not GC'd, and this leads to all kinds of ugly
workarounds. This behaviour is widely considered to be a wart, and there
is a proposal to fix it: .
(That document mainly discusses implementation in Erlang/OTP, but the
motivation and rationale sections are relevant.) It would be nice not
to repeat this mistake in ECMAScript.

> If not, is this an issue that should be raised on one of the es*-discuss
> lists?

Cc: and Reply-To: set to es-discuss.

-- 
David-Sarah Hopwood
___
Es-discuss mailing list
Es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: return when desugaring to closures

2008-10-09 Thread David Herman
> I argued for "let" desugaring to "function" and I understand the
> problems with "arguments", "this" and "return". In light of the
> "lambda" idea below and that "let" could desugar to that more
> intuitively (i.e. Tenent's principle) to "lambda", I think what I was
> really asking/arguing for was an axiomatic definition of the
> language.
> That is, "let" should should desugar to something more fundamental.

Exactly -- and from our standpoint, we weren't arguing that "let" *shouldn't* 
desugar to something more fundamental, just that 'function' wasn't the right 
primitive. My intention was for 'lambda' to be the "dialectical synthesis" to 
our debate. Glad to hear it has appeal.

> Please call it "lambda"! :)

Knowing full well that we've already had long, silly, drawn-out, painful 
bike-shedding sessions on alternative names for 'lambda' on es-discuss, and at 
the risk of picking at old wounds... 

How would people feel about the declaration form being 'define' instead of 
lambda? As in:

define const(x) {
lambda(y) x
}

Maybe I'm just accustomed to Scheme, but it looks awkward to me for the 
declaration form to be called lambda. Dylan also used 'define'.

Dave
___
Es-discuss mailing list
Es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: return when desugaring to closures

2008-10-09 Thread David Herman
> My question was whether the semantics of break and continue would
> support the following:

Yes, this is another good case to consider. Thanks for pointing it out; I'll 
add this to the strawman:lambdas proposal. Essentially this is another aspect 
of the semantics of 'function' that is implicit -- that it cancels out the 
scope of break/continue labels -- and it's precisely these implicit elements of 
a language feature that break expected equivalences. (They are essentially 
"unhygienic" -- if you push me, I can explain the connection to macros.)

> while(true) {
> (function() {
> if (--x == 0) break;
> })();
> }

Note that the 'lambda' proposal is intended to be separate from 'function', 
whose semantics would be left unchanged. So your example would still be 
disallowed, but this:

while(true) {
(lambda() {
 if (--x == 0) break;
 })();
}

would be allowed.

> I honestly don't know, but it shouldn't cause any real trouble to
> allow it. The implementation would be analogous to that for labeled
> return. For example, if the appropriate while loop is no longer on the
> stack, the "break" would turn into an exception.

That's correct.

Dave
___
Es-discuss mailing list
Es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: return when desugaring to closures

2008-10-09 Thread Brendan Eich
On Oct 9, 2008, at 3:31 PM, Peter Michaux wrote:

>> So, to avoid trouble, we've been thinking of new forms including a  
>> better
>> function, call it lambda,
>
> Please call it "lambda"! :)

We do. Hard to beat, IMHO -- even if it originated in a typographical  
compromise (http://dn.codegear.com/article/6 cites sources  
averring that Church wrote something like a circumflex).


>> that has none of the compatibility baggage. I say
>> "we" but really Dave Herman deserves credit for championing this.
>
> Dave Herman for president!

He has my vote! ;-)

/be


___
Es-discuss mailing list
Es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: return when desugaring to closures

2008-10-09 Thread Peter Michaux
On Thu, Oct 9, 2008 at 2:31 PM, Brendan Eich <[EMAIL PROTECTED]> wrote:

[snip]

> Sorry for the very tardy reply. You make good points in the abstract, and
> the messy language-specific details of existing semantics for functions not
> being clean enough deserves a better response than just "don't desugar".
>
> I stand by "don't desugar let to functions as-is".

I argued for "let" desugaring to "function" and I understand the
problems with "arguments", "this" and "return". In light of the
"lambda" idea below and that "let" could desugar to that more
intuitively (i.e. Tenent's principle) to "lambda", I think what I was
really asking/arguing for was an axiomatic definition of the language.
That is, "let" should should desugar to something more fundamental.


> I'm also pretty certain
> "don't add more modes or subsets to try to fix existing forms" is sound,
> since versionitis does not  help us either keep the spec simple or specify
> the backward-compatible semantics in the full language.

This makes really good sense to me. Things like modes that affect
semantics of forms makes me uncomfortable.


> So, to avoid trouble, we've been thinking of new forms including a better
> function, call it lambda,

Please call it "lambda"! :)


> that has none of the compatibility baggage. I say
> "we" but really Dave Herman deserves credit for championing this.

Dave Herman for president!


> A "lambda"
> form has been a topic now and then for a while, on this list and in
> committee, and sometimes only as syntactic sugar (which would miss the
> opportunity for semantic reform) -- yet without it getting the breathing
> room it needs.
>
> Dave is working now in the
>
> http://wiki.ecmascript.org/doku.php?id=strawman:strawman
>
> space on the wiki. Don't throw stones, this is not in the harmony: namespace
> for good reason. Constructive comments welcome. And I still owe the list a
> story on wiki access that keeps Ecma happy and doesn't throw open the edit
> wars doors.
>
> Among the new strawman pages, the following are relevant and (I hope)
> helpful:
>
> http://wiki.ecmascript.org/doku.php?id=strawman:lambdas
> http://wiki.ecmascript.org/doku.php?id=strawman:lexical_scope
> http://wiki.ecmascript.org/doku.php?id=strawman:return_to_label

I wasn't sure if there was going to be a day when I saw these exciting
ideas as potential/maybe ideas that might/perhaps end up in
ECMAScript. I'm going to cross my fingers and start holding my breath
now.

Peter
___
Es-discuss mailing list
Es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: return when desugaring to closures

2008-10-09 Thread Brendan Eich
On Oct 9, 2008, at 3:05 PM, Lex Spoon wrote:

> On Thu, Oct 9, 2008 at 5:31 PM, Brendan Eich <[EMAIL PROTECTED]>  
> wrote: JS has break from labeled statement, and continue to labeled  
> loop bottom, a la Java. These look trouble-free to me. Let me know  
> if you see a hard case. Thanks,
>
> My question was whether the semantics of break and continue would  
> support the following:
>
> while(true) {
>   (function() {
> if (--x == 0) break;
>   })();
> }

That's currently a specified error (possibly at runtime; chapter 16 of  
ES3 allows it to be at compile time).

So a future edition could allow it, probably without opt-in  
versioning. Our compatibility model does not guarantee exceptions,  
since it allows contemporaneous extensions that remove those  
exceptions (see ES3 chapter 16 again, second bulleted list, first  
bullet -- these lists need their own sub-sections and numbers!).


> I honestly don't know, but it shouldn't cause any real trouble to  
> allow it.  The implementation would be analogous to that for labeled  
> return.

Right, and break to label outside the function's body, but lexically  
in scope, would be completely analogous (or just "the same" ;-)):

L: while (true) {
   (function () {
 ... // stuff possibly including a loop or switch that brackets  
the next line
 if (--x == 0) break L;
 ...
   })();
}

> For example, if the appropriate while loop is no longer on the  
> stack, the "break" would turn into an exception.

Yes, this new runtime exception is the price of admission.

The exception seems to a major source of grief in the Java BGGA  
closures controversy, or at least it did when I last looked. But it  
comes up with escape continuations in Scheme, and it is inevitable if  
we want these kinds of program equivalences.

I'm interested in the reactions of others on the list to such "return/ 
break/continue from already-deactivated statement/frame" exceptions.  
They could be caught and handled, of course. Feature and bug, dessert  
topping and floor wax ;-).

/be
___
Es-discuss mailing list
Es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: return when desugaring to closures

2008-10-09 Thread Lex Spoon
On Thu, Oct 9, 2008 at 5:31 PM, Brendan Eich <[EMAIL PROTECTED]> wrote:
>
> JS has break from labeled statement, and continue to labeled loop bottom, a
> la Java. These look trouble-free to me. Let me know if you see a hard case.
> Thanks,
>

My question was whether the semantics of break and continue would support
the following:

while(true) {
  (function() {
if (--x == 0) break;
  })();
}

I honestly don't know, but it shouldn't cause any real trouble to allow it.
 The implementation would be analogous to that for labeled return.  For
example, if the appropriate while loop is no longer on the stack, the
"break" would turn into an exception.

As my usual disclaimer, I am not closely following the different ES trends
including Harmony.  I'm only commenting about what could possibly make the
language more consistent and orthogonal.

-Lex
___
Es-discuss mailing list
Es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: return when desugaring to closures

2008-10-09 Thread Brendan Eich
On Sep 2, 2008, at 2:16 PM, Lex Spoon wrote:

> On Sun, Aug 24, 2008 at 3:17 AM, Brendan Eich <[EMAIL PROTECTED]>  
> wrote:
>> First, let's settle the hash over whether any desugaring without
>> extensions such as return-to-label, reformed lexical scope, tamed
>> this, banished arguments, etc. etc., trumps adding a new binding
>> form, to wit: let as block scoped var.
>
> With no extensions, it is true, return would end up returning from a
> different method under the proposed rewrite.  Likewise, this and
> arguments would cause trouble.

Sorry for the very tardy reply. You make good points in the abstract,  
and the messy language-specific details of existing semantics for  
functions not being clean enough deserves a better response than just  
"don't desugar".

I stand by "don't desugar let to functions as-is". I'm also pretty  
certain "don't add more modes or subsets to try to fix existing forms"  
is sound, since versionitis does not  help us either keep the spec  
simple or specify the backward-compatible semantics in the full  
language.

So, to avoid trouble, we've been thinking of new forms including a  
better function, call it lambda, that has none of the compatibility  
baggage. I say "we" but really Dave Herman deserves credit for  
championing this. A "lambda" form has been a topic now and then for a  
while, on this list and in committee, and sometimes only as syntactic  
sugar (which would miss the opportunity for semantic reform) -- yet  
without it getting the breathing room it needs.

Dave is working now in the

http://wiki.ecmascript.org/doku.php?id=strawman:strawman

space on the wiki. Don't throw stones, this is not in the harmony:  
namespace for good reason. Constructive comments welcome. And I still  
owe the list a story on wiki access that keeps Ecma happy and doesn't  
throw open the edit wars doors.

Among the new strawman pages, the following are relevant and (I hope)  
helpful:

http://wiki.ecmascript.org/doku.php?id=strawman:lambdas
http://wiki.ecmascript.org/doku.php?id=strawman:lexical_scope
http://wiki.ecmascript.org/doku.php?id=strawman:return_to_label

> Possibly break and continue would,
> depending on what their precise semantics are.

JS has break from labeled statement, and continue to labeled loop  
bottom, a la Java. These look trouble-free to me. Let me know if you  
see a hard case. Thanks,

/be
___
Es-discuss mailing list
Es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Garbage collection of Name objects

2008-10-09 Thread Mike Samuel
I was looking at http://wiki.ecmascript.org/doku.php?id=strawman:names on
Name objects, and was wondering whether garbage collection of name objects
has been discussed.

I'm not a GC expert, so the below may be hopelessly naive, and I don't know
whether this kind of thing is appropriate for a language spec, but I wanted
to raise the issue because some cool things become possible if short lived
namespaces don't leak memory when attached to long-lived objects.

My understanding is that existing ES3 interpreters consider an object
reachable if it is any of the following
  (1) a value of a variable/actual/const from the scope chain of any
executing or reachable function  -- this includes the global object and any
objects in with clauses
  (2) the value of a property of a reachable object
  (3) pinned in memory by a host object.

With Name objects, that has to change.  A name object is additionally
reachable if it is the key in an enumerable property, since a for(...in...)
loop can always bring a Name object back into the scope chain of an
executing function.
If it is the key in a non-enumerable property, then there is no way that it
can be brought back into scope.

Can reachability in the presence of Names be specified thus: An object is
reachable if it is any of the following
  (1) a value of a variable/actual/const from the scope chain of any
executing or reachable function
  (2) the value of a property of a reachable object (* where the key is a
string or a reachable Name *)
  (3) pinned in memory by a host object
  (4) (* the Name key of an enumerable property *)
?

So if a Name were only used as a key of an unenumerable property, then it
could be collected as could the properties.  This would not break frozenness
if Object freezing were defined in terms of visible mutations.

cheers,
mike
___
Es-discuss mailing list
Es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss