I am trying to figure out the proper usage of funcall
. I have this function:
(defun frame-add-slot (frame slot)
(push (list slot) (rest (assoc frame *frames*))))
and I'm trying to get this other function to call it.
(defun frame-add-subframe (superframe subframe)
(let ((res (push (list subframe) (rest *frames*))))
(funcall (frame-add-slot) subframe 'ako))))
However, when I try to pass it two arguments in this fashion, clisp tells me the called function receives too few arguments. What am I doing wrong? *Frames*
is my knowledge base. It looks like this:
(setf *frames* '((mammal
(eats
(:value meat)
(:if-needed (food))))
(4-legged-animal
(ako
(:type mammal)
(:default beings))
(blood
(:type warm-blooded)))
(husky
(ako
(:type dog))
(origin
(:value alaska)
(:default north-america))
(roots
(:value unknown)))
(dog
(ako
(:type 4-legged-animal))
(exterior
(:value furry)
(:default skin)))
(abner
(isa
(:type husky)
(:default dog))
(shape
(:weight 40-lbs)
(:height 20-inches)
(:color brown))
(acts
(:demeanor friendly)
(:sometimes rough)))
(gypsy
(isa
(:default dog))
(acts
(:demeanor unpredictable))
(shapes
(:weight 45-lbs)
(:color black-and-brown)))))
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.
to indicate the value of a symbol in the value namespace and use it as a function, Lisp requires to use funcall , as in (funcall fn &rest arguments) , for the symbol fn . to indicate the functional value of a symbol or of an expression, Lisp uses the special form (function fn) , which is commonly abbreviated as #' .
LISP uses the self-evaluating symbol nil to mean false. Anything other than nil means true. Unless we have a reason not to, we usually use the self-evaluating symbol t to stand for true.
Can you explain why you need FUNCALL
?
FRAME-ADD-SLOT
is a normal named function and you can call it as such - without FUNCALL
.
(defun frame-add-subframe (superframe subframe)
(let ((res (push (list subframe) (rest *frames*))))
(frame-add-slot subframe 'ako))))
Literal data
Later in your code you set *frames*
to constant literal data. In your functions you are modifying this constant data. In standard Common Lisp the effect of these modifications is undefined. You need freshly allocated data structures - these can be modified without problems. See for example the function COPY-TREE
to recursively make a fresh copy of a deeply nested list. The result of COPY-TREE
can be modified.
There's several problems with your frame-add-subframe
function:
funcall
in this instance? You should be able to directly call frame-add-slot
: (frame-add-slot subframe 'ako)
funcall
usage is merited, then you'd use it like this: (funcall #'frame-add-slot subframe 'ako)
'ako
hardcoded, you meant to use res
somehow? That variable is unused.In (funcall (frame-add-slot) subframe 'ako))))
, you are calling frame-add-slot by putting parens around it.
Try (funcall #'frame-add-slot subframe 'ako)
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With