Self type

Eylon Stroh estroh at
Mon Aug 13 16:25:29 PDT 2007

>From the proposal:
"The return type T2 is ok, even if the function returns a T1 instead...
covariant occurrences of Self (eg in the result type) are replaced by

Please correct me if I'm wrong, but it seems to me that return types can
also be placed in contexts where covariance is not guaranteed.  In the
following (admittedly contrived) code snippet, the type of y.f cannot be
function(this:T2):T2, or even function(this:*):T2 (where * denotes
run-time type checking).  As far as I can tell, it has to be

type T1 = { w:int, f:function(this:Self):Self };
var x:T1 = { w:5, f:function(this:T1):T1
		var result:T1;
		if(this.w < 1)
			result = { w:1, f:this.f }:T1;
			result = { w:this.w-1, f:this.f }:T1;
			// this requires f to return T1
			result = this.f(result);
			result.w *= this.w;
		return result;

type T2 = { f:function(this:Self):Self };
var y:T2 = x;

Have I missed something that allows for stronger typing of y.f?


-----Original Message-----
From: es4-discuss-bounces at
[mailto:es4-discuss-bounces at] On Behalf Of Brendan Eich
Sent: Monday, August 13, 2007 2:40 PM
To: Peter Hall
Cc: es4-discuss; Cormac Flanagan
Subject: Re: Self type

On Aug 13, 2007, at 1:59 PM, Peter Hall wrote:

>>> Or can't Self be used outside of the sorts of usage found in the 
>>> proposal examples?
>> That's it.
> In that case, I think it needs to be clearer about how the syntax can 
> be used.

No doubt the proposal needs to be clearer to become a spec.

> Is it only for use as the "this" parameter for function types?

No, but it is only for function types within object structural types.  
See the "Use Cases" section:

     * clone, iterators: {f:function():Self}
     * binary methods, equals: { f : function(x:Self):boolean }
     * structural object methods: { f : function(this:Self, ...) } -
only useful if structural objects with types


Note that the "same type" case, equals, requires a runtime check to be
generated. This eliminates the kind of instanceof or downcasting
hand-written boilerplate seen in Java's equals implementations.

> Seems to me like it should be usable anywhere that the compiler can 
> reasonably detect the type at compile-time.
> e.g.
> // this usage is handy for boiler-plate code that you can just copy //

> and paste without modification, or from an IDE code snippet template 
> class A { var a:Self; // or...
> // var a:this type;
> }

This is not a strong motivation IMHO.

> type B = {b:Self};

We don't allow recursive structural types in general, but this kind of
degenerate cycle might be ok. Cormac should comment.

> Other places where special treatment of the keyword would be useful is

> in interfaces, where the a function argument or return value should be

> the same as the type:
> interface IClonable {
> public function clone():Self;
> }
> class A implements IClonable {
>   public function clone():A { return new A() }; }

Indeed -- those are use-cases for interfaces and classes as well as for
structural types. However, the proposal is focused on structural types
since unlike classes, |this| binding defaults to the dynamic rule from
ES1-3, which is weak.

> That is, users of the interface see the type as being the same as the 
> interface, but implementors must use their own type here. The example 
> is identical to clone's return type being IClonable, except that 
> implementors are required to declare a stronger type.

Good point. I'll defer to Cormac on commenting further.


Es4-discuss mailing list
Es4-discuss at

More information about the Es4-discuss mailing list