need some clarification on compile-time type vs. run-time type
Brendan Eich
brendan at mozilla.org
Sat Nov 10 22:50:03 PST 2007
On Nov 10, 2007, at 9:57 PM, Brendan Eich wrote:
> If I understand your point, it's that if we allow
>
> (a is T)
>
> given a type name T bound by a type, class, or interface definition;
> but we disallow
>
> let (t = T) (a is t)
>
> and insist on
>
> let (t = T) (a is type t)
Make that
let (t = type T) (a is type t)
But even that doesn't work. I forgot an agreement from the September
face-to-face meeting, to make 'is' less future-hostile to an "ES5"
that merges type and value expressions somehow: change 'is' to insist
on a type expression only, therefore not including the unary 'type E'
vaue-expression.
This results in the current RI's behavior, modulo that bug where
'type T' => null (those FIXME comments in eval.sml):
>> type T = {p:int}
>> let t = T
[locn] /Users/brendaneich/Hacking/es4/com.mozilla.es4.smlnj/builtins/
Error.es:86:55-86.55
[stack] [init t()]
**ERROR** EvalError: uncaught exception: TypeError: getValue on a
type property: <public >::T (near /Users/brendaneich/Hacking/es4/
com.mozilla.es4.smlnj/builtins/Error.es:86:55-86.55)
>> let t = type T
>> t
null
>> o = {p:42}
[object Object]
>> o is T
false
>> q = {p:42}:T
[object Object]
>> q is T
true
>> q is t
**ERROR** VerifyError: expected type fixture for: [[<public >,
<internal >], [<public __ES4__>]]::t (near <no filename>:1:2-1.1)
while normalizing <TypeName: {(<public >, <internal >), (<public
__ES4__>)}::t> (near <no filename>:1:2-1.1)
>> q is type t
**ERROR** ParseError: expecting semicolon before identifier(t) (near
<no filename>:1:2-1.1)
>> q is (type t)
**ERROR** ParseError: unknown token in unionType (near <no filename>:
1:2-1.1)
See, 'is' won't even begin to parse 'type t' or parenthesized
(union!) forms of same. The RI bug that made t null doesn't matter.
> The issues are (AFAIK):
>
> * Should instanceof do its loosey-goosey ES3 thing for functions,
> which have mutable .prototype, and mix this backward-compatible
> feature into different-in-many-ways subtype tests done by 'is'-as-
> proposed?
My current thinking is "no" but I'd like to think more.
> * Should 'is' insist on fixed type name in its right operand, or is
> this inconsistent and pointless, an RI bug even?
So it's not an RI bug (ignoring the lack of meta-object hookup). It's
intentional future-proofing against the day when merging type and
value expressions (somehow!) is upon us. Which you've expedited! ;-)
If we allow a value expression on the right of 'is', the only
syntactic ambiguities are structural type expressions:
record: {p:int, q:string}
array: [boolean, double, string]
union: (undefined, string)
function: function (A,B):C /* no body, I'm a type */
Requiring these to be prefixed by unary 'type' and committing to the
consequences (no strict-mode checking of 'is' by fancy, even
conservative analyses; no future where we merge type and value
expressions differently) does seem better to me. But I'm forgetting
something from that September meeting, maybe. Checking minutes...
http://wiki.ecmascript.org/doku.php?
id=meetings:minutes_sep_27_2007#proposal_walkthrough
Ticket 103: http://bugs.ecmascript.org/ticket/103
Seems the resolution ruled narrowly by pointing to meta-objects, as
I've done a couple of times in this thread. But the big picture
confusion you point out, that users expect dyadic operators to take
value expression operands, and that fixed type names vs. other names,
even well-bound let variable names (let const even!) can't be used on
the right of 'is', seems not to have been considered.
If I nerd out over types, yeah: is/cast/wrap all take a right operand
which must be a type expression. Get used to it, poindexter! ;-) But
really, it's a bit harsh and anti-JS to say this, for 'is' at any
rate. Possibly the verb is too short and overloaded. More work
needed, I think.
/be
More information about the Es4-discuss
mailing list