Mailing list for all users of the OCaml language and system.
 help / color / mirror / Atom feed
From: Jon Harrop <jon@ffconsultancy.com>
To: caml-list@yquem.inria.fr
Subject: try .. finally ..
Date: Sun, 20 May 2007 18:42:59 +0100	[thread overview]
Message-ID: <200705201842.59978.jon@ffconsultancy.com> (raw)


This is a very useful construct found in many other languages including F#. 
This construct can be implemented in OCaml as a macro. Martin Jambon gives an 
example on his camlp4 tutorial:

(* The function that returns unique identifiers *)
let new_id = 
  let counter = ref 0 in
  fun () ->
    incr counter;
    "__finally" ^ string_of_int !counter

(* The function that converts our syntax into a single OCaml expression,
   i.e. an "expr" node of the syntax tree *)
let expand loc e1 e2 =
  let id = new_id () in
  let id_patt = <:patt< $lid:id$ >> in
  let id_expr = <:expr< $lid:id$ >> in
  <:expr<
  let $id_patt$ =
    try do { $e1$; None } 
    with [ exn -> Some exn ] in
  do { $e2$;
       match $id_expr$ with
           [ None -> ()
           | Some exn -> raise exn ] }
  >>

(* The statement that extends the default grammar, 
   i.e. the regular syntax of OCaml if we use camlp4o 
   or the revised syntax if we use camlp4r *)
EXTEND
  Pcaml.expr: LEVEL "expr1" [
    [ "try"; e1 = Pcaml.expr; "finally"; e2 = Pcaml.expr -> expand loc e1 e2 ]
  ];
END;;

Just looking at this code, the creation of new identifiers with obfuscated 
names in an attempt to avoid conflicts is rather ugly.

Can this functionality be implemented more elegantly in terms of an 
unwind_protect function, moving the new identifiers into their own scope:

  let unwind_protect f g =
    let fin = ref false in
    try
      let x = f () in
      fin := true;
      g();
      x
    with exn when !fin ->
      g();
      raise exn

  EXTEND
    Pcaml.expr: LEVEL "expr1" [
      [ "try"; e1 = Pcaml.expr; "finally"; e2 = Pcaml.expr ->
         <:expr< unwind_protect (fun () -> $e1$) (fun () -> $e2$) >> ]
    ];
  END

Is this a general observation about macros?

-- 
Dr Jon D Harrop, Flying Frog Consultancy Ltd.
The F#.NET Journal
http://www.ffconsultancy.com/products/fsharp_journal/?e


             reply	other threads:[~2007-05-20 17:48 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-05-20 17:42 Jon Harrop [this message]
2007-05-20 19:30 ` [Caml-list] " Alain Frisch
2007-05-21  7:49   ` Florian Weimer

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=200705201842.59978.jon@ffconsultancy.com \
    --to=jon@ffconsultancy.com \
    --cc=caml-list@yquem.inria.fr \
    /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