Lisp Symbol
Lisp Symbol
원래는 Flet과 Labels에 대한 차이점을 찾고 있었다. Labels는 재귀가 된다는데, 함수 정의에서 어느 부분이 다른건지 CLHS 을 보고 있었다. 그랬더니 이런 코드가 나오더라
(defun dummy-function () 'top-level) => DUMMY-FUNCTION
(funcall #'dummy-function) => TOP-LEVEL
(flet ((dummy-function () 'shadow))
(funcall #'dummy-function)) => SHADOW
(eq (funcall #'dummy-function) (funcall 'dummy-function))
=> true
(flet ((dummy-function () 'shadow))
(eq (funcall #'dummy-function)
(funcall 'dummy-function)))
=> false
-_-;? 왜 결과가 True랑 False가 나오는지 모르겠더라. 그래서 #'function 과 'function 의 차이점을 알아야 했다. 그래서 일단 CLHS 에서 funcall 부터 찾기 시작함.
Funcall
funcall 은 심플했다. 정의는
Syntax:
funcall function &rest args => result*
Arguments and Values:
function---a function designator.
args---arguments to the function.
results---the values returned by the function.
근데, 설명이 조금 신기하게 되어 있었다.
funcallapplies 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.
만약에, funcall 의 인자인 function이 symbol 이라면, functional value를 global env 에서 찾는단다. 근데 함수는 다 심볼 아닌가 -_-;? 그래서 결국 심볼을 찾게 된거임.
What is symbol?
우선, 여기에 따르면 심볼은 리스트와 함께 LISP 언어를 구성하는 요소다. (아톰..은?!?) 근데, 이 심보르는 값(Value) 로 변한되어야 하고 이 과정이 Evaluation이다.
근데, Evaluation 에는 몇 가지 규칙이 있다.
- 숫자는 항상 그 자체로 Evaluation 됌
- 심볼은 그 값으로 Evaluation 됌
- Quote(’ 인듯) 처리가 된 것은, 평가하지 않는다.
- 리스트를 Eval 하려면, 리스트의 첫 번째 요소는 반드시 Function 또는 Special Form 이어야 함.
Keyword vs Symbol
여기에 의하면,
Symbol : 무언가를 지칭함.
Keyword : 심볼과 유사하지만, 그 자체로 평가가 완결된다.
심볼은 값(Value)와 연관 되어 있기 때문에심볼-테이블과 연관되어 있다. 이 테이블에서 값을 얻어 온단다. 더 정확히 말하면,심볼은 해당 테이블과 연결되는 순간의 값을 가져 온다. 예를 들어서
(progn
(setf x 42)
(print x)
(let ((x 'nothing))
(print x)))
위에서 가장 아래 x는 문자열 nothing 이 된다. 왜냐하면, x가 평가되는 시점에는 심볼-테이블 에는 nothing 이 값이니까. 여기서 잠깐 딴 길로 새면, 심볼의 평가를 방지하려면 (quote) 를 붙이면 된다. 근데 quote 붙은 심볼을 평가하려면,eval` 함수를 쓰면 된단다.
(let ((x 'nothing))
(print (eval x))))
점점 더 깊이 들어가는 것 같은데.. 음. 더 정확히는 심볼은 심볼-테이블 에서 symbol-value 를 통해 얻어온다고 함.
CL-USER> (symbol-value 'pi) 3.1415926535897932385L0
근데, 함수는 이 symbol-value 를 통해 얻어올수가 없단다. 함수를 위한 심볼-테이블과 변수를 위한 심볼-테이블이 나누어져 있기 때문이라고 한다. 그리고 이런 Lisp을 Lisp-2 라고 부름. Lisp-1은 스킴과 같은 것들인데, 분리하면 무슨 장점이 있고, 분리 안 하면 무슨 장점이 있는가? 여기 참조하시오.
근데, 중요한건. 이렇게 함수를 위한 테이블과 변수를 위한 테이블을 나누었으면, 그때 그때 어떻게 가져오는지에 대한 규칙이 분명히 있을거다. 그리고 이런 규칙이 Lisp을 Lisp 답게 만드는 거고. 일반적으로 심볼은 다음 두가지 용도로 사용된다.
– 심볼 그 자체로서 심볼을 나타내기 위해서 활용(quote 붙여서?)
– 심볼을 평가하여 심볼과 연관된 값이나 함수등을 지칭하기 위해 활용
Keyword 는 Symbol 앞에: 를 붙여, 평가 결과가 자기 자신인 self-evaluating-symbol 이 된다. 자기 자신을 평가하기 위해 별도로 quote 하거나 할 필요가 없다.
Back to basics
처음으로 다시 돌아가서. 대체 #'function 과 ‘’function’은 무엇이 다른가?.. 는 다음시간에..
Ref : )
– http://www.gurugail.com/pmwiki.php?n=Main.Lisp
– http://ageldama.blogspot.kr/2012/04/commonlisp.html