Re: destructuring: as patterns?

2012-04-23 Thread Andreas Rossberg
On 21 April 2012 11:56, Herby Vojčík he...@mailbox.sk wrote:
 Andreas Rossberg wrote:
 Of course, it is absolutely true that the same argument can be made
 about someExpression.x, but I file that under historic legacy. If we
 were to design JS from scratch -- and with the ES6 feature set! --
 then I'd surely vote for making that throw as well (like, btw, I would
 for argument arity mismatches in function calls, if the callee doesn't
 have appropriate default or rest parameters). Clearly, it's not
 possible to correct that, but why should that imply that all new
 features need to inherit sloppy semantics, too?

 I disagree. Borrowing from Alan Kay IIRC, this is like making an octopus
 from a dog by nailing more legs on it - that is, these two points of view
 are incompatible.

Well, that already is the case. ES5 added strict mode. With 1JS in
ES6, the rules may get more fuzzy. You gonna have 'let' vs 'var'. You
gonna have '=' vs 'function'. You gonna have 'for-of' vs 'for-in'.
All additions that fit your description. It's not pretty, but bolting
on new legs next to the old ones is the only way to keep a language
like JS moving forward.


 JS model _is_ about sloppy semantics (I do not call it sloopy, I'd rather
 called it liberal), that is, undefined if not present.

It's a term sometimes used on TC39, I didn't invent it (I used to call
it classic mode for improved neutrality).

I may take issues with associating pre-strict-mode sweeping under the
rug with liberal ideals, though. :)

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


Re: destructuring: as patterns?

2012-04-23 Thread Allen Wirfs-Brock

On Apr 23, 2012, at 2:40 AM, Andreas Rossberg wrote:

 On 21 April 2012 11:56, Herby Vojčík he...@mailbox.sk wrote:
 
...
 
 JS model _is_ about sloppy semantics (I do not call it sloopy, I'd rather
 called it liberal), that is, undefined if not present.
 
 It's a term sometimes used on TC39, I didn't invent it (I used to call
 it classic mode for improved neutrality).
 
 I may take issues with associating pre-strict-mode sweeping under the
 rug with liberal ideals, though. :)

I like Martin Rinard's concept of code that is  failure oblivious 
http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.68.9926rep=rep1type=pdf
 

Arguably, the robustness of the web is dependent up the fact many Javascript 
based webpages will continue to operate, perhaps in a slight degraded mode, 
even in the face of runtime errors.  I'm all for early errors that cause a 
structurally ill-formed script from loading.  But for a well-formed program I 
don't see why throwing a (probably uncaught) exception is necessarily any more 
robust than simply returning undefined when various dynamic failures (such as 
the destructuring situations we are talking about) are encountered.

To me, undefined propagation  feels a lot like NaN propagation in numeric 
expressions.  Those of us who don't do a lot of numeric computation may be 
puzzled by NaNs, but it is a lot easier to simply let a NaN propagate through a 
complex formula and check it at the end, then it is to check for an exception 
on each operation of the formula.  And, sometimes it turns out that the NaN 
didn't really matter at all...

It is important that JavaScript programmer are able to harden the failure 
critical portions of their applications.  Trying to automatically harden 
everything may actually make JS a less useful languages.

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


Re: destructuring: as patterns?

2012-04-21 Thread Andreas Rossberg
On 21 April 2012 01:08, Brendan Eich bren...@mozilla.org wrote:
 Allen Wirfs-Brock wrote:

 What I'm really pushing at here is the throw. Let's are  used for
 establishing and initializing bindings.  From a binding perspective:

    let x ;
 and
    let {x} = {};

 are almost exactly the same thing.  They both establish a hoisted
 uninitialized lexical binding for x.  They both delimit the end of the TDZ
 for x. They both supply undefined as the initialization value of x. Why
 should the second form throw when the first doesn't?

 That is a good question.

It's about expression of intent. When you write

  let x;

it is syntactic sugar for

  let x = undefined;

So clearly, you want x to be undefined, and you pretty much said so
explicitly. However, nobody ever writes

  let {x} = {};

What destructuring is meant for, and what programmers write in reality is

  let {x, y} = someExpressionThatIsNotALiteral

and here, the apparent intention is that someExpression results in an
object with an x and y property. If it doesn't, that typically means
there is a bug. And masking a bug and/or letting it proliferate
silently is rarely a good idea. Much less so if the language does it
implicitly.

Now, a stricter semantics does not preclude that the language provides
some convenient way to also express the sloppy intent for the cases
where you really want it, which is what Brendan's ?-operator would do.
So I'd be happy with that, as long as it is sufficiently explicit and
not the default.

Of course, it is absolutely true that the same argument can be made
about someExpression.x, but I file that under historic legacy. If we
were to design JS from scratch -- and with the ES6 feature set! --
then I'd surely vote for making that throw as well (like, btw, I would
for argument arity mismatches in function calls, if the callee doesn't
have appropriate default or rest parameters). Clearly, it's not
possible to correct that, but why should that imply that all new
features need to inherit sloppy semantics, too?

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


Re: destructuring: as patterns?

2012-04-21 Thread Herby Vojčík



Andreas Rossberg wrote:

On 21 April 2012 01:08, Brendan Eichbren...@mozilla.org  wrote:

Allen Wirfs-Brock wrote:

What I'm really pushing at here is the throw. Let's are  used for
establishing and initializing bindings.  From a binding perspective:

let x ;
and
let {x} = {};

are almost exactly the same thing.  They both establish a hoisted
uninitialized lexical binding for x.  They both delimit the end of the TDZ
for x. They both supply undefined as the initialization value of x. Why
should the second form throw when the first doesn't?

That is a good question.


It's about expression of intent. When you write

   let x;

it is syntactic sugar for

   let x = undefined;

So clearly, you want x to be undefined, and you pretty much said so
explicitly. However, nobody ever writes

   let {x} = {};

What destructuring is meant for, and what programmers write in reality is

   let {x, y} = someExpressionThatIsNotALiteral

and here, the apparent intention is that someExpression results in an
object with an x and y property. If it doesn't, that typically means
there is a bug. And masking a bug and/or letting it proliferate
silently is rarely a good idea. Much less so if the language does it
implicitly.

Now, a stricter semantics does not preclude that the language provides
some convenient way to also express the sloppy intent for the cases
where you really want it, which is what Brendan's ?-operator would do.
So I'd be happy with that, as long as it is sufficiently explicit and
not the default.

Of course, it is absolutely true that the same argument can be made
about someExpression.x, but I file that under historic legacy. If we
were to design JS from scratch -- and with the ES6 feature set! --
then I'd surely vote for making that throw as well (like, btw, I would
for argument arity mismatches in function calls, if the callee doesn't
have appropriate default or rest parameters). Clearly, it's not
possible to correct that, but why should that imply that all new
features need to inherit sloppy semantics, too?


I disagree. Borrowing from Alan Kay IIRC, this is like making an octopus 
from a dog by nailing more legs on it - that is, these two points of 
view are incompatible.


JS model _is_ about sloppy semantics (I do not call it sloopy, I'd 
rather called it liberal), that is, undefined if not present. It should 
not be changed in other part of languages as well, or it will be mess of 
learning where this applies and where opposite of this applies.




/Andreas


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


Re: destructuring: as patterns?

2012-04-21 Thread Brendan Eich

Andreas Rossberg wrote:

Clearly, it's not
possible to correct that, but why should that imply that all new
features need to inherit sloppy semantics, too?


There's no strict logical implication. On the plus side, the new 
features are stricter (if you are pro-strict and anti-sloppy -- let's 
assume we all agree on this, pace Herby).


On the minus side, you're making the language a mixture of strictness 
that is more complicated (who cares about legacy?) and possibly harder 
to use in practice. The in practice part is crucial.


We've all had bugs in JS code where you pull out undefined (due to a 
property name typo, e.g. -- more insidiously due to type confusion) and 
it flows way downstream before someone notices. This is a pain. But it's 
in the language. Does trying to close the barn door only for 
destructuring -- closing the new upper half of the dutch-style door -- 
help? The lower half is wide open.


Users who want the strictness can use destructuring always:

  let {p} = o;

instead of

  let p = o.p;

and get an error on missing o.p -- that could be the new style for those 
wanting to avoid the legacy behavior. If that's the idea, I get it. But 
I'm skeptical that such an intentional style will be adopted widely, or 
at all. There's no help for all the open-coded


  if (o.p) ...
  foo(o.p)

