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.3 required=5.0 tests=AWL,HTML_MESSAGE, 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 C4A4CBC69 for ; Fri, 5 Oct 2007 19:39:07 +0200 (CEST) X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AgAAAJcTBkdC+VLjkmdsb2JhbACCOzaLSAIBAQcEBBMW X-IronPort-AV: E=Sophos;i="4.21,236,1188770400"; d="scan'208";a="2198169" Received: from concorde.inria.fr ([192.93.2.39]) by mail1-smtp-roc.national.inria.fr with ESMTP; 05 Oct 2007 19:39:07 +0200 Received: from mail1-relais-roc.national.inria.fr (mail1-relais-roc.national.inria.fr [192.134.164.82]) by concorde.inria.fr (8.13.6/8.13.6) with ESMTP id l95Hd71M008839 (version=TLSv1/SSLv3 cipher=RC4-SHA bits=128 verify=OK) for ; Fri, 5 Oct 2007 19:39:07 +0200 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AgAAAJcTBkdC+VLjkmdsb2JhbACCOzaLSAIBAQcEBBMW X-IronPort-AV: E=Sophos;i="4.21,236,1188770400"; d="scan'208";a="2198166" Received: from wx-out-0506.google.com ([66.249.82.227]) by mail1-smtp-roc.national.inria.fr with ESMTP; 05 Oct 2007 19:39:06 +0200 Received: by wx-out-0506.google.com with SMTP id h28so591805wxd for ; Fri, 05 Oct 2007 10:39:05 -0700 (PDT) Received: by 10.142.191.2 with SMTP id o2mr1744655wff.1191605943970; Fri, 05 Oct 2007 10:39:03 -0700 (PDT) Received: by 10.142.80.4 with HTTP; Fri, 5 Oct 2007 10:39:03 -0700 (PDT) Message-ID: <28fa90930710051039o7d34aaddw62b9e095215513bd@mail.gmail.com> Date: Fri, 5 Oct 2007 10:39:03 -0700 From: "Luca de Alfaro" To: "Edgar Friendly" Subject: Re: [Caml-list] Re: Why can't I call a function over a subclass? Cc: "William D. Neumann" , "Inria Ocaml Mailing List" In-Reply-To: <4706679B.9030706@gmail.com> MIME-Version: 1.0 Content-Type: multipart/alternative; boundary="----=_Part_28932_20591190.1191605943937" References: <28fa90930710050048p3d6f4e8cs8e13d0fe49d296f2@mail.gmail.com> <4705EF58.3040605@bik-gmbh.de> <1191580233.6509.26.camel@Blefuscu> <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> X-Miltered: at concorde with ID 470676BB.000 by Joe's j-chkmail (http://j-chkmail . ensmp . fr)! X-Spam: no; 0.00; bool:01 compiler:01 checker:01 ocaml:01 checker:01 val:01 mutable:01 val:01 mutable:01 overriding:01 inference:01 bool:01 compiler:01 ocaml:01 overriding:01 ------=_Part_28932_20591190.1191605943937 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit Content-Disposition: inline I thank you all for the help... in the end, I solved the practical problem by collapsing p and p2 into the same class -- not so nice, but it works, and it is simpler than other solutions. 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? 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. > ------=_Part_28932_20591190.1191605943937 Content-Type: text/html; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit Content-Disposition: inline I thank you all for the help... in the end, I solved the practical problem by collapsing p and p2 into the same class -- not so nice, but it works, and it is simpler than other solutions.

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?
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 <thelema314@gmail.com> 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.

------=_Part_28932_20591190.1191605943937--