Browse thread
Avoiding shared data
[
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: | 2005-10-01 (08:26) |
From: | Wolfgang Lux <wlux@u...> |
Subject: | Re: Ant: Re: [Caml-list] Avoiding shared data |
Pal-Kristian Engstad wrote: > The author argues that "Writing loops with tail-recursive function > calls is > the equivalent of writing them with goto’s." and gives an example that > I've > rewritten from Scheme-ish into OCaml-ish: > > let myfunc l = > let rec loop rest result = > match rest with > | [] -> List.rev result > | x::xs -> > if xpred x then > let y = verbose_code_using_x x in > if ypred y then > let z = verbose_code_using_y y in > loop xs (z_expression :: result) > else > loop xs result > else > loop xs result > in > loop l [] > ;; > > Obviously, one would like to refactor this into HOF, but in this > situation it > is hard to see how one should do it. Oh come on! IMHO, most loops can easily be transformed by using map, filter, fold_left, and fold_right. The example given is no exception. The loop essentially applies some complex code to every element of the list and includes the result in the output list only if a condition is satisfied that is computed along with result. This is always the structure of a fold. (If the condition were independent from the result one could combine a filter and a map.) Thus, a straight forward rewrite of the loop is: let myfunc l = let f x result = if xpred then let y = verbose_code_using_x x in if ypred y then let z = verbose_code_using_y y in z_expression :: result else result else result in fold_right f l [] Furthermore, I would turn the two if expressions into local functions let myfunc l = let g y result = if ypred y then let z = verbose_code_using_y y in z_expression :: result else result in let f x result = if xpred x then let y = verbose_code_using_x x in g y result else result in fold_right f l [] Regards Wolfgang