Lisp: why does this code throw a "function x is undefined" error?

69 Views Asked by At

I am trying to create a card guessing game in lisp (ECL). However i get an error.

(defun random-card ()
  (coerce '(                                        
    (char (random 4) "SCDH")
    (char (random 13) "A23456789JQK"))
  'string)
)

(defun repeat (x n)
  (if (zerop n)
    nil
    (cons (x) (repeat x (1- n)))))

(print (repeat #'random-card 3))

The error:

An error occurred during initialization:
The function X is undefined..

Is the undefined function X the parameter of repeat? What am i missing?

1

There are 1 best solutions below

4
Silvio Mayolo On

Common Lisp is a Lisp-2, which means that functions and variables have different namespaces. That's why you had to write #'random-card rather than just random-card. random-card as an argument looks in the value namespace. #'random-card is a shortcut for (function random-card), which looks up the name in the function namespace (function itself is not a function; it's one of a handful of special operators which are extremely baked into the Common Lisp system).

So function takes a name in the function namespace and binds it to a value. Now you've got a value called x in your repeat function. x is a variable in the value namespace, and when you write (x), Common Lisp is looking in the function namespace. That is, it's looking for something that was defuned, fleted, or labelsed. To call a function that's stored in a value-level variable, we use funcall.

(defun repeat (x n)
  (if (zerop n)
    nil
    (cons (funcall x) (repeat x (1- n)))))