The first is less likely to require debugging in the first place.
> There are lots of data structures in this style of programming that don't have any names.
So you can only reason about things that have names? Now we know where idiomatic Java comes from.
> Who knows what kind of data structures map and filter create in order to do their work.
In most reasonable implementations, the only data structure being created is the final result (a functorial value in map's case, a sequence in filter's case). For example, in SML:
fun map _ nil = nil
| map f (x :: xs) = f x :: map f xs
fun filter _ nil = nil
| filter p (x :: xs) =
if p x then x :: filter p xs
else filter p xs
> But the core promise of functional programming—that you can stop thinking about the underlying procedures—never seems to fully pan out.Functional programming doesn't promise freedom from procedures. It promises (and delivers) freedom from physical object identities when you only care about logical values.
---
@banachtarski:
Code that's likely to require debugging (say, because it implements tricky algorithms) should be isolated from the rest anyway, regardless of whether your program is written in a functional style or not. Say, in Haskell:
Bad:
filter (\x -> tricky_logic_1) $
map (\x -> tricky_logic_2) $ xs
Good: -- Now trickyFunction1 and trickyFunction2 can be
-- tested in isolation. Or whatever.
trickyFunction1 x = ...
trickyFunction2 x = ...
filter trickyFunction1 (map trickyFunction2 xs)