From mboxrd@z Thu Jan 1 00:00:00 1970 Received: (from majordomo@localhost) by pauillac.inria.fr (8.7.6/8.7.3) id UAA22756; Thu, 21 Aug 2003 20:45:12 +0200 (MET DST) X-Authentication-Warning: pauillac.inria.fr: majordomo set sender to owner-caml-list@pauillac.inria.fr using -f Received: from nez-perce.inria.fr (nez-perce.inria.fr [192.93.2.78]) by pauillac.inria.fr (8.7.6/8.7.3) with ESMTP id UAA27967 for ; Thu, 21 Aug 2003 20:45:11 +0200 (MET DST) Received: from pyramid.twistedmatrix.com (adsl-64-123-27-105.dsl.austtx.swbell.net [64.123.27.105]) by nez-perce.inria.fr (8.11.1/8.11.1) with ESMTP id h7LIitT24229 for ; Thu, 21 Aug 2003 20:44:59 +0200 (MET DST) Received: from chris by pyramid.twistedmatrix.com with local (Exim 3.35 #1 (Debian)) id 19puQD-0001c5-00 for ; Thu, 21 Aug 2003 13:44:33 -0500 Date: Thu, 21 Aug 2003 13:44:33 -0500 From: Chris Clearwater To: caml-list@inria.fr Subject: Re: [Caml-list] does class polymorphism need to be so complicated? Message-ID: <20030821184433.GA3068@pyramid.twistedmatrix.com> References: <3F440702.8040704@socialtools.net> <20030821102946Y.garrigue@kurims.kyoto-u.ac.jp> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20030821102946Y.garrigue@kurims.kyoto-u.ac.jp> User-Agent: Mutt/1.3.28i X-Loop: caml-list@inria.fr X-Spam: no; 0.00; caml-list:01 0900,:01 jacques:01 lablgtk:01 shorter:01 ditch:01 closures:01 printf:01 printf:01 inference:01 chris:01 chris:01 int:01 garrigue:01 coercion:01 Sender: owner-caml-list@pauillac.inria.fr Precedence: bulk On Thu, Aug 21, 2003 at 10:29:46AM +0900, Jacques Garrigue wrote: > Another approach which was not described yet, and which I use in > lablgtk for instance, is to add a coercion method to classes which form > the top of a hierarchy. This way you just have to write > printer#print obj#printable > in place of a coercion, which may be shorter and avoid strange error > messages when failing. > To do this you just have to add the following to the printable virtual > class: > class virtual printable = object (self) > method virtual ... > method printable = (self :> printable) > end Another approach if you are using abstract base classes to simulate an interface it to ditch the object system altogether and use closures. You might do something like this: printable.ml: type printable = { print: unit -> unit; } let create p print = { print = fun () -> print p } let print p = p.print () circle.ml: type circle = {radius: float} let create r = {radius=r} let print c = Printf.printf "Circle, radius: %f" c.radius let as_printable c = Printable.create c print main.ml: let c = Circle.create 10.0 let p = Circle.as_printable c let _ = Printable.print p Some nice side effects of this is that you get better type inference, non-virtual function calls when you dont need an abstract type (Circle.print) and probally better performance for virtual calls as well. Also keep in mind that for any virtual function that takes more arguments besides the object itself (most of them) you can avoid the unit hack and use partial application (say draw took a size and color arguments): drawable.ml: type drawable = { draw: int -> color -> unit } let create d draw = { draw = draw d } let draw d = d.draw etc.. main.ml somewhere: .. Drawable.draw c 10 red > And if you're going to change the requirements of a method in the > middle of your development, this means that there was something wrong > in your design. Overall object-oriented languages are much weaker > than functional languages at changing design afterwards. With this method you just change the as_printable functions :) ------------------- To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/ Beginner's list: http://groups.yahoo.com/group/ocaml_beginners