[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
RE: Wanted: mapcar() without nils
From: |
Drew Adams |
Subject: |
RE: Wanted: mapcar() without nils |
Date: |
Sat, 13 Jun 2009 13:02:54 -0700 |
> (defun extract-elements (pred seq)
> (delq nil (mapcar `(lambda (elm)
> (when (,pred elm)) elm)
> seq)))
>
> But why does my test-cases return '(a b 1 2) all the time?
The body of your lambda is this: (when X) Y
The body is an implicit progn. It returns the value of the last sexp, which is
Y.
You meant (when X Y), not (when X) Y.
Better yet, you meant (and X Y), since you are interested in the value returned
- you are not interested only in some side effect.
(defun extract-elements (pred seq)
(delq nil (mapcar (lambda (elm)
(and (funcall pred elm) elm))
seq)))
Or instead of constructing a list and then filtering it, construct it with only
the elements you want. IOW, promote the filter to be inside the iteration/map.
(defun extract-elements (pred seq)
(let ((r ()))
(dolist (e seq) (when (funcall pred e) (push e r)))
(nreverse r)))
That's not better or worse - just a different style (in this case).
You can debug problems like this yourself, by using `M-x debug-on-entry
extract-elements'.
Or try evaluating parts of your code using your concrete test args:
(mapcar (lambda (elm) (when (symbolp elm)) elm) '(a b 1 2))
(progn (when (symbolp 1)) 1)
Doing that, you see right away that the problem is a misplaced paren, not
something particular to `delq' or `mapcar' or backquote syntax or... IOW,
simplify the problem.