Allen Wirfs-Brock wrote:
Various thoughts...
Thanks, it's pre-strawman here so all are welcome.
Slipping in support for redefining 'typeof null' feels like the sort of thing I
sometimes try to squeeze through ;-)
Heh. It's one reason for Function as the static namespace (no methods on
null). More below.
Why is setTypeOf attached to Function? There would seem to be very little to
naturally associate it with Function. I suppose it's because that's where you
put 'defineOperator'.
I mentioned why already: to accomodate (null | value-object-constructor)
as the first parameter.
Even there, the association with Function seems tenuous. I actually find a
stronger association with Math.
I took lots of Math in school, never ran across typeof :-P.
But really, why aren't these just functions export from the reflection module
or some other standard module?
Could do that instead -- Reflect.defineOperator, Reflect.setTypeOf for
now as Tom has done with Proxies (awaiting the name of the standard
reflection module).
Regarding realm associations? What is the rationale for making the typeof
binding per realm? I would expect the people would want (at least operator
associated) value object instances to be freely used across realms, just like
numbers, strings, and booleans are.
Why would you expect methods attached to prototypes to be cross-realm?
They wouldn't be even for double-dispatch, in this sense: you would not
know which "@@ADD" or (Python) "__add__" you were calling across a
realm. In an OOP sense this works, but for dyadic operators as Chambers,
et al. argue, it's wrong. The multimethod approach fits the problem
precisely, but only same-realm or (if cross-realm) only if you load the
same value object extension in both realms.
All methods have realm dependencies. If you are assuming built-in status
means string primitives get the same indexOf, e.g., even that can be
monkeypatched to diverge cross-realm.
And I don't think you have mentioned anything about defineOperator creating
realm specific operator bindings.
You missed the point Luke made at the meeting: see the v + u operator
semantics slide, where p intersect q is based on function object
indentity, and functions are realm-specific without extra work (e.g.,
loading a value object extension once in an iframe and ensuring all
instances come from that iframe -- artificial, contrived!).
So, I would expect that in:
x + 1
the value of x may be (for example) a decimal number defined in a different
realm and that the + gets appropriately dispatched to do a Decimal+Number add
operation.
Which one, though? However the dispatch works, methods on prototypes are
per-realm.
In that case, I would also expect
typeof x
to give me 'decimal' (or whatever) as registered in the original defining
domain.
If you mean x's domain that makes typeof depend on a symbol-named
prototype property, or equivalent relationship. But that is not wanted,
because per the meeting any attempt to redefine a value object's typeof
should throw, but we can't control what's defined or redefined on
prototypes.
As Jasvir suggested, lexically scoped extensions compose better, and in
that case, typeof x would definitely not depend on x's realm if it
weren't same-realm with the scope of that expression.
There also seems like a possible consistancy that should maintained between new
typeof values and the new Literal Syntax suffix support.
Cross-realm inconsistency due to prototypes differing is a thing in JS.
Anywhere you can say '0m' you probably should be able to say typeof x ==
'decimal. But this seems like it should be lexically scoped rather than Realm
scoped.
No, lexical wouldn't cut it if x flowed into the evaluation context's
realm from realm 2 where 0m was originally evaluated and assigned to x.
You really do need pan-realm typeof (as the built-ins provide), which is
not a thing in JS for user-code to extend.
I would argue that Functioun.setTypeOf(null, "null") is actually a different
kind of beast and one that you would want to be lexically scoped. The difference is that
it is changing the meaning of a pre-existing operator applied to a pre-existing value.
This reinterpretation really does need to be scoped only to code that wants to see that
change.
Ok, good feedback between you and jasvir. This suggests using the syntax
I mooted:
typeof null = "null"; // lexically rebind typeof null
new code here
typeof null = "object"; // restore for old code after
Also see below:
On Jul 28, 2013, at 2:24 PM, Brendan Eich wrote:
Brendan Eich wrote:
Function.setTypeOf(V, U)
1. Let S = ToString(U)
2. Let T = V
3. If T is null then
3a. If S is not "null" and S is not "object", throw
4. Else
4a. If T is not a value object constructor, throw
4b. T = T.prototype
4c. If TypeofToExemplarMap.has(S), throw
5. Call TypeofToExemplarMap.set(S, T)
6. Call ExemplarToTypeofMap.set(T, S)
Correction, see new 4b below:
1. Let S = ToString(U)
2. Let T = V
3. If T is null then
3a. If S is not "null" and S is not "object", throw
4. Else
4a. If T is not a value object constructor, throw
4b. If T and Function are not same-realm, throw
setTypeOf itself has a realm association so that's what I would expect you
would test against. You don't really have access to Function. It might have
been passed in as the this value or might not if setTypeOf was invoked via
call or been hung-off of a namespace object.
Right, thanks.
But just like setPrototypeOf, I'm not sure that it matters which Realm you
retrieved your setTypeOf function from. If each Realm has it's own
TypeToExemplarMap than everything will be fine if setTypeOf just gets the map
associated with T's (actually V.prototype) Realm.
Does that rescue the realm-dependency in your view?
/be
_______________________________________________
es-discuss mailing list
[email protected]
https://mail.mozilla.org/listinfo/es-discuss