etc. uses that evaluate to undefined when p is not in o.

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


Re: destructuring: as patterns?

2012-04-20 Thread Andreas Rossberg
On 20 April 2012 02:15, Allen Wirfs-Brock al...@wirfs-brock.com wrote:
 On Apr 19, 2012, at 4:16 PM, David Herman wrote:
    let { unidentifiedAdult: mom as dad, unidentifiedChild: sister as brother 
 }

 or

    let { undentifiedAdult as mom as dad, unidentifiedChild as sister as 
 brother }


 I actually  I found
      propertyName :  bindingIdentifier as bindingPattern

 (do I have the subparts right?) somewhat confusing at first and I think other 
 might also.  What is the difference between : and |as|?

Essentially the same as the difference between : and = in expressions.

Having said that, I don't like Dave's suggestion of overloading 'as'
for object destructuring. I agree that object patterns may be
confusing at first, but you also get used to that quickly. And
overloading 'as' is probably even more confusing, as this discussion
already shows.


  Why are different things allowed after each?  Only one |as|?  I actually 
 think your second alternative is clearer but why not:

  let {unidentifiedAdult : mom : dad : auntie, unidentifiedChild : sister : 
 brother} = peopleComstants.

*gulp*

Not sure if that was a serious suggestion, but let me emphasize again
that layered patterns need to be _compositional_, because you want to
be able to use them in other places, e.g. parameter lists. Tying them
to one particular, unrelated destructuring construct is not right.


 If you think about destructuring simply as an alternative initialization 
 syntax that seems to make more sense.  Essentially : and = are duals that 
 operate in opposite directions:

       let {unidentifiedAdult : mom : dad : auntie} = peopleComstants;  
 //right to left initialization
 vs
       let mom = dad = auntie = peopleComstants. unidentifiedAdult;  //left to 
 right initialization

I disagree. That is a bogus analogy. An object pattern is completely
different from a 'let'. In particular, the latter binds 'mom', but not
'dad' and 'auntie'. The proper equivalence (I wouldn't call it a
duality) would be

       let {unidentifiedAdult : mom as dad as auntie} = peopleComstants;
vs
       let mom as dad as auntie = peopleComstants.unidentifiedAdult;

You cannot even express it without a compositional 'as'.

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


Re: destructuring: as patterns?

2012-04-20 Thread Brendan Eich

Andreas Rossberg wrote:

I disagree. That is a bogus analogy. An object pattern is completely
different from a 'let'. In particular, the latter binds 'mom', but not
'dad' and 'auntie'. The proper equivalence (I wouldn't call it a
duality)


Right. The duality I've cited is between

  let o = {p: q};

and

  let {p: q} = o;

where q and o change places.

Dave's suggestion of

  let {p as q} = o;

does read better in my subjective opinion, even though it diverges the 
pattern langauge (moreso; already diverged) from the object literal 
language.



  would be

let {unidentifiedAdult : mom as dad as auntie} = peopleComstants;
vs
let mom as dad as auntie = peopleComstants.unidentifiedAdult;

You cannot even express it without a compositional 'as'.


Agreed. But is it unthinkable to have 'as' (compositional of course) in 
the pattern language only? I bow to your SuccessorML skills :-).


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


Re: destructuring: as patterns?

2012-04-20 Thread Allen Wirfs-Brock

On Apr 20, 2012, at 2:16 AM, Andreas Rossberg wrote:

 On 20 April 2012 02:15, Allen Wirfs-Brock al...@wirfs-brock.com wrote:
 On Apr 19, 2012, at 4:16 PM, David Herman wrote:
let { unidentifiedAdult: mom as dad, unidentifiedChild: sister as 
 brother }
 
 or
 
let { undentifiedAdult as mom as dad, unidentifiedChild as sister as 
 brother }
 
 
 I actually  I found
  propertyName :  bindingIdentifier as bindingPattern
 
 (do I have the subparts right?) somewhat confusing at first and I think 
 other might also.  What is the difference between : and |as|?
 
 Essentially the same as the difference between : and = in expressions.

I don't understand.  : isn't used in expressions and the productions to the 
right of an = doesn't introduce any bindings.  The : as syntax seems to contain 
identifier bindings in both what follows : and what follows as.  How is : and 
as different other than which binding forms are allowed after each?


 
 Having said that, I don't like Dave's suggestion of overloading 'as'
 for object destructuring. I agree that object patterns may be
 confusing at first, but you also get used to that quickly. And
 overloading 'as' is probably even more confusing, as this discussion
 already shows.
 
 
  Why are different things allowed after each?  Only one |as|?  I actually 
 think your second alternative is clearer but why not:
 
  let {unidentifiedAdult : mom : dad : auntie, unidentifiedChild : sister : 
 brother} = peopleComstants.
 
 *gulp*
 
 Not sure if that was a serious suggestion, but let me emphasize again
 that layered patterns need to be _compositional_, because you want to
 be able to use them in other places, e.g. parameter lists. Tying them
 to one particular, unrelated destructuring construct is not right.
 

What's not compositional about the above?  I'm not going to quote the whole BNF 
from the draft specification but the key productions are:

BindingPattern :
ObjectBindingPattern
ArrayBindingPattern

ObjectBindingPattern :
{ BindingPropertyList }

ArrayBindingPattern :
[ BindingElementList ]

BindingProperty :
PropertyName : BindingElement

BindingElement :
BindingIdentifier
BindingPattern

All I was saying is that references to BindingElement in that grammar could be 
replaced with Bindings defined as

Bindings :
   Bindings : BindingElement
   BindingElement

Still completely compositional.  It is simply permitting a single value from 
the source object to be used as the initializer of multiple bindings.  This 
could work anywhere, include argument lists.


 
 If you think about destructuring simply as an alternative initialization 
 syntax that seems to make more sense.  Essentially : and = are duals that 
 operate in opposite directions:
 
   let {unidentifiedAdult : mom : dad : auntie} = peopleComstants;  
 //right to left initialization
 vs
   let mom = dad = auntie = peopleComstants. unidentifiedAdult;  //left 
 to right initialization
 
 I disagree. That is a bogus analogy. An object pattern is completely
 different from a 'let'. In particular, the latter binds 'mom', but not
 'dad' and 'auntie'.

You're right, I made the mistake of thinking that the assignments in the let 
initializer were binding forms.  They aren't. I'm sure others will make this 
same mistake.  It makes me want to restrict assignment operators in let/const 
initializers!


 The proper equivalence (I wouldn't call it a
 duality) would be
 
   let {unidentifiedAdult : mom as dad as auntie} = peopleComstants;
 vs
   let mom as dad as auntie = peopleComstants.unidentifiedAdult;

or, since we are making up syntax:

  let mom : dad : auntie = peopleComstants.unidentifiedAdult;

or

  let (mom, dad, auntie) = peopleComstants.unidentifiedAdult;


 
 You cannot even express it without a compositional 'as'.

or something...


 
 /Andreas
 

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


Re: destructuring: as patterns?

2012-04-20 Thread Brendan Eich

Andreas Rossberg wrote:

On 20 April 2012 17:12, Brendan Eichbren...@mozilla.org  wrote:

But is it unthinkable to have 'as' (compositional of course) in the
pattern language only?


Perhaps, but what exactly do you mean? ;)


Patterns can have custom grammar in binding contexts (after let, in 
catch heads, etc.), whereas in an assignment expression's left-hand side 
we'd need ObjectLiteral and ArrayLiteral to cover the grammar.


I sense trouble trying to add 'as' to the expression grammar 
(AssignmentExpression to be precise). We could parse it and reject it 
with supplemental syntax for rvalues, and allow it in lvalues, but there 
is a spec smell. I think from past discussions that TC39 wants the 
grammar to be as precise as possible while still LR(1) with lookahead 
and other restrictions.


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


Re: destructuring: as patterns?

2012-04-20 Thread Andreas Rossberg
On 20 April 2012 17:53, Allen Wirfs-Brock al...@wirfs-brock.com wrote:

 On Apr 20, 2012, at 2:16 AM, Andreas Rossberg wrote:

 On 20 April 2012 02:15, Allen Wirfs-Brock al...@wirfs-brock.com wrote:
 On Apr 19, 2012, at 4:16 PM, David Herman wrote:
    let { unidentifiedAdult: mom as dad, unidentifiedChild: sister as 
 brother }

 or

    let { undentifiedAdult as mom as dad, unidentifiedChild as sister as 
 brother }


 I actually  I found
      propertyName :  bindingIdentifier as bindingPattern

 (do I have the subparts right?) somewhat confusing at first and I think 
 other might also.  What is the difference between : and |as|?

 Essentially the same as the difference between : and = in expressions.

 I don't understand.  : isn't used in expressions and the productions to the 
 right of an = doesn't introduce any bindings.  The : as syntax seems to 
 contain identifier bindings in both what follows : and what follows as.  How 
 is : and as different other than which binding forms are allowed after each?

