caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
From: oleg@okmij.org
To: caml-list@inria.fr
Subject: Re: existentials [was: Formal specifications of programming languages]
Date: Tue, 19 Feb 2008 00:54:23 -0800 (PST)	[thread overview]
Message-ID: <20080219085423.B7350A99B@Adric.metnet.fnmoc.navy.mil> (raw)


Jacques Garrigue wrote:
> There are no existentials in ocaml, only first-class universal types
> (in polymorphic methods and polymorphic record fields.)

Surely object types are existentials with respect to the types of their
fields?!

Wasn't it the very motivation of objects -- encapsulation -- to
abstract over the types of the fields and so prevent the outsiders
from finding out not only the values of the fields but also their types.
Outsiders should only use the methods of the object and should know
nothing about object's fields, if any.

As the illustration, here is the standard counter example, defining
one existential type and two its values. The values use two
different representations of the internal state of the counter: a pair
of integers and a float. This state is not observable: and so we can
place the two counter objects in the same list without any need for
coercions. OCaml knows that the state is not observable and so the two
objects have the same type, difference in the type of their state
notwithstanding. 

One must say that exactly the same example has been implemented
without any existentials whatsoever:

 Eliminating existentials, finally
 Caml-list, Nov 14, 2007
 http://caml.inria.fr/pub/ml-archives/caml-list/2007/11/dcd3aab066b5f28852db8ccaf35d35d7.en.html

which poses the question if existentials are really needed.


On with the example: the declaration of the existential type
 
class type counter = object ('self)
  method observe : int
  method step : unit -> 'self
end;;

Here are two different counters, with two different
representations of the internal state (a pair of int, or a float).

let counter1 = 
  object
   val seed = 0
   val upper = 5
   method observe = seed
   method step () = 
     let new_seed = if seed >= upper then 0 else succ seed in
     {< seed = new_seed >}
end;;

(* use FP seed *)
let counter2 = 
  object
   val seed = 0.0
   method observe = int_of_float (10.0 *. seed)
   method step () = {< seed = cos seed >}
end;;

We can place them into a list

let lst = [counter1; counter2];;

and iterate over:

let advance_all = List.map (fun c -> c#step ());;
let show_all = List.iter (fun c -> Printf.printf "%d\n" c#observe);;

let test = let () = show_all lst in
           let () = show_all (advance_all (advance_all lst))
           in ();;

result:
0
0
2
5
val test : unit = ()


                 reply	other threads:[~2008-02-19  8:57 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

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=20080219085423.B7350A99B@Adric.metnet.fnmoc.navy.mil \
    --to=oleg@okmij.org \
    --cc=caml-list@inria.fr \
    --cc=oleg@pobox.com \
    /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;
as well as URLs for NNTP newsgroup(s).