views:

348

answers:

3

I'm looking at OCaml's functors. It looks to me pretty identical to the so called generic objects in C++/C#/Java. If you ignore Java's type erasion for now, and ignore the implementation details for C++ templates (I'm interested with the language feature), functors are quite indentical to generics. If I understand it correctly, functor gives you a new set of functions from a type you provide, so that for example

List<MyClass>.GetType() != List<MyOtherClass>.GetType()

But you could roughly rewrite OCaml's

#module Set =
   functor (Elt: ORDERED_TYPE) ->
     struct
       type element = Elt.t
       type set = element list
       let empty = []
       let rec add x s =
         match s with
           [] -> [x]
         | hd::tl ->
            match Elt.compare x hd with
              Equal   -> s         (* x is already in s *)
            | Less    -> x :: s    (* x is smaller than all elements of s *)
            | Greater -> hd :: add x tl
       let rec member x s =
         match s with
           [] -> false
         | hd::tl ->
             match Elt.compare x hd with
               Equal   -> true     (* x belongs to s *)
             | Less    -> false    (* x is smaller than all elements of s *)
             | Greater -> member x tl
     end;;

into C#

class Set<T> where T : ISortable
{
    private List<T> l = new List<T>();
    static public Set<T> empty = new Set<T>();
    public bool IsMember(T x) {return l.IndexOf(x) > -1;}
    public void Add(T x) {l.Add(x);}
}

Sure there's a slight different since a functor affects a Module (which is just a bunch of types function and values definitions, similar to C#'s namespace).

But is it just it? Are functors merely generics applied to namespaces? Or is there any signifcant different between functors and generics which I'm missing.

Even if functors are just generics-for-namespace, what's the significant advantage of that approach? Classes can also be used as ad-hoc namespaces using nested classes.

+1  A: 

I just found a source that may help you with your problem - as OCaml has a different meaning for functors:

http://books.google.de/books?id=lfTv3iU0p8sC&amp;pg=PA160&amp;lpg=PA160&amp;dq=ocaml+functor&amp;source=bl&amp;ots=vu0sdIB3ja&amp;sig=OhGGcBdaIUR-3-UU05W1VoXQPKc&amp;hl=de&amp;ei=u2e8SqqCNI7R-Qa43IHSCw&amp;sa=X&amp;oi=book_result&amp;ct=result&amp;resnum=9#v=onepage&amp;q=ocaml%20functor&amp;f=false

still - I find it confusing if the same word is used for different concepts.


I don't know if OCaml has a different meaning - but normally a Functor is a "Function object" (see here: http://en.wikipedia.org/wiki/Function_object). This is totally different to generics (see here: http://en.wikipedia.org/wiki/Generic_programming)

A function object is an object that can be used as a function. Generics are a way to parametrize objects. Generics are kind of orthogonally to inheritance (which specializes objects). Generics introduce typesafety and reduce the need for casting. Functors are an improved function pointer.

Tobias Langner
Functor does indeed mean something different in OCaml (that is much closer to 'generic' than e.g. a C++ 'functor').
Brian
+3  A: 

But is it just it? Are functors merely generics applied to namespaces?

Yes, I think one can treat functors as "namespaces with generics", and that by itself would be very welcome in C++ where the only option left is to use classes with all static members which becomes pretty ugly soon. Comparing to C++ templates one huge advantage is the explicit signature on module parameters (this is what I believe C++0x concepts could become, but oops).

Also modules are quite different from namespaces (consider multiple structural signatures, abstract and private types).

Even if functors are just generics-for-namespace, what's the significant advantage of that approach? Classes can also be used as ad-hoc namespaces using nested classes.

Not sure whether it qualifies for significant, but namespaces can be opened, while class usage is explicitly qualified.

All in all - I think there is no obvious "significant advantage" of functors alone, it is just different approach to code modularization - ML style - and it fits nicely with the core language. Not sure whether comparing module system apart from the language makes much sense.

PS C++ templates and C# generics are also quite different so that comparing against them as a whole feels little strange.

ygrek
C++ and C# are different in the aspect of type system? I don't see how, in the bottom line you have a new type of List<string> whether it's supported by the VM or being automatically generated at compilation time. Do enlight me.
Elazar Leibovich
You are welcome.template<class T>class X{ T t; public: int hello() { return t.hello(); }};class Hello { public: int hello() { return 1; } };int main(){ X<Hello> x; return x.hello(); }
ygrek
Maybe I'm a little dense, but I didn't get it. In your example you have class Hello, and a class of the type X<Hello>, just like in C#. I verified that it prints 1 as expected http://codepad.org/vZUPwFgs what's the difference in the aspect of the type-system in the example you gave (of course, you used non-reference types you can only use in C++, but except of that I don't see the difference).
Elazar Leibovich
Note that template class parameter doesn't have any constraints in C++. Can you achieve this in C#?Templates have two distinct phases - definition and instantiation. This has many consequences : template classes must be available fully at instantiation hence tons of headers needed for moderately templatized code - leading to awfully long compilation times, errors in templates are detected late, compiler can easily perform more inlining and optimization, linker has more job to do to eliminate duplicate template instantions, etc
ygrek
A: 

You can curry functors.

Jon Harrop