Re: [Q] Four micro-questions on objects and modules.

From: Jerome Vouillon (Jerome.Vouillon@inria.fr)
Date: Wed Nov 03 1999 - 22:40:29 MET


Date: Wed, 3 Nov 1999 22:40:29 +0100
From: Jerome Vouillon <Jerome.Vouillon@inria.fr>
To: Christian RINDERKNECHT <rinderkn@hugo.int-evry.fr>
Subject: Re: [Q] Four micro-questions on objects and modules.
In-Reply-To: <19991102140952.A16438@jones.int-evry.fr>; from Christian RINDERKNECHT on Tue, Nov 02, 1999 at 02:09:52PM +0100

Hello,

> 1) Assume I compile m.ml made of: class c = object end
> and m.mli: class c : object end
>
> Now:
>
> Objective Caml version 2.02
>
> # #load "m.cmo";;
> # let f = fun (x : #M.c) -> x;;
> val f : (#M.c as 'a) -> 'a = <fun>
>
> OK. What strikes me is:
>
> # let g = fun (x : M.c) -> x;;
> val g : M.c -> M.c = <fun>
>
> What is the difference between f and g? If the type of g is
> equivalent to #M.c -> #M.c, then according to the manual (#-types)
> there is a difference, isn'it?

If you remove the abbreviations, the type of f is
  (< .. > as 'a) -> 'a
So, this function can be applied to any object and returns an object
of the same type (you should understand the ellipsis as a type
variable that can be instantiated to any row of methods). If it had
type #M.c -> #M.c, that is,
   < .. > -> < .. >
then, it could be apply to any object and would returns an object of
any type. You cannot write a function of this type unless it never
terminates or always raises an exception.
Finally, the type of g is
   < > -> < >
This function can only be applied to an object with no method (you can
actually apply it to any object by using a coercion first), and it
returns an object with no method.

> Moreover, I tought "M.c" was not syntactically correct when "c"
> is a class (hence the "#" symbol)...
>
> 2) What is the semantics of the syntactic productions
> (http://caml.inria.fr/pub/old_caml_site/ocaml/htmlman/node6.5.html):
>
> typexpr : typexpr # class-path
> | ( typexpr {, typexpr}) # class-path

A class defines two type abbreviations: here M.c and #M.c. The first
one is the type of an object of this class. The second one is more
general, and is the type of any object that has at least the methods
of class M.c, but may have more methods. In particular the type of an
object of any subclass of M.c will be an instance of type #M.c.

> 3) Would it be possible to allow the "include" feature in class
> types?

What do you mean ? A class type can inherit from another class type :
   class type c = object method m : int end
   class type d = object inherit c method n : bool end

> 4) With values one can equivalently write:
>
> # let (h : unit -> unit) = fun x -> x;;
> val h : unit -> unit = <fun>
>
> or
 
> # let h = ((fun x -> x) : unit -> unit);;
> val h : unit -> unit = <fun>
>
> I prefer the former when the function expression is big and I don't
> want my eyes to read it only in order to find the type annotation
> at the end.
>
> For the same sake, I think it would be consistent and useful to
> allow class types, module types to qualify directly the module
> names and the class names:
>
> # module (M : S) = struct (* lot of stuff here *) end;;
> ^
> Not a Syntax error!
>
> and
>
> # class (x : ct) = object (* lot of stuff here *) end;;
> ^
> Not a Syntax error!
>
> ...and the same for method and value instances.

You can also write
    let h : unit -> unit = fun x -> x;;
(without parentheses)
The same syntax is also accepted for modules and classes.

-- Jérôme



This archive was generated by hypermail 2b29 : Sun Jan 02 2000 - 11:58:28 MET