Allen Wirfs-Brock (2013-07-22T20:59:35.000Z)
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          //true    similarly 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
>
domenic at domenicdenicola.com (2013-07-24T00:16:34.547Z)
On Jul 20, 2013, at 4:14 PM, Brendan Eich wrote:

> Relax "mutable" in the first comment and remove "object" from the second comment and we have relevant precedent:
> 
> ```js
>  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:

```js
new Boolean(false) === false //false   similarly String and Number
Boolean(false) === false          //true    similarly 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:

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

bikesheding starts here...