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

Reply via email to