Common Lisp idiom for filtering a list and applying a function to the unfiltered elements?
Asked Answered
K

1

5

What is the Common Lisp idiom for this:

Remove the elements in a list that don't satisfy a predicate and for those that do satisfy the predicate apply a function.

Is this the Common Lisp idiom:

mapcar applied to remove-if
Keare answered 14/4, 2016 at 21:45 Comment(1)
yes it is mapcar over remove-ifParcenary
S
9

The idiom would be MAPCAR over REMOVE-IF-NOT, since you want to keep elements that match the predicate. The -IF-NOT functions are deprecated according to the standard, but for Common Lisp deprecation is mostly meaningless1 and as such we rarely see anyone use COMPLEMENT with REMOVE-IF.

However most people would use a LOOP here:

(lambda (elements test function)
  (loop
    for e in elements
    when (funcall test e)
      collect (funcall function e)))

A possible problem with MAPCAR over REMOVE-IF-NOT is that it is going to allocate memory for a temporary list just to discard it after. You can call this premature optimisation, but if I wanted to use higher-order functions (e.g. because I want to work with generalised sequences instead of just lists), I would use MAP-INTO:

(lambda (elements test function)
  (let ((tmp (remove-if-not test elements)))
    (map-into tmp function tmp)))

1. "Everything that has been marked as deprecated can be considered un-deprecated since there won't be another standard.", R. Strandh (beach).

Sanorasans answered 15/4, 2016 at 7:55 Comment(1)
+1 for mentioning the underappreciated map-into.Dropping

© 2022 - 2024 — McMap. All rights reserved.