Brendan Eich (2013-07-23T01:30:58.000Z)
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
domenic at domenicdenicola.com (2013-07-24T00:19:59.060Z)
Allen Wirfs-Brock wrote:
> My concern is that the pattern
>
> ```js
> 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.
>
> ```js
> 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.