Maybe we are talking past each other, but why do you say : isn't used
in expressions? It's part of the syntax of object literals, and I
think it should keep the same meaning in patterns. On the other hand,
you have an expression form 'e1 = e2', where all free variables are
use-sites. Analogously, in patterns you have 'p1 as p2' (at least if
you think of the most general form), where all free variables are
binding sites (because that's the very nature of a pattern).

What's left of : in an object literal is not a variable, in neither
expressions nor patterns. That's why I think you shouldn't conflate :
and 'as', neither one way (Dave's suggestion) nor the other (your
suggestion).

 What's not compositional about the above?  I'm not going to quote the whole 
 BNF from the draft specification but the key productions are:

 BindingPattern :
    ObjectBindingPattern
    ArrayBindingPattern

 ObjectBindingPattern :
    { BindingPropertyList }

 ArrayBindingPattern :
    [ BindingElementList ]

 BindingProperty :
    PropertyName : BindingElement

 BindingElement :
    BindingIdentifier
    BindingPattern

 All I was saying is that references to BindingElement in that grammar could 
 be replaced with Bindings defined as

 Bindings :
   Bindings : BindingElement
   BindingElement

 Still completely compositional.  It is simply permitting a single value from 
 the source object to be used as the initializer of multiple bindings.  This 
 could work anywhere, include argument lists.

OK, I thought you wanted to tie it to BindingPropertyList. Still,
BindingElement seems to be the wrong place. According to the current
grammar, it would not allow me to write any of

  let x as {a, b} = bla
  for (let x as {a, b} of bla) ...
  {set c(x as {a, b}) {...}}
  try { ...} catch (x as {a, b}) { ... }

That is, the canonical place in the grammar would be BindingPattern AFAICS.

 or, since we are making up syntax:

      let mom : dad : auntie = peopleComstants.unidentifiedAdult;

 or

      let (mom, dad, auntie) = peopleComstants.unidentifiedAdult;

The latter looks far too much like a tuple, and would be particularly
confusing in a parameter list, I'd say.

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


Re: destructuring: as patterns?

2012-04-20 Thread Andreas Rossberg
On 20 April 2012 18:18, Brendan Eich bren...@mozilla.org wrote:
 Patterns can have custom grammar in binding contexts (after let, in catch
 heads, etc.), whereas in an assignment expression's left-hand side we'd need
 ObjectLiteral and ArrayLiteral to cover the grammar.

 I sense trouble trying to add 'as' to the expression grammar
 (AssignmentExpression to be precise). We could parse it and reject it with
 supplemental syntax for rvalues, and allow it in lvalues, but there is a
 spec smell. I think from past discussions that TC39 wants the grammar to
 be as precise as possible while still LR(1) with lookahead and other
 restrictions.

I see, I haven't thought of destructuring assignment. Yes, that's a
bit of an annoyance. But IMHO not a big issue either. Honestly, my
feeling is that strictly sticking to that principle will overly
constrain pattern syntax anyway, if not for 'as' then for the next
nice feature. I dimly remember that we had it coming up before.

One alternative of course would be to restrict what can occur in an
assignment pattern, compared to bindings. The two are quite different
semantically, so it could perhaps be argued. But it's not the most
pleasant idea either.

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


Re: destructuring: as patterns?

2012-04-20 Thread Brendan Eich

Andreas Rossberg wrote:

Honestly, my
feeling is that strictly sticking to that principle will overly
constrain pattern syntax anyway, if not for 'as' then for the next
nice feature. I dimly remember that we had it coming up before.


Dave and I were talking about making fail-soft or irrefutable match 
opt-in:


js let {x} = {};
js x

(SpiderMonkey shell.)

IOW, destructuring has been conceived of as pretty thin sugar for 
getting a property, and if no such property, you get undefined. Of 
course, this makes a deeper pattern fail hard:


js let {y:{z}} = {};
typein:4: TypeError: (void 0) is undefined

(Atrocious SpiderMonkey failure to pretty-print the blamed expression 
instead of its portable (void 0) value there -- my fault I think.)


Dave suggested making the first case, let {x} = {}, throw, and requiring 
? as a pattern modifier (I suggested prefix):


let {?x} = {}; // x is undefined, no throw
let {y} = {};  // throws

So there's another place the pattern language wants to diverge from 
object literal notation.



One alternative of course would be to restrict what can occur in an
assignment pattern, compared to bindings. The two are quite different
semantically, so it could perhaps be argued. But it's not the most
pleasant idea either.


Turns out Allen has already done this in ES6 drafts. 11.13.1 is for 
destructuring assignment. 12.2.4 is destructuring binding patterns. So 
we can diverge patterns further.


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


Re: destructuring: as patterns?

2012-04-20 Thread Brendan Eich

Brendan Eich wrote:
Dave suggested making the first case, let {x} = {}, throw, and 
requiring ? as a pattern modifier (I suggested prefix):


let {?x} = {}; // x is undefined, no throw
let {y} = {};  // throw


I forgot to mention something Dave noticed. Should

  let {?x:{y}} = {};

This too would not throw, rather it would bind y to undefined -- unlike 
the get-undefined-and-then-fail-trying-to-get-y-from-it approach of 
destructuring as implemented in SpiderMonkey and Rhino (based on ES4, 
then ES6 drafts).


So ? as pattern prefix is a deep opt-in flag. Thoughts?

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


Re: destructuring: as patterns?

2012-04-20 Thread Brendan Eich

Brendan Eich wrote:

Should

  let {?x:{y}} = {};


I lost a line finishing the obvious Should ... throw? question.

We could make ? shallow and require another ?-prefix to avoid the throw:

  let {?x:{?y}} = {}

but that seems like it might be user-hostile.

CoffeeScript has ?. and ?( fail-soft operators which are quite popular. 
We talked about them last over a year ago, IIRC. Not proposing them here 
but citing them as nearby, and noting that CoffeeScript does require a 
?. per level:


coffee a = {}
{}
coffee a.?b
Error: In repl, Parse error on line 1: Unexpected '?'
...
coffee a?.b
undefined
coffee a?.b.c
TypeError: Cannot read property 'c' of undefined
...
coffee a?.b?.c
undefined

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


Re: destructuring: as patterns?

2012-04-20 Thread Allen Wirfs-Brock

On Apr 20, 2012, at 2:22 PM, Brendan Eich wrote:

 Andreas Rossberg wrote:
 Honestly, my
 feeling is that strictly sticking to that principle will overly
 constrain pattern syntax anyway, if not for 'as' then for the next
 nice feature. I dimly remember that we had it coming up before.
 
 Dave and I were talking about making fail-soft or irrefutable match opt-in:
 
 js let {x} = {};
 js x
 
 (SpiderMonkey shell.)
 
 IOW, destructuring has been conceived of as pretty thin sugar for getting a 
 property, and if no such property, you get undefined. Of course, this makes a 
 deeper pattern fail hard:

But also remember that we allow default value expressions in binding patterns 
(but not destructuring assignments, where they would be ambiguous):

let (x=default} =  {};
print(x);  //default


 
 js let {y:{z}} = {};
 typein:4: TypeError: (void 0) is undefined

alternatively:
   let {y:{z} = {z:default}} = {};
or
   let {y:{z = default}} = {};

 
 (Atrocious SpiderMonkey failure to pretty-print the blamed expression instead 
 of its portable (void 0) value there -- my fault I think.)
 
 Dave suggested making the first case, let {x} = {}, throw, and requiring ? as 
 a pattern modifier (I suggested prefix):

Then shouldn't
   let x;
be illegal?  Would you have to say:
   let ?x;

 
 let {?x} = {}; // x is undefined, no throw
 let {y} = {};  // throws

so, why not:

  let {x=undefined} = {};

 
 So there's another place the pattern language wants to diverge from object 
 literal notation.
 
 One alternative of course would be to restrict what can occur in an
 assignment pattern, compared to bindings. The two are quite different
 semantically, so it could perhaps be argued. But it's not the most
 pleasant idea either.
 
 Turns out Allen has already done this in ES6 drafts. 11.13.1 is for 
 destructuring assignment. 12.2.4 is destructuring binding patterns. So we can 
 diverge patterns further.
 
 /be
 ___
 es-discuss mailing list
 es-discuss@mozilla.org
 https://mail.mozilla.org/listinfo/es-discuss
 

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


Re: destructuring: as patterns?

2012-04-20 Thread Brendan Eich

Allen Wirfs-Brock wrote:
  
  js  let {y:{z}} = {};

  typein:4: TypeError: (void 0) is undefined


alternatively:
let {y:{z} = {z:default}} = {};
or
let {y:{z = default}} = {};


Too verbose, for one.


  (Atrocious SpiderMonkey failure to pretty-print the blamed expression 
instead of its portable (void 0) value there -- my fault I think.)
  
  Dave suggested making the first case, let {x} = {}, throw, and requiring ? as a pattern modifier (I suggested prefix):


Then shouldn't
let x;
be illegal?


No. I know destructuring requires an initialiser but let does not and I 
think should not. It's a different beast. What you seem to be suggesting 
is that we relax the initialiser requirement, not that we ban let x.



   Would you have to say:
let ?x;


No way!


  let {?x} = {}; // x is undefined, no throw
  let {y} = {};  // throws


so, why not:

   let {x=undefined} = {};

Again, too verbose and (this is the part I left out, see followup) not 
deep. How would defaulting work here?


  let {x:{y:{z}}} = {};

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


Re: destructuring: as patterns?

2012-04-20 Thread Allen Wirfs-Brock

On Apr 20, 2012, at 2:43 PM, Brendan Eich wrote:

 Allen Wirfs-Brock wrote:
 js  let {y:{z}} = {};
   typein:4: TypeError: (void 0) is undefined
 
 alternatively:
let {y:{z} = {z:default}} = {};
 or
let {y:{z = default}} = {};
 
 Too verbose, for one.
 
   (Atrocious SpiderMonkey failure to pretty-print the blamed expression 
  instead of its portable (void 0) value there -- my fault I think.)
 Dave suggested making the first case, let {x} = {}, throw, and 
  requiring ? as a pattern modifier (I suggested prefix):
 
 Then shouldn't
let x;
 be illegal?
 
 No. I know destructuring requires an initialiser but let does not and I think 
 should not. It's a different beast. What you seem to be suggesting is that we 
 relax the initialiser requirement, not that we ban let x.
 
   Would you have to say:
let ?x;
 
 No way!

What I'm really pushing at here is the throw. Let's are  used for establishing 
and initializing bindings.  From a binding perspective:

let x ;
and
let {x} = {};

are almost exactly the same thing.  They both establish a hoisted uninitialized 
lexical binding for x.  They both delimit the end of the TDZ for x. They both 
supply undefined as the initialization value of x. Why should the second form 
throw when the first doesn't

Or, here is another way to think about it:

  let tmp1 = {};
  let x =  temp1.x;

I don't think anybody is suggesting that the above should throw on the let 
initialization of x.  so why should
   let {x} = {};
which is just a refactoring of the same bindings and accesses.

 
   let {?x} = {}; // x is undefined, no throw
   let {y} = {};  // throws
 
 so, why not:
 
   let {x=undefined} = {};
 
 Again, too verbose

which is why we allow the =undefined to be left out and it don't throw.

What I think is going on in this discussion is a difference between viewing 
destructuuring as a shorthand (relative to the desugaring I used above) for 
initializing bindings and thinking of desugaring as a pattern matching 
operation. Desugaring isn't generalized pattern matching (see,  
http://blog.fogus.me/2011/01/14/pattern-matching-vs-destructuring-electric-boogaloo/
  and http://www.mail-archive.com/es-discuss@mozilla.org/msg11341.html ). This 
is quite clear when you look at what is going on from the perspective of its 
specification.


 and (this is the part I left out, see followup) not deep. How would 
 defaulting work here?
 
  let {x:{y:{z}}} = {};

let {x:{y:{z}} = {y:{z:defaultZ}}} = {};
//note that z is the only bound name above

 
 /be
 

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


Re: destructuring: as patterns?

2012-04-20 Thread Brendan Eich

Allen Wirfs-Brock wrote:
What I'm really pushing at here is the throw. Let's are  used for 
establishing and initializing bindings.  From a binding perspective:


let x ;
and
let {x} = {};

are almost exactly the same thing.  They both establish a hoisted 
uninitialized lexical binding for x.  They both delimit the end of the 
TDZ for x. They both supply undefined as the initialization value of 
x. Why should the second form throw when the first doesn't?


That is a good question.

Lars Hansen spec'ed destructuring for ES4 based on the array-pattern 
destructuring he had implemented in Opera, which does not throw. It 
plucks out undefined, of course, and trying to destructure deeper from 
undefined will throw. This is what we implemented in JS1.7+ in 
SpiderMonkey and Rhino.


Andreas and Dave can make the throwing case better than I, so I will tag 
one or both of them in.


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


Re: destructuring: as patterns?

2012-04-19 Thread Andreas Rossberg
On 19 April 2012 00:45, Allen Wirfs-Brock al...@wirfs-brock.com wrote:

 On Apr 18, 2012, at 2:48 PM, Brendan Eich wrote:

 David Herman wrote:
 *Please*, let's do this right.
 This says to me (what I originally expected) that duplicate property name at 
 any ply in an object pattern should be an early error.

 Anyone disagree?

I wholeheartedly agree.

 I'm not sure that the concern about repeated side-effects is very significant 
 given that any property access can have arbitrary side-effects including 
 adding and removing properties from the RHS object.

I agree with that, too, though my impression is that implementations
already get the exact sequences of such observable steps wrong in
quite a few other cases (I played around with corner cases when doing
proxies). The case above looks easy enough, but in general, the fewer
possible micro observations the better.

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


Re: destructuring: as patterns?

2012-04-19 Thread Allen Wirfs-Brock

On Apr 18, 2012, at 2:48 PM, Brendan Eich wrote:

 David Herman wrote:
 *Please*, let's do this right.
 This says to me (what I originally expected) that duplicate property name at 
 any ply in an object pattern should be an early error.
 
 Anyone disagree?

I got as far as being ready to type into the spec. the first line to implement 
this restriction.  Then my reservations flamed-up. 

If you think of a destructuring declaration as simply a way to provide the 
initial values to a set of declaration is isn't so clear that duplicate 
property names are bogus.  Consider:

//initialize some variable with default objects
let {
 unidentifedAdult: mom,
 unidetifiedAdult: dad, 
 unidentiedChild: brother,
 unidentifiedChild: sister
 } = peopleConstants;

why is this less desirable than:

//initialize some variable with default objects
let mon = peopleConstants.unidentifiedAdult,
  dad = peopleConstants.unidentifiedAdult,
  brother = peopleConstants.unidentifiedChild,
  sister = peopleConstants.unidentifiedChild;
   

The former style is less familiar, but is it really bad enough to disallow at 
the language level?

Disallowing duplicate property names may make sense if you think about 
destructuring in ES declarations as  pattern matching (which it really isn't) 
or a means to break a composite into its constituent parts. But duplicate 
properties as initializers for a set of variables seem quite reasonable. 

Allen


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


Re: destructuring: as patterns?

2012-04-19 Thread David Herman
On Apr 19, 2012, at 2:18 PM, Allen Wirfs-Brock wrote:

 //initialize some variable with default objects
 let {
 unidentifedAdult: mom,
 unidetifiedAdult: dad, 
 unidentiedChild: brother,
 unidentifiedChild: sister
 } = peopleConstants;
 
 why is this less desirable than:
 
 //initialize some variable with default objects
 let mon = peopleConstants.unidentifiedAdult,
  dad = peopleConstants.unidentifiedAdult,
  brother = peopleConstants.unidentifiedChild,
  sister = peopleConstants.unidentifiedChild;

Well, it's rare that you *need* to re-evaluate the dot-pattern. It saves 
typing, repetition (DRY!), side-effects, and running time to evaluate each 
selector only once:

let mom = peopleConstants.unidentifiedAdult,
dad = mom,
brother = peopleConstants.unidentifiedChild,
sister = brother;

And you should be able to do that just fine with nested as-patterns:

let { unidentifiedAdult: mom as dad, unidentifiedChild: sister as brother }

or

let { undentifiedAdult as mom as dad, unidentifiedChild as sister as 
brother }

Dave

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


Re: destructuring: as patterns?

2012-04-18 Thread Brendan Eich
We've supported destructuring for years and no one has asked for this. I 
say YAGNI and when in doubt, leave it out. One can always write two 
destructuring declarations without much repetition:


  let {b} = obj;
  let {x,y} = b;

but of course one would just write

  let {x, y} = obj.b;

in that contrived case.

Main thing is, not having as-patterns is not a big deal based on 
experience with JS1.7+ since 2006 in Mozilla code.


/be

Claus Reinke wrote:

Looking through the destructuring proposal

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

there seems to be no mention of 'as' patterns. In typical pattern
matching constructs (SML, Haskell, ..), 'as' patterns allow to name a 
sub-object while continuing the match for its sub-structures.

For instance, with
   var obj = { a: 0, b: { x: 1, y: 2} };

something like

   let { b: b as {x,y} } = obj

would result in the bindings of b to obj.b, x to obj.b.x, y to obj.b.y.

This avoids needless repetition when both a subobject and its
components need to be extracted. Without 'as', each such case
leads to a separate destructuring assignment

   let { b  } = obj
   let { b: {x,y} } = obj

Shouldn't 'as' patterns be included in destructuring? Or have I
missed an equivalent feature?

Claus

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


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


Re: destructuring: as patterns?

2012-04-18 Thread David Nolen
On Wed, Apr 18, 2012 at 11:26 AM, Brendan Eich bren...@mozilla.org wrote:

 We've supported destructuring for years and no one has asked for this. I
 say YAGNI and when in doubt, leave it out. One can always write two
 destructuring declarations without much repetition:


But who has been using it? Certainly not the general JS development
community.


  let {b} = obj;
  let {x,y} = b;

 but of course one would just write

  let {x, y} = obj.b;

 in that contrived case.

 Main thing is, not having as-patterns is not a big deal based on
 experience with JS1.7+ since 2006 in Mozilla code.

 /be


I've found it quite useful in Clojure/Script and I'm sure folks who have
encountered the feature in the ML derived languages would agree.

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


Re: destructuring: as patterns?

2012-04-18 Thread Herby Vojčík

David Nolen wrote:

On Wed, Apr 18, 2012 at 11:26 AM, Brendan Eich bren...@mozilla.org
mailto:bren...@mozilla.org wrote:

We've supported destructuring for years and no one has asked for
this. I say YAGNI and when in doubt, leave it out. One can always
write two destructuring declarations without much repetition:


But who has been using it? Certainly not the general JS development
community.

  let {b} = obj;
  let {x,y} = b;


Maybe allowing
  let {b, b:{x,y}} = obj;
would be enough. It sort-of comforms to existing syntax as well as 
semantics.




but of course one would just write

  let {x, y} = obj.b;

in that contrived case.

Main thing is, not having as-patterns is not a big deal based on
experience with JS1.7+ since 2006 in Mozilla code.

/be


I've found it quite useful in Clojure/Script and I'm sure folks who have
encountered the feature in the ML derived languages would agree.

David


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


Re: destructuring: as patterns?

2012-04-18 Thread Brendan Eich

Clearly it has utility. Same with callable object protocols ;-).

The debate is always about whether every useful thing must be included, 
when there are long-hands aplenty. This cuts both ways, since 
destructuring is mainly an affordance, syntactic sugar.


The other issue here is standardized grammar and parsing algorithm 
(LR(1) with lookahead and [no LineTerminator here] restrictions). In 
binding forms we can specialize the pattern sub-grammar and IIRC Allen's 
draft ES6 spec does.


In contrast, for general destructuring assignment expressions, the LHS 
must be covered by ObjectLiteral or ArrayLiteral. No 'as' in those, but 
perhaps this just says that 'as', if we add it, is only in the binding 
forms' pattern sub-grammar.


/be

David Nolen wrote:
On Wed, Apr 18, 2012 at 11:26 AM, Brendan Eich bren...@mozilla.org 
mailto:bren...@mozilla.org wrote:


We've supported destructuring for years and no one has asked for
this. I say YAGNI and when in doubt, leave it out. One can always
write two destructuring declarations without much repetition:


But who has been using it? Certainly not the general JS development 
community.


 let {b} = obj;
 let {x,y} = b;

but of course one would just write

 let {x, y} = obj.b;

in that contrived case.

Main thing is, not having as-patterns is not a big deal based on
experience with JS1.7+ since 2006 in Mozilla code.

/be


I've found it quite useful in Clojure/Script and I'm sure folks who 
have encountered the feature in the ML derived languages would agree.


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

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


Re: destructuring: as patterns?

2012-04-18 Thread Brendan Eich

Herby Vojčík wrote:

Maybe allowing
  let {b, b:{x,y}} = obj;
would be enough. It sort-of comforms to existing syntax as well as 
semantics.


That looks like a mistake. ES5 strict mode and so 1JS wants duplicate 
property names in object literals to be errors, so I expect the same for 
duplicate property names in destructuring patterns. Claus's 'as' syntax 
avoids that problem and could even be shortened:


   let { b as {x,y} } = obj

to bind b, x, and y, instead of what was in the o.p.:

   let { b: b as {x,y} } = obj

DRY and EIBTI argue for 'as' and the shorter shorthand.

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


Re: destructuring: as patterns?

2012-04-18 Thread Andreas Rossberg
On 18 April 2012 17:51, Herby Vojčík he...@mailbox.sk wrote:
 Maybe allowing
  let {b, b:{x,y}} = obj;
 would be enough. It sort-of comforms to existing syntax as well as
 semantics.

That won't work for arrays, for example.

I agree that 'as' patterns (and even more so, wildcard patterns) are
basic building blocks that are currently missing. They are extremely
useful in practice, for a very small price -- i.e., they are trivial
to spec and implement, (unlike callable objects, because Brendan just
mentioned those :) ).

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


Re: destructuring: as patterns?

2012-04-18 Thread Irakli Gozalishvili


On Wednesday, 2012-04-18 at 08:26 , Brendan Eich wrote:

 We've supported destructuring for years and no one has asked for this. I 
 say YAGNI and when in doubt, leave it out. One can always write two 
 destructuring declarations without much repetition:
 
 let {b} = obj;
 let {x,y} = b;
 
 but of course one would just write
 
 let {x, y} = obj.b;
 
 in that contrived case.
 
 Main thing is, not having as-patterns is not a big deal based on 
 experience with JS1.7+ since 2006 in Mozilla code.
 

To be honest I've being running into cases where I wished I could match both 
parent and children in some way.  Also, I think that Herby's version is better 
in fact I had to learn that it's illegal. Unless it's too much of a deal I'd 
also like following to work:

let { a, b, b: { x, y } } = object;
 
 
 /be
 
 Claus Reinke wrote:
  Looking through the destructuring proposal
  
  http://wiki.ecmascript.org/doku.php?id=harmony:destructuring
  
  there seems to be no mention of 'as' patterns. In typical pattern
  matching constructs (SML, Haskell, ..), 'as' patterns allow to name a 
  sub-object while continuing the match for its sub-structures.
  For instance, with
  var obj = { a: 0, b: { x: 1, y: 2} };
  
  something like
  
  let { b: b as {x,y} } = obj
  
  would result in the bindings of b to obj.b, x to obj.b.x, y to obj.b.y.
  
  This avoids needless repetition when both a subobject and its
  components need to be extracted. Without 'as', each such case
  leads to a separate destructuring assignment
  
  let { b } = obj
  let { b: {x,y} } = obj
  
  Shouldn't 'as' patterns be included in destructuring? Or have I
  missed an equivalent feature?
  
  Claus
  
  ___
  es-discuss mailing list
  es-discuss@mozilla.org (mailto:es-discuss@mozilla.org)
  https://mail.mozilla.org/listinfo/es-discuss
  
 
 ___
 es-discuss mailing list
 es-discuss@mozilla.org (mailto:es-discuss@mozilla.org)
 https://mail.mozilla.org/listinfo/es-discuss
 
 


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


Re: destructuring: as patterns?

2012-04-18 Thread Herby Vojčík



Herby Vojčík wrote:


Maybe allowing
let {b, b:{x,y}} = obj;
would be enough. It sort-of comforms to existing syntax as well as
semantics.


BTW, if you use var instead of let, if already works out of the box (in 
FF11 firebug console; just tried), so why include as if it already is 
there, albeit in different form?




Herby

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


Re: destructuring: as patterns?

2012-04-18 Thread Irakli Gozalishvili
Another option that feels intuitive to me is: 

let { a, b: ({ x, y }) } = object; 

Parentesis imply that I want both parent and matched children.
Regards
--
Irakli Gozalishvili
Web: http://www.jeditoolkit.com/


On Wednesday, 2012-04-18 at 09:01 , Irakli Gozalishvili wrote:

 
 
 On Wednesday, 2012-04-18 at 08:26 , Brendan Eich wrote:
 
  We've supported destructuring for years and no one has asked for this. I 
  say YAGNI and when in doubt, leave it out. One can always write two 
  destructuring declarations without much repetition:
  
  let {b} = obj;
  let {x,y} = b;
  
  but of course one would just write
  
  let {x, y} = obj.b;
  
  in that contrived case.
  
  Main thing is, not having as-patterns is not a big deal based on 
  experience with JS1.7+ since 2006 in Mozilla code.
  
 
 To be honest I've being running into cases where I wished I could match both 
 parent and children in some way.  Also, I think that Herby's version is 
 better in fact I had to learn that it's illegal. Unless it's too much of a 
 deal I'd also like following to work:
 
 let { a, b, b: { x, y } } = object;
  
  /be
  
  Claus Reinke wrote:
   Looking through the destructuring proposal
   
   http://wiki.ecmascript.org/doku.php?id=harmony:destructuring
   
   there seems to be no mention of 'as' patterns. In typical pattern
   matching constructs (SML, Haskell, ..), 'as' patterns allow to name a 
   sub-object while continuing the match for its sub-structures.
   For instance, with
   var obj = { a: 0, b: { x: 1, y: 2} };
   
   something like
   
   let { b: b as {x,y} } = obj
   
   would result in the bindings of b to obj.b, x to obj.b.x, y to obj.b.y.
   
   This avoids needless repetition when both a subobject and its
   components need to be extracted. Without 'as', each such case
   leads to a separate destructuring assignment
   
   let { b } = obj
   let { b: {x,y} } = obj
   
   Shouldn't 'as' patterns be included in destructuring? Or have I
   missed an equivalent feature?
   
   Claus
   
   ___
   es-discuss mailing list
   es-discuss@mozilla.org (mailto:es-discuss@mozilla.org)
   https://mail.mozilla.org/listinfo/es-discuss
   
  
  ___
  es-discuss mailing list
  es-discuss@mozilla.org (mailto:es-discuss@mozilla.org)
  https://mail.mozilla.org/listinfo/es-discuss
  
  
  
 
 

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


Re: destructuring: as patterns?

2012-04-18 Thread Herby Vojčík

Andreas Rossberg wrote:

On 18 April 2012 17:51, Herby Vojčíkhe...@mailbox.sk  wrote:

Maybe allowing
  let {b, b:{x,y}} = obj;
would be enough. It sort-of comforms to existing syntax as well as
semantics.


That won't work for arrays, for example.


Yeah. :-/
Then either not have it or syntax must be added for it.

I'd say use '=' as in assignment:

  let {b:b={x,y}} = obj;
  let [a,b={x,y},c] = arr;



I agree that 'as' patterns (and even more so, wildcard patterns) are
basic building blocks that are currently missing. They are extremely
useful in practice, for a very small price -- i.e., they are trivial
to spec and implement, (unlike callable objects, because Brendan just
mentioned those :) ).

