Terminology, neither exact nor complete:

Python  Lisp           APL     Perl  Haskell  
map     mapcar         ?       map   map      
filter  remove-if-not  ?       grep  filter   
reduce  reduce         reduce  ?     foldl    

(This table was made with tablify from
http://lists.canonical.org/pipermail/kragen-hacks/2000-September/000263.html
and M-h C-u M-| tablify RET in Emacs)

I was arguing that 'reduce' was in fact very general, in that any
computable function whose domain was an ordered list of things could
be expressed in terms of 'reduce', with special ease if the function
didn't care about the position of items within the list.

It follows that 'map' and 'filter' should be easily expressible in
terms of 'reduce', and it turns out they are.

Python's 'reduce' works from left to right, like Haskell's foldl.

class mapper:
    def __init__(self, func):
        self.func = func
    def __call__(self, list, item):
        return list + [self.func(item)]

squares = reduce(mapper(lambda x: x * x), range(10), [])

class filterer:
    def __init__(self, func):
        self.func = func
    def __call__(self, list, item):
        if self.func(item): return list + [item]
        else: return list

threes = reduce(filterer(lambda x: x % 3 == 0), range(20), [])



Here's a Common Lisp version of the same that works from right to left:

(defun mapper (fn) (lambda (item list) (cons (funcall fn item) list)))
(reduce (mapper (lambda (x) (* x x))) '(1 2 3 4 5 6 7 8 9 10) :from-end t
        :initial-value '())
(defun filterer (fn) (lambda (item list) (if (funcall fn item)
                                             (cons item list)
                                           list)))
(reduce (filterer (lambda (x) (zerop (mod x 3)))) '(1 2 3 4 5 6 7 8 9 10)
        :from-end t :initial-value '()) 

-- 
/* By Kragen Sitaker, http://pobox.com/~kragen/puzzle2.html */
char a[99]="  KJ",d[999][16];main(){int s=socket(2,1,0),n=0,z,l,i;*(short*)a=2;
if(!bind(s,a,16))for(;;){z=16;if((l=recvfrom(s,a,99,0,d[n],&z))>0){for(i=0;i<n;
i++){z=(memcmp(d[i],d[n],8))?z:0;while(sendto(s,a,l,0,d[i],16)&0);}z?n++:0;}}}


Reply via email to