4 ms·
Modules as Odersky refers to them here (modules "in the sense of ML") do not exist in Erlang or Haskell at all. They are a unique typing discipline. In MLs, in
by tel 12y ago
Modules as Odersky refers to them here (modules "in the sense of ML") do not exist in Erlang or Haskell at all. They are a unique typing discipline.
In MLs, in large part to ensure that HM-style type inference remains "complete", the module type language is stratified from the value type language. This feels a bit repetitive, causes slow expansion of flexibility and power in the module language, and makes it difficult to refer to modules dynamically.
For some, these are all good things. In this point of view, modules are "large" in a way that makes them difficult to reason about and so the restrictive language they're manipulated with is vital for making them reasonable.
For others, you might as well just unify the "large" module language and the "small" value language. If you do this carefully you might not even lose "complete" HM inference [0].
This is the path that Scala takes though it unabashedly tosses out HM inference for the a highly incomplete (e.g. "local") subtype/supertype logic.
Now there's a bit of an assertion that floats around that Scala's objects are essentially equal in power to what ML's modules would be if they were first class. I'm not sure if anyone could quite make this formal prior to the core calculus clean-up that is going through with dotty. Perhaps after that point the unique features of Scala will be emphasized... or we'll truly determine that Scala is just a unique approach to ML modules which has a different type inference engine.
[0] http://www.mpi-sws.org/~rossberg/1ml/ http://www.mpi-sws.org/~rossberg/1ml/
- tomp 12y agoI'm not sure you can emulate objects with modules. In particular, there is no "self" type with modules... or am I missing something?
- jamii 12y agoNo, ML modules are usually early bound which prevents open recursion eg module First = struct let rec even x = if (x >= 0) then ( print_endline "even!"; odd (x-1) ) else () and odd x = if (x >= 0) then ( print_endline "odd!"; even (x-1) ) else () module Second = struct include First let odd x = if (x >= 0) then ( print_endline "weird!"; even (x-1) ) else () end Second.odd(3) (* weird! * even! * odd! * even! *) In ocaml you can use classes for open recursion but that is implemented using dynamic dispatch. For static dispatch you would have to hack something together using a record that is passed itself.
- tomp 12y agoThat's more of an issue with implementation than with typing. I mean more like, in an OO language it is possible to declare an interface with a method that returns the final subtype (i.e. the object's this type), which isn't even know yet at the point the interface is defined.
- jamii 12y agoAh, I see what you are getting at. They seem related to me though. Open recursion requires calling the method from the final subtype rather than the current type - `even` would have to call `this#odd` instead of `odd`. The core problem in both cases is not being able to refer to the final subtype in any way. Hmmm, even if modules could refer to this final subtype you would probably have to choose between doing it via dynamic dispatch or sacrificing separate compilation, since the parent module doesn't know what method to dispatch to at the time of compilation.
- tel 12y agoThere are recursive modules but you're right if you're noting that modules don't offer open recursion. That's definitely something Scala offers that ML modules cannot.
- kvb 12y agoAndreas Rossberg comments a bit on the differences between ML modules and Scala objects/traits here [0]. [0] http://stackoverflow.com/questions/23006951/encoding-standard-ml-modules-in-oo/23019436#23019436 http://stackoverflow.com/questions/23006951/encoding-standar...