Brendan Eich (2013-07-22T22:25:21.000Z)
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          //true    similarly 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
domenic at domenicdenicola.com (2013-07-24T00:17:58.809Z)
Allen Wirfs-Brock wrote:
> 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.

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.).

> 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?

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

```js
int64.value(x)
```

and not

```js
int64(x)
```

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

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

?