Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Common lisp idiom - is there a better way?

Tags:

common-lisp

I find myself doing this sort of thing all the time. I've been considering writing a macro/function to make this sort of thing easier, but it occurs to me that I'm probably reinventing the wheel.

Is there an existing function that will let me accomplish this same sort of thing more succinctly?

(defun remove-low-words (word-list)   
  "Return a list with words of insufficient score removed."
  (let ((result nil))
    (dolist (word word-list)  
      (when (good-enough-score-p word) (push word result)))                                      
    result))  
like image 437
r00k Avatar asked Sep 01 '08 22:09

r00k


2 Answers

There are several built-in ways of doing this. One way would be:

(remove-if-not 'good-enough-score-p word-list)

And another:

(loop for word in word-list  
      when (good-enough-score-p word)
      collect word)

And yet another:

(mapcan (lambda (word)
          (when (good-enough-score-p word)
            (list word)))
        word-list)

Etc... There's also SERIES and Iterate. The Iterate version is identical to the LOOP version, but the SERIES version is interesting:

(collect (choose-if 'good-enough-score-p (scan word-list))))

So, yes, you're very likely to reinvent some wheel. :-)

like image 82
Luís Oliveira Avatar answered Nov 05 '22 06:11

Luís Oliveira


The function you want is remove-if-not, which is built-in.

(defun remove-low-words (word-list)
  (remove-if-not #'good-enough-score-p word-list))

If you feel like you are re-inventing something to do with lists, you probably are. Check the Hyperspec to see.

  • The Hyperspec documentation on remove-if-not
  • All sequence functions
  • All list-specific functions
like image 6
Nathan Shively-Sanders Avatar answered Nov 05 '22 05:11

Nathan Shively-Sanders