/Andreas


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


Re: destructuring: as patterns?

2012-04-18 Thread Irakli Gozalishvili


On Wednesday, 2012-04-18 at 09:02 , Herby Vojčík wrote:

  
  
 Herby Vojčík wrote:
   
  Maybe allowing
  let {b, b:{x,y}} = obj;
  would be enough. It sort-of comforms to existing syntax as well as
  semantics.
   
  
  
 BTW, if you use var instead of let, if already works out of the box (in  
 FF11 firebug console; just tried), so why include as if it already is  
 there, albeit in different form?
  

OMG, you're right!!! I could swear it did not worked before as I had 
unsuccessful attempts to use that form. I guess it's ok if Brendan did not knew 
it either :D  
  
  
   
  Herby
 ___
 es-discuss mailing list
 es-discuss@mozilla.org (mailto:es-discuss@mozilla.org)
 https://mail.mozilla.org/listinfo/es-discuss
  
  


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


Re: destructuring: as patterns?

2012-04-18 Thread Andreas Rossberg
On 18 April 2012 18:09, Herby Vojčík he...@mailbox.sk wrote:
 Andreas Rossberg wrote:

 On 18 April 2012 17:51, Herby Vojčíkhe...@mailbox.sk  wrote:

 Maybe allowing
  let {b, b:{x,y}} = obj;
 would be enough. It sort-of comforms to existing syntax as well as
 semantics.


 That won't work for arrays, for example.

 Yeah. :-/

