Allen Wirfs-Brock (2013-07-23T01:22:04.000Z)
On Jul 22, 2013, at 3:25 PM, Brendan Eich wrote:

> Allen Wirfs-Brock wrote:
>> On Jul 20, 2013, at 4:14 PM, Brendan Eich wrote:
>>> Allen Wirfs-Brock wrote:

right, to all of the above.

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

Yes, I agree that is a separate discussion.  We already have constructors that do different things and it remains possible to define them using ES6 class declarations regardless of whether or not it ends up being considered a pattern or an anti=pattern.

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

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.  Also Map/Set as currently implemented in FF, but that is also a seperate (but related) discussion.

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

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.

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.

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.

Allen

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20130722/9c07dce7/attachment.html>
domenic at domenicdenicola.com (2013-07-24T00:19:19.320Z)
On Jul 22, 2013, at 3:25 PM, Brendan Eich wrote:

> Allen Wirfs-Brock wrote:
>> On Jul 20, 2013, at 4:14 PM, Brendan Eich wrote:
>>> Allen Wirfs-Brock wrote:

right, to all of the above.

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

Yes, I agree that is a separate discussion.  We already have constructors that do different things and it remains possible to define them using ES6 class declarations regardless of whether or not it ends up being considered a pattern or an anti=pattern.

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

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.  Also Map/Set as currently implemented in FF, but that is also a seperate (but related) discussion.

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

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.

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.

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