Symbol 여행의 끝
#’(Sharp Single-Quote)와 ’(Quote)의 차이
CLHS 에 의하면 #' 은function 과 동일하다. 예를들어
(apply #'+ l) == (apply (function +) l)
분명히 #'car 과 'car 은 다르다. #'car 은 function car 로서 car의 functional value 값이고 'car 은 그냥 평가를 지연시킨 심볼인데, funcall은 왜 아래와 같이 둘다 동일하게 인자로 받아들일까?
CL-USER> (funcall 'car '(a b c)) A CL-USER> (funcall #'car '(a b c)) A
해답을 찾기 위해서 funcall의 첫 번째 인자 해설을 봐야 했다.
Arguments and Values:
function— a function designator.
args— arguments to the function.
results— the values returned by the function.Description:
funcall applies function to args. If function is a symbol, it is coerced to a function as if by finding its functional value in the global environment.
function이 심볼일 경우에만 global env에서 함수 value를 찾는댄다. 내 생각엔,'car이 심볼이 아니고,#'car가 심볼인 것 같다는 생각을 했다. 근데, 그 반대다.
CL-USER> (defun dummy-function() 'top-level)
DUMMY-FUNCTION
CL-USER> (flet ((dummy-function() 'two-level))
(cons
(funcall #'dummy-function)
(funcall 'dummy-function)))
(TWO-LEVEL . TOP-LEVEL)
이제 이 코드를 이해할 수 있다.
(funcall #'+ 1 2 3) => 6
(funcall 'car '(1 2 3)) => 1
(funcall 'position 1 '(1 2 3 2 1) :start 1) => 4
(cons 1 2) => (1 . 2)
(flet ((cons (x y) `(kons ,x ,y)))
(let ((cons (symbol-function '+)))
(funcall #'cons
(funcall 'cons 1 2)
(funcall cons 1 2))))
=> (KONS (1 . 2) 3)
'cons는 global로, cons는 let 에서 정의된, #'cons는 flet으로 정의된 cons를 찾는다. 특이한건 let에서 cons를 정의하기 위해 symbol-function 이란 함수를 사용하는 것.
CL-USER> (function +) CL-USER> (symbol-function '+) FUNCTION +
둘다 똑같은 결과를 출력한다. 찾아보니, symbol-function 은 Accessor 이란다. CLSP에서. 여길 참조. 다시 새로운 여행의 시작이다. Special form은 뭐고, Accessor 은 무엇일까..?