Argument lists are the more interesting case, btw. Layering has to be
an independent and compositional construct.

 Then either not have it or syntax must be added for it.

 I'd say use '=' as in assignment:

  let {b:b={x,y}} = obj;
  let [a,b={x,y},c] = arr;

Unfortunately, that's already taken for default values, 'as' probably
is as good as you can get.

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


Re: destructuring: as patterns?

2012-04-18 Thread Brendan Eich

Herby Vojčík wrote:

Herby Vojčík wrote:


Maybe allowing
let {b, b:{x,y}} = obj;
would be enough. It sort-of comforms to existing syntax as well as
semantics.


BTW, if you use var instead of let, if already works out of the box 
(in FF11 firebug console; just tried), so why include as if it already 
is there, albeit in different form? 


We implemented destructuring years ago to implementor- and user-test ES4 
proposals. They did not forbid duplicates. That's all.


Nothing normative in experimental Firefox implementation features, of 
course. You cite them as already [there] and that's true but it 
doesn't govern what goes into ES6.


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


Re: destructuring: as patterns?

2012-04-18 Thread Brendan Eich

Irakli Gozalishvili wrote:
OMG, you're right!!! I could swear it did not worked before as I had 
unsuccessful attempts to use that form. I guess it's ok if Brendan did 
not knew it either :D


