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: | -- (:) |
| 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