Brendan Eich (2013-07-29T23:04:56.000Z)
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
domenic at domenicdenicola.com (2013-08-12T05:22:36.229Z)
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:

```js
typeof null = "null"; // lexically rebind typeof null
/* new code here */
typeof null = "object"; // restore for old code after
```


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