Version française
Home     About     Download     Resources     Contact us    
Browse thread
[Caml-list] Confusion about chapter 3 in the OCaml manual
[ Home ] [ Index: by date | by threads ]
[ Search: ]

[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
Date: -- (:)
From: Jacques Garrigue <garrigue@k...>
Subject: Re: [Caml-list] Confusion about chapter 3 in the OCaml manual
From: "Ishmael Yavitz" <ishmaelyavitz@hotmail.com>

> COMMENTS ON CHAPTER 3 OF THE OBJECTIVE CAML MANUAL
> (10 DEC 2001 RELEASE)
> 
> Section 3.1 - Classes and Objects
> 
> After the definition of the class point and an instantiation of the
> class, the text reads, " [point] stands for the object type
> <get_x : int; move : int -> unit>, listing the methods of class point
> along with their types."  Should this be taken to mean that an object
> type is defined by its methods, and not at all by its member
> variables?

Yes. You cannot access member variables from outside an object.

> Are classes with exactly the same methods then somehow equivalent?

Yes: their objects are equivalent. But their class types are not
equivalent: you can do different things using inheritance.

> Why is the type of the class "point" printed as in the above excerpt,
> when after entering the definition the interpreter returns
> 
> class point :
> object method get_x : int method move : int -> unit
> val mutable x : int end
> 
> It seems to me that the above suggests that the member variables (x in
> this case) are a part of the type of the class, not just the methods,
> as was suggested above.  Is this correct?

Yes. Class type and object type are different.
An object type contains only the public methods of the corresponding
class type.

> Section 3.5 - Private methods
> 
> Below the definition of the restricted_point class and some examples
> is the sentence, "Private methods are inherited (they are by default
> visible in subclasses), unless they are hidden by signature matching,
> as described below."  Where is the signature matching described?  If
> I understand correctly, (I did execute the code) the rest of the
> examples in the section describe how to make a previously private
> method public in a child class, not how to hide it.  How can one hide
> a method so it can't become public in a child class?

# class c = object (self)
    val x = 1
    method m = self#n
    method private n = x
  end;;
class c : object method m : int method private n : int val x : int end
# class d : object method m : int end = c;;
class d : object method m : int end

This way method n is hidden in class d, but you can still call it via
method m.

> In the first definition of point_again appears the line
> 
> object (self : < move : _; ..> )
> 
> but what exactly does this line mean?

It forces the move method to be public, using hidden behaviour of type
inference. But this looks more confusing than useful... It is probably
more readable to use the other way.

> So in this context, the "problem" is how to make a method become
> public, not how to hide a method?  Also, what does "heavier" mean in
> this context?

It refers to the "method move = super#move" line, by opposition to the
constraint on the type of self in the previous version.
 
> Another question: the class definition the above text refers to is
> 
> class point_again x =
>   object (self : < move : _; ..> )
>     inherit restricted_point x as super
>     method move = super#move
>   end;;

Here the annotation on self is superfluous. This is an error of the
documentation.

> Section 3.6 - Class interfaces
> 
> After the definition of the class restricted_point_type appears the
> text, "Both instance variables and concrete private methods can be
> hidden by a class type constraint. Public and virtual methods,
> however, cannot."  I don't understand what this means.  Is this
> referring to the hiding of methods that was mentioned briefly in
> the previous section?

Yes, see my example above.

> Section 3.7 - Inheritance
> 
> Near the end of the section appears the text, "Methods need not be
> declared previously, as shown by the example..."  I don't understand
> this sentence.  Does this mean that after the following instruction:
> 
> #let set_x p = p#set_x;;
> 
> set_x can be applied to any object that has a set_x method?

Yes. Isn't it cool ? And all this type safe !

> Section 3.8 - Multiple inheritance
> 
> It is my understanding that multiple inheritance refers to a class
> that inherits directly from more than one class.  (For example, class
> colored_line inherits from both the class color and the class line.)
> Some languages do not permit this because of problems - for example,
> when both parents have a method or member variable of the same name,
> which one should be used in the child?  What does "multiple
> inheritance" refer to in the manual text?

In case of name conflict, OCaml uses the code from the last inherit
statement. Note that all identically named methods should have same
types, since all calls will be redirected to the last one.

> At the end of this section is the sentence, "A private method that has
> been hidden in the parent class is no longer visible, and is thus not
> overridden." Is this the same "hiding" that was discussed previously?

Yes: if a private method is hidden, then it will not be merged with
identically named methods when inherited. This is an interesting case
were hiding changes the semantics.

> Section 3.9 - Parameterized classes
> 
> Prior to the definition of the ref_succ class is the sentence, "The
> type parameter in the declaration may actually be constrained in the
> body of the class definition."  Is this referring to the "x_init + 1"
> statement?  If I understand correctly, this constrains x_init to the
> integer type because + operates on integers.  Because of this, is
> 
>   class ['a] ref_succ (x_init:'a) =  (etc...)
> 
> necessary?  Can't one write
> 
>   class ref_succ x_init =  (etc...)
> 
> and the type of x_init will be determined by the body?

Yes, of course, but the intent of this example was to show that a
parameter may in fact be forced to be a specific type. This is not
really useful in practice (you would expect this type to have some
free variables), but is just there for demonstration.

> Section 3.12 - Cloning objects
> 
> The text reads, "The library function Oo.copy makes a shallow copy
> of an object. That is, it returns an object that is equal to the
> previous one. The instance variables have been copied but their
> contents are shared."  Should the last sentence read, "The instance
> variables have been copied but their contents are _not_ shared"?

No, the text is correct. Think of an array of arrays. If you copy the
array, you will get a new array containing the same arrays, so that
modifications on the arrays will be shared between the two copies.

Of course, this only matters if you put mutable data structures inside
your fields, otherwise you will not see the sharing.

> Later in the section, the text reads, "Two objects are equal if and
> only if they are physically equal. In particular, an object and its
> copy are not equal."  However, in the previous excerpt, it states
> that Oo.copy "returns an object that is equal to the previous one."

Interesting: the previous excerpt was plainly wrong (only true in very
old versions of ocaml). An object is not equal to its copy, for both
logical (=) and physical (==) equality. Only their fields are equal.


It seems that this chapters needs a bit of re-writing.
Hope this helps,

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