Mailing list for all users of the OCaml language and system.
 help / color / mirror / Atom feed
From: "Nicolas Pouillard" <nicolas.pouillard@gmail.com>
To: micha <micha-1@fantasymail.de>
Cc: caml-list@inria.fr
Subject: Re: [Caml-list] using camlp4
Date: Tue, 8 May 2007 11:19:11 +0200	[thread overview]
Message-ID: <cd67f63a0705080219t4f026055t12196e9f8e2ff150@mail.gmail.com> (raw)
In-Reply-To: <20070508001706.32a70243@hmmm.de>

[-- Attachment #1: Type: text/plain, Size: 978 bytes --]

On 5/8/07, micha <micha-1@fantasymail.de> wrote:
> hi,
>
> I have classes which have many getter/setter methods. At the moment I
> use two naming schemes intermixed: get_property / set_property and
> property / set_property and I don't like that very much.
> I would like to integrate one camlp4 extension which allows to define
> the getter and setter methods for members, to be able to write:
>
> obj#prob <- xxx;
> print_endline obj#prob;

The pa_oo extension from Jacques Garrigue  does exactly this kind of things:

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

I attach the upgraded to 3.10 extension.

> Is this a good idea to integrate camlp4 macros in my project?

No in particular when using clean and simple extensions pa_oo.

> If someone who might use my lib  also uses a camlp4 extension, can this
> lead to trouble?

No since people use a compiled version of your library, so all the
sugar provided by macros is gone.

Regards,

-- 
Nicolas Pouillard

[-- Attachment #2: pa_oo.ml --]
[-- Type: text/plain, Size: 3143 bytes --]

(*
  With ocamlbuild:
    To compile (using this _tags file):
      ocamlbuild pa_oo.cmo
    To use:
      ocaml camlp4o.cma ./_build/pa_oo.cmo
    or
      ocamlc -pp 'camlp4o ./_build/pa_oo.cmo'

  Without:
    To compile:
      ocamlc -I +camlp4 -c -pp camlp4orf pa_oo.ml
    To use:
      ocaml camlp4o.cma pa_oo.cmo
    or
      ocamlc -pp 'camlp4o -I . pa_oo.cmo'
*)

open Camlp4.PreCast

module Caml = Syntax

let expand_access _loc mut id e kind =
  let id' = id^"'" in
  let reader = <:class_str_item< method $id$ = $lid:id$ >>
  and writer =
    <:class_str_item< method $"set_"^id$ $lid:id'$ = $lid:id$ := $lid:id'$ >>
  in
  let accessors =
    match kind with None -> <:class_str_item<>>
    | Some k -> match k with
      | `R -> reader
      | `W -> writer
      | `RW -> <:class_str_item< $reader$; $writer$ >>
  in
  <:class_str_item<
    value $mutable:mut$ $lid:id$ = $e$;
    $accessors$
  >>

(* Copied from camlp4/Camlp4Parsers/Camlp4OCamlRevisedParser.ml *)
let bigarray_set _loc var newval =
  match var with
  | <:expr< Bigarray.Array1.get $arr$ $c1$ >> ->
      Some <:expr< Bigarray.Array1.set $arr$ $c1$ $newval$ >>
  | <:expr< Bigarray.Array2.get $arr$ $c1$ $c2$ >> ->
      Some <:expr< Bigarray.Array2.set $arr$ $c1$ $c2$ $newval$ >>
  | <:expr< Bigarray.Array3.get $arr$ $c1$ $c2$ $c3$ >> ->
      Some <:expr< Bigarray.Array3.set $arr$ $c1$ $c2$ $c3$ $newval$ >>
  | <:expr< Bigarray.Genarray.get $arr$ [| $coords$ |] >> ->
      Some <:expr< Bigarray.Genarray.set $arr$ [| $coords$ |] $newval$ >>
  | _ -> None

let expand_set _loc e1 e2 =
  match bigarray_set _loc e1 e2 with
  | Some e -> e
  | None -> match e1 with
    | <:expr< $o$ # $x$ >> -> <:expr< $o$ # $"set_"^x$ $e2$ >>
    | _ -> <:expr< $e1$ := $e2$ >>

DELETE_RULE Caml.Gram Caml.expr: SELF; "<-"; Caml.expr LEVEL "top" END;;

EXTEND Caml.Gram
  GLOBAL: Caml.class_str_item Caml.expr Caml.opt_mutable Caml.ctyp;
  Caml.class_str_item: [
    [ "val"; "mutable"; `LIDENT lab; e = cvalue_binding; kind = cvalue_kind ->
      expand_access _loc Ast.BTrue lab e kind
    | "val"; `LIDENT lab; e = cvalue_binding; kind = cvalue_kind ->
      expand_access _loc Ast.BFalse lab e kind ]
  ];
  cvalue_kind: [
    [ kind = OPT [ "with"; k =
       [ "reader" -> `R | "writer" -> `W | "accessor" -> `RW ] -> k] ->
      kind ]
  ];
  cvalue_binding: [
    [ "="; e = Caml.expr -> e
    | ":"; t = Caml.ctyp; "="; e = Caml.expr -> <:expr< ($e$ : $t$) >> ]
  ];
  Caml.expr: LEVEL ":=" [
    [ e1 = SELF; "<-"; e2 = Caml.expr LEVEL "top" -> expand_set _loc e1 e2 ]
  ];
  Caml.expr: LEVEL "simple" [
    [ "{|"; cf = LIST1 obj_record SEP ";"; "|}" ->
      (* self = OPT
        [ "("; p = patt; ":"; t = ctyp; ")" -> <:patt< ($p$ : $t$) >>
        | "("; p = patt; ")" -> <:patt< $p$ >> ]; *)
      <:expr< object $Ast.crSem_of_list cf$ end >> ]
  ];
  obj_record: [
    [ "inherit"; ce = Caml.class_expr -> <:class_str_item< inherit $ce$ >>
    | mf = Caml.opt_mutable; `LIDENT lab; ty = OPT [ ":"; t = Caml.ctyp -> t];
      "="; e = Caml.expr LEVEL "top" ->
        expand_access _loc mf lab e (Some(if mf = Ast.BFalse then `R else `RW)) ]
  ];
END;;


      reply	other threads:[~2007-05-08  9:19 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-05-07 22:17 micha
2007-05-08  9:19 ` Nicolas Pouillard [this message]

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=cd67f63a0705080219t4f026055t12196e9f8e2ff150@mail.gmail.com \
    --to=nicolas.pouillard@gmail.com \
    --cc=caml-list@inria.fr \
    --cc=micha-1@fantasymail.de \
    /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