From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Original-To: caml-list@yquem.inria.fr Delivered-To: caml-list@yquem.inria.fr Received: from concorde.inria.fr (concorde.inria.fr [192.93.2.39]) by yquem.inria.fr (Postfix) with ESMTP id 8419EBB9A for ; Sat, 22 Oct 2005 07:49:30 +0200 (CEST) Received: from kurims.kurims.kyoto-u.ac.jp (kurims.kurims.kyoto-u.ac.jp [130.54.16.1]) by concorde.inria.fr (8.13.0/8.13.0) with ESMTP id j9M5nSJ0020003 for ; Sat, 22 Oct 2005 07:49:29 +0200 Received: from localhost (suiren [130.54.16.25]) by kurims.kurims.kyoto-u.ac.jp (8.13.1/8.13.1) with ESMTP id j9M5nHh8014061; Sat, 22 Oct 2005 14:49:18 +0900 (JST) Date: Sat, 22 Oct 2005 14:49:16 +0900 (JST) Message-Id: <20051022.144916.23305070.garrigue@math.nagoya-u.ac.jp> To: stephen.brackin@verizon.net Cc: caml-list@yquem.inria.fr Subject: Re: [Caml-list] Duplicate functionality? From: Jacques Garrigue In-Reply-To: <0IOQ006I7LO24OK2@vms044.mailsrvcs.net> References: <0IOQ006I7LO24OK2@vms044.mailsrvcs.net> X-Mailer: Mew version 4.2 on Emacs 21.3 / Mule 5.0 (SAKAKI) Mime-Version: 1.0 Content-Type: Text/Plain; charset=us-ascii Content-Transfer-Encoding: 7bit X-Miltered: at concorde with ID 4359D2E8.000 by Joe's j-chkmail (http://j-chkmail.ensmp.fr)! X-Spam: no; 0.00; caml-list:01 ocaml:01 ocaml:01 subtyping:01 functors:01 recursive:01 constructors:01 functors:01 constructors:01 inference:01 subtyping:01 reuse:01 late-binding:01 verbose:01 model:01 X-Spam-Checker-Version: SpamAssassin 3.0.3 (2005-04-27) on yquem.inria.fr X-Spam-Level: X-Spam-Status: No, score=0.4 required=5.0 tests=DNS_FROM_RFC_ABUSE autolearn=disabled version=3.0.3 From: "Stephen Brackin" > My biggest initial question is why OCaml has both a modules system and > objects: Aren't they different ways of accomplishing the same things? I'm not aware of any detailed comparison between objects and modules in ocaml. However I'll try to give my thoughts on that. Both modules and object have multiple roles, and they only overlap for some. For instance, modules offer some kind of namespace management, which objects do not. This is different from Java which has no modules, and where classes have a role in namespace management. Similarly object subtyping allows the creation of heterogeneous collections of values, which is impossible with modules. Another specificity of objects is their extensibility through inheritance, with late binding (i.e. components can depend on each other.) You can try to do this with functors and recursive modules, but this quickly becomes rather heavy-weight. The real overlap between the two concepts is in their ability to create collections of methods, and to have parameterized constructors (functors for modules). Indeed, apart of the capacity to hide types, one could argue that objects alone can encode the whole module system, thanks to polymorphic methods. Practice shows that it ends up being rather clumsy: type parameters can only be expressed by type variables, which do not behave exactly like type constructors. Moreover object typing relies strongly on type inference, which can cause confusing error messages. Encoding objects into modules, as abstract data types, generally works well, but you lose object subtyping, and you must specify the module name for each method call (a light burden in general, but not so nice when using functors, and you end up with lots of module names around.) So yes, one could say that objects and modules provide different ways to do some similar things. This is particularly true for simple data structures like stacks or queues: there is no good reason to use one approach over the other. In practice they provide very different tradeoffs between flexibility and robustness. Modules are extremely robust, in that you are so explicit that the origin of any problem should be immediately clear. But this also means more verbosity, and some difficulties in reuse: you may have to parameterize on more modules than you would like to. On the other hand objects let you pass your implementation around with your data, making things much simpler at first. But their typing being more brittle, it can hurt when something goes wrong. Since one uses ML mostly for robustness, I suppose that when there is no explicit need for subtyping or late-binding, the natural way to go is modules. But when they become so verbose as to be cumbersome, and the underlying model is object-oriented, objects may be more comfortable. Both approaches expose their weaknesses when pattern-matching is involved: this essential feature of functional programming doesn't like any form of abstraction. By the way, I believe there is one further hurdle when using objects: their definitions are not compositional. That is, a module is just a collection of functions, which can exist themselves independently from one another (yet not independently of type defintions), but methods are not just functions (for instance you cannot pass the complete self to a function), and they cannot exist independently from objects. This makes harder the transition from the core language, where one usually starts writing, to the object language, where one might want to move. Jacques Garrigue