caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
* [Caml-list] polymorphic methods
@ 2015-12-18  9:18 Christoph Höger
  2015-12-18 10:07 ` Leo White
  0 siblings, 1 reply; 20+ messages in thread
From: Christoph Höger @ 2015-12-18  9:18 UTC (permalink / raw)
  To: caml users

Dear all,

I am attempting to store polymorphic methods in classes (i.e. keep the
type variables out of the class-type by putting them directly into the
method signatures).

However, I have some trouble when it comes to convince the compiler that
my code is typecorrect:

type ('a, 'b) f_arg = < x : 'b; .. > as 'a ;;
let f : 'a 'b . (('a,'b) f_arg) -> 'b  = fun a -> a#x ;;
class foo = object method f : 'a 'b . ('a, 'b) f_arg -> 'b = f end  ;;

yields:

Error: This expression has type
'a 'b. (< x : 'b; .. > as 'a) -> 'b
but an expression was expected of type
'c 'b. (< x : 'b; .. > as 'c) -> 'b
The type variable 'd occurs inside 'd

What is 'd? Why do these types not unify?

-- 
Christoph Höger

Technische Universität Berlin
Fakultät IV - Elektrotechnik und Informatik
Übersetzerbau und Programmiersprachen

Sekr. TEL12-2, Ernst-Reuter-Platz 7, 10587 Berlin

Tel.: +49 (30) 314-24890
E-Mail: christoph.hoeger@tu-berlin.de

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [Caml-list] polymorphic methods
  2015-12-18  9:18 [Caml-list] polymorphic methods Christoph Höger
@ 2015-12-18 10:07 ` Leo White
  0 siblings, 0 replies; 20+ messages in thread
From: Leo White @ 2015-12-18 10:07 UTC (permalink / raw)
  To: caml-list

Hi,

This probably constitutes a bug, seeing as the problem only occurs when using a type alias:

# class foo = object
    method f : 'a 'b. (< x: 'b; ..> as 'a) -> 'b = assert false
  end;;
    class foo : object method f : < x : 'b; .. > -> 'b end

# type ('a, 'b) f_arg = < x : 'b; .. > as 'a;;
type ('a, 'b) f_arg = 'a constraint 'a = < x : 'b; .. >

