need some clarification on compile-time type vs. run-time type

Yuh-Ruey Chen maian330 at
Tue Nov 13 22:40:22 PST 2007

Brendan Eich wrote:
> > I think that would be a good thing. Another thought: if |x is v|,  
> > where |v| is a meta-object, works, then one would think that it  
> > should also work for |like|, e.g.
> >
> > var x = int
> > 10 is x; // ok
> > 10 is like x; // ?
> >
> > But if that last statement is allowed, then so is |var y: like x|,  
> > which is undecidable (if that's the correct term), so evidently | 
> > like| shouldn't work with value exprs.
> This is a hot topic. We could indeed allow all sorts of type  
> expressions, and define evaluation rules so that (I hope) nothing  
> diverges and we don't need to set a watchdog timer on strict mode's  
> type checker. The static guarantees go down because strict mode will  
> punt anything it can't figure out to runtime, treating the compile- 
> time type as *. It seems wiser at the moment to restrict type  
> annotations and remain future proof, but make 'is' friendlier as you  
> and I have been discussing.

I agree.

> > Might want to mention this in any clarification you put into the  
> > spec, even if it's strictly disallowed in the formal grammar - that  
> > even though |is| allows a value expr on the right side, it cannot  
> > be nested within a type expr. That means given |var x|, none of |10  
> > is like x|, |10 is (x)|, |10 is {p: x}|, etc. are syntactically  
> > allowed.
> I think we're now inclined to allow those but insist on a type at  
> runtime. But this is something to discuss more.

I don't see how that's workable. I mean, technically it is, since |is|
is a runtime check. But it creates another "incompatibility" between
type annotations and |is|, and you seem pretty adamant to keep the two
as coherent as possible. Just consider:

T = cond? int : double;
x is {p: T}; // ok
var y : like {p: T}; // early type error

> > There are couple potential problems with upgrading |instanceof| to  
> > match the syntax of the revised |is|:
> >
> > 1) Function expr syntax ambiguity. Consider:
> >
> > a) x is function(p: int): int // ok
> > b) x is function(p: int): int {} // syntax error
> > c) x instanceof function(p: int): int // ok?
> > d) x instanceof function(p: int): int {} // syntax error?
> Oh, I see -- on second thought I meant nothing like allowing (d) --  
> sorry. instanceof only takes a value expression on its right, but if  
> that evaluates to a type meta-object, it does something sane and  
> "instance-of"ish.

So I take that |x instanceof {p: int}| won't work, and we'd have to use
|T = type {p: int}; x instanceof T| instead?

>From your other email:
> Er, I meant (c), if you remove type annotations from the function  
> param and result. In ES3 today, you can write
> js> ({}) instanceof function (){}
> false
> It's silly, of course, because the function expression is captured by  
> the right operand and could not have been constructed via operator  
> new to get the left operand. But it's valid ES3 syntax, so we can't  
> switch instanceof's right operand to favor a function structural type.

I truly doubt there is any code out there with (d). It's a backwards
incompatibility I'd be willing to break. If there is code out there with
this, well, the new syntax error should tell them that they're doing
something really stupid.

> > 3) Parenthesis ambiguity. This is the most troublesome one. Consider:
> >
> > a) x is (int) // ok
> > b) x is (some_constructor) // syntax error
> > c) x is ({p: int}) // ok
> > d) x instanceof (int) // ok
> > e) x instanceof (some_constructor) // syntax error?
> > f) x instanceof ({p: int}) // how should this be treated?
> Yes, and parenthesized expression may follow operator new, so this is  
> a hard limit.

Plenty of discussion going on in ticket 300 concerning this. Ugh, this
semi-merging of value and type exprs is getting awkward. We're ending up
with just as many gotchas as we had before at this rate.

Alright, overview time again. Our current goals are:
1) Make |is| less restrictive and allow it accept (some) value exprs.
2) Keep |is| and type annotations coherent.
3) Keep |is| and |instanceof| (somewhat) coherent.
4) Keep all the type operators coherent (to a certain extent).
5) Try not to introduce too many exceptions to the rule a.k.a. gotchas.

Whatever we do to advance one goal, another goal becomes more
compromised. Maybe we can place priorities on these goals? If we can
abandon one or two of these in favor of the other goals, this job would
be much simpler. Need to think on this some more...

-Yuh-Ruey Chen

More information about the Es4-discuss mailing list