Вызов списка функций в Common Lisp

В 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?

1 ответ

Решение

Поскольку пространство имен для функций и пространство имен для данных разделены в LISP-2 (и, следовательно, в common-lisp), вам необходимо использовать funcall при передаче функций в качестве параметров:

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

funcall функция является примерно эквивалентом Clojure applyи будет применять op функция по заданным параметрам. В этом случае происходит еще одна вещь, так как op является символом, связанным с функцией, но funcall заботится об этом.

Другие вопросы по тегам