# class foo = object
    method f : 'a 'b. ('a, 'b) f_arg -> 'b = assert false
  end;;
    Characters 30-76:
      method f : 'a 'b. ('a, 'b) f_arg -> 'b = assert false
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Error: This expression has type 'a 'b. (< x : 'b; .. > as 'a, 'b) f_arg -> 'b
       but an expression was expected of type
         'c 'b. (< x : 'b; .. > as 'c, 'b) f_arg -> 'b
       The type variable 'd occurs inside 'd

Regards,

Leo

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [Caml-list] polymorphic methods
  2003-03-13  9:27     ` Jacques Garrigue
@ 2003-03-13 14:49       ` Damien
  0 siblings, 0 replies; 20+ messages in thread
From: Damien @ 2003-03-13 14:49 UTC (permalink / raw)
  Cc: caml-list

On Thu, 13 Mar 2003 18:27:02 +0900
Jacques Garrigue <garrigue@kurims.kyoto-u.ac.jp> wrote:


> > but that's not really a beautiful piece of code !
> And I would not have expected it to be!
> This was just a theoretical answer.
:-)

> If you are bothered by coercions, you may have a look at the trick in
> lablgtk, which avoids polymorphic methods: give the parent as
> argument.
> let new_node ?parent () =
>   let n = new node in
>   begin match parent with None -> ()
>   | Some (p : #a_t) -> p#add (n :> a_t)
>   end;
>   n
> You can also do the trick in an initializer.
That's what I planned to do, but my trees are 'dynamic', i.e. I need to
move nodes across the tree, so an initializer is not sufficient ...
-> I'll use some helper function, or the tricks that have been proposed


> Alternatively, you might just have an interface of a_t without
> the method m. This way you have no problem with recursion:
> 
> class type a0_t = object
>   ... everything but add ...
> end
> class type a_t = object
>   inherit a0_t
>   method add : #a0_t -> unit
> end
But then, when I retrieve a child from its parent, it has no more add
capability :-(


> > I don't know what do you mean when saying 
> > "such a type cannot be defined", in fact, I could define this 
> > equivalent (I think it is...) :
> > 
> > >#class type a_t = object 
> > >   method m: 'a.(<m: 'a -> unit; ..> as 'a) -> unit 
> > >end 
> 
> This is not equivalent: the m in a_t is a polymorphic method, but not
> the one in the recursion. Polymorphic and monomorphic methods are
> incompatible, so you cannot pass an a_t to m.
thanks for the explanation !


Now, questions :
Would it be useful to accept such a type (not just for my trees) ?
Would it be correct (semantically) ?

You told about "a way to recurse on a quantified polymorphic method
rather than on the whole object." (that does not exists), 
Would it be useful (and correct) ? Has someone studied this ?

damien

-------------------
To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr
Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [Caml-list] polymorphic methods
  2003-03-13  9:04   ` Damien
  2003-03-13  9:27     ` Jacques Garrigue
@ 2003-03-13  9:41     ` Olivier Andrieu
  1 sibling, 0 replies; 20+ messages in thread
From: Olivier Andrieu @ 2003-03-13  9:41 UTC (permalink / raw)
  To: Damien; +Cc: caml-list

 Damien [Thursday 13 March 2003] :
 > My goal is to define a tree, whose node's type is a class
 > type a_t, containing a method for adding children.
 > but the child type can be any subtype of a_t
 > 
 > * this method can safely be typed [a_t->unit], but this will require a
 > lot of coercions in the rest of the code...

How about adding a coerce method in a_t ? That way, the coercion
appears only in the class definition, not everytime you want to add a
node.

,----
| class type a_t = object
|   method add : a_t -> unit
|   method children : a_t list
|   method coerce : a_t
| end
| 
| class a : a_t =
|   object (self)
|     val mutable children = []
|     method add c = children <- c :: children
|     method children = children
|     method coerce = (self :> a_t)
|   end
`----
 and then :

  parent#add child#coerce

or even :
let adder p c =
  p#add c#coerce

Hope this helps,

-- 
   Olivier

-------------------
To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr
Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [Caml-list] polymorphic methods
  2003-03-13  9:04   ` Damien
@ 2003-03-13  9:27     ` Jacques Garrigue
  2003-03-13 14:49       ` Damien
  2003-03-13  9:41     ` Olivier Andrieu
  1 sibling, 1 reply; 20+ messages in thread
From: Jacques Garrigue @ 2003-03-13  9:27 UTC (permalink / raw)
  To: Damien.Pous; +Cc: caml-list

From: Damien <Damien.Pous@ens-lyon.fr>
> > > Does someone know why the following class type
> > > is not accepted ?
> > > 
> > > # class type a = object method m: 'a. (#a as 'a) -> unit end;;
> > > The abbreviation #a expands to type #a but is used with type < .. >
> > [...]
> > Now, the serious part: can such a type be defined?
> > After working a bit on this riddle, I'm afraid the answer is no.
> > The reason is that there is no way to recurse on a quantified
> > polymorphic method rather than on the whole object.
> > The closest I found is:
> >   class type a =
> >     object method m : < d : 'b. (< m : 'a; .. > as 'b) -> unit > as 'a
> >     end
> > The dummy wrapper <d : 'b. ... > is just there to allow one to recurse
> > on the polymoprhic method itself. You can call the method m by doing
> > [a#m#d a'] in place of [a#m a'].
> I worked with this class type, but it is a bit tedious :-(
> 
> My goal is to define a tree, whose node's type is a class
> type a_t, containing a method for adding children.
> but the child type can be any subtype of a_t
> 
> * this method can safely be typed [a_t->unit], but this will require a
> lot of coercions in the rest of the code...
> 
> * that's why I wanted to type it ['a. (#a_t as 'a)->unit] (i.e. the
> coercion is written only once, in the method)
> 
>  using your trick, I obtained the attached code. It works fine,
> but that's not really a beautiful piece of code !

And I would not have expected it to be!
This was just a theoretical answer.

If you are bothered by coercions, you may have a look at the trick in
lablgtk, which avoids polymorphic methods: give the parent as
argument.
let new_node ?parent () =
  let n = new node in
  begin match parent with None -> ()
  | Some (p : #a_t) -> p#add (n :> a_t)
  end;
  n
You can also do the trick in an initializer.

Alternatively, you might just have an interface of a_t without
the method m. This way you have no problem with recursion:

class type a0_t = object
  ... everything but add ...
end
class type a_t = object
  inherit a0_t
  method add : #a0_t -> unit
end

> I don't know what do you mean when saying 
> "such a type cannot be defined", in fact, I could define this 
> equivalent (I think it is...) :
> 
> >#class type a_t = object 
> >   method m: 'a.(<m: 'a -> unit; ..> as 'a) -> unit 
> >end 

This is not equivalent: the m in a_t is a polymorphic method, but not
the one in the recursion. Polymorphic and monomorphic methods are
incompatible, so you cannot pass an a_t to m.

Jacques Garrigue

-------------------
To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr
Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [Caml-list] polymorphic methods
  2003-03-13  1:56 ` Jacques Garrigue
@ 2003-03-13  9:04   ` Damien
  2003-03-13  9:27     ` Jacques Garrigue
  2003-03-13  9:41     ` Olivier Andrieu
  0 siblings, 2 replies; 20+ messages in thread
From: Damien @ 2003-03-13  9:04 UTC (permalink / raw)
  Cc: caml-list

[-- Attachment #1: Type: text/plain, Size: 2980 bytes --]

On Thu, 13 Mar 2003 10:56:56 +0900
Jacques Garrigue <garrigue@kurims.kyoto-u.ac.jp> wrote:

> From: Damien <Damien.Pous@ens-lyon.fr>
> 
> > Does someone know why the following class type
> > is not accepted ?
> > 
> > # class type a = object method m: 'a. (#a as 'a) -> unit end;;
> > The abbreviation #a expands to type #a but is used with type < .. >
> [...]
> Now, the serious part: can such a type be defined?
> After working a bit on this riddle, I'm afraid the answer is no.
> The reason is that there is no way to recurse on a quantified
> polymorphic method rather than on the whole object.
> The closest I found is:
>   class type a =
>     object method m : < d : 'b. (< m : 'a; .. > as 'b) -> unit > as 'a
>     end
> The dummy wrapper <d : 'b. ... > is just there to allow one to recurse
> on the polymoprhic method itself. You can call the method m by doing
> [a#m#d a'] in place of [a#m a'].
I worked with this class type, but it is a bit tedious :-(

My goal is to define a tree, whose node's type is a class
type a_t, containing a method for adding children.
but the child type can be any subtype of a_t

* this method can safely be typed [a_t->unit], but this will require a
lot of coercions in the rest of the code...

* that's why I wanted to type it ['a. (#a_t as 'a)->unit] (i.e. the
coercion is written only once, in the method)

 using your trick, I obtained the attached code. It works fine,
but that's not really a beautiful piece of code !



I don't know what do you mean when saying 
"such a type cannot be defined", in fact, I could define this 
equivalent (I think it is...) :

>#class type a_t = object 
>   method m: 'a.(<m: 'a -> unit; ..> as 'a) -> unit 
>end 

this class type definition being accepted, why is the former 
rejected ? 
both should be either rejected if this make no sense, or accepted else


then I tried to implement it, 
but I couldn't  do it "meaningfully" :

># class a: a_t = object
>   val mutable l = []
>   method m: 'a.(<m: 'a -> unit; ..> as 'a) -> unit = 
>     fun o -> l <- (o:>a_t) :: l
> end;;
>        Characters 116-117:
>      fun o -> l <- (o:>a_t) :: l
>                     ^
>This expression cannot be coerced to type
>  a_t = < m : 'a. (< m : 'a -> unit; .. > as 'a) -> unit >;
>it has type < m : 'b -> unit; .. > as 'b but is here used with type
>  'b = < m : 'c. < m : 'c -> unit; .. > -> unit; .. >.
>This simple coercion was not fully general. Consider using a double
>coercion.
>
>
># class a: a_t = object
>   val mutable l = []
>   method m: 'a.(<m: 'a -> unit; ..> as 'a) -> unit = 
>     fun o -> l <- (o:(<m: 'a -> unit; ..> as 'a):>a_t) :: l
> end;;
>
>        Characters 115-151:
>      fun o -> l <- (o:(<m: 'a -> unit; ..> as 'a):>a_t) :: l
>                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>Type < m : 'a -> unit; .. > as 'a is not a subtype of type
>  a_t = < m : 'b. (< m : 'b -> unit; .. > as 'b) -> unit > 
>The universal variable 'b would escape its scope


any idea ?


damien

[-- Attachment #2: a_trees.ml --]
[-- Type: application/octet-stream, Size: 2031 bytes --]

(* using the trick *)

class type a_t = object
  method add: <it: 'b. (< add : 'a; children: a_t list; ga: int; .. > as 'b) -> unit > as 'a 
  method children: a_t list
  method ga: int
end

class ['a] wrap l = object
  method it: 'b. (< add : 'a; children: a_t list; ga: int; .. > as 'b) -> unit = 
    fun o -> l := (o :> <add: 'a; children: a_t list; ga: int>):: !l
end

class a: a_t = 
let children = ref [] in
let it = new wrap children in
object 
  method children = !children	      
  method add = it
  method ga = 33
end


class a1 = object 
  inherit a
  method bu = true
end

class a2 = object 
  inherit a
  method zo = ""
end

let a  = new a
let a1 = new a1
let a2 = new a2
let _ = a#add#it a
let _ = a#add#it a1
let _ = a#add#it a2
let _ = a1#add#it a
let c = a#children






(* equivalent un-implemented... *)
class type a_t = object 
  method m: 'a.(<m: 'a -> unit; ..> as 'a) -> unit 
end 

class a: a_t = object (* don't work :-( *)
  val mutable l = []
  method m: 'a.(<m: 'a -> unit; ..> as 'a) -> unit = 
    fun o -> l <- (o:>a_t) :: l
end




(* an other trick ... *)


(* container for objects of type 'b *)
class type ['b] at = object
  method b: 'b
end
(* objects contained by objects of type 'b #at *)
class type ['b] bt = object
  method al: 'b at list
  method add: 'b #at -> unit
end
(* container and contained *)
class type abt = object
  inherit [abt] at
  inherit [abt] bt
  method ga: int
end

(* implementation *)
class ['b] a b : ['b] at = object
  method b = b
end
class ['b] b : ['b] bt = object
  val mutable al = []
  method al = al
  method add : 'a. ('b #at as 'a) -> unit = fun a -> al <- (a :> 'b at)::al
end
class ab b: abt = object
  inherit [abt] a (b:>abt)
  inherit [abt] b
  method ga = 50
end

class ab1 b = object
  inherit ab b
  method bu = ""
end
class ab2 b = object
  inherit ab b
  method zo = true
end

(* tests *)
let c = new ab (Obj.magic()) (*sorry*)
let a = new ab c
let a1 = new ab1 a
let a2 = new ab2 c
let _ = c#add a
let _ = c#add a2
let _ = a#add a1
let l = c#al

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [Caml-list] polymorphic methods
  2003-03-12 23:07 Damien
  2003-03-13  0:56 ` brogoff
@ 2003-03-13  1:56 ` Jacques Garrigue
  2003-03-13  9:04   ` Damien
  1 sibling, 1 reply; 20+ messages in thread
From: Jacques Garrigue @ 2003-03-13  1:56 UTC (permalink / raw)
  To: Damien.Pous; +Cc: caml-list

From: Damien <Damien.Pous@ens-lyon.fr>

> Does someone know why the following class type
> is not accepted ?
> 
> # class type a = object method m: 'a. (#a as 'a) -> unit end;;
> The abbreviation #a expands to type #a but is used with type < .. >

Essentially because the type abbreviation #a is not yet fully defined
when its methods are typed. So what is happening here is that the type
uses a first definition of #a, with no methods at all, and then tries
to unify it with the real #a, with a method m, and fails because the
first one is supposed to be polymorphic.
I admit the error message could be clearer, but polymorphic methods
are a recent addition to ocaml, and it is really hard to give proper
error messages for their definitions.

Now, the serious part: can such a type be defined?
After working a bit on this riddle, I'm afraid the answer is no.
The reason is that there is no way to recurse on a quantified
polymorphic method rather than on the whole object.
The closest I found is:
  class type a =
    object method m : < d : 'b. (< m : 'a; .. > as 'b) -> unit > as 'a end
The dummy wrapper <d : 'b. ... > is just there to allow one to recurse
on the polymoprhic method itself. You can call the method m by doing
[a#m#d a'] in place of [a#m a'].

Thank you for pointing at this interesting phenomenon.

Jacques Garrigue

-------------------
To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr
Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [Caml-list] polymorphic methods
  2003-03-12 23:07 Damien
@ 2003-03-13  0:56 ` brogoff
  2003-03-13  1:56 ` Jacques Garrigue
  1 sibling, 0 replies; 20+ messages in thread
From: brogoff @ 2003-03-13  0:56 UTC (permalink / raw)
  To: Damien; +Cc: caml-list

Why are you trying to use a polymorphic method here? Can't you just do 

# class type a = object ('a) method m : 'a -> unit end ;;
class type a = object ('a) method m : 'a -> unit end

-- Brian

On Thu, 13 Mar 2003, Damien wrote:

> Hello,
> 
> Does someone know why the following class type
> is not accepted ?
> 
> # class type a = object method m: 'a. (#a as 'a) -> unit end;;
> The abbreviation #a expands to type #a but is used with type < .. >
> # 
> 
> Thanks,
> Damien
> 
> -------------------
> To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr
> Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/
> Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
> 

-------------------
To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr
Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners


^ permalink raw reply	[flat|nested] 20+ messages in thread

* [Caml-list] polymorphic methods
@ 2003-03-12 23:07 Damien
  2003-03-13  0:56 ` brogoff
  2003-03-13  1:56 ` Jacques Garrigue
  0 siblings, 2 replies; 20+ messages in thread
From: Damien @ 2003-03-12 23:07 UTC (permalink / raw)
  To: caml-list

Hello,

Does someone know why the following class type
is not accepted ?

# class type a = object method m: 'a. (#a as 'a) -> unit end;;
The abbreviation #a expands to type #a but is used with type < .. >
# 

Thanks,
Damien

-------------------
To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr
Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [Caml-list] Polymorphic methods
  2002-08-23 15:46 [Caml-list] Polymorphic methods Frederic Tronel
  2002-08-23 17:32 ` Fred Smith
@ 2002-08-23 18:21 ` Remi VANICAT
  1 sibling, 0 replies; 20+ messages in thread
From: Remi VANICAT @ 2002-08-23 18:21 UTC (permalink / raw)
  To: caml-list

Frederic Tronel <Frederic.Tronel@inrialpes.fr> writes:

> Hello list,
>
>
> I've just compiled the new 3.05 version (I will change for 3.06
> tomorrow),
> and start playing a little bit with polymorphic methods. 
> But this small piece of code does not compile:
>
> class node =
> object 
> val mutable t = None
> method set_t: 'a. 'a -> unit = fun nt -> t <- Some nt
> end
>
> File "essai.ml", line 4, characters 31-53:
> This method has type 'a -> unit which is less general than 'b. 'b ->
> unit

you should look to this bug :
http://caml.inria.fr/bin/caml-bugs/fixed?id=1274;page=44;user=guest
(bug which had be fixed). 

To be more precise, the type of t can't be polymorphic, so the type of
set_t can't too.

look to this example :

class node =
object 
  val mutable t = None
  method set_t: 'a. 'a -> unit = fun nt -> t <- Some nt
  method get_t: 'a. unit -> 'a option = fun () -> t
end

the one could do this :

let t : int =
  let a = new node
  a #set_t 1.23
  match a #get_t () with Some x -> x

which is obviously wrong.

you probably want :

class ['a] node =
object 
  val mutable t = None
  method set_t: 'a -> unit = fun nt -> t <- Some nt
  method get_t: unit -> 'a option = fun () -> t
end


-- 
Rémi Vanicat
vanicat@labri.u-bordeaux.fr
http://dept-info.labri.u-bordeaux.fr/~vanicat
-------------------
To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr
Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners


^ permalink raw reply	[flat|nested] 20+ messages in thread

* RE: [Caml-list] Polymorphic methods
  2002-08-23 15:46 [Caml-list] Polymorphic methods Frederic Tronel
@ 2002-08-23 17:32 ` Fred Smith
  2002-08-23 18:21 ` Remi VANICAT
  1 sibling, 0 replies; 20+ messages in thread
From: Fred Smith @ 2002-08-23 17:32 UTC (permalink / raw)
  To: Frederic Tronel, caml-list


Hi,

The method set_t would not be type safe given the type you have assigned it.
OK, the code snippet you wrote happens to be safe but won't be as soon as
you try to use it.

With the type you have assigned set_t the following would be legal:

n#set_t 3.4;
n#set_t "hello";

because set_t takes any type as input ('a.'a->unit).

What type would n#t have?  Neither float option nor string option will work.
In particular, if you had provided a function get_t it could not return a
useful single type.  To see the problem consider

if myWhackoCondition then (n#set_t 3.4) else (n#set_t "hello");
let w = n#get_t () in (* What type should w have? *)

A class definition that is legal and may solve your problem is:

class ['a] node = object
  val mutable t : 'a option = None
  method set_t nt = t<- Some nt
  method get_t () = (match t with Some x -> x | _ -> failwith "Empty node")
  method is_empty () = (t = None)
end

Now you can create values of type int node, float node, etc... and set_t and
get_t will return the appropriate types.  But you cannot create a value of
type 'a.'a node for the same reasons as above.

Hope this helps.

-Fred

> -----Original Message-----
> From: owner-caml-list@pauillac.inria.fr
> [mailto:owner-caml-list@pauillac.inria.fr]On Behalf Of Frederic Tronel
> Sent: Friday, August 23, 2002 11:46 AM
> To: caml-list@inria.fr
> Subject: [Caml-list] Polymorphic methods
>
>
> Hello list,
>
>
> I've just compiled the new 3.05 version (I will change for 3.06
> tomorrow),
> and start playing a little bit with polymorphic methods.
> But this small piece of code does not compile:
>
> class node =
> object
> val mutable t = None
> method set_t: 'a. 'a -> unit = fun nt -> t <- Some nt
> end
>
> File "essai.ml", line 4, characters 31-53:
> This method has type 'a -> unit which is less general than 'b. 'b ->
> unit
>
> while this one is OK (useless).
>
> class node =
> object
> val mutable t = None
> method set_t: 'a. 'a -> unit = fun nt -> ()
> end
> class node : object val mutable t : 'a option method set_t : 'b -> unit
> end
>
> Where am I going wrong ??
>
> Best regards,
>
> Frederic.
> -------------------
> To unsubscribe, mail caml-list-request@inria.fr Archives:
> http://caml.inria.fr
> Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ:
> http://caml.inria.fr/FAQ/
> Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
>

-------------------
To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr
Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners


^ permalink raw reply	[flat|nested] 20+ messages in thread

* [Caml-list] Polymorphic methods
@ 2002-08-23 15:46 Frederic Tronel
  2002-08-23 17:32 ` Fred Smith
  2002-08-23 18:21 ` Remi VANICAT
  0 siblings, 2 replies; 20+ messages in thread
From: Frederic Tronel @ 2002-08-23 15:46 UTC (permalink / raw)
  To: caml-list

Hello list,


I've just compiled the new 3.05 version (I will change for 3.06
tomorrow),
and start playing a little bit with polymorphic methods. 
But this small piece of code does not compile:

class node =
object 
val mutable t = None
method set_t: 'a. 'a -> unit = fun nt -> t <- Some nt
end

File "essai.ml", line 4, characters 31-53:
This method has type 'a -> unit which is less general than 'b. 'b ->
unit

while this one is OK (useless).

class node =
object 
val mutable t = None
method set_t: 'a. 'a -> unit = fun nt -> ()
end
class node : object val mutable t : 'a option method set_t : 'b -> unit
end

Where am I going wrong ??

Best regards,

Frederic.
-------------------
To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr
Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [Caml-list] polymorphic methods
  2002-07-15  1:05 ` Jacques Garrigue
  2002-07-15  2:08   ` Brian Smith
@ 2002-07-15 16:24   ` nadji
  1 sibling, 0 replies; 20+ messages in thread
From: nadji @ 2002-07-15 16:24 UTC (permalink / raw)
  To: Jacques Garrigue; +Cc: caml-list

Jacques Garrigue wrote:

> > # let f = (new c)#m ();;
> > val f : '_a -> '_a = <fun>
>
> Unsound. RTFM (polymorphism restricted to values)
> Try "let f x = (new c)#m () x"
>

Oups, sorry. I did'nt recognize this classical problem ...
In fact this example was an attempt to simplify my
next question, but I can see now that they are not related.

> But I don't see why you need ().
>

You're right. It was there for historical reasons and I had
not realized I did'nt need an argument anymore.

> > Can someone give me some hints why I can't coerce subd ?
>
> Sorry, but there is no handling of instanciation via subtyping.
> Currently subtyping and instanciation are orthogonal concepts: you
> cannot subtype in an .mli, and you cannot instanciate an
> explicitly polymorphic type when subtyping.

That's a shame because if one tries to use objects for manipulating
lists :

# exception Emptylist

class type ['a] olist = object
  method hd : 'a
  method tl : 'a olist
end

 class nil = object
  method ~hd: 'a . 'a = raise Emptylist
  method ~tl: 'a . 'a olist = raise Emptylist
end

let objnil = (new nil :>  'a olist);;
Characters 14-21:
  let objnil = (new nil :>  'a olist);;
                ^^^^^^^
This expression cannot be coerced to type
  'a olist = < hd : 'a; tl : 'a olist >;
it has type nil = < hd : 'b. 'b; tl : 'c. 'c olist >
but is here used with type < hd : 'a; tl : 'a #olist >.
This simple coercion was not fully general. Consider using a double coercion.

Too bad. Also this is the first time I get this error message. Does it mean that
I have to try something like (a : b :> c) ? If not, what is a double coercion,
and
can you give a case where is it needed ?


>
> I believe it's correct, but you won't make me write the code without a
> proof :-)

This is why I like Ocaml :)

-------------------
To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr
Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [Caml-list] polymorphic methods
  2002-07-15  1:05 ` Jacques Garrigue
@ 2002-07-15  2:08   ` Brian Smith
  2002-07-15 16:24   ` nadji
  1 sibling, 0 replies; 20+ messages in thread
From: Brian Smith @ 2002-07-15  2:08 UTC (permalink / raw)
  Cc: caml-list

Jacques Garrigue wrote:
> 
> Sorry, but there is no handling of instanciation via subtyping.
> Currently subtyping and instanciation are orthogonal concepts: you
> cannot subtype in an .mli, and you cannot instanciate an
> explicitly polymorphic type when subtyping.
> I believe it's correct, but you won't make me write the code without a
> proof :-)

That is really an interesting comment. I wonder, what are people 
currently researching w.r.t. the object-oriented features of O'Caml? 
Besides the above, Jacques said that recursive types with classes is not 
completely defined because (paraphrasing) recursive types are 
polymorphic and recursive classes are monomorphic:

     type variant = Node of node
     and
     class node =
       object
         method as_variant : variant = Node self
       end

I wonder, does a similar problem apply to recursive exceptions and classes?:

     (* email me for a complete example *)
     exception NotFound of node
     and
     class node  =
       object
         method find x = ... else raise (NotFound self)
       end;;

And, similarly, it does seem odd that currently it is impossible to 
create a polymorphic method equivalent to "map" (This type of problem is 
mentioned in http://citeseer.nj.nec.com/remy98objective.html).

Besides polymorphism, I wonder if it is possible to add open classes and 
multiple dispatch to O'Caml like MultiJava does for Java 
(http://www.cs.iastate.edu/~cclifton/multijava/).

I'm just a beginner and I don't know any of the theory of this yet, so 
i'm hoping somebody else will give Jacques some proofs of solutions to 
the above :)

Thanks,
Brian



-------------------
To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr
Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [Caml-list] polymorphic methods
  2002-07-14 23:16 [Caml-list] polymorphic methods nadji
@ 2002-07-15  1:05 ` Jacques Garrigue
  2002-07-15  2:08   ` Brian Smith
  2002-07-15 16:24   ` nadji
  0 siblings, 2 replies; 20+ messages in thread
From: Jacques Garrigue @ 2002-07-15  1:05 UTC (permalink / raw)
  To: nadji; +Cc: caml-list

From: nadji@noos.fr

> While playing with the current cvs version of ocaml (3.04+15),
> several questions came to me concerning the semantics of
> polymorphic methods. For example :
> 
> # class c = object
>   method m: 'a . unit -> 'a -> 'a = fun _ x -> x
> end;;
>     class c : object method m : unit -> 'a -> 'a end
> # let f = (new c)#m ();;
> val f : '_a -> '_a = <fun>
> 
> Shouldn't the type of f be : 'a -> 'a  ?
> (Would it be sound/implementable/easy to add ?)

Unsound. RTFM (polymorphism restricted to values)
Try "let f x = (new c)#m () x"
But I don't see why you need ().

> Second question:
> # class ['a] d = object
>   method m: 'a -> 'a = fun x -> x
> end;;
>     class ['a] d : object method m : 'a -> 'a end
> # class subd = object
>   method ~m: 'a. 'a -> 'a = fun x -> x
> end;;
>     class subd : object method m : 'a -> 'a end
> # let v = (new subd :> 'a d);;
> Characters 9-17:
>   let v = (new subd :> 'a d);;
>            ^^^^^^^^
> This expression cannot be coerced to type 'a d = < m : 'a -> 'a >;
> it has type subd = < m : 'b. 'b -> 'b > but is here used with type 'a d
> 
> Or even the easier :
> # class d' = object
>   method m x = x + 0
> end;;
>     class d' : object method m : int -> int end
> # let v' = (new subd :> d');;
> Characters 10-18:
>   let v' = (new subd :> d');;
>             ^^^^^^^^
> This expression cannot be coerced to type d' = < m : int -> int >;
> it has type subd = < m : 'a. 'a -> 'a > but is here used with type d'
> 
> But the type ('b. 'b -> 'b) is more general than ('a -> 'a)
> or (int -> int), no ?
> Can someone give me some hints why I can't coerce subd ?

Sorry, but there is no handling of instanciation via subtyping.
Currently subtyping and instanciation are orthogonal concepts: you
cannot subtype in an .mli, and you cannot instanciate an
explicitly polymorphic type when subtyping.
I believe it's correct, but you won't make me write the code without a
proof :-)

Jacques Garrigue
-------------------
To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr
Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners


^ permalink raw reply	[flat|nested] 20+ messages in thread

* [Caml-list] polymorphic methods
@ 2002-07-14 23:16 nadji
  2002-07-15  1:05 ` Jacques Garrigue
  0 siblings, 1 reply; 20+ messages in thread
From: nadji @ 2002-07-14 23:16 UTC (permalink / raw)
  To: caml-list

Hello,

While playing with the current cvs version of ocaml (3.04+15),
several questions came to me concerning the semantics of
polymorphic methods. For example :

# class c = object
  method ~m: 'a . unit -> 'a -> 'a = fun _ x -> x
end;;
    class c : object method m : unit -> 'a -> 'a end
# let f = (new c)#m ();;
val f : '_a -> '_a = <fun>

Shouldn't the type of f be : 'a -> 'a  ?
(Would it be sound/implementable/easy to add ?)

Second question:
# class ['a] d = object
  method m: 'a -> 'a = fun x -> x
end;;
    class ['a] d : object method m : 'a -> 'a end
# class subd = object
  method ~m: 'a. 'a -> 'a = fun x -> x
end;;
    class subd : object method m : 'a -> 'a end
# let v = (new subd :> 'a d);;
Characters 9-17:
  let v = (new subd :> 'a d);;
           ^^^^^^^^
This expression cannot be coerced to type 'a d = < m : 'a -> 'a >;
it has type subd = < m : 'b. 'b -> 'b > but is here used with type 'a d

Or even the easier :
# class d' = object
  method m x = x + 0
end;;
    class d' : object method m : int -> int end
# let v' = (new subd :> d');;
Characters 10-18:
  let v' = (new subd :> d');;
            ^^^^^^^^
This expression cannot be coerced to type d' = < m : int -> int >;
it has type subd = < m : 'a. 'a -> 'a > but is here used with type d'

But the type ('b. 'b -> 'b) is more general than ('a -> 'a)
or (int -> int), no ?
Can someone give me some hints why I can't coerce subd ?

Btw, thanks for the upcoming release, it seems _really_ excellent !
Nadji

-------------------
To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr
Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [Caml-list] Polymorphic methods
  2001-11-20  0:29 ` Jacques Garrigue
  2001-11-20  9:33   ` Alain Frisch
@ 2001-11-20 20:55   ` Xavier Leroy
  1 sibling, 0 replies; 20+ messages in thread
From: Xavier Leroy @ 2001-11-20 20:55 UTC (permalink / raw)
  To: Jacques Garrigue; +Cc: frisch, caml-list

> After two years, my promises may seem void, but I intend to
> implement polymorphic methods, probably as soon as 3.03 is released.
> Or should I start before?  This is a rather large chunk of work,
> modifying very sensitive parts of the compiler...
> 
> What would you need them for?

I believe my ever-ongoing Caml/Java mapping could make good use of
polymorphic methods.  Indeed, in this particular example of
translating a Java class hierarchy to Caml, polymorphic methods seem
to offer exactly what is needed to simulate Java-like implicit
subsumption with OCaml's row polymorphism.

This said, I understand polymorphic methods impact the type inference
engine quite a lot, and I'm not pushing for additional complexity in
this (already rather hairy) part of the OCaml implementation...

- Xavier Leroy
-------------------
Bug reports: http://caml.inria.fr/bin/caml-bugs  FAQ: http://caml.inria.fr/FAQ/
To unsubscribe, mail caml-list-request@inria.fr  Archives: http://caml.inria.fr


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [Caml-list] Polymorphic methods
  2001-11-20  0:29 ` Jacques Garrigue
@ 2001-11-20  9:33   ` Alain Frisch
  2001-11-20 20:55   ` Xavier Leroy
  1 sibling, 0 replies; 20+ messages in thread
From: Alain Frisch @ 2001-11-20  9:33 UTC (permalink / raw)
  To: Jacques Garrigue; +Cc: caml-list

Good news that polymorphic methods are still considered !

On Tue, 20 Nov 2001, Jacques Garrigue wrote:

> What would you need them for? One reason I was not so eager to start
> working on them is that they do not solve all problems of
> polymorphism. For instance, you cannot define a map method, even with
> polymorphic methods.

Oh, I never used OLabl and was not aware of this kind of restriction;
why is a map method impossible ?  I can't find the argument
in your _Extending ML with semi-explicit higher order polymorphism_

I currently need polymorphic method for the Bedouin project.
We use polymorphic variants to statically enforce DTD constraints
on produced documents. For instance, we have:

val html_ :
  ?lang:string ->
  ?dir:[ `Ltr | `Rtl ] ->
  ('a,[< `Head ]) t ->
  ('a,[< `Body ]) t ->
  ('a,[> `Html]) t

Now I want to define GUI-like widgets, such as HTML forms, or INPUT
interactors. For instance, the form widget should have
a method html, with polymorphic type:

[< `P | `H1 | `H2 | `H3 | `H4 | `H5 | `H6 | `Ul | `Ol | `Dir | `Menu
   | `Pre | `Dl | `Div | `Center | `Noscript | `Noframes | `Blockquote
   | `Isindex | `Hr | `Table | `Fieldset | `Address | `Pcdata | `Tt
   | `I | `B | `U | `S | `Strike | `Big | `Small | `Em | `Strong
   | `Dfn | `Code | `Samp  | `Kbd | `Var | `Cite | `Abbr | `Acronym
   | `A | `Img | `Applet | `Object | `Font | `Basefont | `Br
   | `Script | `Map | `Q | `Sub | `Sup | `Span | `Bdo | `Iframe
   | `Input | `Select | `Textarea | `Label | `Button > `Input]
      html list -> [> `Form] html

(btw, in the type to left of the arrow, isn't the " > `Input "
redundant ?)

Would such a method be accepted ?

As the html methods are normally (but not necessarily) used only
once to display widgets, it is possible to parametrize widget classes with
the type of their html method (this produces constraints on the
type parameter, such as :  constraint 'a = [ < `P ... ]),
but then, as there is a hierarchy of objects (a widget belongs
to a form belongs to a dialog), the type parameters accumulate,
and the interface of the widget library becomes ugly.

> > Did OLabl raise some practical problems with polymorphic methods ?
>
> There was a problem of compilation speed. I have now a few ideas of
> how to improve it, but this may still mean that the change would only
> be provided as a patch.

Does the compilation scheme impact on the whole language, even for
programs not using polymorphic methods ?

> Another problem is that such methods cannot be inferred. As a result
> you can have strange type errors, because you used a method before
> knowing its actual type. In OLabl there was a warning every time you
> used a method whose type was unkwown, but I have been told it was not
> very Caml-like.

Well, with the class parametrization trick, it is also necessary
to give a type annotations (just 'a is ok, and let the type system
infer constraints on 'a).



Thank you !


Alain

-------------------
Bug reports: http://caml.inria.fr/bin/caml-bugs  FAQ: http://caml.inria.fr/FAQ/
To unsubscribe, mail caml-list-request@inria.fr  Archives: http://caml.inria.fr


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [Caml-list] Polymorphic methods
  2001-11-19 15:29 [Caml-list] Polymorphic methods Alain Frisch
@ 2001-11-20  0:29 ` Jacques Garrigue
  2001-11-20  9:33   ` Alain Frisch
  2001-11-20 20:55   ` Xavier Leroy
  0 siblings, 2 replies; 20+ messages in thread
From: Jacques Garrigue @ 2001-11-20  0:29 UTC (permalink / raw)
  To: frisch; +Cc: caml-list

From: Alain Frisch <frisch@clipper.ens.fr>

> is there any plan to add polymorphic methods to OCaml ?  The more I use
> objects, the more I miss this feature. There is a poly_meth branch in
> the CVS, but it does not seem really active nowadays ...

After two years, my promises may seem void, but I intend to implement
polymorphic methods, probably as soon as 3.03 is released.
Or should I start before?
This is a rather large chunk of work, modifying very sensitive parts
of the compiler...

What would you need them for? One reason I was not so eager to start
working on them is that they do not solve all problems of
polymorphism. For instance, you cannot define a map method, even with
polymorphic methods.

> Did OLabl raise some practical problems with polymorphic methods ?

There was a problem of compilation speed. I have now a few ideas of
how to improve it, but this may still mean that the change would only
be provided as a patch.

Another problem is that such methods cannot be inferred. As a result
you can have strange type errors, because you used a method before
knowing its actual type. In OLabl there was a warning every time you
used a method whose type was unkwown, but I have been told it was not
very Caml-like.

Jacques Garrigue
-------------------
Bug reports: http://caml.inria.fr/bin/caml-bugs  FAQ: http://caml.inria.fr/FAQ/
To unsubscribe, mail caml-list-request@inria.fr  Archives: http://caml.inria.fr


^ permalink raw reply	[flat|nested] 20+ messages in thread

* [Caml-list] Polymorphic methods
@ 2001-11-19 15:29 Alain Frisch
  2001-11-20  0:29 ` Jacques Garrigue
  0 siblings, 1 reply; 20+ messages in thread
From: Alain Frisch @ 2001-11-19 15:29 UTC (permalink / raw)
  To: Caml list

Hello,

is there any plan to add polymorphic methods to OCaml ?  The more I use
objects, the more I miss this feature. There is a poly_meth branch in
the CVS, but it does not seem really active nowadays ...

Did OLabl raise some practical problems with polymorphic methods ?


-- 
  Alain

-------------------
Bug reports: http://caml.inria.fr/bin/caml-bugs  FAQ: http://caml.inria.fr/FAQ/
To unsubscribe, mail caml-list-request@inria.fr  Archives: http://caml.inria.fr


^ permalink raw reply	[flat|nested] 20+ messages in thread

end of thread, other threads:[~2015-12-18 10:07 UTC | newest]

Thread overview: 20+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-12-18  9:18 [Caml-list] polymorphic methods Christoph Höger
2015-12-18 10:07 ` Leo White
  -- strict thread matches above, loose matches on Subject: below --
2003-03-12 23:07 Damien
2003-03-13  0:56 ` brogoff
2003-03-13  1:56 ` Jacques Garrigue
2003-03-13  9:04   ` Damien
2003-03-13  9:27     ` Jacques Garrigue
2003-03-13 14:49       ` Damien
2003-03-13  9:41     ` Olivier Andrieu
2002-08-23 15:46 [Caml-list] Polymorphic methods Frederic Tronel
2002-08-23 17:32 ` Fred Smith
2002-08-23 18:21 ` Remi VANICAT
2002-07-14 23:16 [Caml-list] polymorphic methods nadji
2002-07-15  1:05 ` Jacques Garrigue
2002-07-15  2:08   ` Brian Smith
2002-07-15 16:24   ` nadji
2001-11-19 15:29 [Caml-list] Polymorphic methods Alain Frisch
2001-11-20  0:29 ` Jacques Garrigue
2001-11-20  9:33   ` Alain Frisch
2001-11-20 20:55   ` Xavier Leroy

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).