갈루아의 반서재


The Symmetry of nil and ()


리스프의 명령어와 데이터 구조의 동작을 자세히 보면 리스프는 대칭이라는 정신으로 똘똘 뭉쳐있는 것으로 보인다. 이러한 대칭성이야말로 리스프 코드를 우아하게 만들어 주고, 리스프의 간결한 구문 역시 이러한 대칭이 가능하게 하는 중요한 요소 중 하나가 된다. 


Empty Equals False


정보를 저장하고 가공하는데 있어 리스트의 효용을 아주 강조하는 리스프의 철학상 리스트를 나누는데 편리한 디자인을 선호하는 것은 당연한 이치일 것이다. 가장 심오한 결정 중의 하나는 리스트에 관해 비어있는 리스트를 false 로 평가한다는 것이다. 

1
2
3
4
[49]> (if '() 'i-am-true 'i-am-false)
I-AM-FALSE
[49]> (if '(1'i-am-true 'i-am-false)
I-AM-TRUE
cs

위에서 보듯이 비어있는 리스트를 폼으로 보내면 false 로 평가한다. 비어있는 리스트를 쉽게 파악할 수 있기 때문에, 재귀를 이용해 리스트 처리가 가능하다. 이 방법을 이용해서, 비어있는 리스트가 될 때까지, 리스트의 앞에서 아이템을 추출하고 리스트의 나머지는 다시 해당 함수로 돌려보내는 작업을 할 수 있는 것이다. 비어있는 리스트를 쉽게 알 수 있다는 것은 매우 유용한 기술이다. 그럼 위의 방법을 리스트의 길이를 체크하는 함수를 만드는데 사용해보자. 

1
2
3
4
5
6
7
[55]> (defun my-length (list)
         (if list
              (1+ (my-length (cdr list)))
          0))
MY-LENGTH
[55]> (my-length '(list with four symbols))
4
cs


The Four Disguises of ()


리스프에서는 비어있는 리스트가 아닌 한 모두 true 로 평가된다. 하지만 리스프에는 비어있는 리스트와 동일하게 대접하는 다른 형태들이 있다. 아래를 보자. 

1
2
3
4
5
6
[56]> (eq '() nil)
T
[56]> (eq '() ())
T
[56]> (eq '() 'nil)
T
cs