From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail4-relais-sop.national.inria.fr (mail4-relais-sop.national.inria.fr [192.134.164.105]) by walapai.inria.fr (8.13.6/8.13.6) with ESMTP id p7VLXHao031891 for ; Wed, 31 Aug 2011 23:33:18 +0200 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AngBAACoXk7UGyoDlGdsb2JhbABCqE4UAQEBAQkLCQkUAyKBQAEBBAE4QAYLCxgJFg8JAwIBAgFFBg0IAQGHbgK7EIZVBJMlhQ6LfQ X-IronPort-AV: E=Sophos;i="4.68,309,1312149600"; d="scan'208";a="107285218" Received: from smtp3-g21.free.fr ([212.27.42.3]) by mail4-smtp-sop.national.inria.fr with ESMTP; 31 Aug 2011 23:33:17 +0200 Received: from [192.168.0.14] (unknown [78.192.0.38]) by smtp3-g21.free.fr (Postfix) with ESMTP id D76DEA60E4 for ; Wed, 31 Aug 2011 23:33:10 +0200 (CEST) Message-ID: <4E5EA894.9060607@frisch.fr> Date: Wed, 31 Aug 2011 23:33:08 +0200 From: Alain Frisch User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:6.0) Gecko/20110812 Thunderbird/6.0 MIME-Version: 1.0 To: caml-list References: <4E58CCC3.4040901@gmail.com> <1314457588.3496.86.camel@thinkpad> <1314473840.3496.132.camel@thinkpad> <1314486489.3496.179.camel@thinkpad> <61B410B8-15EF-4B18-9CC5-C224FB495353@math.nagoya-u.ac.jp> In-Reply-To: <61B410B8-15EF-4B18-9CC5-C224FB495353@math.nagoya-u.ac.jp> Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Subject: Re: [Caml-list] Ocaml and the Fragile Base Class Problem On 8/29/2011 5:35 AM, Jacques Garrigue wrote: > If you want just to structure your program, modules are better in most cases. > There are still situations where classes are stronger than modules for structuring: > * when you have a default for some operation, but want to be able to change it > * when you want to mix components, using multiple inheritance and virtual methods > and instance variables I second that. We are moving some parts of our code base to a mixin style implemented with multiple inheritance, virtual methods, constraints, very rare overridding (and no instance variables). This results in drastic reduction of code size compared to our previous approach where code sharing between components was implemented with simple function calls. The code is also easier to evolve. We create objects (without state) to represent bags of properties computed from parameters; each method represents a property. An object is created by assembling reusable mixins (inheritance) and implementing remaining virtual methods. Once the object is created, we observe a few properties and throw the object away. In effect, we use objects to describe purely functional computation graphs, with reusable sub-graphs. (Most methods don't take argument; in order to avoid repeated evaluation, we have a special hack which rewrites an object's method table so as to give its methods a lazy behavior.) The nice thing with this approach is that the object layer does all the plumbing automatically. Combining several reusable components does not require to pass data around from one component to another explicitly. The old style with functions required to pass many arguments, deconstruct the result (a component typically computes several things), organize reusable components to avoid mutual recursions, and define many data types (records to represent the result of components). In some cases, a large amount of the code was caused by such plumbing. > Also, for various reasons, objects are not beginner friendly. > I think the main problem is that they don't fit that well with type inference: > both subtyping and polymorphic methods require explicit type annotations. Time to advertise the implicit-subtyping branch? -- Alain