在运行时按名称调用函数

Ada*_*m S 1 lisp common-lisp

我意识到可以使用#'PRINT引用函数来引用PRINT函数.如果我们有一个列表S,其中第一个元素是'PRINT,我们可以使用#(car S)引用它吗?

假设我正在查看一个列表,其中列表中的元素是原子,它们是某些函数的名称.目前,我可以这样做:

(defun aritheval (S)
    (funcall
        (cond
            ((eq '+ (car S)) #'+)
            ((eq '- (car S)) #'-)
            ((eq '* (car S)) #'*)
            ((eq '/ (car S)) #'/)
        )
        '2
        '3
    )
)
Run Code Online (Sandbox Code Playgroud)

此函数将根据列表S中的第一个元素计算2 + 3,2-3,2*3或2/3 .S包含这些函数的名称.

Rai*_*wig 6

#(汽车S)毫无意义.语法存在但是表示带符号CAR和S的向量.

使用

(funcall (first somelist) someargument)
Run Code Online (Sandbox Code Playgroud)

要么

(apply (first somelist) a-list-of-arguments)
Run Code Online (Sandbox Code Playgroud)

您的函数是非Lispy格式的.

在正确的Lisp代码中不使用尾随括号.您也不需要引用数字.数字是自我评估的,他们对自己进行评估.此外,我们现在可能更喜欢FIRST over CAR和REST over CDR.功能相同,但名称更好.每当我们处理简单列表时,使用FIRST,SECOND,THIRD,......和REST.

(defun aritheval (S)
  (funcall (cond ((eq '+ (car S)) #'+)
                 ((eq '- (car S)) #'-)
                 ((eq '* (car S)) #'*)
                 ((eq '/ (car S)) #'/))
            2 3)))
Run Code Online (Sandbox Code Playgroud)

由于符号可以用作全局函数的名称,因此上面没有必要.

考虑到符号到函数的映射是相同的,下面的函数也是如此.

(defun aritheval (s)
  (funcall (first s) 2 3)))
Run Code Online (Sandbox Code Playgroud)