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

Marijn Haverbeke marijnh at gmail.com
Mon Apr 16 15:26:03 PDT 2012

It's not just monads that require parameterized self types. It comes
up even in something like a generic collection type, if you want to
have a map operator.

I agree that the problems you raised are real, but I think giving up
on the self type this easily would be a shame. It seems that it
wouldn't be hard to take the low-tech approach of simply spitting out
a well-defined error when one of the situations you describe occurs.
Self types are used only as a kind of templates that are filled in
when an impl implements an iface. They don't leak into the type system
in general, as far as I can see (granted, I can't see all that far,
for I am not a type theoretician).


On Fri, Apr 13, 2012 at 12:52 AM, Niko Matsakis <niko at alum.mit.edu> wrote:
> 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
> _______________________________________________
> Rust-dev mailing list
> Rust-dev at mozilla.org
> https://mail.mozilla.org/listinfo/rust-dev

More information about the Rust-dev mailing list