From: users-...@racket-lang.org [mailto:users-...@racket-lang.org] On Behalf Of Will Kurt
Sent: 13 August 2010 03:53
To: us...@racket-lang.org
Subject: [racket] question about foldl implementation
I don't think there is a canonical implementation. In Racket is seen
as the same function as right fold; it just happens to process the
list in a different order and so can be tail recursive. Hence it has
the same interface. Racket values consistency and clarity in code.
In Haskell left fold is seen as a different function to right fold,
and hence has a different interface. Haskell values confusing code so
Haskell programmers appreciate having different interfaces for very
similar functions (and the type system will catch some errors).
HTH,
N.
PS: Some of the above is not to be taken seriously.
_________________________________________________
For list-related administrative tasks:
http://lists.racket-lang.org/listinfo/users
> In Haskell left fold is seen as a different function to right fold,
> and hence has a different interface. Haskell values confusing code so
> Haskell programmers appreciate having different interfaces for very
> similar functions (and the type system will catch some errors).
In seriousness, in Haskell the functions are really different regarding how strict they are, so it maybe makes more sense for them to have different interfaces. (Though, of course, in Racket, they differ in space usage, as Noel pointed out, so the same logic could apply.)
Will
rather than
(procedure (car list1) (car list2) ... accumulator)
This means that reverse cannot be defined as (foldl cons '() list),
but rather (foldl rcons '() list) where rcons = (lambda (cdr car)
(cons car cdr))
I think the consistency of keeping the argument list in the same order
trumps the cleverness of a hack definition of reverse (which definition
wouldn't be used anyway). Also, it is more common to see accumulator
arguments earlier in the argument list than the thing being accumulated.
--
~jrm
The Haskell ordering also has the advantage of fitting with the Typed
Racket type system for variable-arity functions.
--
sam th
sa...@ccs.neu.edu
This also makes the obvious many-argument version more efficient:
(define (foldl kons knil . lists)
(if (ormap null? lists)
knil
(apply foldl kons (apply kons knil (map car lists)) (map cdr lists))))
as opposed to
(define (foldl* kons knil . lists)
(if (ormap null? lists)
knil
(apply foldl* kons (apply kons (append (map car lists) (list knil))) (map cdr lists))))
The extra append is kinda annoying in the foldl* version....
Will