Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Common Lisp - Using a function as input to another function

Say I have a function that takes a list and does something:

(defun foo(aList)
   (loop for element in aList ...))

But if the list is nested I want to flatten it first before the loop does stuff, so I want to use another function (defun flatten(aList)) that flattens any list:

(defun foo(flatten(aList))
   (loop for element in aList ...))

Lisp doesn't like this. Is there another direct way around this?

like image 753
John Avatar asked Sep 13 '10 15:09

John


People also ask

How do you define a function in a Common Lisp?

Use defun to define your own functions in LISP. Defun requires you to provide three things. The first is the name of the function, the second is a list of parameters for the function, and the third is the body of the function -- i.e. LISP instructions that tell the interpreter what to do when the function is called.

What is Setf function in Lisp?

setf is actually a macro that examines an access form and produces a call to the corresponding update function. Given the existence of setf in Common Lisp, it is not necessary to have setq, rplaca, and set; they are redundant. They are retained in Common Lisp because of their historical importance in Lisp.

What does Funcall do in Lisp?

funcall applies function to args. If function is a symbol, it is coerced to a function as if by finding its functional value in the global environment.

What are let and let * forms in Lisp?

LET suggests that you're just doing standard parallel binding with nothing tricky going on. LET* induces restrictions on the compiler and suggests to the user that there's a reason that sequential bindings are needed. In terms of style, LET is better when you don't need the extra restrictions imposed by LET*.


2 Answers

Here's one way:

(defun foo (alist)
  (loop for element in (flatten alist) ...)
like image 152
Xach Avatar answered Oct 12 '22 13:10

Xach


You can pass the function as an &optional argument.

(defun foo (alist &optional fn)
  (if (not (null fn))
      (setf alist (funcall fn alist)))
  (dostuff alist))

A sample run where dostuff just print its argument:

(foo '(1 2 (3)))
=> (1 2 (3))
(foo '(1 2 (3)) #'flatten)
=> (1 2 3)

This approach is more flexible as you are not tied to just one 'pre-processor' function.

like image 24
Vijay Mathew Avatar answered Oct 12 '22 14:10

Vijay Mathew