caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
* camlp4 & free variables
@ 2006-07-19 23:27 Christophe TROESTLER
  2006-07-20  8:28 ` [Caml-list] " Nicolas Pouillard
                   ` (3 more replies)
  0 siblings, 4 replies; 8+ messages in thread
From: Christophe TROESTLER @ 2006-07-19 23:27 UTC (permalink / raw)
  To: O'Caml Mailing List

Hi,

Is it possible to write a camlp4 syntax extension that "extract" the
free variables of an expression?  As an example, say I write

  FUNCTION(let z = x + 2 in x + 2 * y * x * z)

and it becomes

  fun ~x ~y -> let z = x + 2 in x + 2 * y * x * z

(of course I'd like good error reporting in case of an error in the
expression).  If it is not possible, what is the best way to build a
tool that does that (short of writing a parser for the OCaml language)?

Thanks,
ChriS


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [Caml-list] camlp4 & free variables
  2006-07-19 23:27 camlp4 & free variables Christophe TROESTLER
@ 2006-07-20  8:28 ` Nicolas Pouillard
       [not found]   ` <20060720.163930.91910937.Christophe.Troestler@umh.ac.be>
  2006-07-20  9:25 ` Guido Kollerie
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 8+ messages in thread
From: Nicolas Pouillard @ 2006-07-20  8:28 UTC (permalink / raw)
  To: Christophe TROESTLER; +Cc: O'Caml Mailing List

On 7/20/06, Christophe TROESTLER <Christophe.Troestler@umh.ac.be> wrote:
> Hi,
>
> Is it possible to write a camlp4 syntax extension that "extract" the
> free variables of an expression?
You are quite lucky, the camlp4 version has one module to do that!

>  As an example, say I write
>
>   FUNCTION(let z = x + 2 in x + 2 * y * x * z)
>
> and it becomes
>
>   fun ~x ~y -> let z = x + 2 in x + 2 * y * x * z

#default_quotation "expr";

open Camlp4.PreCast;
open Format;

module FV = Camlp4.Struct.FreeVars.Make Ast;
module PP = Camlp4.Printers.OCaml.Make Syntax;
module S = FV.S;

value _loc = Loc.ghost;

value pervasives =
  let list =
    [ "+"; "-"; "/"; "*" (* ... *) ]
  in List.fold_right S.add list S.empty;

value f e =
  let fv = FV.free_vars pervasives e in
  S.fold (fun x acc -> << fun ~ $x$ -> $acc$ >>) fv e;

value print_expr = (new PP.printer ())#expr;

printf "%a@." print_expr (f <<let z = x + 2 in x + 2 * y * x * z>>);

(* end *)

# using an up to date CVS checkout of ocaml.

$ ocamlc -I +camlp4 Camlp4.cma -pp camlp4rf free_vars_test.ml
$ ./a.out
fun ~y ~x -> let z = x + 2 in x + (((2 * y) * x) * z)

Best regards,

-- 
Nicolas Pouillard


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [Caml-list] camlp4 & free variables
  2006-07-19 23:27 camlp4 & free variables Christophe TROESTLER
  2006-07-20  8:28 ` [Caml-list] " Nicolas Pouillard
@ 2006-07-20  9:25 ` Guido Kollerie
  2006-07-20  9:25 ` Guido Kollerie
  2006-07-20  9:25 ` [Caml-list] camlp4 & free variables Guido Kollerie
  3 siblings, 0 replies; 8+ messages in thread
From: Guido Kollerie @ 2006-07-20  9:25 UTC (permalink / raw)
  To: Christophe TROESTLER; +Cc: O'Caml Mailing List



^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [Caml-list] camlp4 & free variables
  2006-07-19 23:27 camlp4 & free variables Christophe TROESTLER
  2006-07-20  8:28 ` [Caml-list] " Nicolas Pouillard
  2006-07-20  9:25 ` Guido Kollerie
@ 2006-07-20  9:25 ` Guido Kollerie
  2006-07-20 10:25   ` Accidentally bounced my email [Was: [Caml-list] camlp4 & free variables] Guido Kollerie
  2006-07-20  9:25 ` [Caml-list] camlp4 & free variables Guido Kollerie
  3 siblings, 1 reply; 8+ messages in thread