I never said I didn't know, I said ES6 new syntax opts into strict mode 
for things like banning duplicate property names in object literals, so 
this might well apply to duplicate property names in object patterns. I 
still think this may be the case.


ES4-era destructuring was very shallow sugar:

var {x: y} = z; = var y = z.x;

and so on -- with a temporary to avoid evaluating z more than once, and 
z is evaluated first (a left-to-right evaluation order break, but others 
exist, e.g. for-in loop head evaluation order).


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


Re: destructuring: as patterns?

2012-04-18 Thread Allen Wirfs-Brock

On Apr 18, 2012, at 9:29 AM, Brendan Eich wrote:

 Herby Vojčík wrote:
 Herby Vojčík wrote:
 
 Maybe allowing
 let {b, b:{x,y}} = obj;
 would be enough. It sort-of comforms to existing syntax as well as
 semantics.
 
 BTW, if you use var instead of let, if already works out of the box (in FF11 
 firebug console; just tried), so why include as if it already is there, 
 albeit in different form? 
 
 We implemented destructuring years ago to implementor- and user-test ES4 
 proposals. They did not forbid duplicates. That's all.
 
 Nothing normative in experimental Firefox implementation features, of course. 
 You cite them as already [there] and that's true but it doesn't govern what 
 goes into ES6.

But is also works this way according to the ES6 draft spec.  It works with var 
because var allows duplicated declarations:

   var a=1;
   var a=2;
   var a=3;

which, from a declaration perspective isn't really any different from 
   var a=1,a=2,a=3;

However let/const does not:

{   //block level duplicate declaration early error
   let b=1;
   let b=2;
}

or just
  let b=1,b=2 ;   //block level duplicate declaration error

var {b,b:{x,y}} = obj;  //fine because var declaration static semantics don't 
disallow duplicates
{  //avoid any conflicts with the preceeding var
   let {b,b:{x,y}} = obj;  //block level duplicate declaration
}

You might argue that the second b in the destructuring isn't actually 
introducing a binding for b.  However,  syntactically it looks like one and 
that is what the static semantic rule is driven off of.  If we allow that, we 
would also be allowing:
let b=somethingElse;
let {b:{x,y})=obj;

If we want to allow that I'll have to some up with a different way to specify 
the static semantics.

Allen

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


Re: destructuring: as patterns?

2012-04-18 Thread Claus Reinke

I've found it quite useful in Clojure/Script and I'm sure folks who have
encountered the feature in the ML derived languages would agree.


