caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
From: Xavier Leroy <Xavier.Leroy@inria.fr>
To: Miles Egan <miles@caddr.com>
Cc: caml-list@inria.fr
Subject: Re: [Caml-list] lisp -> ocaml
Date: Sun, 27 May 2001 15:01:19 +0200	[thread overview]
Message-ID: <20010527150119.A8468@pauillac.inria.fr> (raw)
In-Reply-To: <20010522093341.A97425@caddr.com>; from miles@caddr.com on Tue, May 22, 2001 at 09:33:41AM -0700

> Second, the PAIP code makes fairly heavy use of Lisp's symbolic
> features and uses symbols as a kind of type tag but also as
> printable strings.  I've been using variants, both traditional and
> polymorphic, as a substitute, but they're not really quite
> equivalent.

Right.  The closest OCaml equivalent to a Lisp atom is unique strings,
which are not provided by the standard library but can easily be
implemented as a module.

With some trickery, you can even implement atoms with property lists,
type safe but dynamically typed of course.  See the code below.
(Warning: the implementation of properties is a real mind-twister,
using a folklore trick to implement dynamics using references and
functions that I learnt from Daniel de Rauglaudre, although it's been
reinvented independently quite a number of times.)

I agree it's best to use variants instead of strings, since this gives
much better static typing guarantees.  As for printing, it is possible
to generate printing functions automatically, as others pointed out,
but it's a bit of a sledgehammer if all your variant constructors are
constant; a simple association list or hash table works fine, e.g.

let name_table = [ One, "one"; Two, "two"; Three, "three"]

let print_name x =
  try
    print_string (List.assoc x name_table)
  with Not_found ->
    print_string "???"

Chris Hecker asked:

> Isn't there something that could be done with the toplevel libraries?
> The toplevel prints variant ctors correctly.

True, but it has access to a wealth of typing information: the
inferred type for the value to be printed, plus the whole typing
environment.  This allows it to decipher the machine representation of
values, using the types to provide symbolic names for constructors and
record labels.  In a separately-compiled program, this typing
information is available at compile-time, but not at run-time.

There have been several attempts at making some type information
available at run-time, e.g. dynamics, or Furuse-Weis' extensional
polymorphism, but this is still ongoing work.

- Xavier Leroy

(* atoms.mli *)

type atom

val intern: string -> atom
val name: atom -> string

type 'a property

val new_property: unit -> 'a property
val put_property: atom -> 'a property -> 'a -> unit
val get_property: atom -> 'a property -> 'a

(* atoms.ml *)

type atom = { name: string; mutable properties: (unit -> unit) list }

let atom_table = (Hashtbl.create 37 : (string, atom) Hashtbl.t)

let intern s =
  try
    Hashtbl.find atom_table s
  with Not_found ->
    let a = { name = s; properties = [] } in
    Hashtbl.add atom_table s a;
    a

let name atom = atom.name

type 'a property = 'a option ref

let new_property () = ref None

let put_property atom prop value =
  atom.properties <- (fun () -> prop := Some value) :: atom.properties

let get_property atom prop =
  let rec get = function
    [] -> raise Not_found
  | fn :: rem ->
      fn();
      match !prop with
        None -> get rem
      | Some v -> prop := None; v
  in get atom.properties

(* A more careful version of put that erases overwritten properties:

let put_property atom prop value =
  let rec put = function
    [] -> [fun () -> prop := Some value]
  | fn :: rem ->
      fn();
      match !prop with
        None -> fn :: put rem
      | Some v -> prop := None; (fun () -> prop := Some value) :: rem
  in atom.properties <- put atom.properties

*)
-------------------
To unsubscribe, mail caml-list-request@inria.fr.  Archives: http://caml.inria.fr


  parent reply	other threads:[~2001-05-27 13:01 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2001-05-22 16:33 Miles Egan
2001-05-22 16:52 ` Markus Mottl
2001-05-22 17:09 ` Brian Rogoff
2001-05-22 18:27 ` Remi VANICAT
2001-05-22 17:12   ` Miles Egan
2001-05-22 18:26     ` Chris Hecker
2001-05-27 13:01 ` Xavier Leroy [this message]
2001-05-27 14:43   ` Miles Egan
2001-05-27 21:24   ` Dave Mason
2001-05-28 17:10     ` William Chesters
2001-05-28  0:06   ` Chris Hecker
2001-05-28 13:32     ` Xavier Leroy
2001-05-28 19:02       ` Chris Hecker

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=20010527150119.A8468@pauillac.inria.fr \
    --to=xavier.leroy@inria.fr \
    --cc=caml-list@inria.fr \
    --cc=miles@caddr.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).