On Friday 30 September 2005 03:57 pm, Oliver Bandel wrote:
> On the other hand: writing mor funtional/recursive code will
> make you more used to to this...
I've always thought that this was a really bad argument from the ML camp. The
logic of complicated control-paths is very easily made a zillion times worse
by writing in a tail-recursive style. It is *not* a good programming practice
to make hard-to-read code!
I encourage people to read the paper by Olin Shivers: "The Anatomy of a Loop -
A story of scope and control", which was presented at ICFP 2005, and can be
found at http://www.cc.gatech.edu/~shivers/papers/loop.pdf.
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. The author instead proposes to use loops
in a monadic style, which I've again rewritten:
let myfunc l =
loop [ for x in l
; when xpred x
; let y = verbose_code_using_x x
; when ypred y
; let z = verbose_code_using_y y
; save z
]
The point being (syntax aside) that this code is much more readible, easier to
change and easier to verify than the code given above. [Of course, Haskell
has the really cool list-comprehension syntax that alleviates some of ML's
problems, but still.]
Thanks,
PKE.
--
_
\`. PÃÂ¥l-Kristian Engstad, Lead Programmer,
\ `| Naughty Dog, Inc., 1601 Cloverfield Blvd, 6000 North,
__\ |`. Santa Monica, CA 90404, USA. (310) 633-9112.
/ /o mailto:engstad@naughtydog.com http://www.naughtydog.com
/ '~ mailto:mrengstad@yahoo.com http://www.engstad.com
/ ,' Hang-gliding Rulez!
~'