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.0 required=5.0 tests=none autolearn=disabled version=3.1.3 X-Original-To: caml-list@yquem.inria.fr Delivered-To: caml-list@yquem.inria.fr Received: from mail4-relais-sop.national.inria.fr (mail4-relais-sop.national.inria.fr [192.134.164.105]) by yquem.inria.fr (Postfix) with ESMTP id 9EC79BBC4 for ; Wed, 1 Apr 2009 00:05:26 +0200 (CEST) X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AukBAPQv0knZSMDqi2dsb2JhbACBU5Q3AQEBCgsKBw8FuCODegY X-IronPort-AV: E=Sophos;i="4.39,304,1235948400"; d="scan'208";a="37604062" Received: from fmmailgate03.web.de ([217.72.192.234]) by mail4-smtp-sop.national.inria.fr with ESMTP; 01 Apr 2009 00:05:26 +0200 Received: from smtp05.web.de (fmsmtp05.dlan.cinetic.de [172.20.4.166]) by fmmailgate03.web.de (Postfix) with ESMTP id D1387F9CC284 for ; Wed, 1 Apr 2009 00:05:00 +0200 (CEST) Received: from [78.43.226.218] (helo=frosties.localdomain) by smtp05.web.de with asmtp (TLSv1:AES256-SHA:256) (WEB.DE 4.110 #277) id 1Lom4q-0003g7-00 for caml-list@yquem.inria.fr; Wed, 01 Apr 2009 00:05:00 +0200 Received: from mrvn by frosties.localdomain with local (Exim 4.69) (envelope-from ) id 1Lom4q-0008Nf-48 for caml-list@yquem.inria.fr; Wed, 01 Apr 2009 00:05:00 +0200 From: Goswin von Brederlow To: caml-list@yquem.inria.fr Subject: Bug? Constraints get ignored in methods Date: Wed, 01 Apr 2009 00:05:00 +0200 Message-ID: <87ab71ic1f.fsf@frosties.localdomain> User-Agent: Gnus/5.110006 (No Gnus v0.6) XEmacs/21.4.21 (linux) MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Sender: goswin-v-b@web.de X-Sender: goswin-v-b@web.de X-Provags-ID: V01U2FsdGVkX1/F3rwVMvFYb8kVEPYmqYQOzboM4YR2PMKVtpmO t8CQC5fr02eAXTnirlyCE4ZjVkJI/XIfIkuc36vJQc6Kr44gxF a1EKsWz4Q= X-Spam: no; 0.00; bug:01 subset:01 ocaml:01 subset:01 val:01 mutable:01 val:01 mutable:01 foo:01 foo:01 superset:01 ocaml:01 superset:01 bug:01 syntax:01 Hi, I want to keep a linked list of structures that have a common subset of functionality. I thought this would be a good use of ocaml objects. A base class with the common subset of functionality and methods to link them. And then derived classes for the specific types. Most simplified it looks like this: # class type base_type = object val mutable next : base_type option method set_next : base_type option -> unit end;; class type base_type = object val mutable next : base_type option method set_next : base_type option -> unit end # class base : base_type = object val mutable next = None method set_next n = next <- n end;; class base : base_type # class foo = object inherit base method foo = () end;; class foo : object val mutable next : base_type option method foo : unit method set_next : base_type option -> unit end # let a = new base in let b = new foo in a#set_next (Some (b :> base_type));; - : unit = () # let a = new base in let b = new foo in a#set_next (Some b);; ^ Error: This expression has type foo but is here used with type base_type The second object type has no method foo This last error isn't nice. I don't want to have to cast the objects all the time. So I thought there must be a better way using polymorphic methods with a constraint. But here is where everything breaks down. First lets look at just the set_next method: # class type virtual vbase_type = object method virtual set_next : 'a. 'a option -> unit constraint 'a = #vbase_type end;; class type virtual vbase_type = object method virtual set_next : 'a option -> unit end # class virtual vbase : vbase_type = object method virtual set_next : 'a. 'a option -> unit constraint 'a = #vbase_type end;; class virtual vbase : vbase_type # class base = object inherit vbase method set_next _ = () end;; class base : object method set_next : 'a option -> unit end # let b = new base;; val b : base = # b#set_next (Some 1);; - : unit = () Huh? That should not work. 1 is not a superset of #vbase_type. The constraint gets completly ignored by ocaml. Adding back the next gives further problems: # class type virtual vbase_type = object val mutable next : #vbase_type option method virtual set_next : 'a. 'a option -> unit constraint 'a = #vbase_type end;; class type virtual vbase_type = object val mutable next : #vbase_type option method virtual set_next : 'a option -> unit end # class virtual vbase : vbase_type = object val mutable next = None method virtual set_next : 'a. 'a option -> unit constraint 'a = #vbase_type end;; class virtual vbase : vbase_type # class base = object inherit vbase method set_next n = next <- (n :> vbase_type option) end;; ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Error: This method has type #vbase_type option -> unit which is less general than 'a. 'a option -> unit Again I blame ocaml for dropping the constraint. Given the constraint the type would be correct. So how do I have to specify the set_next method that any superset of #base_type will be accepted as argument? Or is that a bug in ocaml and my syntax is perfectly fine? MfG Goswin