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
_______________________________________________
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss