4

I was playing with method redefinition, and I found this silly example :

class a =
object 
    method get (x : a) = x
end

class b =
object
    inherit a
    method get (x : b) = x
end

I'm clearly specifying that I want the get method from the b class to take a b and return a b, but the method signature is a -> a. And if I do (new b)#get(new a) he's very happy, when he really shouldn't. After that I added something silly :

class a =
object 
    method get (x : a) = x
end

class b =
object
    inherit a
    method get (x : b) = x#foo(x)
    method foo (x : a) = x
end

And I get Error: This expression has type b It has no method foo

What on earth is happening ?

bruce_ricard
  • 743
  • 1
  • 7
  • 15

1 Answers1

5

Taking the first example first: OCaml has structural typing of objects, not nominal typing. In other words, the type of an object is determined entirely by its methods (and their types). So the classes a and b are in fact the same type.

$ ocaml
        OCaml version 4.00.0

# class a = object method get (x: a) = x end;;
class a : object method get : a -> a end
# class b = object inherit a method get (x: b) = x end;;
class b : object method get : a -> a end
# let a0 = new a;;
val a0 : a = <obj>
# let b0 = new b;;
val b0 : b = <obj>
# (a0: b);;
- : b = <obj>
# (a0: a);;
- : a = <obj>
# (b0: a);;
- : a = <obj>
# (b0: b);;
- : b = <obj>
# 

(What I'm trying to show here is that both a0 and b0 are of type a and of type b.)

In the second example, I'd say you're trying to give a new type to the get method. When you override a method in OCaml, the parameter and return types need to be the same as in the parent class.

The error message seems unfortunate. My guess is that the compiler is believing you that type b is another name for type a.

One of OCaml's strengths is that it will infer types. If you leave off the : b for the parameter of get in class b, you get the following error instead:

This expression has type a. It has no method foo

This is a little more helpful, in that it shows (I think) that you're required to have type a for the parameter.

Side comment (forgive me): if you come to the OO part of OCaml from a mainstream OO language, it might strike you as strange. But if you learn the FP part of OCaml first, you might wonder why all the mainstream OO languages get so many things wrong :-). (Granted, everything is tradeoffs and there is no one right way to structure computation. But OCaml's OO subsystem is doing something pretty impressive.)

Jeffrey Scofield
  • 65,646
  • 2
  • 72
  • 108