From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.1.3 (2006-06-01) on yquem.inria.fr X-Spam-Level: X-Spam-Status: No, score=0.4 required=5.0 tests=AWL,DNS_FROM_RFC_ABUSE autolearn=disabled version=3.1.3 X-Original-To: caml-list@yquem.inria.fr Delivered-To: caml-list@yquem.inria.fr Received: from mail1-relais-roc.national.inria.fr (mail1-relais-roc.national.inria.fr [192.134.164.82]) by yquem.inria.fr (Postfix) with ESMTP id 213DCBBCA for ; Wed, 27 Feb 2008 02:37:46 +0100 (CET) X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: Ao8CAAJOxEeCNhAB/2dsb2JhbACuLw X-IronPort-AV: E=Sophos;i="4.25,410,1199660400"; d="scan'208";a="8631204" Received: from kurims.kurims.kyoto-u.ac.jp ([130.54.16.1]) by mail1-smtp-roc.national.inria.fr with ESMTP; 27 Feb 2008 02:37:44 +0100 Received: from localhost (orion [130.54.16.5]) by kurims.kurims.kyoto-u.ac.jp (8.13.8/8.13.8) with ESMTP id m1R1bbWk006031; Wed, 27 Feb 2008 10:37:37 +0900 (JST) Date: Wed, 27 Feb 2008 10:37:33 +0900 (JST) Message-Id: <20080227.103733.43387508.garrigue@math.nagoya-u.ac.jp> To: Tiphaine.Turpin@free.fr, caml-list@yquem.inria.fr Subject: Re: [Caml-list] OO programming From: Jacques Garrigue In-Reply-To: <47C4AE08.5000604@free.fr> References: <47BD44FE.3050001@irisa.fr> <20080226.151750.16504093.garrigue@math.nagoya-u.ac.jp> <47C4AE08.5000604@free.fr> X-Mailer: Mew version 4.2 on Emacs 22.1 / Mule 5.0 (SAKAKI) Mime-Version: 1.0 Content-Type: Text/Plain; charset=us-ascii Content-Transfer-Encoding: 7bit X-Spam: no; 0.00; guis:01 model:01 indirection:01 high-level:01 ocaml:01 ocaml:01 subtyping:01 subtyping:01 modular:01 verbose:01 explicitely:01 verbose:01 coherence:01 bug:01 recursive:01 From: "Tiphaine.Turpin" > First, my desired use of objects is not (reduced to) programming a gui. > I can imagine that, in guis, the actions that may be invoked on objects > or that may originate from them are just signals with rather simple > types, which form a simple case of object communication for which action > connection is enough, but when it comes to using objects to model the > objects of the application domain, stronger links (i.e., fields) are > sometimes natural. Note that, in class diagrams, links between classes > are one of the most basic concepts. My point was that it's not because it is a good concept that it is necessarily a good programming technique. That is, you might want to right your class diagram with links between classes, but use an indirection at the connection level in your implementation, if it makes things simpler. I see no contradiction there. But as I wrote in my previous mail, OO people often prefer to have their concepts directly apparent in their programs. > > But I think your disagreement lies at a different level: OO > > programmers often want to express their own view of things directly > > into the language. > Yes. Clearly, I want the abstractions, patterns, etc. I have in mind to > be expressed themselves as language objects, and not just their > "instanciation". Isn't this the very goal of high-level languages after > all ? Yes, but the ocaml approach is to define entities independently, and let types handle the interconnections. This does not fit well with class diagrams. So if you want to keep your class diagram apparent, you need painful contorsions. Note also that your original goal, being able to extend families of classes at the type level, is an active research area. When ocaml was created, there was no OO language able to do it explicitly, or even implicitly (as ocaml does). Now you might have your chance with Scala or gBeta. > > Klaus Ostermann. Nominal and structural subtyping in component-based > > programming. Journal of Object Technology, 7(1):121 - 145, 2008. > > > An interesting reading. The expressive power that he adds to nominal > subtyping gives me more arguments to consider structural subtyping not > very usefull (but I understand that structural is much more consistent > with everything else in ocaml). Not really. He build his nominal subtyping as an extension of structural subtyping. And I'm personally not sure that the nominal part gets him much (out of better error messages, which do matter) > >> Hence my question: does anyone knows a way of combining the reusability > >> of sets of related classes with a more modular (type/consistency)-checking ? > >> > > > > I'm not sure whether it helps, but I attach here the same example of > > observer pattern as in the tutorial, > which tutorial ? Section 5.3 of the reference manual, which is a variation on the one you were mentionning. > > but without using type parameters. They are replaced by private row types. > > > which is very verbose (having to explicitely write class types), and I'm > not sure I understand the benefits of doing this. Verbose indeed. I didn't say this was the right way to do it, just that it lets you express more relations in the interfaces. > > Ideally, one would like to check coherence too by writing > > module rec Check : S' = Window(Check) > > Unfortunately, this doesn't seem to work currently. I'm not yet sure > > whether this is a bug or a limitation of recursive modules. > > > If the typing of recursive modules just types the body of each module in > the environment given by the declared module types of all modules > involved in the recursive definition, then this cannot work, since > Window(Check) would have to be of type S' for any Check : S', which is > clearly false (e.g. Check = struct ... type observer = notify : ...). No, the typing of recursive modules is much more clever, otherwise it wouldn't be useful. So, conceptually, this could work. For instance, if you drop the ability to add methods to the observer, the check goes through: module type S' = sig type event = private [> `Move] type subject = private type observer = event -> unit> end module Window(X:S') = struct module AX = Any(X) type event = X.event class observer = object inherit AX.observer method notify s e = s#draw end let count = ref 0 class virtual subject = let id = count := succ !count; !count in object (self) inherit AX.subject val mutable position = 0 method identity = id method move x = position <- position + x; self#notify_observers `Move method draw = Printf.printf "{Position = %d}\n" position; end end module rec Check : S' = Window(Check) This way you can see that subject and observer are compatible without providing concrete instances. However, when the observer and subject have both extensible types, there seems to be an interaction between nominal and structural types, and the knot cannot be tied. > As for extension, I'm fully satisfied. But the verbosity level is > annoying for scalability... Well, yes, that's always the problem with functors... Jacques Garrigue