Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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
like image 863
Roger Costello Avatar asked Apr 14 '16 21:04

Roger Costello


1 Answers

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

like image 138
coredump Avatar answered Sep 22 '22 05:09

coredump