caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
From: Jacques Garrigue <garrigue@math.nagoya-u.ac.jp>
To: dave@ramenlabs.com
Cc: darioteixeira@yahoo.com, caml-list@yquem.inria.fr
Subject: Re: [Caml-list] Width subtyping
Date: Mon, 01 Jun 2009 13:21:23 +0900 (JST)	[thread overview]
Message-ID: <20090601.132123.210988323.garrigue@math.nagoya-u.ac.jp> (raw)
In-Reply-To: <4A22132E.30505@ramenlabs.com>

From: Dave Benjamin <dave@ramenlabs.com>

> Heavier in terms of efficiency, or syntax? If you mean the latter, I 
> wonder if a camlp4 syntax extension might help ease the burden; perhaps 
> something like:
> 
>    #{x=5; y=6}
> 
> could be translated to:
> 
>    object method x = 5 method y = 6 end
> 
> and then you could benefit from a lightweight syntax and still get the 
> static type checking.

This is already possible with pa_oo, which you can get from the same
place as pa_polymap:

http://www.math.nagoya-u.ac.jp/~garrigue/code/ocaml.html

Also, concerning the typing of pa_polymap, the "weakness" is intended,
otherwise you wouldn't be able to add new fields to an existing value
(using the with notation).
If you just want to create values without allowing modifications, here
is a modified of pa_polymap.ml which gives them closed types. (It
still needs the original Polymap module.)

Concerning efficiency, since pa_polymap is based on the Map module,
you cannot expect it to be more efficient than the pa_oo based approach,
neither in terms of data size or runtime speed. It only probably wins
for generated code size, as classes are big.

Of course, both are much worse than real records. But whether it
matters or not depends much on what you use them for in your program.

        Jacques Garrigue

(*
   To compile:
     ocamlc -I +camlp4 -c -pp camlp4orf pa_polymap.ml
     ocamlc -c polymap.ml
   To use:
     ocaml dynlink.cma camlp4o.cma pa_polymap.cmo polymap.cmo
   or
     ocamlc -pp 'camlp4o -I . pa_polymap.cmo'
*)

open StdLabels
open Camlp4.PreCast
module Pcaml = Syntax

let next =
  let n = ref 0 in
  fun () -> incr n; string_of_int !n

let add _loc org (s,e) tv =
  <:expr< Polymap.add (Obj.magic `$s$) (Obj.magic ($e$ : $tv$))
            ($org$ : Polymap.t [> `$s$ of $tv$ ]) >>

let test_key_eq =
  let test strm =
    match Stream.npeek 2 strm with
      [(UIDENT _|LIDENT _), _; KEYWORD "=", _] -> ()
    | _ -> raise Stream.Failure
  in
  Gram.Entry.of_parser "test_key_eq" test

let upper_bound _loc e l =
  match l with
    [] -> e
  | s::l ->
     let typ = List.fold_left ~init:<:ctyp< `$s$ of _ >> l
       ~f:(fun t s -> <:ctyp< `$s$ of _ | $t$ >>)
     in <:expr< ($e$ : Polymap.t [< $typ$ ]) >>

EXTEND Pcaml.Gram
  GLOBAL: Pcaml.expr;
  Pcaml.expr: LEVEL "." [
    [ e = SELF; "."; "`"; s = Pcaml.a_ident ->
      let tv = <:ctyp< '$"pm_"^next()$ >> in
      <:expr<
        (Obj.magic
           (Polymap.find (Obj.magic `$s$) ($e$ : Polymap.t [> `$s$ of $tv$ ]))
        : $tv$)
      >> ]
  ];
  Pcaml.expr: LEVEL "simple" [
    [ "`"; "{"; "}" -> <:expr< Polymap.empty >>
    | "`"; "{"; test_key_eq; lel = lbl_expr_list; "}" ->
        let (e, tl) = lel <:expr< Polymap.empty >> in
        upper_bound _loc e tl
    | "`"; "{"; e = Pcaml.expr LEVEL "."; "with"; lel = lbl_expr_list;
      "}" -> fst (lel e) ]
  ];
  lbl_expr_list: [
    [ fields = LIST1 field SEP ";" ->
        let tl = List.map fields ~f:(fun _ -> <:ctyp< '$"pm_"^next()$ >>) in
        fun org ->
          (match fields with
            [s,e] -> add _loc org (s,e) (List.hd tl)
          | _ ->
            List.fold_left2 ~init:org fields tl ~f:(add _loc)),
          List.map fst fields ]
  ];
  field: [[ s = Pcaml.a_ident; "="; e = Pcaml.expr LEVEL "top"  -> (s,e) ]];
END;;


  parent reply	other threads:[~2009-06-01  4:21 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-05-30 15:36 Dario Teixeira
2009-05-31  5:18 ` Dave Benjamin
2009-05-31  7:34   ` David Allsopp
2009-06-01  4:21   ` Jacques Garrigue [this message]
  -- strict thread matches above, loose matches on Subject: below --
2009-06-01 13:56 Dario Teixeira
2009-06-01 14:21 ` David Allsopp
2009-06-01 17:04   ` Peng Zang
2009-05-31 23:08 Dario Teixeira
2009-06-01 11:34 ` Yaron Minsky
2009-05-29 15:50 Dario Teixeira
2009-05-29 15:45 Dario Teixeira
2009-05-29 16:06 ` Till Varoquaux
2009-05-29 15:38 Dario Teixeira
2009-05-29 14:10 Dario Teixeira
2009-05-29 14:21 ` [Caml-list] " Jacques Carette
2009-05-29 14:43 ` David Allsopp
2009-05-29 15:33 ` Richard Jones

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=20090601.132123.210988323.garrigue@math.nagoya-u.ac.jp \
    --to=garrigue@math.nagoya-u.ac.jp \
    --cc=caml-list@yquem.inria.fr \
    --cc=darioteixeira@yahoo.com \
    --cc=dave@ramenlabs.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).