From: Guido Kollerie @ 2006-07-20  9:25 UTC (permalink / raw)
  To: Christophe TROESTLER; +Cc: O'Caml Mailing List

On 7/20/06, Christophe TROESTLER <Christophe.Troestler@umh.ac.be> wrote:
> Hi,
>
> Is it possible to write a camlp4 syntax extension that "extract" the
> free variables of an expression?
You are quite lucky, the camlp4 version has one module to do that!

>  As an example, say I write
>
>   FUNCTION(let z = x + 2 in x + 2 * y * x * z)
>
> and it becomes
>
>   fun ~x ~y -> let z = x + 2 in x + 2 * y * x * z

#default_quotation "expr";

open Camlp4.PreCast;
open Format;

module FV = Camlp4.Struct.FreeVars.Make Ast;
module PP = Camlp4.Printers.OCaml.Make Syntax;
module S = FV.S;

value _loc = Loc.ghost;

value pervasives =
  let list =
    [ "+"; "-"; "/"; "*" (* ... *) ]
  in List.fold_right S.add list S.empty;

value f e =
  let fv = FV.free_vars pervasives e in
  S.fold (fun x acc -> << fun ~ $x$ -> $acc$ >>) fv e;

value print_expr = (new PP.printer ())#expr;

printf "%a@." print_expr (f <<let z = x + 2 in x + 2 * y * x * z>>);

(* end *)

# using an up to date CVS checkout of ocaml.

$ ocamlc -I +camlp4 Camlp4.cma -pp camlp4rf free_vars_test.ml
$ ./a.out
fun ~y ~x -> let z = x + 2 in x + (((2 * y) * x) * z)

Best regards,

-- 
Nicolas Pouillard

_______________________________________________
Caml-list mailing list. Subscription management:
http://yquem.inria.fr/cgi-bin/mailman/listinfo/caml-list
Archives: http://caml.inria.fr
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
Bug reports: http://caml.inria.fr/bin/caml-bugs


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [Caml-list] camlp4 & free variables
  2006-07-19 23:27 camlp4 & free variables Christophe TROESTLER
                   ` (2 preceding siblings ...)
  2006-07-20  9:25 ` Guido Kollerie
@ 2006-07-20  9:25 ` Guido Kollerie
  3 siblings, 0 replies; 8+ messages in thread
From: Guido Kollerie @ 2006-07-20  9:25 UTC (permalink / raw)
  To: Christophe TROESTLER; +Cc: O'Caml Mailing List

On 7/20/06, Christophe TROESTLER <Christophe.Troestler@umh.ac.be> wrote:
> Hi,
>
> Is it possible to write a camlp4 syntax extension that "extract" the
> free variables of an expression?
You are quite lucky, the camlp4 version has one module to do that!

>  As an example, say I write
>
>   FUNCTION(let z = x + 2 in x + 2 * y * x * z)
>
> and it becomes
>
>   fun ~x ~y -> let z = x + 2 in x + 2 * y * x * z

#default_quotation "expr";

open Camlp4.PreCast;
open Format;

module FV = Camlp4.Struct.FreeVars.Make Ast;
module PP = Camlp4.Printers.OCaml.Make Syntax;
module S = FV.S;

value _loc = Loc.ghost;

value pervasives =
  let list =
    [ "+"; "-"; "/"; "*" (* ... *) ]
  in List.fold_right S.add list S.empty;

value f e =
  let fv = FV.free_vars pervasives e in
  S.fold (fun x acc -> << fun ~ $x$ -> $acc$ >>) fv e;

value print_expr = (new PP.printer ())#expr;

printf "%a@." print_expr (f <<let z = x + 2 in x + 2 * y * x * z>>);

(* end *)

# using an up to date CVS checkout of ocaml.

$ ocamlc -I +camlp4 Camlp4.cma -pp camlp4rf free_vars_test.ml
$ ./a.out
fun ~y ~x -> let z = x + 2 in x + (((2 * y) * x) * z)

Best regards,

-- 
Nicolas Pouillard

_______________________________________________
Caml-list mailing list. Subscription management:
http://yquem.inria.fr/cgi-bin/mailman/listinfo/caml-list
Archives: http://caml.inria.fr
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
Bug reports: http://caml.inria.fr/bin/caml-bugs


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Accidentally bounced my email [Was: [Caml-list] camlp4 & free variables]
  2006-07-20  9:25 ` Guido Kollerie
@ 2006-07-20 10:25   ` Guido Kollerie
  0 siblings, 0 replies; 8+ messages in thread
From: Guido Kollerie @ 2006-07-20 10:25 UTC (permalink / raw)
  To: O'Caml Mailing List


I am sorry. I seem to have accidentally bounced a number of messages.  
That's what you get when trying to master Dvorak and typing Qwerty  
keyboard shortcuts on a Dvorak keyboard layout. :-(

-- 
Guido




^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [Caml-list] camlp4 & free variables
       [not found]   ` <20060720.163930.91910937.Christophe.Troestler@umh.ac.be>
@ 2006-07-21 12:01     ` Nicolas Pouillard
  2006-07-21 18:16       ` Martin Jambon
  0 siblings, 1 reply; 8+ messages in thread
From: Nicolas Pouillard @ 2006-07-21 12:01 UTC (permalink / raw)
  To: Christophe TROESTLER; +Cc: caml-list

On 7/20/06, Christophe TROESTLER <Christophe.Troestler@umh.ac.be> wrote:
> On Thu, 20 Jul 2006, "Nicolas Pouillard" <nicolas.pouillard@gmail.com> wrote:
> >
> > On 7/20/06, Christophe TROESTLER <Christophe.Troestler@umh.ac.be> wrote:
> > > Hi,
> > >
> > > Is it possible to write a camlp4 syntax extension that "extract" the
> > > free variables of an expression?
> > You are quite lucky, the camlp4 version has one module to do that!
>
> Thank you very much for your help!  Is there an updated manual for
> camlp4 (if possible written more from a user perspective :)?
>

Alas not now.

> If I understand well your code (I really ought to learn camlp4!)
> FV.free_vars first argument is a set of names which should net be
> considered as free variables.  Is it possible to do it contextually,
> e.g. in
>
>      open_out("X" ^ x)
>
> only "x" is returned as free because "open_out" and "^" are known from
> Pervasives?  Or in
>
>      let z = 1
>      ...
>      FUNCTION(x + z)
>
> only "x" is returned as free because "z" is known from the context?
>

In my previous program, I provide a function f that takes an AST:

f <<let z = x + 2 in x + 2 * y * x * z>>

Here the AST is given using a quotation but there is no relation
between the code outside and inside the quotation so:

let x = 42 in f <<let z = x + 2 in x + 2 * y * x * z>>

This code does not bind x inside the quotation.

Now if you want to use FUNCTION(...) as a sort of macro function there
is a camlp4 filter for that.

Let's call close_expr the this macro function (instead of FUNCTION)

$ cat expression_closure_filter.ml
(* camlp4r *)
#default_quotation "expr";

open Camlp4.PreCast;
open Format;

module FV = Camlp4.Struct.FreeVars.Make Ast;
module S = FV.S;

value _loc = Loc.ghost;

value pervasives =
  let list =
    [ "+"; "-"; "/"; "*" (* ... *) ]
  in List.fold_right S.add list S.empty;

