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.1 required=5.0 tests=AWL,MAILTO_TO_SPAM_ADDR 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 DA93BBCCE for ; Mon, 8 Oct 2007 10:02:08 +0200 (CEST) X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AgAAAG74CEfAXQImh2dsb2JhbACOOQEBAQgKKQ X-IronPort-AV: E=Sophos;i="4.21,240,1188770400"; d="scan'208";a="2296986" Received: from discorde.inria.fr ([192.93.2.38]) by mail1-smtp-roc.national.inria.fr with ESMTP; 08 Oct 2007 00:20:02 +0200 Received: from mail3-relais-sop.national.inria.fr (mail3-relais-sop.national.inria.fr [192.134.164.104]) by discorde.inria.fr (8.13.6/8.13.6) with ESMTP id l97MK1wM023228 (version=TLSv1/SSLv3 cipher=RC4-SHA bits=128 verify=OK) for ; Mon, 8 Oct 2007 00:20:02 +0200 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AgAAAG74CEdCbwQZmWdsb2JhbACOOQEBAQEHBAQLCBg X-IronPort-AV: E=Sophos;i="4.21,240,1188770400"; d="scan'208";a="3892854" Received: from out1.smtp.messagingengine.com ([66.111.4.25]) by mail3-smtp-sop.national.inria.fr with ESMTP; 08 Oct 2007 00:20:00 +0200 Received: from compute2.internal (compute2.internal [10.202.2.42]) by out1.messagingengine.com (Postfix) with ESMTP id CB5D02FC37; Sun, 7 Oct 2007 18:19:58 -0400 (EDT) Received: from heartbeat1.messagingengine.com ([10.202.2.160]) by compute2.internal (MEProxy); Sun, 07 Oct 2007 18:19:58 -0400 X-Sasl-enc: ngD6Ca3XaaP8WnSFZqhepyNH5g2L7nyaZpI2V/hJwsY7 1191795598 Received: from [192.168.1.11] (AMontsouris-753-1-6-219.w90-2.abo.wanadoo.fr [90.2.193.219]) by mail.messagingengine.com (Postfix) with ESMTP id E49754586; Sun, 7 Oct 2007 18:19:57 -0400 (EDT) Date: Mon, 8 Oct 2007 00:19:51 +0200 (CEST) From: Martin Jambon X-X-Sender: martin@martin.ec.wink.com To: Luca de Alfaro Cc: caml-list@inria.fr Subject: Re: [Caml-list] Re: Why can't I call a function over a subclass? In-Reply-To: <28fa90930710052153k2128bb63m5132455868eb2008@mail.gmail.com> Message-ID: References: <28fa90930710050048p3d6f4e8cs8e13d0fe49d296f2@mail.gmail.com> <87ejg9oms3.fsf@pps.jussieu.fr> <1191592931.6509.33.camel@Blefuscu> <28fa90930710050759m682d8b65g72a31cc311acc276@mail.gmail.com> <28fa90930710050812i204e975ap847e7474ec9580bc@mail.gmail.com> <20071005152130.M41697@cs.unm.edu> <28fa90930710050849y64f2cc5en16d15c80c5576a61@mail.gmail.com> <4706679B.9030706@gmail.com> <28fa90930710051039o7d34aaddw62b9e095215513bd@mail.gmail.com> <28fa90930710052153k2128bb63m5132455868eb2008@mail.gmail.com> MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII; format=flowed X-Miltered: at discorde with ID 47095B91.000 by Joe's j-chkmail (http://j-chkmail . ensmp . fr)! X-Spam: no; 0.00; ens-lyon:01 bool:01 bool:01 ens-lyon:01 compiler:01 compiler:01 variants:01 checker:01 ocaml:01 checker:01 val:01 mutable:01 val:01 mutable:01 overriding:01 Luca, I think what you meant is: ---------- class r (x_init: int) = object method get_x : int = x_init end let f (r1: r) (r2: r) : bool = (r1#get_x = r2#get_x) class r' (x_init: int) = object inherit r x_init method get_xx : int = 2 * x_init end let q (r1: r') (r2: r') = f (r1 :> r) (r2 :> r) -------------- You could also write: let f r1 r2 : bool = ((r1 :> r)#get_x = (r2 :> r)#get_x) let q (r1: r') (r2: r') = f r1 r2 I think the second form is nicer, since f is now polymorphic, and accepts any object type which is compatible with r, such as r'. Martin On Fri, 5 Oct 2007, Luca de Alfaro wrote: > I am not so used to ":>"... looking at the example I posted, would you be > able to tell me how to make it type-check by adding ":>"? This would be > very much appreciated... > > Luca > > On 10/5/07, Martin Jambon wrote: >> >> On Fri, 5 Oct 2007, Luca de Alfaro wrote: >> >>> But the larger issue is: when a type is used for an input parameters, as >> the >>> type p in: >>> f : int -> p -> bool >>> why does the compiler have to complain that p has too many methods? >> >> That's your point of view. The compiler complains about different types, >> but it doesn't know which one is intended: does one object have >> too many methods or does the other object miss some methods? >> >> With some experience, you will learn that artificially annotating types >> of objects or polymorphic variants leads to much clearer and earlier error >> messages. >> >> So I would say that using ":>" is a rather mild annoyance, except that you >> have to learn what it means. >> >> >> Martin >> >> >>> Would it not be possible to make the type checker smarter, and ensure >> that >>> when p is an input type, it is ok to have more methods? >>> And for output types as well, it would seem? >>> In other words, what is that fundamentally breaks if one were to change >> the >>> ocaml type checker in this way? >>> >>> Luca >>> >>> On 10/5/07, Edgar Friendly wrote: >>>> >>>> Luca de Alfaro wrote: >>>>> Yes, here is some code. Any help would be very much appreciated. >>>>> The following fails to type check: >>>>> >>>>> class p (x: int) = object >>>>> method plus1 : int = x + 1 >>>>> end >>>>> >>>>> class p2 (x: int) = object >>>>> inherit p x >>>>> method plus2 : int = x + 2 >>>>> end >>>>> >>>>> class r = object (self) >>>>> val mutable l = [] >>>>> method make_el x = new p x >>>>> method add (x: int) : unit = l <- (self#make_el x) :: l >>>>> method length : int = List.length l >>>>> method total : int = List.fold_left (fun t el -> t + el#plus1) 0 l >>>>> end >>>>> >>>>> class r2 = object >>>>> inherit r >>>>> method make_el x = new p2 x >>>>> method total2 : int = List.fold_left (fun t el -> t + el#plus2) 0 l >>>>> end >>>>> >>>> if I manually perform the inherit operation by pasting the code from r1 >>>> into r2, I get: >>>> >>>> class r2 = object (self) >>>> val mutable l = [] >>>> method make_el x = new p2 x >>>> method add (x: int) : unit = l <- (self#make_el x) :: l >>>> method length : int = List.length l >>>> method total2 : int = List.fold_left (fun t el -> t + el#plus2) 0 l >>>> end >>>> >>>> which compiles just fine, and probably works as intended. If I include >>>> the original method make_el above the new one like this: >>>> method make_el x = new p x >>>> method make_el x = new p2 x >>>> Ignoring the warning about overriding methods within the same class, we >>>> come to the root of the type problem: make_el must have a type. After >>>> inference completes on the first line, make_el's type is determined to >>>> be p. The second make_el's type must match, but it doesn't. I don't >>>> see a solution for your problem that doesn't involve this kind of >> manual >>>> expansion and removal of duplicate methods, but I'm fairly sure this is >>>> the real problem for you. >>>> >>>> E. >>>> >>> >> >> -- >> http://martin.jambon.free.fr >> > -- http://martin.jambon.free.fr