help-gnu-emacs
[Top][All Lists]
Advanced

[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.





reply via email to

[Prev in Thread] Current Thread [Next in Thread]