Blog

Symbol 여행의 끝

November 18, 2013

Symbol 여행의 끝

#’(Sharp Single-Quote)와 ’(Quote)의 차이

CLHS 에 의하면 #'function 과 동일하다. 예를들어

(apply #'+ l) ==  (apply (function +) l)

분명히 #'car'car 은 다르다. #'carfunction 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 은 무엇일까..?

Array