Allen Wirfs-Brock (2013-07-20T03:49:09.000Z)
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 at mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss
> 

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20130719/813f1ebb/attachment.html>
domenic at domenicdenicola.com (2013-07-24T00:15:20.990Z)
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:

```js
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):

```js
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