schemelispcommon-lispfuncall

Writing a test function leveraging two namespaces in lisp


I started to learn Lisp and using Lispworks personal edition 6.1.1 and I hit on problem when evaluating basic functions. I am able to get them right in Scheme but they are not working when I try to evaluate them in Lisp.

I know in Lisp that every symbol has two namespaces. So I tried to write simple procedure for composing two procedures. It is working perfectly in Scheme but in Lisp there is a problem with evaluation.

Code in scheme it is working perfectly and return 2

(define (comp a b)
  (lambda (x)
    (a (b x))))

(define test (comp car cdr))
(test '(1 2 3))

Same code rewritten in Lisp

(defun comp (a b)
  (lambda (x)
    (funcall a (funcall b x))))

(defun test (comp #'car #'cdr))

(funcall test '(1 2 3))

Error in lispworks is:

Trying to bind a non-symbol, (FUNCTION CAR).

so when I try to evaluate (defun test (comp #'car #'cdr)) in listener I get

Non-symbol (FUNCTION CAR) used as variable name in function TEST.

I do not understand why it is not working written like that. I would aprreciate any help


Solution

  • defun is used to define a function with parameters:

    defun function-name lambda-list [[declaration* | documentation]] form*
    

    so it requires a lambda list after the function name, but you have written:

    (defun test (comp #'car #'cdr))
    

    which does not respect this syntax. If you want to define a variable that contains the function resulting from composing two functions you have several possibilities:

    1. Use a special variable:

      (defvar test (comp #'car #'cdr))
      
    2. Use a local variable inside a form:

      (let ((test (comp #'car #'cdr)))
        (funcall test '(1 2 3))
      

    You can even assign it to a global function name, like in:

    (setf (symbol-function 'test) (comp #'car #'cdr)
    

    and in this case you can use the name as a regular function name, without funcall:

    (test '(1 2 3))