# proposal extensions (Was: Re: Sep 26 meeting notes)
On Sep 29, 2011, at 9:03 PM, Sean Eagan wrote:
On Mon, Sep 26, 2011 at 7:27 PM, Waldemar Horwat <waldemar at google.com> wrote:
Reached consensus on the following # proposal:
before an object literal seals the object
before a propoerty makes that property nonconfigurable and nonwritable.
All method properties are nonenumerable. All value properties are enumerable.
I like it! Here are some extensions to consider:
to seal, ## to freeze:
Too much chicken-scratching. It's tempting but I think we should focus on one funny prefix char per special form and make it count, optimize for the common case. Uncommon cases use APIs.
##{ p: 1, m() {} }
non-configurable, ## non-writable as well:
{ #p: 1, ##m() {} }
These do regularize things from the consensus Waldemar recorded: you need one # to seal, two to freeze, whether property or object. But the consensus we reached was aimed at common use-cases. The idea is that sealing an object is more common than freezing it, while freezing a property is more common than sealing it.
Extend to other literal forms ala <|:
#[a, b, c] #function(){...} #/\d+/ #1 #"" #true
We don't want # as a prefix for value types. I did propose in HoMD that we support #(a,b){...} but that fell to completion leak concerns and the desire of some for shorter syntax without freezing/joining (so without # prefix in this scenario, but (a){} is ambiguous with current JS if you insert a newline between the ) and the {).
Compose with <|:
null <| ##{...} // record-esque null <| ##[...] // tuple-esque
These are too long if common, they want the HoMD single # prefixing.
Include tuple-isms for #[], ##[]:
holes => syntax error length cannot be greater than 2^32 - 1
Sure, this carries over for all tuple proposals (I assert). But we want shorter syntax, no doubled funny chars, no verbose regularity at the expense of common cases being relatively overlong.
On Thu, Sep 29, 2011 at 3:30 PM, Brendan Eich <brendan at mozilla.com> wrote:
The idea is that sealing an object is more common than freezing it, while freezing a property is more common than sealing it.
I was thinking freezing an object is more common than sealing, but # for freeze, ## for seal looks backwards anyways.
We don't want # as a prefix for value types.
Agree, but why not for at least Arrays if not Functions and Regexps as well ?
Probably shouldn't have <| for value types either then right ?
Compose with <|:
null <| ##{...} // record-esque null <| ##[...] // tuple-esque
These are too long if common, they want the HoMD single # prefixing.
Agree. I think composition with <| still is needed though for consistency with non-#-prefixed literals if nothing else.
Include tuple-isms for #[], ##[]:
holes => syntax error length cannot be greater than 2^32 - 1
Sure, this carries over for all tuple proposals (I assert). But we want shorter syntax, no doubled funny chars, no verbose regularity at the expense of common cases being relatively overlong.
So if #[] is added as shorthand for a sealed Array, do you agree that #[0,,1] should be a syntax error ?
Thanks, Sean Eagan
On Sep 29, 2011, at 10:07 PM, Sean Eagan wrote:
On Thu, Sep 29, 2011 at 3:30 PM, Brendan Eich <brendan at mozilla.com> wrote:
The idea is that sealing an object is more common than freezing it, while freezing a property is more common than sealing it.
I was thinking freezing an object is more common than sealing, but # for freeze, ## for seal looks backwards anyways.
Yes, if we allow doubling then obviously two is colder than one ;-). But should we allow doubling? I was arguing against, on the basis that one ugly character is enough for the common case. This led to the irregular but use-case oriented (we think -- you could be right, we haven't measured and not enough code uses ES5 freeze and seal) consensus Waldemar reported.
We don't want # as a prefix for value types.
Agree, but why not for at least Arrays if not Functions and Regexps as well ?
What about the function's .prototype object? Would that be sealed or frozen too? Perhaps not.
How about lastIndex updating on a #/.../g regexp?
Probably shouldn't have <| for value types either then right ?
That's right, they are not objects.
Compose with <|:
null <| ##{...} // record-esque null <| ##[...] // tuple-esque
These are too long if common, they want the HoMD single # prefixing.
Agree. I think composition with <| still is needed though for consistency with non-#-prefixed literals if nothing else.
It should work -- at first it looks like evaluation order will result in <| cloning the sealed (at least) RHS and then try to update its [[Prototype]], but that seems legal. [[Extensible]] = false does not prevent internal properties from changing. Should check with Allen on this, though.
Include tuple-isms for #[], ##[]:
holes => syntax error length cannot be greater than 2^32 - 1
Sure, this carries over for all tuple proposals (I assert). But we want shorter syntax, no doubled funny chars, no verbose regularity at the expense of common cases being relatively overlong.
So if #[] is added as shorthand for a sealed Array, do you agree that #[0,,1] should be a syntax error ?
I thought I just said so ("Sure, this carries over for all tuple proposals" in reply to your "holes => syntax error").
On Sep 29, 2011, at 11:03 PM, Brendan Eich wrote:
Probably shouldn't have <| for value types either then right ?
That's right, they are not objects.
Or hrm, now that you mention it Allen did spec these, and they get wrapped implicitly (string "foo" becomes new String("foo"), etc.).
I still find implicit primitive wrapping where the wrapper is observable raises my hackles. Anyone feel the same?
On Sep 29, 2011, at 3:03 PM, Brendan Eich wrote:
On Sep 29, 2011, at 10:07 PM, Sean Eagan wrote:
...
So if #[] is added as shorthand for a sealed Array, do you agree that #[0,,1] should be a syntax error ?
I thought I just said so ("Sure, this carries over for all tuple proposals" in reply to your "holes => syntax error").
If sparse arrays are believed to have general utility then why wouldn't a initializer form for immutable sparse arrays also have utility? Perhaps because anything you might reasonably write as an literal initializer is too small for sparseness to matter? But I'm not so sure that argument applies to mechanically generated code.
On Thu, Sep 29, 2011 at 3:10 PM, Brendan Eich <brendan at mozilla.com> wrote:
I still find implicit primitive wrapping where the wrapper is observable raises my hackles. Anyone feel the same?
I do. In ES5/strict code, nothing implicitly creates a reachable wrapper. Put another way, if all your code is strict and you never explicitly create a wrapper, you can ignore the existence of wrappers. The one remaining bit of semantics that is currently explained in terms of wrappers is how, for example,
"foo".chatAt(1)
looks up "charAt" on String.prototype. We can easily rephrase these explanations to avoid mentioning the wrapper concept.
Let's not backslide on this important bit of progress. No implicit creation of reachable wrappers in ES-next, please!
On Sep 29, 2011, at 3:10 PM, Brendan Eich wrote:
On Sep 29, 2011, at 11:03 PM, Brendan Eich wrote:
Probably shouldn't have <| for value types either then right ?
That's right, they are not objects.
Or hrm, now that you mention it Allen did spec these, and they get wrapped implicitly (string "foo" becomes new String("foo"), etc.).
I included them so we didn't have special cases for <|. Any literal form can appear on the RHS. My thinking was that there is some value to such consistency although I could also argue that saying (foo <| 1) is much more likely a mistake rather than a valid use case and hence it would be more beneficial to just make it an error.
Was also trying to get rid of "non-subclassable" built-ins. Allowing non-object to the right <| takes care of this for the wrapper built-ins. However, I could also address this in the same way that I plan fix Date. Just make their [[PrimativeValue]] a private named property. Then let ExtendedNumber = Number <| function(val) {super.constructor(val)} could would work for sublcassing Number, String, and Boolean as well as for Date.
I still find implicit primitive wrapping where the wrapper is observable raises my hackles. Anyone feel the same?
Yes, but we have them and I don't seen anyway to eliminate them.
On Sep 29, 2011, at 11:34 PM, Allen Wirfs-Brock wrote:
I still find implicit primitive wrapping where the wrapper is observable raises my hackles. Anyone feel the same?
Yes, but we have them and I don't seen anyway to eliminate them.
AFAIK, "we have them" is false in ES5 -- implicitly created primitive wrappers do not escape, and engines do optimize them away.
With <| you could argue you're not leaking the wrapper, rather a clone it, but that's easily optimized to avoid the clone, and in any case the hackle-raising thing is the implicit primitive wrapper "escaping". Maybe I'm overreacting, though.
On Sep 29, 2011, at 3:44 PM, Brendan Eich wrote:
AFAIK, "we have them" is false in ES5 -- implicitly created primitive wrappers do not escape, and engines do optimize them away.
Yup, you are MarkM are correct about that. The implicit ones don't escape if you keep inside strict mode.
With <| you could argue you're not leaking the wrapper, rather a clone it, but that's easily optimized to avoid the clone, and in any case the hackle-raising thing is the implicit primitive wrapper "escaping". Maybe I'm overreacting, though.
I don't see foo <| "abc" as creating an implicit wrapping. I see it as explicit wrapping as you have to create a wrapper in order to set [[Prototype]] to foo.
But, of limited utility. Syntactic restrictions are cheaper to implement than not very useful semantics. However, the ore such syntactic restrictions we have the more the language feels like a patchwork of special cases.
On Sep 30, 2011, at 12:20 AM, Allen Wirfs-Brock wrote:
I don't see foo <| "abc" as creating an implicit wrapping. I see it as explicit wrapping as you have to create a wrapper in order to set [[Prototype]] to foo.
Yes, it's not quite so bad in this light.
But, of limited utility. Syntactic restrictions are cheaper to implement than not very useful semantics. However, the ore such syntactic restrictions we have the more the language feels like a patchwork of special cases.
Yeah. Not sure how I feel now, weighing wrapper-hackles vs. universality of <|.
On 11:59 AM, Brendan Eich wrote:
I still find implicit primitive wrapping where the wrapper is observable raises my hackles. Anyone feel the same? /be
It's like you're reading my mind.
On Mon, Sep 26, 2011 at 7:27 PM, Waldemar Horwat <waldemar at google.com> wrote:
I like it! Here are some extensions to consider:
to seal, ## to freeze:
##{ p: 1, m() {} }
non-configurable, ## non-writable as well:
{ #p: 1, ##m() {} }
Extend to other literal forms ala <|:
#[a, b, c] #function(){...} #/\d+/ #1 #"" #true
Compose with <|:
null <| ##{...} // record-esque null <| ##[...] // tuple-esque
Include tuple-isms for #[], ##[]:
holes => syntax error
length cannot be greater than 2^32 - 1
Thanks, Sean Eagan