From: Zheng Li <zheng_li@users.sourceforge.net>
To: Jacques Garrigue <garrigue@math.nagoya-u.ac.jp>
Cc: caml-list@yquem.inria.fr
Subject: Re: Instance variables can't be polymorphic? {a few more annoyances on "val" syntax}
Date: Mon, 06 Apr 2009 10:35:35 +0200 [thread overview]
Message-ID: <49D9BED7.4000201@users.sourceforge.net> (raw)
In-Reply-To: <20090406.124055.116565018.garrigue@math.nagoya-u.ac.jp>
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
next prev parent reply other threads:[~2009-04-06 8:34 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-04-05 23:16 Instance variables can't be polymorphic? Zheng Li
2009-04-06 3:40 ` [Caml-list] " Jacques Garrigue
2009-04-06 8:35 ` Zheng Li [this message]
2009-04-06 9:55 ` [Caml-list] Re: Instance variables can't be polymorphic? {a few more annoyances on "val" syntax} Goswin von Brederlow
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=49D9BED7.4000201@users.sourceforge.net \
--to=zheng_li@users.sourceforge.net \
--cc=caml-list@yquem.inria.fr \
--cc=garrigue@math.nagoya-u.ac.jp \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox