Browse thread
camlp4
[
Home
]
[ Index:
by date
|
by threads
]
[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
| Date: | -- (:) |
| From: | Christian Sternagel <Christian.Sternagel@u...> |
| Subject: | Re: [Caml-list] camlp4 |
Quoting Nicolas Pouillard <nicolas.pouillard@gmail.com>: > Excerpts from oandrieu's message of Fri Jan 18 20:30:59 +0100 2008: > > On Jan 18, 2008 6:08 PM, Christian Sternagel > > <Christian.Sternagel@uibk.ac.at> wrote: > > > When using `camlp4o -parser Camlp4ListComprehension' as preprocessor, > > > is the resulting code the naive translation, like in, > > > > > > [(x, y) | x <- xs, even xs, y <- ys] > > > > > > => > > > > > > List.flatten ( > > > List.map (fun x -> List.map (fun y -> (x, y)) ys) (List.filter even xs) > > > ) > > > > > > or is there an optimization in order to avoid appends and minimize the > > > number of cons? > > > > > > FYI, my (old) syntax extension¹ for camlp4 <= 3.09 expands list > > comprehensions to a combination of folds: > > > > [+ (x, y) | x <- xs | when even x | y <- ys] > > > > => > > > > List.fold_right > > (fun x __acc__ -> > > if even x then > > List.fold_right (fun y __acc__ -> (x, y) :: __acc__) ys __acc__ > > else __acc__) > > xs [] > > > > Less cons operations, but it's not tail recursive. > > Hum... That's nice and I could accept patches in that direction. However > can > you do it without introducing variables, that's always dangerous to > add > variables because we should check that the user is not using the same. > > > [1] http://oandrieu.nerim.net/ocaml/#pa_compr > > -- > Nicolas Pouillard aka Ertai > > How about the transformation from Chapter 7 of [1] (by Philip Wadler)? It should be similar to the `pseudo code': type expr = ...;; type patt = ...;; type qualifier = Gen of patt * expr | Filt of expr;; type compr = (expr * qualifier list);; let rec expr = function | ... | (e, qs) -> transform [] (e, qs) | ... and transform l = function | (e, []) -> expr e :: expr l | (e, Filt f :: qs) -> if expr f then transform l (e, qs) else expr l | (e, Gen (p, l1) :: qs) -> let rec h = function | [] -> expr l | u :: us -> (function p -> transform (h us) (e, qs) | _ -> h us) u in h (expr l1) ;; (* where h, u, us are fresh variables not occurring in e, l1, l, or qs *) Sorry I'm not yet familiar with camlp4 grammar extensions, but of course above code would make use of them otherwise. It is stated in [1] that the resulting code is optimal in that it performs the minimum number of cons operations. I'm not sure whether this isn't equivalent to oandrieu's code. And I did ignore the hint that fresh variables make things complicated :). cheers christian [1] Simon P. Jones, 1987. The implementation of functional programming languages. Available online at: http://research.microsoft.com/~simonpj/papers/slpj-book-1987/index.htm