Explaining Functional Programming to Eight-Year-Olds
prog21.dadgum.com
prog21.dadgum.com
a1 op a2 op a3 op ... op an
where op is some binary operation. Executing op can either start from the left or right, so you have a left-fold or right-fold respectively. In Unify ATM I've defined the functions: (fold iv ar f)
(foldr ar iv f)
(foldn ar f)
(foldrn ar f)
Where:
-r = right fold, -n = no injected value
ar = an array (Unify uses arrays not lists)
f = a function taking 2 arguments
iv = an injection valueAlthough it might be better to cut the functions down to 2, and make iv an optional argument:
(fold f ar vararg iv)
(foldr f ar vararg iv)
Alternately I could use 'reduce' for the injectionless, and 'inject' for the injectionful versions of the function.map is obviously parallelized in a purely functional language. My opinion is that fold, otoh, is better limited to use with commutative and associative operators for clarity and transparent parallelization. That way, you don't have to think about whether you need to use a left or a right fold, or indeed a parellel fold.
Other "iterations" can be expressed using explicit recursion using an accumulator ... again, for clarity.
Unify isn't a functional language, nor do I particularly care about execution speed at present -- I'm writing it to test a concept I call Viewability. Having said that, the next version of Unify may well be more functional than the current one, and if so it could havre a way of tagging operators as commutative or associative, so the compiler can produce efficient code.
> map is obviously parallelized in a purely functional language
It's obviously parallelisable. It can only actually be parallelised if you have more than one CPU.
> My opinion is that fold, otoh, is better limited to use with commutative and associative operators for clarity and transparent parallelization.
I think it makes more sense in those cases, yes.
In fact you could make fold a method with multiple implementations depending on the type of function, e.g:
/* version that works with any function */
(fold ((Function f) ar) ...)
/* version that requires a function that is associative
and commutative, and can do appropriate optimisations */
(fold ((AssComFunction f) ar) ...)In Clojure its preduce, I believe (for parallel reduce; in Intel Threading Building Blocks its called parallel_reduce).
I am not a programmer of any singular talent, but I understood foldl when I was 9. I understood it in terms of Pascal and iteration, but the knowledge was there.
I think the name doesn't help either. People understand "reduce" more intuitively than "fold".