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

Reply via email to