[英]Evaluate function from list in lisp
我需要在lisp中編寫一個帶有兩個參數的函數-無參數函數列表和整數列表。 我需要按第二個給定的順序從第一個列表評估函數,即((fun'(#'a#'b#'c)'(2 0 1))應該評估c,a,b。 我試過這樣的功能:
(defun z4(funs kols)
(funcall (nth (first kols) funs))
(z4 funs (rest kols))
)
但是在funcall中我得到了錯誤
NIL不是CONS類型。
這是什么意思? 我通過簡單地打電話來得到同樣的錯誤
(funcall (first funs))
所以我認為這與從功能列表中獲取功能有關。 如何評估從功能列表中獲取的功能?
對於每個遞歸調用,您都可以減少kols
參數,直到它變為nil
kols
。 當kols
變為nil
您應該終止遞歸,因此您應該為終止條件添加測試(例如,對於空列表):
(defun foo (funcs order)
(unless (endp order)
(funcall (nth (first order) funcs))
(foo funcs (rest order))))
我建議使用一種更具可讀性的解決方案(由於ANSI Common Lisp Standard不會強制實現執行尾部調用優化,因此也更可取):
(defun foo (funcs order)
(loop for n in order do (funcall (nth n funcs))))
在前面的示例中,我假設您為它們的副作用而不是為返回值運行函數。
編輯1
正如Vatine指出的那樣,使用nth
和list提供具有隨機訪問權限的集合對性能不利,因此可能有必要將函數存儲在vector
(即一維array
)中,而不是列表中。 因此,假設funcs
是函數的vector
,則函數可以定義如下:
(defun foo (funcs order)
(loop for n in order do (funcall (aref funcs n))))
此外,如果函數數組是simple vector
( 詞匯表條目 ),則可以用svref
替換aref
。 前者較為籠統,但后者在某些實現中可能會更快。
可以使用以下任一方法創建simple vector
的函數simple vector
(vector #'func-a #'func-b ...)
要么
#(func-a func-b ...)
也可以使用make-array
函數創建一個simple vector
的函數simple vector
,但前提是:adjustable
和:fill-pointer
關鍵字參數未指定或為nil
。
'(#'a #'b #'c)
不是功能A,B,C的列表。它是這樣的:
((FUNCTION A) (FUNCTION B) (FUNCTION C))
上面不是函數,而是列出了第一個符號FUNCTION
和另一個符號。
使用任一
(list #'a #'b #'c)
要么
'(a b c)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.