funcall 実行例
そのまま定義済の関数を実行
? (funcall #'+ 1 2 3 4 5) 15 ? (defun hello (name) (format t "Hello, ~A!~%" name)) HELLO ? (funcall #'hello "Taro") Hello, Taro! NIL ?
lambda 式を指定する
? (funcall #'(lambda (name) (format t "Hello, ~A!~%" name)) "Taro") Hello, Taro! NIL ?
何らかの方法で返された lambda 式を実行する
? (setf f #'(lambda (name) (format t "Hello, ~A!~%" name))) #<Anonymous Function #x302000D9B48F> ? (funcall #'f "Taro") > Error: Undefined function: F > While executing: CCL::%FUNCTION, in process Listener(4). > Type cmd-. to abort, cmd-\ for a list of available restarts. > Type :? for other options. 1 > q ? (funcall f "Taro") Hello, Taro! NIL ? f #<Anonymous Function #x302000D5054F> ? (setf f (lambda (name) (format t "Hello, ~A!~%" name))) #<Anonymous Function #x302000DBC69F> ? f #<Anonymous Function #x302000DBC69F> ? (funcall f "Taro") Hello, Taro! NIL ?
lambda 式をどこかに定義する際、#' と一緒に定義してもしなくてもどちらも Anonymous Function として定義されるようだ。
どこかの要素から lambda 式を取り出す
? (defparameter x '("aaa" (lambda (name) (format t "Hello, ~A!~%" name)))) X ? x ("aaa" (LAMBDA (NAME) (FORMAT T "Hello, ~A!~%" NAME))) ? (cdr x) ((LAMBDA (NAME) (FORMAT T "Hello, ~A!~%" NAME))) ? (cadr x) (LAMBDA (NAME) (FORMAT T "Hello, ~A!~%" NAME)) ? (funcall (cadr x) "Taro") > Error: (LAMBDA (NAME) (FORMAT T "Hello, ~A!~%" NAME)) is not of type (OR SYMBOL FUNCTION), and can't be FUNCALLed or APPLYed > While executing: FUNCALL, in process Listener(4). > Type cmd-. to abort, cmd-\ for a list of available restarts. > Type :? for other options. 1 >
lambda 式を setf したとき、#' があってもなくても結果が同じだったので #' なしの lambda 式を cdr に持つリストを定義して実行してみたが、funcall は失敗した。
では、#' を付けてやればうまくいくのか?
? (defparameter x '("aaa" #'(lambda (name) (format t "Hello, ~A!~%" name)))) X ? (cadr x) #'(LAMBDA (NAME) (FORMAT T "Hello, ~A!~%" NAME)) ? (funcall (cadr x) "Taro") > Error: #'(LAMBDA (NAME) (FORMAT T "Hello, ~A!~%" NAME)) is not of type (OR SYMBOL FUNCTION), and can't be FUNCALLed or APPLYed > While executing: FUNCALL, in process Listener(4). > Type cmd-. to abort, cmd-\ for a list of available restarts. > Type :? for other options. 1 >
違いがよくわからないが失敗。function を明示してもダメ。
? (defparameter x '("aaa" (function (lambda (name) (format t "Hello, ~A!~%" name))))) X ? (cadr x) #'(LAMBDA (NAME) (FORMAT T "Hello, ~A!~%" NAME)) ? (funcall (cadr x) "Taro") > Error: #'(LAMBDA (NAME) (FORMAT T "Hello, ~A!~%" NAME)) is not of type (OR SYMBOL FUNCTION), and can't be FUNCALLed or APPLYed > While executing: FUNCALL, in process Listener(4). > Type cmd-. to abort, cmd-\ for a list of available restarts. > Type :? for other options. 1 >
lambda だけでなく、このやり方は他の関数もダメっぽい。
? (defparameter x '("aaa" #'+)) X ? (cadr x) #'+ ? (funcall (cadr x) 1 2 3) > Error: #'+ is not of type (OR SYMBOL FUNCTION), and can't be FUNCALLed or APPLYed > While executing: FUNCALL, in process Listener(4). > Type cmd-. to abort, cmd-\ for a list of available restarts. > Type :? for other options. 1 >
何らかのキーを受け取り、そのキーに対応した関数を呼び出す、ということをしたい。上記の例では "aaa" がキーの想定だが、どうすればできるだろうか。