ultimate dynamic language?
다들 lisp family 를 이야기 하는 이유는?
나의 리습에 대한 태도는 여러번 바뀌어 왔다.
1. it's elegant & beautiful (학부 2년때 처음 접하면서)
2. stupid syntax all over the place (1년 전쯤 다시 공부하기 시작하면서)
3. ultimate cheating!(이건 사기야)
아무튼 3번은 리습이 좋은 랭귀지란 뜻이고, 이글은 왜 리습이 ultimate dynamic language 인지를 설명하기 위한 글이다.
소프트웨어의 세계는 complex software 와 complicated software 로 양분 되어 있다. 현재의 discipline 의 주류는 complex software 제작에 맞추어져 있다. 이해 못할 만큼 복잡한 것은 없지만, 컴포넌트간의 플로우가 복잡한 시스템을 complex software 라고 하고, 대표적인 예로 word processor 를 들 수 있으며, 이런 소프트웨어 제작에는 M$ 가 무적이다.
그와 반대되는 complicated software 는 내부가 아무리 복잡하고 어렵더라도, 외부로 노출되는 인터페이스는 몇개의 API 로 정리되는 물건을 이야기하고, OS 의 서브시스템인 file system 과 memory management API 가 대표적인 예다.
문제는 현재의 디서플린과 다르게, 우리가 일상생활에서 만드는 대부분의 소프트웨어는 complicated software 이다.
complex software 는 top down 으로 서로간의 interaction 과 제작자와 컴포넌트의 룰을 명확하게 구분하면서 만드는것이 맞지만, complicated software 의 경우에는 그 따위로 개발했다가는 중복 투자는 기본에, 바닥부터 다시 만드느라 data structure 와 algorithm 및 flow 조금이 바뀐다면, 꽤나 괴로워 진다. (물론 핸들하는 방법은 있겠으나, 핸들하는 방법은 correct 한 software 를 upgrade 한다는 가정하에 이루어지므로 현실적이지 않다.)
저런 분야야 말로 bottom-up programming 이 빛을 발한다. 제대로 된 bottom-up programming 을 하기에 필수적인 요소는
1. universal data type 및 dynamic typing - data structure 가 바뀔경우 처리가 자연스럽다.
2. reflection - program 이 자신에 대해 discover 를 하고 그 내용을 이용하거나 수정할 수 있는 것을 말한다. 가장 일반적인 예는 eval() 이다.
이 둘을 사용하기 위해서는 랭귀지가 dynamic 인 편이 좋다. 1번은 보통 쉽게 제공 된다. 2번의 경우는 대부분의 다이나믹 랭귀지에서 제공된다.
직관적으로 2번을 제공하기 위해서는 code parsing module 및 AST 를 들고 다녀야 함을 알 수 있다. run-time parsing & code generation 을 위해서는 그런 이유로 꽤 overhead 가 커진다.
그렇지만, lisp 의 case 를 살펴 본다면 code 와 data 가 s-expression 으로 표현되고 parsing 하기가 쉽기 때문에, additional cost 는 zero 에 가까움을 알 수 있다. 심지어는 compile time syntax translation 따위도 공짜로 따라온다. reflection 을 마음껏 쓰면서도 performance penalty 에 대한 죄책감을 덜 가져도 된다. 게다가 오래전 부터 lisp 의 성명절기는 self-modifying code 였다.
이런 이유로 lisp 은 die-hard 랭귀지이고, dynamic language 를 쓰는 사람은 결국 lisp 에 맛을 들이는게 아닐까 싶다.
0 Comments:
댓글 쓰기
<< Home