Indeed, all of the pattern-match-supporting functional languages
I've used also supported 'as'-patterns in some form ('var@pat' in 
Haskell,  'var as pat' in SML and variants, 'pat=pat' in Erlang, 
'as pat var' in (little-known) KiR).


Those constructs are hard to search for on github (too many
false matches, though searching for 'as' in Standard ML code
might work), but I find them both useful and popular. 

Some of the usefulness comes from using pattern matching 
as a structural guard (checking the substructure conforms to 
a pattern, then just naming the substructure wholesale). I 
have no experience with a language that only destructures, 
without matching, but I would expect to use as-patterns 
with destructuring as well, increasingly so with upcoming

language constructs.

The main problems seem to be cover-grammars (construct
should be valid expression and pattern), and that the obvious
choice '=' is already taken for default parameters. 

A common generalization of as-patterns are conjunctive 
patterns (as in Successor ML or Erlang), which suggests 
'patpat' or perhaps '(pat,pat)' as alternative syntax.


Claus

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


Re: destructuring: as patterns?

2012-04-18 Thread Brendan Eich

Irakli Gozalishvili wrote:

I'm sorry for inappropriate comment.


No worries!

My citing Mozilla's experimental JS1.7+ implementation/user-testing 
experience is informative, not nearly definitive or anywhere near 
normative; somewhat convincing when something is popular, best when we 
learned from a negative result that's clear (no confounders).


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


Re: destructuring: as patterns?

2012-04-18 Thread Herby Vojčík



Allen Wirfs-Brock wrote:

On Apr 18, 2012, at 9:29 AM, Brendan Eich wrote:


Herby Vojčík wrote:

Herby Vojčík wrote:

Maybe allowing
let {b, b:{x,y}} = obj;
would be enough. It sort-of comforms to existing syntax as well as
semantics.

BTW, if you use var instead of let, if already works out of the box (in FF11 
firebug console; just tried), so why include as if it already is there, albeit 
in different form?

We implemented destructuring years ago to implementor- and user-test ES4 
proposals. They did not forbid duplicates. That's all.

Nothing normative in experimental Firefox implementation features, of course. You cite 
them as already [there] and that's true but it doesn't govern what goes into 
ES6.


But is also works this way according to the ES6 draft spec.  It works with var 
because var allows duplicated declarations:

var a=1;
var a=2;
var a=3;

which, from a declaration perspective isn't really any different from
var a=1,a=2,a=3;

However let/const does not:

{   //block level duplicate declaration early error
let b=1;
let b=2;
}

or just
   let b=1,b=2 ;   //block level duplicate declaration error

var {b,b:{x,y}} = obj;  //fine because var declaration static semantics don't 
disallow duplicates
{  //avoid any conflicts with the preceeding var
let {b,b:{x,y}} = obj;  //block level duplicate declaration
}


But the 'let {b:b, b:{x,y}}' is different beast, it is:
{
  let b = {x:1,y:2};
  let {x,y} = {x:1,y:2};
}
and there is, imo, no conflict in this.




 You might argue that the second b in the destructuring isn't actually
 introducing a binding for b.  However,  syntactically it looks like
 one and that is what the static semantic rule is driven off of.  If
 we allow that, we would also be allowing:
  let b=somethingElse;
  let {b:{x,y})=obj;

 If we want to allow that I'll have to some up with a different way to

But, AFAICT, this should be allowed. The 'b:' from destructuring is 
different from 'b' from let. Is the previous code disallowed in current 
state?


 specify the static semantics.

 Allen

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


Re: destructuring: as patterns?

2012-04-18 Thread Herby Vojčík



Herby Vojčík wrote:

But, AFAICT, this should be allowed. The 'b:' from destructuring is
Sorry for caps, I don't know why I write it that way... I somehow 
automatically held shift because it is an acronym, probably.

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


Re: destructuring: as patterns?

2012-04-18 Thread Allen Wirfs-Brock

On Apr 18, 2012, at 9:49 AM, Allen Wirfs-Brock wrote:
 ...
 var {b,b:{x,y}} = obj;  //fine because var declaration static semantics don't 
 disallow duplicates
 {  //avoid any conflicts with the preceeding var
   let {b,b:{x,y}} = obj;  //block level duplicate declaration
 }
 
 You might argue that the second b in the destructuring isn't actually 
 introducing a binding for b.  However,  syntactically it looks like one and 
 that is what the static semantic rule is driven off of.  If we allow that, we 
 would also be allowing:
let b=somethingElse;
let {b:{x,y})=obj;
 
 If we want to allow that I'll have to some up with a different way to specify 
 the static semantics.

False alarm! Actually the above isn't correct.  The current spec draft actually 
does allow
   let {b,b:{x,y}};
but would issue an early error on
let {b,b:{x:b,y}};

It is all in the static semantics production Bound Names in 12.2.4

The BoundNames of
 let {b}=obj
is [b]

The BoundNames of
   let {b:x} = obj
is [x]

