Parameterized Modules

Edit: ouch, i misread “Nov '15” as being “15. Nov” and now i realize this thread is actually 2 years not 2 days old and that this is probably a necropost, sorry about that :confused:

Interesting thread! It’s cool to see people thinking about this kind module system / type system evolutions. I wanted to comment on “Rust traits/impls == ML signature/module/functor”.

So indeed, there is not that much difference between (existing) trait impls and ML-like functors that you propose but i don’t think these differences have actually been laid down:

  • trait implementations are anonymous, modules/functors are named,
  • consequently there is the coherance rule in Rust, ie for every trait-type couple there can be only one implementation (the rules are being loosened a bit by specialization but that doesn’t change the big picture).

Apart from that they are basically the same. So to bring an ML-like module system to Rust there are two paths: parametrizing modules or naming trait implementation items (shameless plug: i started a thread about that second path which i believe would be smoother syntax-wise). The weird thing is that Rust already has modules, but these modules are just namespaces and in ML they use non-parametrized modules with inferred signature as namespaces.

My main argument for this changes is the added consistency of merging the story of currently distinct parts of Rust (modules, traits and impls). Moreover it would bring a new light to some other things that are currently not so bright or under discussion:

  • When we want to implement a trait for a type that already implements it differently, the story could be changed from using the newtype pattern and derive (which is a complicated machinery) to having named implementations and the possibility to opt-out from the automatic resolving and give the specific instance we want at the call site or to explicitely manage the resolving with implicit use stuff::good_impl; (instead of the usual use stuff::Trait;).
  • For opaque signature (we want to constrain the interface, the usual struct Miles(f64); example) we could stop the newtype pattern and go the ML way of differenciating abstract types and transparent aliases. One way to go would be to add a new abstract item that has locally the same semantic as type but would only advertise an opaque type outside of the local module.
  • I believe this would provide a solid ground to naturally add a few fancy type stuff that are often requested (has already been a bit mentionned in the thread): higher-kinded types could be as traits associated items or parameters, generic const parameters by reifying types to kinds with the foo<X: const T> parameter annotation…