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?
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 defun
ed, flet
ed, or labels
ed. 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)))))