The Bound Names of 
   let {b,b:{x,y}
is [b,x,y]

The Bound Names of 
   let {b,b:{x:b,y}}; 
is [b,b,y] and produces a duplicate declaration early error.  For a var 
declaration it would be allowd.

Sorry for the confusion.  I should have read my own spec. more carefully.

Allen




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


Re: destructuring: as patterns?

2012-04-18 Thread Allen Wirfs-Brock

On Apr 18, 2012, at 10:59 AM, Herby Vojčík wrote:

 ...
 But, AFAICT, this should be allowed. The 'b:' from destructuring is different 
 from 'b' from let. Is the previous code disallowed in current state?

You're right, I was wrong.  See my followup response.

Thanks,

Allen

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


Re: destructuring: as patterns?

2012-04-18 Thread Brendan Eich

Allen Wirfs-Brock wrote:
False alarm! Actually the above isn't correct.  The current spec draft 
actually does allow

   let {b,b:{x,y}};


Nice -- is this sufficient to avoid 'as'?

For array patterns we would need to allow property assignments in array 
literals:


  let [b, 0:{x,y}];

This was proposed at one point, IIRC, but a while ago.

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


Re: destructuring: as patterns?

2012-04-18 Thread Allen Wirfs-Brock

On Apr 18, 2012, at 11:42 AM, Brendan Eich wrote:

 Allen Wirfs-Brock wrote:
 False alarm! Actually the above isn't correct.  The current spec draft 
 actually does allow
   let {b,b:{x,y}};
 
 Nice -- is this sufficient to avoid 'as'?
 
 For array patterns we would need to allow property assignments in array 
 literals:
 
  let [b, 0:{x,y}];
 
 This was proposed at one point, IIRC, but a while ago.

It was also suggested that we allow iterators/generators to supply the  
initialization values to array destructurings.  This currently isn't in the 
draft spec. and I think it would introduce some fairly significant 
specification and practical complications (eg, rest bindings and open-ended 
generators).

However, the reason I bring it up it that if we ever do want to add that sort 
of generative initialization value feature, it would seem to have significant 
interactions with the explicit array property designator feature shown above.  
The most future proof thing for right now would be to do neither.

Allen







 
 /be
 

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


Re: destructuring: as patterns?

2012-04-18 Thread Brendan Eich

Allen Wirfs-Brock wrote:

For array patterns we would need to allow property assignments in array 
literals:
  
let [b, 0:{x,y}] = ...;
  
  This was proposed at one point, IIRC, but a while ago.


Of course, one could destructure like so:

  let {0: b, 0: {x, y}} = ...;



It was also suggested that we allow iterators/generators to supply the  
initialization values to array destructurings.  This currently isn't in the 
draft spec. and I think it would introduce some fairly significant 
specification and practical complications (eg, rest bindings and open-ended 
generators).


Destructuring patterns should be static. I don't see a conflict if we 
stick to this rule, but given the ability to use an object pattern, I 
don't see a need for the array literal element label syntax either.


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


Re: destructuring: as patterns?

2012-04-18 Thread Herby Vojčík

Brendan Eich wrote:

Allen Wirfs-Brock wrote:

For array patterns we would need to allow property assignments in
array literals:
  let [b, 0:{x,y}] = ...;
  This was proposed at one point, IIRC, but a while ago.


Of course, one could destructure like so:

let {0: b, 0: {x, y}} = ...;



It was also suggested that we allow iterators/generators to supply the
initialization values to array destructurings. This currently isn't in
the draft spec. and I think it would introduce some fairly significant
specification and practical complications (eg, rest bindings and
open-ended generators).


Destructuring patterns should be static. I don't see a conflict if we
stick to this rule, but given the ability to use an object pattern, I
don't see a need for the array literal element label syntax either.


As was already pointed out, problems are not only _array_ 
destructurings, but more argument list destructrings, where if you want 
to destructure 0-th argument both as b and as {x,y}, you would need 
something like that, since you already are inside list, you cannot opt 
for object.


(but if it is not the problem, I'd gladly see at least the object 
double-destructure-same-field in ES6. It is not violating the no double 
property names of strict mode since the assignment goes the other way)



/be


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


Re: destructuring: as patterns?

2012-04-18 Thread Brendan Eich

Herby Vojčík wrote:
As was already pointed out, problems are not only _array_ 
destructurings, but more argument list destructrings, where if you 
want to destructure 0-th argument both as b and as {x,y}, you would 
need something like that, since you already are inside list, you 
cannot opt for object.


Why can't you use an object pattern? Array pattern is just shorthand for 
object pattern.


(but if it is not the problem, I'd gladly see at least the object 
double-destructure-same-field in ES6. It is not violating the no 
double property names of strict mode since the assignment goes the 
other way) 


Yes, Allen covered this five messages back in the thread. There's no 
problem because the set of bindings has no dups. Destructuring as dual 
of object or array literals threw me (even me, a big fan of duality -- 
but only briefly ;-).


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


Re: destructuring: as patterns?

2012-04-18 Thread Herby Vojčík

Brendan Eich wrote:

Herby Vojčík wrote:

As was already pointed out, problems are not only _array_
destructurings, but more argument list destructrings, where if you
want to destructure 0-th argument both as b and as {x,y}, you would
need something like that, since you already are inside list, you
cannot opt for object.


Why can't you use an object pattern? Array pattern is just shorthand for
object pattern.


Not implicitly, not inside the argument list itself.
You would need to write

  function foo (...args) {
let {0:b, 0:{x,y}, foo, bar, baz} = args;
...
  }

but between 'foo (' and ') {' you must play by the rules of array 
destructuring, where '0:' is not allowed.



/be


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


Re: destructuring: as patterns?

2012-04-18 Thread Allen Wirfs-Brock

On Apr 18, 2012, at 1:45 PM, Herby Vojčík wrote:

 Brendan Eich wrote:
 Allen Wirfs-Brock wrote:
 For array patterns we would need to allow property assignments in
 array literals:
   let [b, 0:{x,y}] = ...;
   This was proposed at one point, IIRC, but a while ago.
 
 Of course, one could destructure like so:
 
 let {0: b, 0: {x, y}} = ...;
 
 
 It was also suggested that we allow iterators/generators to supply the
 initialization values to array destructurings. This currently isn't in
 the draft spec. and I think it would introduce some fairly significant
 specification and practical complications (eg, rest bindings and
 open-ended generators).
 
 Destructuring patterns should be static. I don't see a conflict if we
 stick to this rule, but given the ability to use an object pattern, I
 don't see a need for the array literal element label syntax either.
 
 As was already pointed out, problems are not only _array_ destructurings, but 
 more argument list destructrings, where if you want to destructure 0-th 
 argument both as b and as {x,y}, you would need something like that, since 
 you already are inside list, you cannot opt for object.


function f({b},...rest) {
   let {x,y}=b;
   ...
}

doesn't seem like too much of a burden


 
 (but if it is not the problem, I'd gladly see at least the object 
 double-destructure-same-field in ES6. It is not violating the no double 
 property names of strict mode since the assignment goes the other way)

It's in the spec. draft.  There aren't actually object literals so the 
duplicate property name rules don't apply.  It's the duplicate lexical binding 
rules that are in play, but only on the target names, not the property 
selectors.

Allen


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


Re: destructuring: as patterns?

2012-04-18 Thread Brendan Eich

Herby Vojčík wrote:

  function foo (...args) {
let {0:b, 0:{x,y}, foo, bar, baz} = args;
...
  }


That's not right, if you go the long way round you want:

  function foo (...args) {
let {0:b, 0:{x,y}, 1:foo, 2:bar, 3:baz} = args;
...
  }

but as Allen just suggested, the right way to do it is:

  function foo ({b}, ...args) {
let {x,y} = b;
let [foo, bar, baz] = args;
...
  }


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


Re: destructuring: as patterns?

2012-04-18 Thread David Herman
Agreed. This is easy to spec and implement, highly composable (it fits neatly 
into the algebra of destructuring patterns everywhere, as opposed to just in 
object property-name positions), has no problems with side effects, and does 
not violate restrictions that IINM strict mode is supposed to ban (repeated 
property names in literals).

The repeated property-name thing is a hack. It does not Say What You Mean (it's 
a total surprise). It is not composable (it only works for property names, not 
for array indices).

Worst of all, it will trigger getters twice:

 let { b, b: { x, y } } = { get b() { console.log(BOO!); return 17 } }
BOO!
BOO!

But if that's the only way to do it, then if you want to destructure a getter, 
you will be forced not to use the hack, and to bind a temporary variable and do 
a second destructuring on a second line.

*Please*, let's do this right. There's no reason to introduce hacks. I'm open 
to various syntaxes, but I think `as` is nice especially because it could work 
well for import/export syntax too. Lots of people complain about confusion over 
which is the bound name and which is the label. IINM, we could allow both:

let { x: x as y } = obj;

and

let { x as y } = obj;

which would be a nice idiom for making it more obvious that x is the label and 
y is the binding. Then this would be especially nice for imports:

import { x as y } from X;

Dave

On Apr 18, 2012, at 8:57 AM, Andreas Rossberg wrote:

 On 18 April 2012 17:51, Herby Vojčík he...@mailbox.sk wrote:
 Maybe allowing
  let {b, b:{x,y}} = obj;
 would be enough. It sort-of comforms to existing syntax as well as
 semantics.
 
 That won't work for arrays, for example.
 
 I agree that 'as' patterns (and even more so, wildcard patterns) are
 basic building blocks that are currently missing. They are extremely
 useful in practice, for a very small price -- i.e., they are trivial
 to spec and implement, (unlike callable objects, because Brendan just
 mentioned those :) ).
 
 /Andreas
 ___
 es-discuss mailing list
 es-discuss@mozilla.org
 https://mail.mozilla.org/listinfo/es-discuss

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


Re: destructuring: as patterns?

2012-04-18 Thread David Nolen
On Wed, Apr 18, 2012 at 5:35 PM, David Herman dher...@mozilla.com wrote:

 Agreed. This is easy to spec and implement, highly composable (it fits
 neatly into the algebra of destructuring patterns everywhere, as opposed to
 just in object property-name positions), has no problems with side effects,
 and does not violate restrictions that IINM strict mode is supposed to ban
 (repeated property names in literals).

 The repeated property-name thing is a hack. It does not Say What You Mean
 (it's a total surprise). It is not composable (it only works for property
 names, not for array indices).

 Worst of all, it will trigger getters twice:

 let { b, b: { x, y } } = { get b() { console.log(BOO!); return 17 }
 }
BOO!
BOO!

 But if that's the only way to do it, then if you want to destructure a
 getter, you will be forced not to use the hack, and to bind a temporary
 variable and do a second destructuring on a second line.

 *Please*, let's do this right. There's no reason to introduce hacks. I'm
 open to various syntaxes, but I think `as` is nice especially because it
 could work well for import/export syntax too. Lots of people complain about
 confusion over which is the bound name and which is the label. IINM, we
 could allow both:

let { x: x as y } = obj;

 and

let { x as y } = obj;

 which would be a nice idiom for making it more obvious that x is the label
 and y is the binding. Then this would be especially nice for imports:

import { x as y } from X;

 Dave


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


Re: destructuring: as patterns?

2012-04-18 Thread Brendan Eich

David Herman wrote:

*Please*, let's do this right.
This says to me (what I originally expected) that duplicate property 
name at any ply in an object pattern should be an early error.


Anyone disagree?

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


Re: destructuring: as patterns?

2012-04-18 Thread Allen Wirfs-Brock

On Apr 18, 2012, at 2:48 PM, Brendan Eich wrote:

 David Herman wrote:
 *Please*, let's do this right.
 This says to me (what I originally expected) that duplicate property name at 
 any ply in an object pattern should be an early error.
 
 Anyone disagree?


I'm not sure that the concern about repeated side-effects is very significant 
given that any property access can have arbitrary side-effects including adding 
and removing properties from the RHS object. 

Regardless, making duplicate property names an early error is easy enough and 
seems to eliminate a potential point of confusion.

I'm not necessarily sold on as yet. 

Allen








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