简体   繁体   中英

Lisp - funcall of function receives too few arguments?

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)))))

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:

  1. Why are you using funcall in this instance? You should be able to directly call frame-add-slot : (frame-add-slot subframe 'ako)
  2. If the funcall usage is merited, then you'd use it like this: (funcall #'frame-add-slot subframe 'ako)
  3. I presume that instead of specifying '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) .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM