Axel Rauschmayer wrote:
1. Absolutely love the multiple dispatch stuff (slide 10).
2. A bit uneasy about typeof, which will never properly express
JavaScript’s “class” hierarchy.
What class hierarchy? primitives have wrappers but those are not what
typeof tests. If you believe
Object
|
+-------+-------+----+----+----...
| | | |
Boolean Number String Function
then where are boolean, number, and string? There's no Value
(ValueObject) either.
Suppose we build a value object class (constructor/prototype) hierarchy:
Object
|
+-------+-------+----+----+--------+
| | | | |
Boolean Number String Function Value
|
+-------+-------+----+----+------+------...
| | | | |
boolean number string int64 uint64 ...
Would we be better off? Not only is there an abstract Value constructor,
but what about double? int32? uint32?
In general we would need a semi-lattice like the one depicted here:
http://asmjs.org/spec/latest/subtypes.png
but without the "-ish", fixnum, and extern types, and with the concrete
types listed above.
That is bound to always confuse people (already: “wait – I thought a
function was an object”, worse with value objects).
I don't hear that typeof f == "function" confuses people -- that's JS's
callable predicate for native (ordinary) objects. I do hear sometimes
that people wish typeof a == "array" worked, mainly because instanceof
doesn't work cross-frame.
Anyway, typeof 0L were to result in "object" we'd have not only
confusion but lack of a useful value-type query operator. TC39 agreed on
the use-case, and it upholds the (typeof x == typeof y && x == y) <=> (x
=== y) invariant.
But maybe it’s the best we can do.
There is no total class hierarchy describing all values in JS. If you
think we should retrofit one, make that case.
Being able to fix typeof null is awesome, though.
One could complain that mutating a typeof registry (map-pair) is a hack,
but hacks sometimes are the best thing in a pinch, and I don't see a
better way.
3. Also love that we’ll get 64 bit integers etc. (slide 11) and
user-definable value objects.
W.r.t. to #1: Couldn’t we extend that to universal multiple dispatch?
const removeAll = new MultiMethod(); // not a realistic example
removeAll.addMethod(Array, Set, (arr, set) => { ... });
removeAll.addMethod(Object, Map, (obj, map) => { ... });
You can do this with proxies and enough work. Operators are special
forms already, so have special semantics that I'm generalizing a bit to
be only somewhat more special-cased (the *last* special case, a general
extension mechanism).
Much as I am a fan of dead languages with multimethods, I'd rather leave
it at this for ES7.
For the plus operator:
import { operatorPlus } from '@operators';
operatorPlus.addMethod(Point, Number, (a, b) => Point(a.x + b, a.y + b);
operatorPlus.addMethod(Number, Point, (a, b) => Point(a + b.x, a + b.y);
operatorPlus.addMethod(Point, Point, (a, b) => Point(a.x + b.x, a.y +
b.y);
This is another way of realizing Function.defineOperator. Is it worth
the extra boilerplate? The strong reason to prefer it is to have
operatorPlus as a function value to pass around and invoke separately on
arbitrary values.
One could have both APIs, Function.defineOperator layered on the
@operators API. Function.defineOperators was Christian's suggestion and
I see the appeal: convenience for users as well as VM implementors (I've
implemented it under the hood in SpiderMonkey's int64/uint64 patch).
/be
_______________________________________________
es-discuss mailing list
[email protected]
https://mail.mozilla.org/listinfo/es-discuss