<br><br><div class="gmail_quote">On Tue, May 24, 2011 at 11:46 AM, Jesper Louis Andersen <span dir="ltr"><<a href="mailto:jesper.louis.andersen@gmail.com">jesper.louis.andersen@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin: 0pt 0pt 0pt 0.8ex; border-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;">
<div class="im">On Tue, May 24, 2011 at 11:05, Kresten Krab Thorup <<a href="mailto:krab@trifork.com">krab@trifork.com</a>> wrote:<br>
><br>
> One of the things he's arguing is that modules should be VALUES.  A "module" in newspeak is kind of a template (function), which take other module instances as arguments.  So you hook up a system by applying such templates (possibly using letrec).<br>

><br>
<br>
</div>This is a great idea. Why? Because it is the path of existential types :-)<br>
<br>
Notice that in Erlang, a module is a Value. It is possible to call<br>
Mod:Fun(..). Second, notice that the parameterized module extension<br>
allows us to parameterize a module over some other module.<br>
Specifically we could have<br>
<br>
-module(RBTree, [OrderMod]).<br>
<br>
where OrderMod is a module which has a function<br>
<br>
-opaque t() :: .....<br>
-export_type([t/0]).<br>
-spec order(t(), t()) -> lt | eq | gt.<br>
<br>
and so we have generalized our RedBlack trees to be able to use any<br>
ordering relation, not simply the one that is built it.<br>
<br>
The style Gilad is advocating is the "Fully functorial style" from the<br>
Standard ML community. A Functor[1] in SML terminology is a function<br>
from module to module ("functor" stems from category theory where it<br>
designates a "function"[2] one level up). In the style, you build up<br>
programs by stitching together smaller modularized parts building<br>
larger and larger modules in the process.<br>
<br>
Example: The gen_server is a functor from a module (which obeys the<br>
gen_server behaviour and has handle_* functions) to a specific<br>
instance of a server.<br>
<br>
It also gives you quite the path towards the concept of OOP, as can be<br>
observed from the parameterized module extension and its uses in<br>
various places.<br>
<br>
In languages with static types, you can of course enforce that functor<br>
applications are type-correct. If you allow modules as values in such<br>
languages you get existential types which is a way to get something<br>
OOP-like into those languages[3].<br>
<br>
So after a little tour around: Erlang already has this :P<br>
<br>
Modules are an essential part of building large systems. The very<br>
notion that you can pack up functions in a module and ship them as a<br>
unit is quite important. Also the notion you can replace a<br>
module-component at once. I feel that the problem of function<br>
placement in the right module is less of a problem compared to the<br>
hell it would be with one large global namespace. And it is much more<br>
than just a "bunch of functions thrown together".<br>
<br>
Specifically, modules allows me to have an *abstract* view of a data<br>
structure. In the above, I have no idea what t() is. I am only allowed<br>
to compare two t()'s to each other with OrderMod:compare(T1, T2). That<br>
is, the only algebraic operation I am allowed to do is this. Other<br>
parts of the program may have a different view of t() and be able to<br>
do more with it, but to me, it is an opaque term. It matters because<br>
someone can go replace t(), and my code does not have to be changed at<br>
all. This is impossible if t() leaks. And I am grateful the dialyzer<br>
can find places where it is leaking.<br>
<br>
Likewise, a module can hide the fact it is implemented with a<br>
gen_server. So I can go replace it with a gen_fsm, and nobody has to<br>
alter their code because the API i exported was exactly the API I will<br>
keep stable.<br>
<br>
Processes componentize the heap.<br>
Modules componentize the code.<br>
<br></blockquote><div><br>If we think of modules as containers of functions, then a module is a "set of functions" -<br>my problem is with granularity. The smallest unit of reuse is the module. Suppose my application<br>
want just one function from a particular module - I'm forced to load the entire module.<br><br>This hampers reuse - I *often* read library code and find a single function and cut-and-paste it into<br>my new code. It also discourages sharing - since the smallest unit I can share is a module.<br>
<br>The unit of distribution is an application - a set of modules - why this could not be a list of functions<br>I do not know.<br><br>I think I'd like to view an application as something that offered a message based service that internally<br>
was constructed from a set of functions rather than a set of modules.<br><br> /Joe<br><br> </div><blockquote class="gmail_quote" style="margin: 0pt 0pt 0pt 0.8ex; border-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;">

<br>
<br>
[1] Beware of connotating the word functor in programming with<br>
something specific in computer science. The meaning is different in<br>
Standard ML, in Haskell and in C++.<br>
<br>
[2] I am lying. The basic notion is a morphism of which the function<br>
is a special case when considering the category of Sets.<br>
<br>
[3] I still don't get why you can't use static typing in Erlang. The<br>
conservative approach is simply to use polymorphic variants for all<br>
message passing and it would essentially work right out of the bat.<br>
<br>
--<br>
<font color="#888888">J.<br>
</font></blockquote></div><br>