value collect_free_vars_sets =
  object (self)
    inherit FV.fold_free_vars [S.t] S.add ~env_init:pervasives S.empty as super;
    value free_sets = [];
    method set_free free = {< free = free >};
    method expr =
      fun
      [ << close_expr $e$ >> -> (self#expr e)#add_current_free#set_free free
      | e -> super#expr e ];
    method add_current_free = {< free_sets = [ free :: free_sets ] >};
    method free_sets = free_sets;
  end;

value apply_close_expr next_free_set =
  object (self)
    inherit Ast.map as super;
    method expr =
      fun
      [ << close_expr $e$ >> ->
          let e = self#expr e in
          let fv = next_free_set () in
          S.fold (fun x acc -> << fun ~ $x$ -> $acc$ >>) fv e
      | e -> super#expr e ];
  end;

value f st =
  let fv_sets = ref (collect_free_vars_sets#str_item st)#free_sets in
  let next_free_set () =
    match fv_sets.val with
    [ [] -> assert False
    | [x::xs] -> let () = fv_sets.val := xs in x ]
  in (apply_close_expr next_free_set)#str_item st;

AstFilters.register_str_item_filter f;

$ ocamlc -c -pp camlp4rf expression_closure_filter.ml

$ cat test_expression_closure_filter.ml
(* x and y are free *)
close_expr(x y);;

(* bind x *)
let x = 42;;

(* y is free *)
close_expr(x y);;

(* bind y locally so the expr is closed *)
close_expr(let y = x in x y);;

(* bind y locally but outside, z is free *)
let y = x in close_expr(x z y);;

$ camlp4o ./expression_closure_filter.cmo test_expression_closure_filter.ml
(* x and y are free *)
let _ = fun ~y ~x -> x y
(* bind x *)
let x = 42
(* y is free *)
let _ = fun ~y -> x y
(* bind y locally so the expr is closed *)
let _ = let y = x in x y
(* bind y locally but outside, z is free *)
let _ = let y = x in fun ~z -> x z y


> Thanks again -- the new camlp4 version seem to really shine
> w.r.t. the previous one !

Thanks, I'm glad to see camlp4 receive appreciations :)

Cheers,

-- 
Nicolas Pouillard


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [Caml-list] camlp4 & free variables
  2006-07-21 12:01     ` Nicolas Pouillard
@ 2006-07-21 18:16       ` Martin Jambon
  0 siblings, 0 replies; 8+ messages in thread
From: Martin Jambon @ 2006-07-21 18:16 UTC (permalink / raw)
  To: Nicolas Pouillard; +Cc: Christophe TROESTLER, caml-list

On Fri, 21 Jul 2006, Nicolas Pouillard wrote:

>> Thanks again -- the new camlp4 version seem to really shine
>> w.r.t. the previous one !
>
> Thanks, I'm glad to see camlp4 receive appreciations :)

If it makes you feel better, I don't think anybody was questioning the 
quality of your work.

What I was pointing out is the lack of trust from the users, which is a 
direct consequence of the lack of communication from the core OCaml team.
For example, why should anyone invest time in using Camlp4, when you see 
that the main developer left the OCaml group angrily a few years ago for 
unexplained reasons, and that the last version of the manual was 
released approximately at that time.

Now that you have been preparing a new version of Camlp4 and you are 
obviously very motivated, why not setup a web page that answers all the 
practical and philosophical questions that people may ask themselves 
about Camlp4 and its relationship with the OCaml language. Tell yourself 
that when someone actually asks one question on the caml-list, it probably 
means that hundreds of people have had the same problem and just gave up.


Thank you for your understanding,


Martin

--
Martin Jambon, PhD
http://martin.jambon.free.fr


^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2006-07-21 18:17 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2006-07-19 23:27 camlp4 & free variables Christophe TROESTLER
2006-07-20  8:28 ` [Caml-list] " Nicolas Pouillard
     [not found]   ` <20060720.163930.91910937.Christophe.Troestler@umh.ac.be>
2006-07-21 12:01     ` Nicolas Pouillard
2006-07-21 18:16       ` Martin Jambon
2006-07-20  9:25 ` Guido Kollerie
2006-07-20  9:25 ` Guido Kollerie
2006-07-20 10:25   ` Accidentally bounced my email [Was: [Caml-list] camlp4 & free variables] Guido Kollerie
2006-07-20  9:25 ` [Caml-list] camlp4 & free variables Guido Kollerie

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).