How to do what you want
filter
is called remove-if-not
in Common Lisp:
(remove-if-not #'evenp '(1 2 3 4 5))
==> (2 4)
What is wrong with your code - syntactically
First Attempt
When you try to call a function stored in a variable (or passed into a
function as a parameter), you need to
use funcall
or apply
:
(mapcar (lambda (n) (funcall #'fn n)) L)
or just pass it along
to mapcar
:
(mapcar fn L)
Second Attempt
This is a total mess.
You need to learn Common Lisp syntax, there are many nice books (see
want to learn common lisp).
The specific problem is that R
is in a function position (first list
element) but it is not defined as a function - it is a variable.
Even if you fix this problem, there are more problems there.
You should read a book and then work it out yourself, it will be a
useful exercise.
Basically, in Common Lisp parentheses are meaningful.
E.g., in C you can write x+y
, (x+y)
, (x)+(y)
&c and they all mean
the same.
In Common Lisp R
, (R)
, ((R))
&c are very different.
Third Attempt ("edit")
(defun filter(fn L)
(if (eq 0 (length L))
(print "list empty")
(remove-if-not #'fn '(1 2 3 4 5))))
Here you have a variable fn
, but you are using it as if it were a function (#'fn
).
You need to do
(remove-if-not fn '(1 2 3 4 5))
instead.
What is wrong with your code - semantically
No need for print
First, print
is virtually
never the right function to use in code. Use princ
, prin1
or
write
instead.
Second, Common Lisp REPL
stands for Read-Eval-Print Loop, so you do NOT need to print the
return value of your function explicitly.
Follow the coding conventions
You write your code for others (including yourself 6 months down the road) to read, not just for a computer to run.
If you follow the conventions, including naming your variables and functions,
parentheses placement, indentation &c, you make your code more readable.
Compare with 0 using zerop
Write (zerop X)
instead of (eq 0 X)
(actually, you should
use eql
for numbers, but this is
getting too hairy for now).
length
can be expensive
Do not scan the whole list if all you need to know is whether it is
empty.
IOW,
(if (zero (length l))
(print "the list is empty")
(mapcar ... l))
is better written as
(if (null l)
(print "the list is empty")
(mapcar ... l))