화요일, 8월 30, 2005

What should we learn from Functional Languages?

1. side-effect management

side effect 는 버그의 근원이다. 성능을 희생하지 않으면서 side effect 를 줄이는 디자인을 언제나 생각해야 한다. 다른말로는 그러한 design philosophy 를 information hiding 이라고도 할 수 있다.

2. bottom-up programming (DSL)

lisp/scheme 을 프로그래밍 하다 보면, 자신이 랭귀지의 키워드를 늘이고 있다는 느낌을 갖게 된다. 잘 프로그램된 lisp/scheme program 은 문제에 걸맞는 keyword 와 문제자체를 잘 기술하는 sub-language 가 프로그램안에 랭귀지 형태로 합쳐지게 된다. 이 어프로치를 계속 따라가다보면 어떤 문제를 만났을때, programming language 를 디자인 하는 방법을 사용하게 되며, 이렇게 해서 생겨난 언어를 Domain Specific Language 라고 한다.

c 같으면 library 를 만드는 방법으로 시작하겠지만, 코드/데이타의 구분이 약한 scheme/lisp 에 비해 문제를 describe 하도록 언어를 만드는 것이 쉽지는 않다. 그렇지만 c++ 에서는template/generic 은 bottom-up programming 의 좋은 툴이다.

c++ 에서 template/generic 은
1) 랭귀지의 세만틱과 충돌하지 않는다. (특히 class의 inheritance)
2) code generation 시 많은 부분의 validation 이 가능하다
는 특성때문에 특히 bottom-up programming 에 적합하며, 실제의 예도 c++ 의 언어적으로 약한 면을 강화시키는 경우를 많이 찾을 수 있다. 예) stl -> data structure 의 부재 해결, smart_ptr -> auto deallocation의 부재 해결

3. function 에 대한 이해

dijkstra 가 "goto considered harmful" 을 썼을때 의미하는 바는, goto 를 쓰지말고, function 을 사용한 abstraction 을 하자이다. (스티브 맥코넬이 주장하는 micro-scopic 한 주장이 아니다.) 그 당시는 function call 시 context save 의 cost 가 아까왔던 때이고 assembly 를 이용한 label 로 떡칠된 spagetti code 가 주류를 이루던 시절이다.

그 당시에 lisp 은 여전히 있었고, lisp 은 이러한 문제를 tail-call optimization 과 macro 를 사용한 inlining 으로 해결했다. 그 외에 lexical closure 와 first-class citizenship 이 제공되는 랭귀지의 특성상 lisp/scheme 을 잘 사용한다면, function 을 잘 사용할 수 있다. (대표적인 예가 c++::boost 의 lambda 이다.)