Re: How primitive are Symbols? Bignums? etc

2013-07-23 Thread Brendan Eich

Brendan Eich wrote:
I think this goes in the wrong direction. 'new' implies heap 
allocation and reference-type semantics. Value objects do not have 
either.


Previously, from Claude Pache in April: 
https://mail.mozilla.org/pipermail/es-discuss/2013-April/029750.html




The idea is simply to avoid adding footguns for new features, even if we can't 
remove the existing ones.

Regarding the issue discussed here, let me elaborate:

Until now, `new Primitive`, where `Primitive` is `Number`, `String` or 
`Boolean` is, in practice, not a problem, because you never need to create a 
new number, string or boolean that way. (You can use `Primitive` as a function 
for typecasting, but it is not felt as the same thing as creating a new value.) 
Things are different with symbols, so the `new Symbol` footgun is practically a 
new type of footgun.

Note also that `new Date`, `new RegExp`, `new Map`, etc., work as intuitively expected, 
and, if I have correctly followed the last discussions, `function* gen() { /* ... */}; 
myIterator = new gen` (meaning: I want to get a *new* iterator from that generator 
function) would also work.

I do agree that special-casing should be avoided. Therefore, I think we should 
make a rule: `new Primitive` should throw for primitive types, except for 
legacy numbers, booleans and strings (Don't Break The Web) for which it is not 
a real issue.

—Claude



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


Re: How primitive are Symbols? Bignums? etc

2013-07-22 Thread Allen Wirfs-Brock

On Jul 20, 2013, at 4:14 PM, Brendan Eich wrote:

 Allen Wirfs-Brock wrote:
 I don't know,
   'new Foo(args)'  create a mutable Foo object
   'Foo(args)'   create an immutable Foo object
 isn't an idiom that we've had before
 
 Relax mutable in the first comment and remove object from the second 
 comment and we have relevant precedent:
 
  new Boolean(false) // create an extensible wrapper object
  Boolean(false) // unobservably return false or create a new false
 
  new Number(42) // create an extensible wrapper object
  Number(42) // unobservably return the argument or create a new 42
 
  new String('hi') // create an extensible wrapper object
  String('hi') // unobservably return argument or create new 'hi'

Except that:
   new Boolean(false) === false //false   similarly String and Number
   Boolean(false) === false  //truesimilarly String and Number

so the difference between wrappers and primitive values is observable.  It 
isn't observable whether there is a single or multiple heap element for each 
logically === equivalent primitive value/ 

 
 The point about value objects to attend to here: their identity based on 
 frozen contents.
 
 (Why are they objects? Because everything's an object except for the legacy 
 primitives.)
 
 The truthiness of new Boolean(false) is a problem for numeric value objects, 
 which my int64/uint64 prototype addresses by including boolean test among the 
 operators that can be defined for value objects.
 
 There's no perfect precedent. Falsy 'new Boolean(false)' was rejected in ES1 
 standardization because it implied a conversion from object to boolean, which 
 might happen more than once for a given sub-expression due to || and  being 
 value-preserving.

I think the truthiness of 'new Boolean(false)'  is a one-off special case that 
we shouldn't worry about as a precedent.  I don't believe there are equivalent 
issues with String or Number.
 
 What's more important given JS's legacy than precedent: serving users by 
 considering use-cases for value objects.
 
 The use-case for mutable structs and vectors is clear from today's objects 
 used for points, homogenous coordinates, rectangles, shapes, etc.
 
 The use-case for immutable structs and vectors is clear from SIMD work under 
 way in TC39, in JS extensions, in Dart.
 
 The propose to serve both use-cases by specifying that 'new T(x)' constructs 
 a mutable value object while calling 'T(x)' makes an immutable one aims to 
 avoid clumsy alternative static method factories or differently named 
 wrappers.

This would be a new idiom, and one that wouldn't necessarily apply to 
non-structured objects. This is a refactoring hazard if someone starts with a 
normal object and decides to re-implement as a struct-based object.

Since this is a new idiom, other new idioms could be considered.  For example:

new T(x) //create a mutable instance:
T.value(x) //create an immutable instance

bikesheding starts here...

 
 Debatable, but showing class BigNum extends ValueObject doesn't decide the 
 question. We are introducing new semantics, starting with by-value identity 
 rather than by-reference, and extending to operators and literals. We can't 
 do this just using ES6 'class' syntax as-is.
 
 /be
 

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


Re: How primitive are Symbols? Bignums? etc

2013-07-22 Thread Brendan Eich

Allen Wirfs-Brock wrote:

On Jul 20, 2013, at 4:14 PM, Brendan Eich wrote:

Allen Wirfs-Brock wrote:

I don't know,
   'new Foo(args)'  create a mutable Foo object
   'Foo(args)'   create an immutable Foo object
isn't an idiom that we've had before

Relax mutable in the first comment and remove object from the second 
comment and we have relevant precedent:

  new Boolean(false) // create an extensible wrapper object
  Boolean(false) // unobservably return false or create a new false

  new Number(42) // create an extensible wrapper object
  Number(42) // unobservably return the argument or create a new 42

  new String('hi') // create an extensible wrapper object
  String('hi') // unobservably return argument or create new 'hi'


Except that:
new Boolean(false) === false //false   similarly String and Number
Boolean(false) === false  //truesimilarly String and Number

so the difference between wrappers and primitive values is observable.


Sure, legacy crap we must not copy into new types. Right?


  It isn't observable whether there is a single or multiple heap element for 
each logically === equivalent primitive value/


I explicitly addressed truthy ToObject later. Did you miss it? Boolean 
is a terrible precedent for value objects, which must include 0 when 
numeric (int64, uint64, bignum, decimal, rational, etc.).



The point about value objects to attend to here: their identity based on frozen 
contents.

(Why are they objects? Because everything's an object except for the legacy 
primitives.)

The truthiness of new Boolean(false) is a problem for numeric value objects, 
which my int64/uint64 prototype addresses by including boolean test among the 
operators that can be defined for value objects.

There's no perfect precedent. Falsy 'new Boolean(false)' was rejected in ES1 
standardization because it implied a conversion from object to boolean, which might 
happen more than once for a given sub-expression due to || and  being 
value-preserving.


I think the truthiness of 'new Boolean(false)'  is a one-off special case that 
we shouldn't worry about as a precedent.  I don't believe there are equivalent 
issues with String or Number.


Sure:  is falsy but new String() is truthy; 0 and NaN are falsy but 
new Number(0), e.g., is truthy.


Ok, so a three-off special case-set we should not imitate with value 
objects in general. Right?



What's more important given JS's legacy than precedent: serving users by 
considering use-cases for value objects.

The use-case for mutable structs and vectors is clear from today's objects used 
for points, homogenous coordinates, rectangles, shapes, etc.

The use-case for immutable structs and vectors is clear from SIMD work under 
way in TC39, in JS extensions, in Dart.

The propose to serve both use-cases by specifying that 'new T(x)' constructs a 
mutable value object while calling 'T(x)' makes an immutable one aims to avoid 
clumsy alternative static method factories or differently named wrappers.


This would be a new idiom, and one that wouldn't necessarily apply to 
non-structured objects. This is a refactoring hazard if someone starts with a 
normal object and decides to re-implement as a struct-based object.


If you are arguing that constructors must not do something other than 
construct when called, let's have that discussion separately. It's a 
general fly in your refactoring ointment -- and has been forever in JS.



Since this is a new idiom, other new idioms could be considered.  For example:

new T(x) //create a mutable instance:
T.value(x) //create an immutable instance

bikesheding starts here...


I thought about such things but it's not only a matter of bikeshedding. 
Usability comes first and is not all about aeshetics. Say we add int64. 
To convert to it, must I call


  int64.value(x)

and not

  int64(x)

merely to preserve some object-idiom idiocy that no one wants for int64, 
namely:


  new int64(x) // throws, does not make a mutable object

?

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


Re: How primitive are Symbols? Bignums? etc

2013-07-22 Thread Allen Wirfs-Brock

On Jul 22, 2013, at 3:25 PM, Brendan Eich wrote:

 Allen Wirfs-Brock wrote:
 On Jul 20, 2013, at 4:14 PM, Brendan Eich wrote:
 Allen Wirfs-Brock wrote:

right, to all of the above.

 
 This would be a new idiom, and one that wouldn't necessarily apply to 
 non-structured objects. This is a refactoring hazard if someone starts with 
 a normal object and decides to re-implement as a struct-based object.
 
 If you are arguing that constructors must not do something other than 
 construct when called, let's have that discussion separately. It's a general 
 fly in your refactoring ointment -- and has been forever in JS.

Yes, I agree that is a separate discussion.  We already have constructors that 
do different things and it remains possible to define them using ES6 class 
declarations regardless of whether or not it ends up being considered a pattern 
or an anti=pattern.

 
 Since this is a new idiom, other new idioms could be considered.  For 
 example:
 
 new T(x) //create a mutable instance:
 T.value(x) //create an immutable instance
 
 bikesheding starts here...
 
 I thought about such things but it's not only a matter of bikeshedding. 
 Usability comes first and is not all about aeshetics. Say we add int64. To 
 convert to it, must I call
 
  int64.value(x)
 
 and not
 
  int64(x)
 
 merely to preserve some object-idiom idiocy that no one wants for int64, 
 namely:
 
  new int64(x) // throws, does not make a mutable object

My concern is that the pattern 

new T(x) //create a mutable instance:
T(x) //create an immutable instance

is a new one that we really don't reflect current usage in either the 
specification or in the wild, eg RegExp, Date.  Also Map/Set as currently 
implemented in FF, but that is also a seperate (but related) discussion.

I agree that int64(x)  is nice for int64 (although I would expect such scalar 
values to me immutable regardless of how you create them).

It is also appealing for structs but not necessarily for objects which means it 
is hard to know when you see  'new Foo(x)' vs 'Foo(x)' whether the 
mutable/immutable pattern applies or not for Foo.

Presumably Structs are subclassable.  But, where I see the real problem is if 
we wanted to support class declarations that use Structs as their private 
state. We would still want such classes to be subclassable and super calls of 
the constructor would still be needed for initialize both mutable and immutable 
subclasses.

It seems like the real usability challenge is finding a scheme that is pleasant 
for both scalars and potentially subclass able objects.

Here another stab at the int64 use case.

let int64 = (...args) = Object.freeze(new Builtins.Int64(...args));
  // int64 is a non-constructable function. It is the normal way of creating 
Int64 instances
  // Builtins.Int64 is (at least conceptually) a normal constructor that uses 
'new' to create instances but would seldom be directly used in that manner
  // For Int64 the Object.freeze may actually be redundant but wouldn't 
necessarily be so if the pattern was extended to structured data.

Allen

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


Re: How primitive are Symbols? Bignums? etc

2013-07-22 Thread Brendan Eich

Allen Wirfs-Brock wrote:

My concern is that the pattern

new T(x) //create a mutable instance:
T(x) //create an immutable instance

is a new one that we really don't reflect current usage in either the 
specification or in the wild, eg RegExp, Date.


Those are definitely not value objects. More's the pity, perhaps, but 
too late.


Also Map/Set as currently implemented in FF, but that is also a 
seperate (but related) discussion.


Definitely not value objects.

I agree that int64(x)  is nice for int64 (although I would expect such 
scalar values to me immutable regardless of how you create them).


The intuition (supported by other languages) is that 'new' 
heap-allocates something mutable by default. Stack allocation and 
(implicit or not) coercion does not. C++ is not far from the mark here, 
but IIRC C# is similar.


It is also appealing for structs but not necessarily for objects which 
means it is hard to know when you see  'new Foo(x)' vs 'Foo(x)' 
whether the mutable/immutable pattern applies or not for Foo.


Indeed, structs are new in this sense. I don't think T.value(x) helps, 
though.


Presumably Structs are subclassable.  But, where I see the real 
problem is if we wanted to support class declarations that use Structs 
as their private state. We would still want such classes to be 
subclassable and super calls of the constructor would still be needed 
for initialize both mutable and immutable subclasses.


That's a challenge to rise to ;-).

It seems like the real usability challenge is finding a scheme that is 
pleasant for both scalars and potentially subclass able objects.


Here another stab at the int64 use case.

let int64 = (...args) = Object.freeze(new Builtins.Int64(...args));
  // int64 is a non-constructable function. It is the normal way of 
creating Int64 instances
  // Builtins.Int64 is (at least conceptually) a normal constructor 
that uses 'new' to create instances but would seldom be directly used 
in that manner
  // For Int64 the Object.freeze may actually be redundant but 
wouldn't necessarily be so if the pattern was extended to structured data.


I think this goes in the wrong direction. 'new' implies heap allocation 
and reference-type semantics. Value objects do not have either.


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


Re: How primitive are Symbols? Bignums? etc

2013-07-22 Thread Allen Wirfs-Brock

On Jul 22, 2013, at 6:30 PM, Brendan Eich wrote:

 Allen Wirfs-Brock wrote:
 ...
 
 I agree that int64(x)  is nice for int64 (although I would expect such 
 scalar values to me immutable regardless of how you create them).
 
 The intuition (supported by other languages) is that 'new' heap-allocates 
 something mutable by default. Stack allocation and (implicit or not) coercion 
 does not. C++ is not far from the mark here, but IIRC C# is similar.
 

pretty much agree, except for the mutable part.  There is no reason that a heap 
allocated entity can't be immutable, by default  if it is appropriate for the 
abstraction. Similar,it is certainly possible to design a language with stack 
allocated mutable structs.

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


Re: How primitive are Symbols? Bignums? etc

2013-07-22 Thread Brendan Eich

Allen Wirfs-Brock wrote:

On Jul 22, 2013, at 6:30 PM, Brendan Eich wrote:


Allen Wirfs-Brock wrote:

...
I agree that int64(x)  is nice for int64 (although I would expect such scalar 
values to me immutable regardless of how you create them).

The intuition (supported by other languages) is that 'new' heap-allocates 
something mutable by default. Stack allocation and (implicit or not) coercion 
does not. C++ is not far from the mark here, but IIRC C# is similar.



pretty much agree, except for the mutable part.  There is no reason that a heap 
allocated entity can't be immutable, by default  if it is appropriate for the 
abstraction.


Ok, but you are picking a nit.


  Similar,it is certainly possible to design a language with stack allocated 
mutable structs.


Let's not.

On the heap-allocated immutable bit, you'd need to say something extra 
to opt in. That's JS!


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


Re: How primitive are Symbols? Bignums? etc

2013-07-20 Thread Brendan Eich

Allen Wirfs-Brock wrote:

I don't know,
   'new Foo(args)'  create a mutable Foo object
   'Foo(args)'   create an immutable Foo object
isn't an idiom that we've had before


Relax mutable in the first comment and remove object from the second 
comment and we have relevant precedent:


  new Boolean(false) // create an extensible wrapper object
  Boolean(false) // unobservably return false or create a new false

  new Number(42) // create an extensible wrapper object
  Number(42) // unobservably return the argument or create a new 42

  new String('hi') // create an extensible wrapper object
  String('hi') // unobservably return argument or create new 'hi'

The point about value objects to attend to here: their identity based on 
frozen contents.


(Why are they objects? Because everything's an object except for the 
legacy primitives.)


The truthiness of new Boolean(false) is a problem for numeric value 
objects, which my int64/uint64 prototype addresses by including boolean 
test among the operators that can be defined for value objects.


There's no perfect precedent. Falsy 'new Boolean(false)' was rejected in 
ES1 standardization because it implied a conversion from object to 
boolean, which might happen more than once for a given sub-expression 
due to || and  being value-preserving.


What's more important given JS's legacy than precedent: serving users by 
considering use-cases for value objects.


The use-case for mutable structs and vectors is clear from today's 
objects used for points, homogenous coordinates, rectangles, shapes, etc.


The use-case for immutable structs and vectors is clear from SIMD work 
under way in TC39, in JS extensions, in Dart.


The propose to serve both use-cases by specifying that 'new T(x)' 
constructs a mutable value object while calling 'T(x)' makes an 
immutable one aims to avoid clumsy alternative static method factories 
or differently named wrappers.


Debatable, but showing class BigNum extends ValueObject doesn't decide 
the question. We are introducing new semantics, starting with by-value 
identity rather than by-reference, and extending to operators and 
literals. We can't do this just using ES6 'class' syntax as-is.


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


Re: How primitive are Symbols? Bignums? etc

2013-07-19 Thread Allen Wirfs-Brock

On Jul 19, 2013, at 7:07 AM, Andreas Rossberg wrote:

 
 
 How do we move forward? Unfortunately, I won't make it to the meeting
 next week...

At this point, the spec. is in a state where it is fairly easy to either stick 
with symbols as exotic objects or switch to symbols as a primitive type with a 
wrapper class. 

From a language design perspective, I think the implications WRT future value 
types is the most important consideration and that is what we need to explore. 
Are we going to have to provide a mechanism for user defined primitive types + 
wrappers if we go that route?

I understand that in V8 you have cross-cutting implementation issues with 
symbols as objects.  However there are also likely to be cross-cutting 
implementation issues for others relating to adding primitive types. I don't 
think either of these implementation perspectives should be the primary 
decision criteria.  Instead, we should focus on the conceptual language design 
level.  Which path will be better for the language and its users in the long 
run.

Allen 



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


Re: How primitive are Symbols? Bignums? etc

2013-07-19 Thread Allen Wirfs-Brock

On Jul 19, 2013, at 6:51 AM, Andreas Rossberg wrote:

 On 18 July 2013 17:53, Brendan Eich bren...@mozilla.com wrote:
 
 
 3. Value object approach: no Symbol wrapper, typeof says symbol, spec
 treats symbol as exotic object per latest draft.
 
 The implementation cost of every new exotic object is fairly
 substantial in a modern VM, due to cross-cutting. That's at least my
 experience from implementing the ones currently on the ES6 radar,
 proxies and symbols (not even considering optimisations). We should be
 _very_ conservative about introducing more of these than absolutely
 necessary.

You have to be able to support Proxy exotic objects so, I don't see why you 
won't use that exact mechanism for Symbol objects. In other words, use a 
self-hosted Proxy-based implementation for Symbol objects. The  MOP operations 
on Symbol exotic objects in all cases either throw an exception or return some 
predetermined result such as undefined or false. These operations have little 
application utility (other than object model consistency) so there should be 
any perf. concerns about using a Proxy to define the symbol MOP behavior.  Of 
course, you would still want to optimize for their use as property keys.

While there are a few standard exotic objects that clearly need optimization, I 
would hope that most future ones could reasonably be implemented using Proxy.  
After all, that was one of the primary motivations for Proxy.  If Proxies are 
only toys then we have wasted an lot of time on them. 

Allen

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


Re: How primitive are Symbols? Bignums? etc

2013-07-19 Thread Allen Wirfs-Brock

On Jul 19, 2013, at 6:54 AM, Andreas Rossberg wrote:

 On 18 July 2013 18:16, Allen Wirfs-Brock al...@wirfs-brock.com wrote:
 
 
 In fact, the
 conclusion/resolution doesn't even say that Symbols will be primitive
 values.  All of the bullet items listed there are apply equally to either
 symbols as primitives or symbols as exotic objects. The current (and
 previous, I believe) spec. draft reflects those explicit conclusions.
 
 Ah, come on. That was the main point of the proposal, and it's
 explicit at the beginning of the notes. It was clear to everybody in
 the room, including you. You went to adopt it in the spec, after all.

Oh, I agree with that.  I was just making a point that the minutes aren't 
always a very reliable record of a discussion.  And that's not meant as a 
criticism of Rick or Arv or anybody else who takes notes.  I couldn't do it 
half as well as they do.

Allen

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


Re: How primitive are Symbols? Bignums? etc

2013-07-19 Thread Rick Waldron
On Fri, Jul 19, 2013 at 11:48 AM, Allen Wirfs-Brock
al...@wirfs-brock.comwrote:


 On Jul 19, 2013, at 6:54 AM, Andreas Rossberg wrote:

  On 18 July 2013 18:16, Allen Wirfs-Brock al...@wirfs-brock.com wrote:
 
 
  In fact, the
  conclusion/resolution doesn't even say that Symbols will be primitive
  values.  All of the bullet items listed there are apply equally to
 either
  symbols as primitives or symbols as exotic objects. The current (and
  previous, I believe) spec. draft reflects those explicit conclusions.
 
  Ah, come on. That was the main point of the proposal, and it's
  explicit at the beginning of the notes. It was clear to everybody in
  the room, including you. You went to adopt it in the spec, after all.

 Oh, I agree with that.  I was just making a point that the minutes aren't
 always a very reliable record of a discussion.  And that's not meant as a
 criticism of Rick or Arv or anybody else who takes notes.  I couldn't do it
 half as well as they do.


Apologies for any ambiguity in the notes—I should've reiterated in the
Conclusion/Resolution, but I distinctly remember that Andreas's proposal to
make Symbols a new primitive was indeed accepted.

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


Re: How primitive are Symbols? Bignums? etc

2013-07-19 Thread Allen Wirfs-Brock

On Jul 19, 2013, at 9:31 AM, Andreas Rossberg wrote:

 On 19 July 2013 18:17, Allen Wirfs-Brock al...@wirfs-brock.com wrote:
 You have to be able to support Proxy exotic objects so, I don't see why you 
 won't use that exact mechanism for Symbol objects.
 
 Because they are different. There is no useful unified mechanism for
 exotic objects, at least no efficient one. Every new form of exotic
 object will be a new special case. As I said, the nice spec-level MOP
 abstraction is largely irrelevant at the implementation level.
 
 I'm speaking from V8 experience here, but I would be surprised if the
 situation is much different in other modern VMs.
 
 In other words, use a self-hosted Proxy-based implementation for Symbol 
 objects. The  MOP operations on Symbol exotic objects in all cases either 
 throw an exception or return some predetermined result such as undefined or 
 false.
 
 You can't use proxies for symbols -- they are special in parts of the
 semantics (and that includes their wrappers, if we want them to be
 special, too). And I doubt that you will be able to use them for other
 exotic objects we might come up with (e.g. value objects would have
 special equality behaviour that proxies can't simulate).

Note that I was talking about the symbols as exotic objects path, not the 
symbols as new primitive type path so there would be no wrappers.  In what way 
are the object semantics of exotic symbol objects special such that  couldn't 
be represented via a Proxy handler?  

The special behavior of symbols appears, to me to be all ready of operations 
that are not part of the MOP. Hashing for property lookup, comparison during 
lookup, etc. I still don't see why the Proxy MOP dispatch mechanism wouldn't be 
perfectly adequate for their generally pointless application to symbols. 

 
 Even if you could, I highly doubt that proxy performance will ever be
 up for the task, at least not for an implementation cost that isn't
 much higher than the special casing.

Like I said, I don't see how this is a performance issue for Symbols exotic 
objects because the MOP operations are never important for them.

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


Re: How primitive are Symbols? Bignums? etc

2013-07-19 Thread Dean Landolt
On Fri, Jul 19, 2013 at 12:31 PM, Andreas Rossberg rossb...@google.comwrote:

 On 19 July 2013 18:17, Allen Wirfs-Brock al...@wirfs-brock.com wrote:
  You have to be able to support Proxy exotic objects so, I don't see why
 you won't use that exact mechanism for Symbol objects.

 Because they are different. There is no useful unified mechanism for
 exotic objects, at least no efficient one. Every new form of exotic
 object will be a new special case. As I said, the nice spec-level MOP
 abstraction is largely irrelevant at the implementation level.

 I'm speaking from V8 experience here, but I would be surprised if the
 situation is much different in other modern VMs.

  In other words, use a self-hosted Proxy-based implementation for Symbol
 objects. The  MOP operations on Symbol exotic objects in all cases either
 throw an exception or return some predetermined result such as undefined or
 false.

 You can't use proxies for symbols -- they are special in parts of the
 semantics (and that includes their wrappers, if we want them to be
 special, too).



I'm curious how symbols differ semantically from null-prototype, empty,
frozen objects? I can't think of any substantive differences other the
power to act as object keys (and some seemingly insignificant details like
toString behavior). If that's truly the case, wouldn't it be a lot easier
to just allow any null-prototype, empty, frozen object to have the
object-key capability?

For consistency Object.prototype.toString could even be specified to return
something along the lines of [object Symbol] for values which fulfill this
criteria (a breaking change, but only very slightly -- I can't imagine this
affecting code in the wild).



 And I doubt that you will be able to use them for other
 exotic objects we might come up with (e.g. value objects would have
 special equality behaviour that proxies can't simulate).

 Even if you could, I highly doubt that proxy performance will ever be
 up for the task, at least not for an implementation cost that isn't
 much higher than the special casing.

 /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: How primitive are Symbols? Bignums? etc

2013-07-19 Thread Brandon Benvie

On 7/19/2013 9:52 AM, Allen Wirfs-Brock wrote:

Even if you could, I highly doubt that proxy performance will ever be
up for the task, at least not for an implementation cost that isn't
much higher than the special casing.

Like I said, I don't see how this is a performance issue for Symbols exotic 
objects because the MOP operations are never important for them.


Indeed, a largely self-hosted implementation of Symbol could look like:


const UNDEFINED = () = {};
const TRUE = () = true;
const FALSE = () = false;
const NULL = () = null;
const ARRAY = () = [];

const symbolHandler = {
  getOwnPropertyDescriptor: UNDEFINED,
  getOwnPropertyNames: ARRAY,
  getPrototypeOf: NULL,
  setPrototypeOf: FALSE,
  defineProperty: FALSE,
  deleteProperty: TRUE,
  freeze: TRUE,
  seal: TRUE,
  preventExtensions: TRUE,
  isFrozen: TRUE,
  isSealed: TRUE,
  isExtensible: FALSE,
  has: FALSE,
  hasOwn: FALSE,
  get: UNDEFINED
  set: FALSE,
  enumerate: ARRAY,
  keys: ARRAY,
};

function Symbol(name){
  const symbol = new Proxy({}, symbolHandler);
  %MarkAsSymbol(symbol, name);
  return symbol;
}


It's rare (and pointless) to perform MOP operations on a Symbol because 
they're inert. There's no need to optimize those. The optimization that 
has to happen is deciding when something is a symbol for the purposes of 
property lookup.

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


Re: How primitive are Symbols? Bignums? etc

2013-07-19 Thread Dean Landolt
On Fri, Jul 19, 2013 at 2:48 PM, Andreas Rossberg rossb...@google.comwrote:

 On 19 July 2013 19:41, Dean Landolt d...@deanlandolt.com wrote:
  I'm curious how symbols differ semantically from null-prototype, empty,
  frozen objects?

 They differ in that the extra cruft that's needed to represent random
 objects is a complete waste of space on them. Also, there is a
 performance benefit if they can share a common representation with
 strings, so that you don't need a case distinction in every place
 dealing with property names (e.g. wrt to hashing).

 In any case, I don't want to focus exclusively on the implementation.
 I also think that there are obvious semantic and usability reasons for
 making them as similar to existing types as possible (esp strings,
 which they are closely related to).



I completely agree that it makes sense to keep them as similar as possible
to existing types. in fact, I'm just extending your argument a bit, but
picking one nit: symbols are more like objects than strings.

Since they're only useful as keys what matters for our purposes is their
unique, unforgeable identity, which they share in common with any other
object. The only thing they have in common specifically with strings (and
not other primitives) is the special capability to act as an object key.
But again, what matters here is *how* -- their intensional identity is
crucially different than the extensional identity of strings.

There's no reason I know of why this capability of being able to key an
object property couldn't be extended from strings to objects -- provided,
of course, that the objects are completely stateless and frozen. Isn't this
the very definition of a Symbol? A symbol is just a stateless frozen object
-- do we really care what it toString's to? Once an object is stateless and
frozen it can't be anything but stateless and frozen, thus any stateless
frozen object could just as well be a symbol. Sure, the language can spec a
Symbol constructor to make it easier to mint stateless frozen objects, but
is there any difference?

So if your ends is to keep symbols as close as possible to existing types I
think suspect this approach does you one better -- it makes Symbols a
perfect subtype of one of the built-ins -- just not the one you were
thinking :)


 I can't think of any substantive differences other the power
  to act as object keys (and some seemingly insignificant details like
  toString behavior). If that's truly the case, wouldn't it be a lot
 easier to
  just allow any null-prototype, empty, frozen object to have the
 object-key
  capability?

 Unfortunately, making other objects into keys would break existing
 code that assumes a ToString conversion for those.



Perhaps. I know it'd be breaking -- perhaps I'm not being imaginative
enough about the kind of code it could break. I doubt I've written code
that would break on this, but I've *definitely* written code that will
break if the range from typeof is expended.

Regardless, I doubt it'd even be useful to hack the spec for a special
toString. Is there any reason a symbol's toString couldn't return [object
Object]? if this is the only drawback to normalizing symbols in the way I
suggest, it seems like a small price when all the other quibbles being
debated melt away.
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: How primitive are Symbols? Bignums? etc

2013-07-19 Thread Tab Atkins Jr.
On Fri, Jul 19, 2013 at 1:48 PM, Andreas Rossberg rossb...@google.com wrote:
 On 19 July 2013 19:41, Dean Landolt d...@deanlandolt.com wrote:
 I'm curious how symbols differ semantically from null-prototype, empty,
 frozen objects?

 They differ in that the extra cruft that's needed to represent random
 objects is a complete waste of space on them. Also, there is a
 performance benefit if they can share a common representation with
 strings, so that you don't need a case distinction in every place
 dealing with property names (e.g. wrt to hashing).

 In any case, I don't want to focus exclusively on the implementation.
 I also think that there are obvious semantic and usability reasons for
 making them as similar to existing types as possible (esp strings,
 which they are closely related to).

 I can't think of any substantive differences other the power
 to act as object keys (and some seemingly insignificant details like
 toString behavior). If that's truly the case, wouldn't it be a lot easier to
 just allow any null-prototype, empty, frozen object to have the object-key
 capability?

 Unfortunately, making other objects into keys would break existing
 code that assumes a ToString conversion for those.

Thus Dean's suggestion of only allowing it for null-prototype, frozen,
empty objects.  These are exceedingly rare in the first place, because
you have to jump through several hoops to create them.

(I don't think I like Dean's suggestion, but I don't want incorrect
assumptions getting thrown about.)

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


Re: How primitive are Symbols? Bignums? etc

2013-07-19 Thread Brandon Benvie
Another factor I haven't seen mentioned but that I think is important is 
introducing a new primitive that has no literal form is another rough 
edge/inconsistency that will be confusing. Having to use a factory to 
make them makes me want to use `new` with that factory. But using `new` 
should always return an object from the builtins, ergo Symbols objects 
(whether wrappers or not) should be usable (either through 
auto-unwrapping or no primitive form) or some inconsistency or another 
will be introduced.

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


Re: How primitive are Symbols? Bignums? etc

2013-07-19 Thread Allen Wirfs-Brock

On Jul 19, 2013, at 11:37 AM, Andreas Rossberg wrote:

 On 19 July 2013 18:52, Allen Wirfs-Brock al...@wirfs-brock.com wrote:
 On Jul 19, 2013, at 9:31 AM, Andreas Rossberg wrote:
 You can't use proxies for symbols -- they are special in parts of the
 semantics (and that includes their wrappers, if we want them to be
 special, too). And I doubt that you will be able to use them for other
 exotic objects we might come up with (e.g. value objects would have
 special equality behaviour that proxies can't simulate).
 
 Note that I was talking about the symbols as exotic objects path, not the 
 symbols as new primitive type path so there would be no wrappers.  In what 
 way are the object semantics of exotic symbol objects special such that  
 couldn't be represented via a Proxy handler?
 
 The special behavior of symbols appears, to me to be all ready of operations 
 that are not part of the MOP. Hashing for property lookup, comparison during 
 lookup, etc. I still don't see why the Proxy MOP dispatch mechanism wouldn't 
 be perfectly adequate for their generally pointless application to symbols.
 
 That would at least require some way of distinguishing ordinary
 proxies from those internal symbol proxies, so that they can cheaply
 be recognised as symbols. Alas, a separate proxy type, or extra
 internal info you need to store in every proxy.

Whether proxies are used or not, you still need to do make that distinction. An 
identify test on the proxy handler or target reference might be one cheap way 
to identify them.  There are undoubtably many other possibilities. 

 
 At the same time, proxies already come with a space overhead that you
 don't want to pay for symbols.
 
 No, I think that proxies would be total overkill here, and yet not
 even sufficient.

This little subthread started with with you wanting to minimize the complex of 
another implementation level exotic object type.  This is one way to do it. 
There are space and time trade-offs to be made but it definitely is not an 
absurd approach to consider.

Allen


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


Re: How primitive are Symbols? Bignums? etc

2013-07-19 Thread Brendan Eich

Brandon Benvie wrote:
Another factor I haven't seen mentioned but that I think is important 
is introducing a new primitive that has no literal form is another 
rough edge/inconsistency that will be confusing. Having to use a 
factory to make them makes me want to use `new` with that factory. But 
using `new` should always return an object from the builtins, ergo 
Symbols objects (whether wrappers or not) should be usable (either 
through auto-unwrapping or no primitive form) or some inconsistency or 
another will be introduced.


Allen's proposal from March, for Symbol and (I think) all scalar value 
objects, would be for new to throw.


Vector and struct value objects would be mutable if new'ed, immutable 
copy-semantics value otherwise.


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


Re: How primitive are Symbols? Bignums? etc

2013-07-19 Thread Allen Wirfs-Brock

On Jul 19, 2013, at 6:02 PM, Brendan Eich wrote:

 Brandon Benvie wrote:
 Another factor I haven't seen mentioned but that I think is important is 
 introducing a new primitive that has no literal form is another rough 
 edge/inconsistency that will be confusing. Having to use a factory to make 
 them makes me want to use `new` with that factory. But using `new` should 
 always return an object from the builtins, ergo Symbols objects (whether 
 wrappers or not) should be usable (either through auto-unwrapping or no 
 primitive form) or some inconsistency or another will be introduced.
 
 Allen's proposal from March, for Symbol and (I think) all scalar value 
 objects, would be for new to throw.

No, that wasn't what I was trying to say in March.  I was saying that if 
symbols were going to be non-object primitive values without a corresponding 
wrapper class and 'Symbol( )') was a function that produced such values, then 
'new Symbol( )' should throw because because 'new' is the object creation 
operator and there would be no such objects to create.

On the other hand if symbols were exotic objects then 'new Symbols( )' would be 
the natural way to create them.  We might choose to also let 'Symbol( )' act as 
a factory function for creating symbols even though I argue that using 
constructors as callable factories should be an ES6 anti-pattern. 

If symbol are primitive values with a corresponding Symbol wrapper class 
(Andreas' preference) then for consistency with Number/String/Boolean 'new 
Symbol(sym)' assuming 'sym' is a primitive symbol value should create a wrapper 
object for 'sym'.   Probably we would choose to make 'Symbol()' be a generator 
(normal English usage, not funciton*) of symbol values.  That, however, is 
somewhat of a departure from the meaning of 'Number()', 'String()', or 
'Boolean()'  each of which returns a specific value (0, , false) rather than 
generating new unique values

For, symbols I argue that the second alternative is the least anomalous because 
it threats  symbols almost exactly as if defined as:

class Symbol extends null {
   static [@@create] () {
 return Object.freeze( %tagAsSymbol({__proto__: null}));
   }
   constructor() {
  if (!%hasSymbolTag(this)) return new Symbol();
   }
}

Maybe this analysis can be extended to other value objects.  I'm in the 'new' 
is the preferred way to create objects camp.  However, applying the same logic 
used for symbols is not all that straightforward.  Consider if you are 
implementing such a class in ES, for example  (very rough):

class BigNum extends ValueObject {
   constructor (value) {
   setPrivateState(this, new DigitVector(value)); //assume that DigitVector 
handles various numeric/sting types (including DigitVectors) as arguments
}
...
plusOperator (rhs) {
return new BigNum(getPrivateState(this).addDigits(getPrivateState(rhs));
}
...
}

You still need a way to instantiate the internal state that represents the 
value.

 
 Vector and struct value objects would be mutable if new'ed, immutable 
 copy-semantics value otherwise.

I don't know,
   'new Foo(args)'  create a mutable Foo object
   'Foo(args)'   create an immutable Foo object
isn't an idiom that we've had before

Allen





 
 /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: How primitive are Symbols? Bignums? etc

2013-07-18 Thread Claude Pache
IIUC, the problem with symbols-as-primitives is that, on one hand, wrapper 
objects are not wanted, but, on the other hand, getting rid of wrappers leads 
to complications.

My suggestion is to allow wrapper objects to exist in the spec, but to 
completely hide them from the user by doing an implicit unwrapping whenever 
applicable. Thus, for any primitive class `P` (such as `Symbol`, `Bignum`), 
except for legacy ones (`Number`, `Boolean` and `String`).

* `new P` produces an unwrapped value;
* `p = Object(p)` becomes a no-op;
* `Object.defineProperty`, Object.getPrototypeOf`, etc., return an unwrapped 
value when applicable;
* plus some further details I've forgotten.

(Technically, I think naively that it suffices to define an 
`UnwrapIfNonLegacyPrimitive()` abstract operation and to apply it in correct 
places.)

Moreover, in order to make primitives look more like objects, some adjustments 
could be done:

* `instanceof` could wrap its LHS if it is a primitive value instead of 
throwing an error, so that tests like `s instanceof Symbol` would work;
* Wrappers should be frozen at creation, so that things like `s.foo = 17` or 
`Object.setPrototypeOf(s, bar)` would fail noisily (at least in strict mode);
* etc.

—Claude


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


Re: How primitive are Symbols? Bignums? etc

2013-07-18 Thread Brendan Eich

Andreas Rossberg wrote:

On 17 July 2013 21:10, Brendan Eichbren...@mozilla.com  wrote:

We should not add more such user-facing pain if we can avoid it -- even if
that means more implementor-facing pain (remember Mr. Spock's Kobayashi Maru
solution ;-).


An inconsistency between strings and symbols is both a user-facing and
an implementor-facing pain.


Strings and symbols are quite different according to typeof and 
behavior, in any proposal or implementation. How does providing a 
wrapper which when used throws -- unlike ({}[new String('x')]) which 
does not throw -- help make symbol like string in any user-facing sense?


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


Re: How primitive are Symbols? Bignums? etc

2013-07-18 Thread Brendan Eich

Andreas Rossberg wrote:

On 18 July 2013 01:09, Brendan Eichbren...@mozilla.com  wrote:

Brandon Benvie wrote:

On 7/17/2013 4:02 PM, Brandon Benvie wrote:

And this is how it currently works in the V8 implementation. The first
thing I did testing it looked like:

 var s = new Symbol();
 var x = {};
 x[s] = 'test';

I was surprised to find that this threw an error instead of doing the (to
me) obvious thing.

(And to clarify, it throws on line 3, not line 1)

This is nuts.


May I humbly remind you that we explicitly discussed and decided this
at the March meeting?


If it's nuts now, it was nuts in March :-P.


  I actually would have preferred if 'new Symbol'
worked, and that was what V8 implemented before the meeting.


You are right, I see this in the March 14 meeting notes. So I'm pleading 
temporary insanity. We'll have to reestablish consensus. I will refrain 
from more (self-)analysis ;-).


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


Re: How primitive are Symbols? Bignums? etc

2013-07-18 Thread Brendan Eich

Brendan Eich wrote:

  I actually would have preferred if 'new Symbol'
worked, and that was what V8 implemented before the meeting.


And just to be clear, what you implemented before the meeting, symbol 
primitive with Symbol auto-wrapper and no throw on ({}[new Symbol]) 
seems better.


I think the issue some of us are having is auto-wrapping rather than 
taking the value objects approach. If we are doing value objects as 
discussed, then for symbols we have a choice: follow the string pattern, 
or follow the int64, bignum, etc. proposal.


Of course value objects are not in ES6, and you may disagree on that 
strawman's eschewing of auto-wrappers (I can't tell). Both of these 
objections, whatever the ultimate disposition of value objects, seem to 
me to be legitimate cause to favor the string pattern in ES6. But we 
could be suffering from path dependence in taking this 
shorter-term-conservative approach.


A separate issue with the string pattern: we do not want symbol objects 
converting by toString, which motivated throwing instead. Claude just 
suggested auto-unwrapping when used as a property name. I'll follow up 
in reply to that sub-thread.


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


Re: How primitive are Symbols? Bignums? etc

2013-07-18 Thread Brendan Eich

Andreas Rossberg wrote:

On 18 July 2013 14:22, Claude Pacheclaude.pa...@gmail.com  wrote:

IIUC, the problem with symbols-as-primitives is that, on one hand, wrapper 
objects are not wanted, but, on the other hand, getting rid of wrappers leads 
to complications.

My suggestion is to allow wrapper objects to exist in the spec, but to 
completely hide them from the user by doing an implicit unwrapping whenever 
applicable. Thus, for any primitive class `P` (such as `Symbol`, `Bignum`), 
except for legacy ones (`Number`, `Boolean` and `String`).

* `new P` produces an unwrapped value;
* `p =  Object(p)` becomes a no-op;
* `Object.defineProperty`, Object.getPrototypeOf`, etc., return an unwrapped 
value when applicable;
* plus some further details I've forgotten.


I'm not sure I understand what this would achieve. AFAICS, it is
observably equivalent to making Symbol an object, no? So it would have
the exact same implications.


What implications do you object to, though. We have trouble making 
symbols like unforgeable strings. They must have distinct typeof-type -- 
a symbol can't be string according to typeof. We must avoid any 
wrapper converting to a string when used as a property name, per your


ARB: The current spec has a toString for implicit conversion, which 
makes it too easy to convert the symbol to a string accidentally without 
realizing.


from the March meeting notes. This leaves only three choices AFAICT:

1. Primitive symbol with Symbol auto-wrapper that throws when used as 
property name, the March consensus.


2. (1) but with Claude's suggestion: auto-unwrap on use of Symbol as 
property name.


3. Value object approach: no Symbol wrapper, typeof says symbol, spec 
treats symbol as exotic object per latest draft.


Is there a 4th choice?

/be


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


Re: How primitive are Symbols? Bignums? etc

2013-07-18 Thread Allen Wirfs-Brock

On Jul 18, 2013, at 5:22 AM, Claude Pache wrote:

 IIUC, the problem with symbols-as-primitives is that, on one hand, wrapper 
 objects are not wanted, but, on the other hand, getting rid of wrappers leads 
 to complications.
 
 My suggestion is to allow wrapper objects to exist in the spec, but to 
 completely hide them from the user by doing an implicit unwrapping whenever 
 applicable. Thus, for any primitive class `P` (such as `Symbol`, `Bignum`), 
 except for legacy ones (`Number`, `Boolean` and `String`).
 
 * `new P` produces an unwrapped value;
 * `p = Object(p)` becomes a no-op;
 * `Object.defineProperty`, Object.getPrototypeOf`, etc., return an unwrapped 
 value when applicable;
 * plus some further details I've forgotten.
 
 (Technically, I think naively that it suffices to define an 
 `UnwrapIfNonLegacyPrimitive()` abstract operation and to apply it in correct 
 places.)
 
 Moreover, in order to make primitives look more like objects, some 
 adjustments could be done:
 
 * `instanceof` could wrap its LHS if it is a primitive value instead of 
 throwing an error, so that tests like `s instanceof Symbol` would work;
 * Wrappers should be frozen at creation, so that things like `s.foo = 17` or 
 `Object.setPrototypeOf(s, bar)` would fail noisily (at least in strict mode);
 * etc.
 

This is very similar to the the point I arrived at in trying to edit 
wrapper-less primitive symbols into the spec.  However,  I quickly realized 
that all these special cases are the equivalent of simply specifying symbols as 
exotic objects. 

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


Re: How primitive are Symbols? Bignums? etc

2013-07-18 Thread Allen Wirfs-Brock

On Jul 18, 2013, at 8:09 AM, Brendan Eich wrote:

 Andreas Rossberg wrote:
 On 18 July 2013 01:09, Brendan Eichbren...@mozilla.com  wrote:
 Brandon Benvie wrote:
 On 7/17/2013 4:02 PM, Brandon Benvie wrote:
 And this is how it currently works in the V8 implementation. The first
 thing I did testing it looked like:
 
 var s = new Symbol();
 var x = {};
 x[s] = 'test';
 
 I was surprised to find that this threw an error instead of doing the (to
 me) obvious thing.
 (And to clarify, it throws on line 3, not line 1)
 This is nuts.
 
 May I humbly remind you that we explicitly discussed and decided this
 at the March meeting?
 
 If it's nuts now, it was nuts in March :-P.
 
  I actually would have preferred if 'new Symbol'
 worked, and that was what V8 implemented before the meeting.
 
 You are right, I see this in the March 14 meeting notes. So I'm pleading 
 temporary insanity. We'll have to reestablish consensus. I will refrain from 
 more (self-)analysis ;-).
 

No, you just need to read carefully, I remember that this is just a summary of 
the discussion, not literal quotes,  and not everything is captured:

AWB: Symbol is a factory that creates symbols, new Symbol creates instance of 
the wrapper class. (same as Number)

BE: Value objects allow new

AWB: I can define the Symbol[@@create] to throw


I'm pretty sure that as part of the first statement I also said that 'new 
Symbol' should not create a primitive value because that would violate the 
wrapper object pattern. 
The Synbol[@@create]] comment is another way of saying 'new Symbol' should 
throw.

There is nothing following this in the Symbols section of the minutes that 
address whether or not there are Symbol wrappers. My take-away from the meeting 
 was we would try to do Symbols as as a primitive, with a factory object named 
'Symbol', but no user visible wrapper instances.  I don't see anything in the 
minutes that says otherwise.  In fact, the conclusion/resolution doesn't even 
say that Symbols will be primitive values.  All of the bullet items listed 
there are apply equally to either symbols as primitives or symbols as exotic 
objects. The current (and previous, I believe) spec. draft reflects those 
explicit conclusions.

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


Re: How primitive are Symbols? Bignums? etc

2013-07-18 Thread Allen Wirfs-Brock

On Jul 18, 2013, at 12:56 AM, Andreas Rossberg wrote:

 On 18 July 2013 01:09, Brendan Eich bren...@mozilla.com wrote:
 Brandon Benvie wrote:
 
 On 7/17/2013 4:02 PM, Brandon Benvie wrote:
 
 And this is how it currently works in the V8 implementation. The first
 thing I did testing it looked like:
 
var s = new Symbol();
var x = {};
x[s] = 'test';
 
 I was surprised to find that this threw an error instead of doing the (to
 me) obvious thing.
 
 (And to clarify, it throws on line 3, not line 1)
 
 This is nuts.
 
 May I humbly remind you that we explicitly discussed and decided this
 at the March meeting? I actually would have preferred if 'new Symbol'
 worked, and that was what V8 implemented before the meeting.

from the minutes:
AWB: I can define the Symbol[@@create] to throw

that means 'new Symbol' would throw.

But, as I mentioned in another message, I actually don't see in the minutes a 
record of consensus one way or another regarding Symbol wrapper objects.  I do 
see push back against them and by I personally went away believing that we 
agreed to try primitive symbols with no wrapper objects.  If you look at the 
Rev15 (May 2013) spec. draft the timestamp on the edits to introduce those 
changes is March 18, 2013.  So, I made those changes 4 days after the meeting 
discussion and presumably with a fresh recollection of what transpired. 

 
 Seriously, all this discussion is about breaking the March consensus.
 I find it rather irritating that some seem surprised about decisions
 they actively had their part in. Moreover, I find it unacceptable when
 the editor decides to break consensus single-handedly and implements
 it without notice, let alone discussion.

Unfortunately, we don't even agree upon the details of the consensus.  These 
consensus agreements at meetings are important, and I always try to get them 
into the spec. draft as soon as possible.  However, they are typically made in 
the context of a relatively short debate where it is impossible for everybody 
to explore and understand all the deep implications of a decision.  Sometimes 
we reach a consensus that latter proves to be problematic.

I have to take the result of those decisions and try to make them work in the 
spec. and implementors should be trying to make them work in their engines.  I 
immediately incorporated the  my understanding of the consensus into what was 
ultimately released as the May draft.  After that I started to routinely 
discover numerous additional special cases in the spec. where primitive symbols 
had to be explicitly accounted for and also discovered that it was something 
that I was having to consider (or was forgetting to consider) as I added new 
material to the spec.  My conclusion, was that primitive symbols without 
wrappers wasn't going to work. 

I know I informally talked about this with several people. I reverted symbol to 
being an exotic object May 29 shortly after getting back  from the May TC39 
meeting so something that came out of that meeting pushed me over the edge 
towards reverting.  I think it probably was things I ran into while changing 
function call to use [[Invoke]].

At a meta level, I need to keep moving forward on the spec. or it will never be 
completed. We seldom are able to definitively resolve issues on es-discuss and 
I can't let myself get blocked for up to two months waiting for a TC39 meeting. 
 So I have to make make informed guesses about ultimate outcomes and use them 
in my working drafts so I can move forward with a reasonably self-consistent 
spec.  Every thing in the draft spec is subject to (and needs) serious review 
by TC39 members. As I say quite often, nothing in the spec. if final until the 
entire thing is approved by TC39. (BTW, I  really appreciate the stream of good 
feedback continue to get from the V8 team via bugs.ecmascript.org).  

In this particular case, I guessed that we were going to ultimately either go 
back to Symbols as objects or to introduce wrapper objects for primitive 
Symbols.  So, I had basically three choices: 1) keep going with special case 
handling of primitive symbols scattered through out the spec. 2) Revert to a 
centralized definition of exotic symbol objects, 3) add symbol wrappers. 

option 1 was the maintenance nightmare I was trying to recover from.  I 
believed there was strong opposition to adding additional wrapper objects, so I 
didn't want to push a Symbol wrapper into the spec. yet.  But it turns out that 
option 2, was also a reasonable place for moving to option 3 if we decided to 
go that route (both option 23 eliminates most of the special case handling). 
So, that's where we stand today.  I'm betting that TC39 will ultimately decide 
on either symbols as exotic objects or primitive symbols with wrappers.  The 
current state of the spec. makes it easy for me to go either direction.

allen___
es-discuss mailing list
es-discuss@mozilla.org

Re: How primitive are Symbols? Bignums? etc

2013-07-18 Thread Brendan Eich

Allen Wirfs-Brock wrote:

On Jul 18, 2013, at 8:09 AM, Brendan Eich wrote:

Andreas Rossberg wrote:
On 18 July 2013 01:09, Brendan Eichbren...@mozilla.com 
mailto:bren...@mozilla.com  wrote:

Brandon Benvie wrote:

On 7/17/2013 4:02 PM, Brandon Benvie wrote:
And this is how it currently works in the V8 implementation. The 
first

thing I did testing it looked like:

var s = new Symbol();
var x = {};
x[s] = 'test';

I was surprised to find that this threw an error instead of doing 
the (to

me) obvious thing.

(And to clarify, it throws on line 3, not line 1)

This is nuts.


May I humbly remind you that we explicitly discussed and decided this
at the March meeting?


If it's nuts now, it was nuts in March :-P.


 I actually would have preferred if 'new Symbol'
worked, and that was what V8 implemented before the meeting.


You are right, I see this in the March 14 meeting notes. So I'm 
pleading temporary insanity. We'll have to reestablish consensus. I 
will refrain from more (self-)analysis ;-).




No, you just need to read carefully,


Do you mean me, or Andreas? Or Rick who took the meeting notes?

The notes should not require reading between the lines, including your 
unrecorded statements! Not that notes are ever perfect.


Ok, everyone take a deep breath

I remember that this is just a summary of the discussion, not literal 
quotes,  and not everything is captured:


AWB: |Symbol| is a factory that creates symbols, |new Symbol|
creates instance of the wrapper class. (same as Number)

BE: Value objects allow new

AWB: I can define the |Symbol[@@create]| to throw


I'm pretty sure that as part of the first statement I also said that 
'new Symbol' should not create a primitive value because that would 
violate the wrapper object pattern.
The Synbol[@@create]] comment is another way of saying 'new Symbol' 
should throw.


Yes, and (whether it was March or May -- March I think) we did talk 
about value object constructors not supporting 'new'.


There is nothing following this in the Symbols section of the minutes 
that address whether or not there are Symbol wrappers. My take-away 
from the meeting  was we would try to do Symbols as as a primitive, 
with a factory object named 'Symbol', but no user visible wrapper 
instances.  I don't see anything in the minutes that says otherwise. 
 In fact, the conclusion/resolution doesn't even say that Symbols will 
be primitive values.  All of the bullet items listed there are apply 
equally to either symbols as primitives or symbols as exotic objects. 
The current (and previous, I believe) spec. draft reflects those 
explicit conclusions.


Ok, but we clearly had two people (at least) at the meeting who came to 
quite different conclusions. That's a problem. These things happen, 
we'll sort it out, but I'm not sure what you are doing here other than 
reiterating what you got from the notes. The notes are incomplete, in a 
way that supports multiple conflicting interpretations.


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


Re: How primitive are Symbols? Bignums? etc

2013-07-17 Thread Brendan Eich

Andreas Rossberg wrote:

As said above, we already have the primitive case, and you are just
adding yet another kind of beast. I don't think that would be
improving anything. On the contrary.


This is an argument from minimization of primitive concepts or kinds, 
but I argue the better way on the web (given backward compatibility) is 
not to mimimize at such a reductive level. Users mostly ignore the 
boolean, number, and string wrappers, which are unobservable in strict 
mode. Users do not want more wrappers, e.g., Uint64 for uint64. No 
use-case is served by such beasts.


You might argue that total cognitive load is lower, but I reply that 
since wrappers are almost completely unobservable and not used 
explicitly, the load of having two types, symbol/Symbol, bignum/Bignum, 
etc., is strictly higher.


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


Re: How primitive are Symbols? Bignums? etc

2013-07-17 Thread Brendan Eich

Mark S. Miller wrote:
On Wed, Jul 17, 2013 at 8:55 AM, Brendan Eich bren...@mozilla.com 
mailto:bren...@mozilla.com wrote:


Andreas Rossberg wrote:

As said above, we already have the primitive case, and you are
just
adding yet another kind of beast. I don't think that would be
improving anything. On the contrary.


This is an argument from minimization of primitive concepts or
kinds, but I argue the better way on the web (given backward
compatibility) is not to mimimize at such a reductive level. Users
mostly ignore the boolean, number, and string wrappers, which are
unobservable in strict mode.


Nit: They are not unobservable. Rather, strict code itself never 
implicitly wraps.


Thanks, I meant that, but my point is users really don't run into 
boolean/Boolean, number/Number, and string/String complexity in the 
main. Yes, one must use String.prototype (not string.prototype, there's 
no 'string' of course), but such minor irregularities in languages are a 
lesser issue.



However, for example,

({}).valueOf.call(3) // 3 wrapper


Right.



Users do not want more wrappers, e.g., Uint64 for uint64. No
use-case is served by such beasts.

You might argue that total cognitive load is lower, but I reply
that since wrappers are almost completely unobservable and not
used explicitly, the load of having two types, symbol/Symbol,
bignum/Bignum, etc., is strictly higher.



I'm hoping you agree here!

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


Re: How primitive are Symbols? Bignums? etc

2013-07-17 Thread Allen Wirfs-Brock

On Jul 17, 2013, at 7:46 AM, Andreas Rossberg wrote:

 On 16 July 2013 19:33, Allen Wirfs-Brock al...@wirfs-brock.com wrote:
 ...
 Because MOP operations on symbols are never important, so that 
 representation should be fine from the object perspective.  For actual 
 property access, its only the identify of the symbol that matters.
 
 That's not true for implementations. For example, you need hash values
 for symbols.
 
 
 I sense, that you issue may be that you have implementation issues relating 
 to property looking/caching that perhaps relates to your representation of 
 string primitive values.  Is your issue that a symbol primitive typed 
 modeled after strings will be easer to fit into your implementation?  If so, 
 it isn't clear that this ease of retrofit consideration carries over to 
 other implementations.
 
 That's certainly true as well, e.g. I want to access hashes uniformly
 (and I believe that other implementations will want to follow a
 similar strategy to avoid the cost of extra case distinctions). But
 it's not the only point, see above.
 


You also need hash values for objects to implement Maps/Sets, etc.

Representationally, I would expect most implementations to have a common base 
representation for all heap allocated entities including strings and objects.  
But your design may be different.

Regardless, I think it is quite possible to exhibit property lookup designs 
where object-baeed keys make absolutely no complexity/performance difference.  
(its a different language, but high perf Smalltalk engines come to mind). So it 
is probably a wash.  Some existing implementations may have to do more and some 
less to support symbols as objects. That's generally the case for most new 
engine-level ES features.


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


Re: How primitive are Symbols? Bignums? etc

2013-07-17 Thread Allen Wirfs-Brock

On Jul 17, 2013, at 9:20 AM, Mark S. Miller wrote:

 I am uncomfortable expanding the typeof namespace. Where do these new names 
 come from, and how do we avoid collision?
  

The typeof namespace has always been extensible and has historically been 
extended by some implementations. But the only possible source of collusions 
are such implementations not the whole web.  Note that providing a typeof value 
is one thing that we have not exposed via the MOP and in particular a Proxies.  
There is current no explicit extensibility mechanism for them.

However, I'm not sure we would want to add a new typeof result for every 
possible value object type.  That probably would require an extension 
mechanism.

Note that instanceof can be made into a reliable test for value objects. 

I will defined Symbols.@@hasInstance such that 
   obj instanceof Symbol 
is a reliable, cross-Realm test of obj's symbolness.

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


Re: How primitive are Symbols? Bignums? etc

2013-07-17 Thread Brendan Eich

Mark S. Miller wrote:
I am uncomfortable expanding the typeof namespace. Where do these new 
names come from, and how do we avoid collision?


You still value the

(x == y  typeof x == y) = x === y

invariant, right? That's the motivation for decimal, int64, etc. having 
their constructor-named decimal, int64, etc., typeof-result strings.


We decide these for ES7 for sure, since we're considering value objects 
for important machine and user-wanted types (int64, bignum).


We also agreed, in deferring decimal (late for ES5 anyway), that it 
should happen via self-hosted user code. You and I discussed 
up-thread, and I'm going to write a strawman for operators and literals.


Suffice to say here that such user-defined value objects should enable 
typeof-result customization. There could be conflicts, just as literals' 
suffixes could conflict. This is not a deal-breaker, and I should work 
on that strawman before we over-rotate on it. But can we agree here that 
we're trying not to hardcode value objects in future editions, rather 
cover the important machine and user-facing types and support 
self-hosting, and let library authors extend the system rather than TC39?


Note also that IE JScript has non-standard typeof-results, and this gave 
us hope (when we last discussed it) that we too could extend typeof's 
codomain.


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


RE: How primitive are Symbols? Bignums? etc

2013-07-17 Thread Domenic Denicola
From: Brendan Eich [bren...@mozilla.com]

 You still value the

 ```js
 (x == y  typeof x == y) = x === y
 ```

 invariant, right? That's the motivation for decimal, int64, etc. having their 
 constructor-named decimal, int64, etc., typeof-result strings.

You have brought up this invariant in many threads. Could you explain its 
importance and value? My feeling is that nobody uses `==`, so a relation tying 
together `==`, `typeof`, and `===` doesn't really impact anything people use.

Put another way: why do you feel this is an important base invariant of the 
language, to be preserved, rather than just an equality that happens to fall 
out of what we have in the language now?
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: How primitive are Symbols? Bignums? etc

2013-07-17 Thread Brendan Eich

Andreas Rossberg wrote:

I doubt that there is a single implementation that would not want to
special-case symbol representations. They will all have to deal with
the extra complexity.


Don't take this as a you're wrong-style absolute argument:

We took this hit way back when, for E4X (to help restart Ecma TC39). 
RIP, and put a stake through it and sew salt into its mouth so it does 
not come back to life, but my point here is that engines *already* 
special-case integer-ish index identifiers and do not use strings (while 
equating strings such as 123 to 123 when used as property names).


True, adding another variant for symbol property names where the symbol 
is an object, not a unique and unforgeable string or similar primitive, 
is a cost. But it's the 3rd tag in the space, not the 2nd. So there 
already exist special cases for int-ish names. The cost is less than you 
suggest, in terms of PIC variants and so on.


Finally, while implementor hardships matter, we must subordinate symbol 
implementation concerns to user-facing ones. But that's an exchange 
where I already made my pitch elsewhere on this thread.


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


Re: How primitive are Symbols? Bignums? etc

2013-07-17 Thread Brendan Eich

Domenic Denicola wrote:

From: Brendan Eich [bren...@mozilla.com]


You still value the

```js
(x == y  typeof x == y)=  x === y
```

invariant, right? That's the motivation for decimal, int64, etc. having their constructor-named 
decimal, int64, etc., typeof-result strings.


You have brought up this invariant in many threads.


Yes, and I've written about why invariants matter on occasion -- perhaps 
you missed that :-P.


https://mail.mozilla.org/pipermail/es-discuss/2008-September/007610.html



Postel's Law means you accept everything that flies in ES1, and have
trouble being less liberal in ES2+. Web authors crawl the feature
vector space and find all the edges, so at least what you did not
accept in v1 becomes law. But these are generalizations from
experience with invariants such as typeof x == object  !x =  x
=== null and typeof x == typeof y =  (x == y=  x === y).


Beyond this conservatism in breaking invariants based on experience,
it turns out that % and / results do flow into array indexes. From
SunSpider's 3d-raytrace.js





  Could you explain its importance and value? My feeling is that nobody uses 
`==`,


Your feeling is wrong. == is used (I miss Google codesearch) widely on 
the web.



  so a relation tying together `==`, `typeof`, and `===` doesn't really impact 
anything people use.


See above. Language designers value and conserve invariants based on 
long experience with painful counterexamples.



Put another way: why do you feel this is an important base invariant of the 
language, to be preserved, rather than just an equality that happens to fall 
out of what we have in the language now?


It's not an equality, rather a two-way implication. It helps us reason 
about all three of typeof, ==, and === as we evolve JS. It's not noise, 
and not nothing. We could deliberately break it, but for what win?


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


Re: How primitive are Symbols? Bignums? etc

2013-07-17 Thread Brendan Eich

Andreas Rossberg wrote:

On 17 July 2013 17:55, Brendan Eichbren...@mozilla.com  wrote:

Andreas Rossberg wrote:

As said above, we already have the primitive case, and you are just
adding yet another kind of beast. I don't think that would be
improving anything. On the contrary.

This is an argument from minimization of primitive concepts or kinds, but I
argue the better way on the web (given backward compatibility) is not to
mimimize at such a reductive level. Users mostly ignore the boolean, number,
and string wrappers, which are unobservable in strict mode. Users do not
want more wrappers, e.g., Uint64 for uint64. No use-case is served by such
beasts.


If users ignore them anyway, why would they care?


I wrote mostlyintentionally. Where they don't or can't ignore 
primitives and their wrappers, they generally feel pain.


We should not add more such user-facing pain if we can avoid it -- even 
if that means more implementor-facing pain (remember Mr. Spock's 
Kobayashi Maru solution ;-).


/be

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


RE: How primitive are Symbols? Bignums? etc

2013-07-17 Thread Domenic Denicola
From: Brendan Eich [bren...@mozilla.com]

 Yes, and I've written about why invariants matter on occasion -- perhaps you 
 missed that :-P.

Heh, 2008 was before my time. But generally yes, I certainly understand the 
importance of invariants. I am just not sure this particular invariant is 
something people actually depend on.

This I guess is the heart of my question. When I said nobody uses `==`, I 
should have said nobody writes code using `==` that depends on that logical 
equivalence. The `typeof x == object  !x = x === null` invariant I can 
certainly see being used in the wild, mainly to avoid the special-caseness of 
`null` being an object-according-to-`typeof`, but I can't for the life of me 
think of how to use the `typeof`/`==`/`===` relation.

 It's not an equality, rather a two-way implication. It helps us reason about 
 all three of typeof, ==, and === as we evolve JS. It's not noise, and not 
 nothing.

My perspective is that reasoning about `==`, and even to some extent `typeof`, 
is not that important, since they are both broken. And thus such a connection 
does feel somewhat like noise; there are plenty of invariants you can state by 
just stringing together logical consequences of the language, but determining 
which of those are important is the trick.

Anyway, I get it that good invariants are useful and that you at least find 
this particular invariant to be a good one, so we can leave it at that. I'd 
still love to see some plausible-in-the-wild code that could break if we lost 
this invariant, though.
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: How primitive are Symbols? Bignums? etc

2013-07-17 Thread Brendan Eich

Domenic Denicola wrote:

From: Brendan Eich [bren...@mozilla.com]


Yes, and I've written about why invariants matter on occasion -- perhaps you 
missed that :-P.


Heh, 2008 was before my time. But generally yes, I certainly understand the 
importance of invariants. I am just not sure this particular invariant is 
something people actually depend on.


People do depend on this, though. Some JS users take advantage of ==, in 
particular of


* null == undefined
* typeof x == typeof y

The latter makes use of knowledge that typeof's result is always of 
string type.


You may argue people should always use === everywhere, but it's a fact 
that == is supported *and* used.



This I guess is the heart of my question. When I said nobody uses `==`, I should have 
said nobody writes code using `==` that depends on that logical equivalence.


False. When operand typeof-types match, == is short for === and people 
use this (second bullet above is the most common case I've seen, but not 
the only case).



  The `typeof x == object  !x =  x === null` invariant I can certainly see 
being used in the wild, mainly to avoid the special-caseness of `null` being an 
object-according-to-`typeof`, but I can't for the life of me think of how to use the 
`typeof`/`==`/`===` relation.


As I wrote last time, *we* language designers/stewards of TC39 care for 
good reason.





It's not an equality, rather a two-way implication. It helps us reason about 
all three of typeof, ==, and === as we evolve JS. It's not noise, and not 
nothing.


My perspective is that reasoning about `==`, and even to some extent `typeof`, is not 
that important, since they are both broken.


Let's cut this thread mercifully short. Language designers tending 
ECMA-262 cannot turn such a blind eye, period, full stop.


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


Re: How primitive are Symbols? Bignums? etc

2013-07-17 Thread Brendan Eich

Brendan Eich wrote:
My perspective is that reasoning about `==`, and even to some extent 
`typeof`, is not that important, since they are both broken.


Let's cut this thread mercifully short. Language designers tending 
ECMA-262 cannot turn such a blind eye, period, full stop.


It's fine if users subset. This relates to my point about users mostly 
ignoring primitives vs. wrappers.


However, you have the burden of proof backwards on TC39 chucking 
invariants. Dave Herman has written about this before and reminded me to 
make this point crystal clear. Show why we should ditch the invariant. 
Otherwise we keep it.


And practically speaking, with typeof-type extensions on the table, and 
typeof-result being a string used to enable == not ===, we need this one.


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


Re: How primitive are Symbols? Bignums? etc

2013-07-17 Thread Claude Pache

Le 17 juil. 2013 à 18:43, Andreas Rossberg rossb...@google.com a écrit :

 
 If users ignore them anyway, why would they care?

If symbols are primitives with wrapper, they *must* care: They must know that 
`new Symbol` does not produce a new symbol, but some useless object. At least, 
`new Symbol` should either (as I have already said) be poisoned or (better) 
produce a new symbol.

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


Re: How primitive are Symbols? Bignums? etc

2013-07-17 Thread Brandon Benvie

On 7/17/2013 3:58 PM, Claude Pache wrote:

Le 17 juil. 2013 à 18:43, Andreas Rossberg rossb...@google.com a écrit :


If users ignore them anyway, why would they care?

If symbols are primitives with wrapper, they *must* care: They must know that 
`new Symbol` does not produce a new symbol, but some useless object.


And this is how it currently works in the V8 implementation. The first 
thing I did testing it looked like:


var s = new Symbol();
var x = {};
x[s] = 'test';

I was surprised to find that this threw an error instead of doing the 
(to me) obvious thing.

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


Re: How primitive are Symbols? Bignums? etc

2013-07-17 Thread Brandon Benvie

On 7/17/2013 4:02 PM, Brandon Benvie wrote:
And this is how it currently works in the V8 implementation. The first 
thing I did testing it looked like:


var s = new Symbol();
var x = {};
x[s] = 'test';

I was surprised to find that this threw an error instead of doing the 
(to me) obvious thing.


(And to clarify, it throws on line 3, not line 1)
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: How primitive are Symbols? Bignums? etc

2013-07-17 Thread Brendan Eich

Brandon Benvie wrote:

On 7/17/2013 4:02 PM, Brandon Benvie wrote:
And this is how it currently works in the V8 implementation. The 
first thing I did testing it looked like:


var s = new Symbol();
var x = {};
x[s] = 'test';

I was surprised to find that this threw an error instead of doing the 
(to me) obvious thing.


(And to clarify, it throws on line 3, not line 1)


This is nuts.

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


Re: How primitive are Symbols? Bignums? etc

2013-07-16 Thread Allen Wirfs-Brock

On Jul 15, 2013, at 10:30 PM, Brendan Eich wrote:

 Axel Rauschmayer wrote:
 The (x === Object(x)) test evaluates to true for value objects in this 
 proposal, though. This may break code looking for primitives but we need 
 to see what such code expects. Is it filtering out the legacy typeof-result 
 primitives (plus null), trying to find values for which typeof currently 
 returns object or function? If so, I don't see a problem: int64, 
 bignum, etc. are not legacy primitives. Is this test looking for objects 
 that are their own wrappers? Again all is well, unless mutable wrapper is 
 assumed -- but that's not safe in the ES5 era to assume, anyway.
 
 The most frequent use case I’ve encountered: does the value have a prototype 
 (i.e., will Object.getPrototypeOf() work)?
 
 I’m assuming that value objects will have a prototype, accessible via 
 Object.getPrototypeOf (?)
 
 Yes, they are after all value objects :-P.
 
 js Object.getPrototypeOf(0UL)
 0UL
 

In the latest spec. draft, Object.getPrototypeOf(new Symbol) returns null 
because that is what the [[GetInheritance]] MOP operation produces for exotic 
symbol objects. That's because symbols symbols aren't supposed to have any 
observable properties.

[[GetInhertance]] would do something else for value objects that actually 
exposed inherited properties.

Allen 



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


Re: How primitive are Symbols? Bignums? etc

2013-07-16 Thread Brendan Eich

Allen Wirfs-Brock wrote:

On Jul 15, 2013, at 10:30 PM, Brendan Eich wrote:

Axel Rauschmayer wrote:

The (x === Object(x)) test evaluates to true for value objects in this proposal, though. This may break code looking for 
primitives but we need to see what such code expects. Is it filtering out the legacy typeof-result primitives (plus 
null), trying to find values for which typeof currently returns object or function? If so, I 
don't see a problem: int64, bignum, etc. are not legacy primitives. Is this test looking for objects that are their own wrappers? 
Again all is well, unless mutable wrapper is assumed -- but that's not safe in the ES5 era to assume, anyway.

The most frequent use case I’ve encountered: does the value have a prototype 
(i.e., will Object.getPrototypeOf() work)?

I’m assuming that value objects will have a prototype, accessible via 
Object.getPrototypeOf (?)

Yes, they are after all value objects :-P.

js  Object.getPrototypeOf(0UL)
0UL



In the latest spec. draft, Object.getPrototypeOf(new Symbol) returns null 
because that is what the [[GetInheritance]] MOP operation produces for exotic 
symbol objects. That's because symbols symbols aren't supposed to have any 
observable properties.

[[GetInhertance]] would do something else for value objects that actually 
exposed inherited properties.


As it should:

js Object.getPrototypeOf(0UL) === uint64.prototype
true

for toString and valueOf at least.

/be

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


Re: How primitive are Symbols? Bignums? etc

2013-07-16 Thread Allen Wirfs-Brock

On Jul 16, 2013, at 4:34 AM, Andreas Rossberg wrote:

 On 15 July 2013 19:44, Allen Wirfs-Brock al...@wirfs-brock.com wrote:
 The is primarily an internal spec. change.  Many internal operations within 
 the spec. require objects as parameters.  This required inserting inserting 
 explicit guards in p=many places within the specification and remembering to 
 include them in new algorithms. At the March meeting you objected to the 
 two pages of specification required to define Symbols as exotic objects.  
 It turned out that those two pages were fair simpler and less intrusive than 
 the all the individual spec. changes (and ongoing additions) that were 
 needed to support symbols as primitive values.
 
 I'm afraid I still don't see how this is the case (the draft diffs are
 not particularly easy to read). Almost everything should be handled by
 ToObject creating a wrapper object in the traditional places,
 shouldn't it? What are the contexts where (a) an object is required,
 but (b) a symbol would behave differently from existing primitives?
 
 
 User visible semantics comes down to whether or not there is a Symbol 
 wrapper object. As far as I can tell, tell from the notes, there was no 
 consensus WRT Symbol wrappers record in March and when I tried to convert to 
 Symbols as primitive values in the spec. I don't provide such wrappers.  
 Instead, I made ToObject throw for symbols values.
 
 OK, that might explain the difficulty you faced. My understanding of
 the March agreement certainly was that there is a wrapper object,
 consistent with other primitive types. And I'm pretty sure that that
 makes the spec quite simple and regular.

Yes, wrappers would make it easier, but my take away from the meeting and 
subsequent discussion was that we didn't want to add any more observable 
wrappers. 
 
 
 We really should avoid adding new  primitive types and wrapper objects.  
 Value objects are the way to go, starting with Symbol.
 
 I'd argue for the contrary, namely that we should avoid artificially
 cramping more inappropriate concepts into the notion of 'object'!
 These are not objects by any useful definition of the word, despite
 the MOP being rich enough to support them as degenerate cases.

Clearly I disagree. In ES and other polymorphic object-based languages, objects 
are really the basis for uniformity of references.  Any abstraction can be 
represented as an object and any operation can be manifested as method 
invocations upon an object. 

It is the ES primitive types that introduce non-uniformity that either needs to 
be special cased or partially hidden behind hacks such as automatic conversion 
to wrapper objects. Clearly at an implementation level you want to have 
optimized representations of certain kinds of entities.  You can get there two 
different ways.  You can expose the optimized representation as primitive 
types that requires user level special casing or you can uniformly expose 
everything as an object and let the implementation opaquely use special case 
representations where it suits it.

It seems clear to me, that if  you want to support an open ended set of new 
abstractions you need to go the uniform objects route.   We're stuck with 
numbers, strings, and booleans and their corresponding wrappers. We don't need 
more special cases at that level.

 
 
 I'd be interested in hearing how this makes any difference to you from an 
 implementation perspective.  Even when symbols are specified as exotic 
 objects you can still encode them as immediate values, just like you would a 
 SmallInteger in Smalltalk. It's only when actual object MOP operations are 
 applied to them that you should have to do any special casing but these are 
 generally the same situations where you would have to auto-wrap primitive 
 values.
 
 The difference is that with real primitives + wrapper objects every
 respective operation has a single place where it does the ToObject
 conversion (which exists already), and downstream you can easily make
 it an invariant that what you've got is an ordinary object with an
 ordinary object representation. No special casing required.
 
 If, on the other hand, you make new primitives pseudo-objects, but
 still want to represent them efficiently, then all parts that deal
 with objects now also have to deal with those denormal
 representations. You say only actual MOP operations, but surely
 there are several times more occurrences of those than of ToObject. It
 involves the majority of language operations, and in contemporary
 implementations, every one of them potentially has a dozen or more
 possible implementations.

Sounds like your are concerned about special casing MOP dispatches on 
primitives representations.  A good concern.  However, I don't actually see 
much benefit of a primitive non-dispatchable representation for symbols and if 
you do, you could still hide it in ToObject.  Nothing saying you can't have 
internal wrapper objects and be careful not to 

Re: How primitive are Symbols? Bignums? etc

2013-07-16 Thread Brendan Eich

Allen Wirfs-Brock wrote:

We're stuck with numbers, strings, and booleans and their corresponding 
wrappers. We don't need more special cases at that level.


I should write an apologator 
(http://www-archive.mozilla.org/apology.html) for inflicting primitives 
as non-objects in those ten days in May. Agree they are an 
anti-pattern at this point, not to be imitated by symbol/Symbol (and I 
thought TC39 agreed on this, and no strawman or proposal had both).


For symbols you don't inherently have to have two different 
representations.


Not only do you, or we, not face _a priori_ arguments for symbol and 
Symbol, users do not want.


Yes, it's drawing a line and saying no added special case primitive 
types and no new wrapper objects. Starting with ES6 all new 
abstractions can be conceptualized as objects.
Agreed. Not to dogpile on, but just to apologize for primitives and say 
that they are the exception that proves the rule, not the pattern for 
novelties. See also int64, bignum, etc.


/be

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


Re: How primitive are Symbols? Bignums? etc

2013-07-15 Thread Jeremy Martin
 s === Object(s)

This should throw a TypeError.  In the case of a Symbol, `Object(*value*)`
results in `ToObject(*value*)` [1].  And, in the case of Symbol, ToObject
should throw a TypeError [2].

[1] http://people.mozilla.org/~jorendorff/es6-draft.html#sec-15.2.1.1
[2] http://people.mozilla.org/~jorendorff/es6-draft.html#sec-9.1.9

On Mon, Jul 15, 2013 at 10:48 AM, Mark S. Miller erig...@google.com wrote:

 Given that s is a Symbol and b is a Bignum, is

 s === Object(s)

 ?

 Is

 b === Object(b)

 ?

 The reason I ask is that x === Object(x) is often used to distinguish
 primitive values from objects. The other thing that's often used is typeof,
 but these uses of typeof usually assume that the full range of possible
 answers is already known. If we're going to be expanding the typeof
 answers, then we need guidance on how to write this test now (es5) such
 that it stays robust.


 --
 Cheers,
 --MarkM

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




-- 
Jeremy Martin
661.312.3853
http://devsmash.com
@jmar777
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: How primitive are Symbols? Bignums? etc

2013-07-15 Thread André Bargull
Allen (cc-ed) changed symbols back to objects in draft rev 16 
(https://bugs.ecmascript.org/show_bug.cgi?id=1546#c2), so I guess 
Object(x) will still work in ES6 to test for object types.


- André



I see. That's unpleasant. In ES5, Object(x) can never throw, and so the
code paths using |x === Object(x)| are not prepared for a throw. Much old
code will break.


On Mon, Jul 15, 2013 at 8:01 AM, Jeremy Martin jmar777 at gmail.com  
https://mail.mozilla.org/listinfo/es-discuss wrote:

/   s === Object(s)
//
//  This should throw a TypeError.  In the case of a Symbol, `Object(*value*)`
//  results in `ToObject(*value*)` [1].  And, in the case of Symbol, ToObject
//  should throw a TypeError [2].
//
//  [1]http://people.mozilla.org/~jorendorff/es6-draft.html#sec-15.2.1.1  
http://people.mozilla.org/%7Ejorendorff/es6-draft.html#sec-15.2.1.1
//  [2]http://people.mozilla.org/~jorendorff/es6-draft.html#sec-9.1.9  
http://people.mozilla.org/%7Ejorendorff/es6-draft.html#sec-9.1.9
//
//  On Mon, Jul 15, 2013 at 10:48 AM, Mark S. Miller erights at google.com  
https://mail.mozilla.org/listinfo/es-discusswrote:
//
//  Given that s is a Symbol and b is a Bignum, is
//
//  s === Object(s)
//
//  ?
//
//  Is
//
//  b === Object(b)
//
//   ?
//
//  The reason I ask is that x === Object(x) is often used to distinguish
//  primitive values from objects. The other thing that's often used is 
typeof,
//  but these uses of typeof usually assume that the full range of possible
//  answers is already known. If we're going to be expanding the typeof
//  answers, then we need guidance on how to write this test now (es5) such
//  that it stays robust.
//
//
//  --
//  Cheers,
//  --MarkM//  https://mail.mozilla.org/listinfo/es-discuss
//
//
//  --
//  Jeremy Martin
//  661.312.3853
//  http://devsmash.com
//  @jmar777
//
/
--
 Cheers,
 --MarkM
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: How primitive are Symbols? Bignums? etc

2013-07-15 Thread Jeremy Martin
 That's unpleasant. [...] Much old code will break.

Indeed.  I hadn't actually noticed that change until just now.  It looks
like ES6 code can take advantage of Object.isObject(), which seems to
delegate the work to Type(*x*) [1].  It wasn't overwhelmingly clear to me,
but I would assume `Object.isObject('foo') === false` and
`Object.isObject(new String('foo')) === true`.

Has anyone surveyed/looked into what the fallout of throwing on stuff like
`Object(undefined)` will be?

[1] http://people.mozilla.org/~jorendorff/es6-draft.html#sec-8

On Mon, Jul 15, 2013 at 11:09 AM, Mark S. Miller erig...@google.com wrote:

 I see. That's unpleasant. In ES5, Object(x) can never throw, and so the
 code paths using |x === Object(x)| are not prepared for a throw. Much old
 code will break.


 On Mon, Jul 15, 2013 at 8:01 AM, Jeremy Martin jmar...@gmail.com wrote:

  s === Object(s)

 This should throw a TypeError.  In the case of a Symbol, `Object(*value*)`
 results in `ToObject(*value*)` [1].  And, in the case of Symbol,
 ToObject should throw a TypeError [2].

 [1] http://people.mozilla.org/~jorendorff/es6-draft.html#sec-15.2.1.1
 [2] http://people.mozilla.org/~jorendorff/es6-draft.html#sec-9.1.9

 On Mon, Jul 15, 2013 at 10:48 AM, Mark S. Miller erig...@google.comwrote:

  Given that s is a Symbol and b is a Bignum, is

 s === Object(s)

 ?

 Is

 b === Object(b)

  ?

 The reason I ask is that x === Object(x) is often used to distinguish
 primitive values from objects. The other thing that's often used is typeof,
 but these uses of typeof usually assume that the full range of possible
 answers is already known. If we're going to be expanding the typeof
 answers, then we need guidance on how to write this test now (es5) such
 that it stays robust.


 --
 Cheers,
 --MarkM

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




 --
 Jeremy Martin
 661.312.3853
 http://devsmash.com
 @jmar777




 --
 Cheers,
 --MarkM




-- 
Jeremy Martin
661.312.3853
http://devsmash.com
@jmar777
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: How primitive are Symbols? Bignums? etc

2013-07-15 Thread Jeremy Martin
Ahh, thanks. Somehow I read that as `Object(undefined)` -
ObjectCreate(undefined)` - throw, but that's not the case.

On Mon, Jul 15, 2013 at 11:39 AM, Mark S. Miller erig...@google.com wrote:

 Object(undefined) would still not throw:
 http://people.mozilla.org/~jorendorff/es6-draft.html#sec-15.2.1.1 step 1


 On Mon, Jul 15, 2013 at 8:37 AM, Jeremy Martin jmar...@gmail.com wrote:

  That's unpleasant. [...] Much old code will break.

 Indeed.  I hadn't actually noticed that change until just now.  It looks
 like ES6 code can take advantage of Object.isObject(), which seems to
 delegate the work to Type(*x*) [1].  It wasn't overwhelmingly clear to
 me, but I would assume `Object.isObject('foo') === false` and
 `Object.isObject(new String('foo')) === true`.

 Has anyone surveyed/looked into what the fallout of throwing on stuff
 like `Object(undefined)` will be?

 [1] http://people.mozilla.org/~jorendorff/es6-draft.html#sec-8

 On Mon, Jul 15, 2013 at 11:09 AM, Mark S. Miller erig...@google.comwrote:

 I see. That's unpleasant. In ES5, Object(x) can never throw, and so the
 code paths using |x === Object(x)| are not prepared for a throw. Much old
 code will break.


 On Mon, Jul 15, 2013 at 8:01 AM, Jeremy Martin jmar...@gmail.comwrote:

  s === Object(s)

 This should throw a TypeError.  In the case of a Symbol, `Object(*value
 *)` results in `ToObject(*value*)` [1].  And, in the case of Symbol,
 ToObject should throw a TypeError [2].

 [1] http://people.mozilla.org/~jorendorff/es6-draft.html#sec-15.2.1.1
 [2] http://people.mozilla.org/~jorendorff/es6-draft.html#sec-9.1.9

 On Mon, Jul 15, 2013 at 10:48 AM, Mark S. Miller erig...@google.comwrote:

  Given that s is a Symbol and b is a Bignum, is

 s === Object(s)

 ?

 Is

 b === Object(b)

  ?

 The reason I ask is that x === Object(x) is often used to distinguish
 primitive values from objects. The other thing that's often used is 
 typeof,
 but these uses of typeof usually assume that the full range of possible
 answers is already known. If we're going to be expanding the typeof
 answers, then we need guidance on how to write this test now (es5) such
 that it stays robust.


 --
 Cheers,
 --MarkM

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




 --
 Jeremy Martin
 661.312.3853
 http://devsmash.com
 @jmar777




 --
 Cheers,
 --MarkM




 --
 Jeremy Martin
 661.312.3853
 http://devsmash.com
 @jmar777




 --
 Cheers,
 --MarkM




-- 
Jeremy Martin
661.312.3853
http://devsmash.com
@jmar777
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: How primitive are Symbols? Bignums? etc

2013-07-15 Thread Allen Wirfs-Brock

On Jul 15, 2013, at 8:35 AM, André Bargull wrote:

 Allen (cc-ed) changed symbols back to objects in draft rev 16 
 (https://bugs.ecmascript.org/show_bug.cgi?id=1546#c2), so I guess Object(x) 
 will still work in ES6 to test for object types. 
 

Correct, Symbols as primitive values were just causing too many issues.  
Essentially, everyplace in the spec. that  needs an object had to be updated to 
explicit deal with Symbols.  That certainly isn't a pattern we want to follow 
in the future if add new value types such as bignums. It's much cleaner to 
freeze the set of primitive types and make all future value types (including 
Symbols) objects. just as it would have been even cleaner if everything was an 
object and there were not primitive types.

Regarding, typeof.  The right way to look at it is that the set of results that 
correspond to non-object types will be fixed and includes only (undefined, 
null, number, string, boolean).  All other typeof values correspond of 
objects (where an object is a value that support the ES internal MOP).



Allen



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


Re: How primitive are Symbols? Bignums? etc

2013-07-15 Thread Dean Landolt
On Mon, Jul 15, 2013 at 12:24 PM, Allen Wirfs-Brock
al...@wirfs-brock.comwrote:


 On Jul 15, 2013, at 8:35 AM, André Bargull wrote:

  Allen (cc-ed) changed symbols back to objects in draft rev 16 (
 https://bugs.ecmascript.org/show_bug.cgi?id=1546#c2), so I guess
 Object(x) will still work in ES6 to test for object types.


 Correct, Symbols as primitive values were just causing too many issues.
  Essentially, everyplace in the spec. that  needs an object had to be
 updated to explicit deal with Symbols.  That certainly isn't a pattern we
 want to follow in the future if add new value types such as bignums. It's
 much cleaner to freeze the set of primitive types and make all future value
 types (including Symbols) objects. just as it would have been even cleaner
 if everything was an object and there were not primitive types.

 Regarding, typeof.  The right way to look at it is that the set of results
 that correspond to non-object types will be fixed and includes only
 (undefined, null, number, string, boolean).  All other typeof
 values correspond of objects (where an object is a value that support the
 ES internal MOP).



I'm very surprised to see null in this list, and not function -- a
typeof typo I hope?
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: How primitive are Symbols? Bignums? etc

2013-07-15 Thread Allen Wirfs-Brock

On Jul 15, 2013, at 9:35 AM, Dean Landolt wrote:

 
 
 
 On Mon, Jul 15, 2013 at 12:24 PM, Allen Wirfs-Brock al...@wirfs-brock.com 
 wrote:
 
 Regarding, typeof.  The right way to look at it is that the set of results 
 that correspond to non-object types will be fixed and includes only 
 (undefined, null, number, string, boolean).  All other typeof 
 values correspond of objects (where an object is a value that support the ES 
 internal MOP).
 
 
 I'm very surprised to see null in this list, and not function -- a typeof 
 typo I hope?

Sorry, null should be in  the list, and is the one legacy value that muddles 
typeof.

functions are objects, not primitive values.




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


Re: How primitive are Symbols? Bignums? etc

2013-07-15 Thread Allen Wirfs-Brock

On Jul 15, 2013, at 9:38 AM, Mark S. Miller wrote:

 typeof x === 'function' and typeof x === 'object' are the current indications 
 of non-primitive types. What Allen is saying is that this set may expand, but 
 the typeof answers that indicate primitive value types will not. Allen was 
 enumerating the non-expanding set of primitive-value answers.

Yes, this better expresses what I meant


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


Re: How primitive are Symbols? Bignums? etc

2013-07-15 Thread Allen Wirfs-Brock

On Jul 15, 2013, at 9:40 AM, Andreas Rossberg wrote:

 On 15 July 2013 18:24, Allen Wirfs-Brock al...@wirfs-brock.com wrote:
 On Jul 15, 2013, at 8:35 AM, André Bargull wrote:
 Allen (cc-ed) changed symbols back to objects in draft rev 16
 (https://bugs.ecmascript.org/show_bug.cgi?id=1546#c2), so I guess Object(x)
 will still work in ES6 to test for object types.
 
 Correct, Symbols as primitive values were just causing too many issues.
 
 Oh. I wasn't aware of this. Is this just a spec language change, or is
 it a semantic change? If the latter, then I have to disagree with the
 change.


The is primarily an internal spec. change.  Many internal operations within the 
spec. require objects as parameters.  This required inserting inserting 
explicit guards in p=many places within the specification and remembering to 
include them in new algorithms. At the March meeting you objected to the two 
pages of specification required to define Symbols as exotic objects.  It 
turned out that those two pages were fair simpler and less intrusive than the 
all the individual spec. changes (and ongoing additions) that were needed to 
support symbols as primitive values.

User visible semantics comes down to whether or not there is a Symbol wrapper 
object. As far as I can tell, tell from the notes, there was no consensus WRT 
Symbol wrappers record in March and when I tried to convert to Symbols as 
primitive values in the spec. I don't provide such wrappers.  Instead, I made 
ToObject throw for symbols values.

If you have wrapper objects, then you have visible semantics such as:
   let s = Symbol();
   console.log(Object(s) === Object(s));  //false, because each call to Object 
produces a new wrapper object
   console(s === Object(s));   //false, because each call to Object produces a 
new wrapper object

If you have symbols as primitive values, but no wrappers you get:
   console.log(Object(s) === Object(s));  //TypeError
   console(s === Object(s));   //TypeError

If you have symbols as exotic objects  you get:
   console.log(Object(s) === Object(s));  //true
   console(s === Object(s));   //true

Because ES5 added auto-wrapping of primitive values within PutValue/GetValue, 
primitive values already act as if they were objects in most situations and 
except for the identify complications numbers/strings/booleans values can 
generally be used and reasoned about as if they were instances of 
Number/String/Boolean.   We really should avoid adding new  primitive types and 
wrapper objects.  Value objects are the way to go, starting with Symbol.

I'd be interested in hearing how this makes any difference to you from an 
implementation perspective.  Even when symbols are specified as exotic objects 
you can still encode them as immediate values, just like you would a 
SmallInteger in Smalltalk. It's only when actual object MOP operations are 
applied to them that you should have to do any special casing but these are 
generally the same situations where you would have to auto-wrap primitive 
values.

I would be interested in hearing if there are places in your implementation 
where specifying symbols as exotic objects will make an actual performance 
difference when using symbols as property keys. 

 
 Essentially, everyplace in the spec. that  needs an object had to be updated
 to explicit deal with Symbols.
 
 Allen, can you elaborate where symbols introduced cases that did not
 already have to be handled for other primitive types?

Every place that did a ToObject, or equivalent.  I'm pushing out a new spec. 
draft today or tomorrow and you can see the changes there.

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


Re: How primitive are Symbols? Bignums? etc

2013-07-15 Thread Brendan Eich

Allen Wirfs-Brock wrote:

On Jul 15, 2013, at 8:35 AM, André Bargull wrote:
Allen (cc-ed) changed symbols back to objects in draft rev 16 
(https://bugs.ecmascript.org/show_bug.cgi?id=1546#c2), so I guess 
Object(x) will still work in ES6 to test for object types.


Correct, Symbols as primitive values were just causing too many 
issues.  Essentially, everyplace in the spec. that  needs an object 
had to be updated to explicit deal with Symbols.  That certainly isn't 
a pattern we want to follow in the future if add new value types 
such as bignums. It's much cleaner to freeze the set of primitive 
types and make all future value types (including Symbols) objects. 
just as it would have been even cleaner if everything was an object 
and there were not primitive types.


+1.

Regarding, typeof.  The right way to look at it is that the set of 
results that correspond to non-object types will be fixed and includes 
only (undefined, null, number, string, boolean).  All other 
typeof values correspond of objects (where an object is a value that 
support the ES internal MOP).


(Regrets on lack of null typeof-result, of course.)

I'm updating my int64/uint64 experimental patch to return int64 and 
uint64 typeof-types, to uphold these invariants:


typeof x == typeof y  x == y =  x === y

If typeof 0L and 0UL were object, this would fail, but we want 0L == 
0UL. This came up with decimal in the ES5 era, where 0m == 0 but 0m !== 
0. It's generally a problem, not just for 0 but for many pairs of 
numeric types subsuming a subset of the Integers where the values in 
common should equate by == but not ===.


The (x === Object(x)) test evaluates to true for value objects in this 
proposal, though. This may break code looking for primitives but we 
need to see what such code expects. Is it filtering out the legacy 
typeof-result primitives (plus null), trying to find values for which 
typeof currently returns object or function? If so, I don't see a 
problem: int64, bignum, etc. are not legacy primitives. Is this test 
looking for objects that are their own wrappers? Again all is well, 
unless mutable wrapper is assumed -- but that's not safe in the ES5 
era to assume, anyway.


/be


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


Re: How primitive are Symbols? Bignums? etc

2013-07-15 Thread Axel Rauschmayer
 The (x === Object(x)) test evaluates to true for value objects in this 
 proposal, though. This may break code looking for primitives but we need to 
 see what such code expects. Is it filtering out the legacy typeof-result 
 primitives (plus null), trying to find values for which typeof currently 
 returns object or function? If so, I don't see a problem: int64, bignum, 
 etc. are not legacy primitives. Is this test looking for objects that are 
 their own wrappers? Again all is well, unless mutable wrapper is assumed -- 
 but that's not safe in the ES5 era to assume, anyway.

The most frequent use case I’ve encountered: does the value have a prototype 
(i.e., will Object.getPrototypeOf() work)?

I’m assuming that value objects will have a prototype, accessible via 
Object.getPrototypeOf (?)

Axel

-- 
Dr. Axel Rauschmayer
a...@rauschma.de

home: rauschma.de
twitter: twitter.com/rauschma
blog: 2ality.com

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


Re: How primitive are Symbols? Bignums? etc

2013-07-15 Thread Brendan Eich

Axel Rauschmayer wrote:
The (x === Object(x)) test evaluates to true for value objects in 
this proposal, though. This may break code looking for primitives 
but we need to see what such code expects. Is it filtering out the 
legacy typeof-result primitives (plus null), trying to find values 
for which typeof currently returns object or function? If so, I 
don't see a problem: int64, bignum, etc. are not legacy primitives. 
Is this test looking for objects that are their own wrappers? Again 
all is well, unless mutable wrapper is assumed -- but that's not 
safe in the ES5 era to assume, anyway.


The most frequent use case I’ve encountered: does the value have a 
prototype (i.e., will Object.getPrototypeOf() work)?


I’m assuming that value objects will have a prototype, accessible via 
Object.getPrototypeOf (?)


Yes, they are after all value objects :-P.

js Object.getPrototypeOf(0UL)
0UL

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