[rust-dev] paring back the self type to be, well, just a type

Niko Matsakis niko at alum.mit.edu
Thu Apr 12 15:52:44 PDT 2012


On 4/12/12 2:08 PM, Dave Halperin wrote:
> I'm not advocating either way on this in terms of the complexity 
> tradeoff for adding a kind system, just pointing out that it's what 
> you'd need to make the current system work and it's not completely 
> crazy to want that flexibility out of the type system.

Yes, this was one use case that the self type was intended to model 
(though not the one that I think will come up most often).  I don't 
think this is crazy by any means, but right now our type system has no 
notion of (Haskell-style) kinds and it'd be a big change to add them.

It's possible that the self type should be yanked altogether, but it's 
come in handy for me many times, but always in its simpler incarnation 
of "the type of the receiver" rather than "the type function defined by 
the current iface".

In any case, I spent some time trying to adapt the iface system---in any 
form!---to writing generic monadic code and I decided it's just not a 
very good fit.  There are two major hurdles.

First, we have no good way to define a "return" function (though perhaps 
we could add static or class methods to ifaces).

Second, and this is more major, we define monadic implementations for 
some concrete type and we should be doing it for all types.  In 
principle, something like
     impl<A> of monad<A> for option<A> { ... }
seems like it does what we want, but it also permits things like:
     impl<A> of monad<uint> for option<A> { ... }
for which there is no clear mapping from which to derive the self type.  
I think to do this correctly, we'd rather write something like:
     impl of monad for option { <A> ... }
which would also fit with the "kind" notion of Haskell: here the type 
being implemented for has kind * => * and so does monad.

Of course, we would also need to be able to write things like:
     fn mapM<A,B,M:monad>(
         a: [A],
         b: fn(A) -> M<B>) -> M<[B]> { ... }
Here the parameter M is bound to some (* => *) type constructor for 
which monad is defined.

I am not opposed to adding such capabilities at some point.  But they 
don't feel like burning issues to me right *now*.


Niko


More information about the Rust-dev mailing list