From: Kaz Kylheku
Subject: Six years makes you slightly smarter.
Date:
Message-ID: <20081217193144.554@gmail.com>
I was just looking at a macro I wrote in 2002, and right away spotted how
the recursive macro expansion is actually a left-associative reduce.
The lower-level expander's arguments just had to be swapped.
The initial expression to the filter nicely lands a role
as the argument to REDUCE's INITIAL-VALUE.
Doh!
--- filter.lisp.orig 2008-12-02 00:01:25.000000000 -0800
+++ filter.lisp 2008-12-02 00:55:52.947889000 -0800
@@ -20,7 +20,7 @@
(when find
(return find)))))))
-(defun expand-filter-expr (expr input)
+(defun expand-filter-expr (input expr)
(cond
((null expr)
input)
@@ -43,9 +43,9 @@
(t `(multiple-value-call (lambda ,(first expr)
,@(rest expr)) ,input))))
((eq 'lambda (first expr))
- (expand-filter-expr (rest expr) input))
+ (expand-filter-expr input (rest expr)))
((eq 'function (first expr))
- (expand-filter-expr (second expr) input))
+ (expand-filter-expr input (second expr)))
((member (first expr) *filter-mapping-functions*)
(cond
((and (consp (second expr))
@@ -55,7 +55,7 @@
`(,(first expr) #',(second expr) ,@(rest (rest expr)) ,input))
(t (let ((input-sym (gensym "INPUT-")))
`(,(first expr) (lambda (,input-sym)
- ,(expand-filter-expr (second expr) input-sym))
+ ,(expand-filter-expr input-sym (second expr)))
,input)))))
((eq 'split (first expr))
(let ((value-list-sym (gensym "VALUE-LIST-")))
@@ -96,10 +96,7 @@
(push sym *filter-single-value-funcs*))
(defmacro filter (initial-expr &body filter-expr-list)
- (if (null filter-expr-list)
- initial-expr
- `(filter ,(expand-filter-expr (first filter-expr-list) initial-expr)
- ,@(rest filter-expr-list))))
+ (reduce #'expand-filter-expr filter-expr-list :initial-value initial-expr))
(defun filter-chatter (&rest args)
(if (= (length args) 1)