3

在 Clojure 中,我可以定义一系列函数,然后像调用其他值一样调用它们,如下所示:

(doseq [op [+ - * /]]
  (println (op 1 2 3 4)))

产生以下输出:

10
-8
24
1/24
nil

尝试在 Common Lisp 中做同样的事情只会导致错误:

(dolist (op '(+ - * /))
  (print (op 1 2 3 4))

; in: DOLIST (OP '(+ - * /))
;     (LET ((OP (TRULY-THE (MEMBER / * - +) (CAR #:N-LIST671))))
;       (SETQ #:N-LIST671 (CDR #:N-LIST671))
;       (TAGBODY (PRINT (OP 1 2 3 4))))
; 
; caught STYLE-WARNING:
;   The variable OP is defined but never used.

; in: DOLIST (OP '(+ - * /))
;     (OP 1 2 3 4)
; 
; caught STYLE-WARNING:
;   undefined function: OP
; 
; compilation unit finished
;   Undefined function:
;     OP
;   caught 2 STYLE-WARNING conditions

debugger invoked on a UNDEFINED-FUNCTION:
  The function COMMON-LISP-USER::OP is undefined.

Type HELP for debugger help, or (SB-EXT:EXIT) to exit from SBCL.

restarts (invokable by number or by possibly-abbreviated name):
  0: [ABORT] Exit debugger, returning to top level.

("undefined function")

打电话给我op#'op不起作用。

那么有没有办法在 CL 中做到这一点?

4

1 回答 1

6

由于函数的命名空间和数据的命名空间在 LISP-2 中是分开的(因此在 common-lisp 中),因此在funcall将函数作为参数传递时需要使用:

(dolist (op '(+ - * /)) 
   (print (funcall op 1 2 3 4))))

funcallfunction 大致相当于 Clojure 的apply,并将该op函数应用于提供的参数。在这种情况下,还有一件事发生,因为op是一个绑定到函数的符号,但funcall会处理它。

于 2014-10-03T16:45:25.457 回答