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.9 required=5.0 tests=AWL,DNS_FROM_RFC_ABUSE autolearn=disabled version=3.1.3 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 5C0B9BBAF for ; Mon, 6 Apr 2009 10:34:13 +0200 (CEST) X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AhsCABxb2UnUGyoDlGdsb2JhbACWJgEBAQEJCwgJEQOyEYQPBoc6 X-IronPort-AV: E=Sophos;i="4.38,431,1233529200"; d="scan'208";a="27106993" Received: from smtp3-g21.free.fr ([212.27.42.3]) by mail1-smtp-roc.national.inria.fr with ESMTP; 06 Apr 2009 10:34:12 +0200 Received: from smtp3-g21.free.fr (localhost [127.0.0.1]) by smtp3-g21.free.fr (Postfix) with ESMTP id 6CFE08181C7; Mon, 6 Apr 2009 10:34:06 +0200 (CEST) Received: from [192.168.17.1] (ivr94-8-88-162-26-239.fbx.proxad.net [88.162.26.239]) by smtp3-g21.free.fr (Postfix) with ESMTP id 68E96818103; Mon, 6 Apr 2009 10:34:04 +0200 (CEST) Message-ID: <49D9BED7.4000201@users.sourceforge.net> Date: Mon, 06 Apr 2009 10:35:35 +0200 From: Zheng Li User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:1.9.1b4pre) Gecko/20090405 Lightning/1.0pre Shredder/3.0b3pre MIME-Version: 1.0 To: Jacques Garrigue Cc: caml-list@yquem.inria.fr Subject: Re: Instance variables can't be polymorphic? {a few more annoyances on "val" syntax} References: <49D93BB3.501@users.sourceforge.net> <20090406.124055.116565018.garrigue@math.nagoya-u.ac.jp> In-Reply-To: <20090406.124055.116565018.garrigue@math.nagoya-u.ac.jp> Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit X-Spam: no; 0.00; val:01 syntax:01 iter:01 polymorphism:01 syntax:01 polymorphism:01 val:01 iter:01 subtyping:01 ocaml:01 semantics:01 decr:01 recursion:01 2009:98 sourceforge:01 Hello Jacques, On 4/6/2009 5:40 AM, Jacques Garrigue wrote: > > Actually it's polymorphic, but only at the level of inheritance. > You could define two objects inheriting from c, one using print_int, > and the other print_string, and this would work. > > Due to functional update (i.e. {< iter = ...>}), object-level > polymorphism would have to be explicit, but as you pointed next, no > syntax is provided for explicitly polymorphic fields. Thanks for your clear explanation! >> Trying to declare the polymorphism explicitly as >> >> -- >> val iter : 'a. ('a -> unit) -> 'a list -> unit = List.iter >> -- >> >> won't work. This syntax is only allowed for methods. > > Yes. It would be too difficult to add such a functionality, but what > kind of application do you have in mind? One of my project relies heavily on OO. We choose OO not in the traditional OO sense, but for the benefits of - structural subtyping - privileges control The OO part is merely an "interface". The core is functional, and all the objects will be dropped right after the declaration/initialization phrase. Here, selective access restriction of some data by declaring them as instance variable is just one way to control privilege, so that only objects of current class and its subclasses can access them. It's not 100% safe since such objects can still expose the data again through public methods, however this will only happen when they really intend and take effort to make the mistake(?) > The simplest way I see currently is to use a let defined field (i.e., > before the object keyword, but then you can't access it after > inheritance), or to use a private method. What is your problem with a > private method? It should be more flexible. > Of course you can also define a record to wrap your polymorphic value. Yes, private method is also the closest solution I could though of. "let" is not acceptable since the definition must be accessible through inheritance. I preferred instance variable (if it could work in the same way) than private method since - it's more lightweight in syntax - it's more lightweight in execution cost - with instance variable, I can totally drop all objects right after the initialization; with private method, some part of the definition will still point back to objects since they contain self#xxx inside. But anyway, assorting to private methods is still acceptable considering various aspects. I will probably take this approach. [OT]: Here are a few more annoyances on the syntax of instance variable I've encountered. I recorded it here for comments: Why it can't just copy the common "let" syntax in OCaml? Even though it's possible to just lift the awkward "val" definitions out of objects and using "let" instead, I'm really uncomfortable when being forced to do that. Besides, the lifted variables won't be accessible through inheritance any more, so they are not strictly equivalent or interchangeable in semantics. Currently, the "val" syntax - doesn't support pattern matching assignment. Instead of -- let a,b,c,d = tuple4 -- one write -- val a = match tuple4 with a,_,_,_ -> a val b = match tuple4 with _,b,_,_ -> b val c = match tuple4 with _,_,c,_ -> c val d = match tuple4 with _,_,_,d -> d -- This is still the easy case, image if your pattern matching will also trigger some side-effect. - doesn't support sharing state. -- let up,down = let r = ref 0 in (fun () -> incr r; !r), (fun () -> decr r; !r) -- can't be expressed directly as instance variables - doesn't support shortcut syntax of function definition like -- val f x y z = x + y + z -- instead one must write -- val f = fun x y z -> x + y + z -- - doesn't support recursion. Instead of -- val rec fact n = if n <= 1 then 1 else n * fact (n-1) -- one must write -- val fact = let rec fact_rec n = if n <= 1 then 1 else n * fact_rec (n-1) in fact_rec -- - all parallel assignments, no assignment orders, hence can't refer to previous assignment -- val x = 3 val y = x + 11 -- is wrong, even if it makes perfect sense in many situations. To access "x", one is simply forced to declare "y" as method! Any comments? -- Zheng