2009년 1월 4일 일요일

함수형언어의 로망 Ocaml

오늘은 공식 홈페이지에 있는 Objective Caml 에 대한 소개에 있는 overview를 살짝 살펴 보며 여담을 해보려고 합니다.

Objective Caml 은 Caml 언어중 가장 인기 있는 변형입니다. 언어의 입장에서 본다면, 핵심적인 부분은 Caml 언어로 되어 있으며 module system 만큼이나 강력한 Object-oriented layer가 sound(건전)하며 polymorphic type system(다형 타입 시스템)과 type inference(타입 추론)을 지닌채로 연결되어 확장된 것입니다.

아마 많은 분들에게는 굉장히 낯설게 느껴지는 용어들이 있을 겁니다.

sound 하다는 것은 safe 하다는 의미와 유사합니다. "잘못이 없는 것을 잘못된 것일 수 있다 라고 알려주기는 할 지언정 잘못된 걸 잘된 거라고 잘못 알려주는 일은 없다." 라는 의미를 지닙니다. 잘못이 없는 것을 잘못된 것일 수 있다고 의심하는 건 불편한 문제이긴 하지만 안정성을 해치지는 않습니다. 하지만 잘못된 것을 잘못된 것이라고 알려 주지 않는다면 이것은 큰 문제를 일으키게 됩니다. 이런 일을 발생하지 않는 다면 이것을 "sound 하다"라고 표현합니다.

사실 C언어가 만들어지던 시기에는 아직 Programming Language자체를 design 하는 것에 대해서 크게 관심이 없었답니다. 주로 어떻게 compiler를 쉽게 만들 수 있을까? 라는 것을 연구를 많이 했죠. 그 결과로 지금은 compiler를 만드는 방법은 완숙한 단계이고 PL 연구자들에게 큰 관심의 대상은 아닙니다.

문제는 그렇게 "이렇게 하면 될 것 같은데?" 정도의 생각으로 만들어낸 언어이다 보니 생각치 못했던 문제들이 많이 발생하게 되었습니다.

바로 bug의 일상화.

bug가 있는 것은 너무나도 당연하게 되는 것입니다.

특히 C언어로 programming 할때 정말 흔하게 접하게 되는 오류가 segmentation fault 에의한 오류 입니다.

기존의 명령형 언어들은 인간의 사고방식 보다는 컴퓨터의 사고방식에 가까이 있는 언어입니다.
최초에는 명령에 번호를 부여해 번호를 가지고 직접 프로그래밍을 했었습니다. 이것이 바로 기계어 이죠. 번호로 프로그램을 짠다는게 상상이 됩니까? 음 이 문제를 해결한 것이 바로 번호대신 연상되는 단어를 사용하자. 라는 것이었습니다. 예컨데 ADD JMP 같은 것이죠. 단지 번호를 단어로 바꾼 것 뿐이죠. 이것이 어셈블러의 탄생입니다. 그리고 자주 사용되는 패턴 몇가지를 묶어 문장으로 만든 것이 현재 사용되는 명령형 언어의 탄생이라고 볼 수 있습니다.
이렇게 기계어에서 부터 조금씩 추상화 되어 올라오면서 구멍을 조금씩 메워 나가는 과정에서 나온 것이 C언어, PASCAL, ... 등등 입니다.

하지만 역시 기반 자체가 약하기 때문에 태생적인 결함이 존재할 수 밖에 없었습니다. 이걸 인지하고 있음에도 표준화 기관에서는 그 문제를 해결하게 되면 현재의 형태와 너무 상이해지는 문제 때문에 그 인기성을 잃게 될 까봐 문제점을 해결하는 것을 포기할 수밖에 없었다는 얘기도 있습니다.

물론 기계에 가깝다는 점은 어셈이 그렇듯이 매우 효율적인 프로그래밍을 할 수 있다는 장점도 갖게 되지만, 발전하고 있는 하드웨어의 성능앞에 그 차이는 큰 의미가 없어지고 있습니다. (속도에 있어서 정말 중요한 것은 compiler에 따른 약간의 performance 차이보다는 logic이나 design에 따른 차이가 더 큽니다.)

소프트웨어 공학을 전공 하신 분이라는 소프트웨어 위기(Software crisis)라는 용어를 한번쯤 들어 보셨을 겁니다. 바야흐로 'bug' 라는 것이 프로그램 개발비용에 있어서 최고의 난적으로 떠오르기 시작한 것이죠.

이것을 해결하기 위해 나타난 도구중 하나가 "type system" 이라는 것이기도 합니다. 하지만, 우리의 용감한 C언어는 매우 약한 type system을 사용하여 융통성있게 type을 무시하는 기능을 제공해주고 있습니다. machine 자체의 동작을 잘 알고 있다면 유용하게 써먹을 수 있는 기능이지만 깜빡 실수라도 하면 굉장히 위험한 것이기도 하답니다.

그래서 아얘 이런 오류 자체가 발생할 가능성을 원천봉쇄한 것이 "strongly typed system" 입니다. "대충 이렇게 하면 될거 같은데?" 라는 발상으로 만들던 기존의 언어와는 달리 최근에는 아얘 "이 언어로 만든 프로그램은 이런 오류는 발생시키지 않는다." 라는 것을 증명할 수도 있습니다.

그리고 바로 이렇게 완벽한 증명의 바탕위에 만들어진 언어들이 functional language 입니다. 때문에 순수한 OCaml의 부분만으로 만들어진 program에서는 절대로 program이 멋대로 down되는 일이 발생하지 않습니다.
(아핫 하지만, 메모리의 한계성에 기인한 stack overflow 라던가-때문에 재귀함수들은 tail-recursive라는 방식으로 구현을 하게 됩니다- 고의적인 infinite loop같은 것은 별개의 문제입니다.)

하지만!!! 이런 순수한 부분만으로 program의 작성만으로는 저수준의 조작이 필요한 program은 작성을 못하게 됩니다. 그래서 library의 형태로 완벽하게 안전하지는 않을 수 있는 것들이 제공되어지고는 있습니다. 어쨌든 이들은 특별한 경우를 위해 제공되는 것일 뿐입니다. 그다지 많이 사용되지는 않는 것들이죠.

sound에 대한 얘기가 이렇게 길어져 버렸군요.. >.<

polymorphic type 으로 넘어가자면, C++ 이나 JAVA 같은 곳에서 흔하게 사용되는 overloading이라는 것을 아십니까? 함수 이름은 같은데 parameter에 따라서 다른 함수가 호출되는 것이죠.

이 overloading이라는 것이 바로 polymorphic을 흉내내기 위해 만들어진 것입니다. 때문에 ad-hoc polymorphism(임시적인 다형성) 이라고 부른답니다. 그나마 functional language의 polymorphism에 가장 가까이 다가가 있는 것이 C++에서 제공되는 template 이라는 것인데 이 녀석은 사실상 macro의 한 형태이기 때문에 제대로 type checking 을 할 수 없다는 치명적인 문제점을 가지고 있습니다.

이와는 달리 ML에서는 정말 제대로된 generic polymorphism을 제공하고 있습니다. polymorphism에 대해서는 나중에 더 자세히 얘기하도록 하겠습니다. :)

그리고 우리의 hope!! type inference(타입 추론) :) 정말 멋진 기능입니다. 우리가 일일이 type을 지정해주지 않아도, 대부분의 경우 compiler가 알아서 type을 붙여준답니다. 치밀한 이론적 배경을 가진 논리적인 type의 추론이기 때문에 실수로 잘못된 type을 붙이는 일은 없습니다.

우리가 의도하지 않았던 type이 붙어있는 것을 발견하게 된다면, 그것은 우리가 그 value를 잘못된 방법으로 사용하려고 했다는 것을 의미합니다. 그리고 실제로 OCaml로 programming을 하면서 가장 많이 접하게 되는 오류 메시지가 바로 이 type 오류 일 것입니다. :)

이렇게 무수하게 발생하는 type 에 대한 오류 메시지가 바로 우리의 program이 안전하게 만드는데 일조를 하고 있는 것입니다.(사실 이것은 strong type하고 밀접합니다.) :)

type inference에 대해 아쉬운 점이 있다면, 이 system으로 인해 overloading을 사용할 수가 없다는 점도 있지만, 이미 더 훌륭한 polymorphic system이 있으므로 overloading을 그다지 중요하지 않답니다.

soundness, polymorphic type, type inference 이것들은 functional programming이 내세우는 대표적인 장점들입니다. 이 장점들을 포기하지 않고 object oriented paradigm을 포함시켰다는 것은 정말 대단한 일입니다. :)

이로 인해서 생기는 O'Caml 의 oop 는 다른 oop 와 차별화 된답니다. (물론 ocaml의 object system에서 부족한 부분도 있기도 하지만 말입니다.) 이 뿐만 아니라 나중에 object에 대해서 다룰 때 언급하겠지만, O'Caml의 object system에만 있는 독특한 feature들도 있답니다. :)

사실 object가 없더라도 이미 module 만으로 충분하지만 표현의 다향성을 위한 것이랄까요?
module system + object system의 결합도 무척 볼만하답니다. :)

나날이 펼쳐지는 멋진 O'Caml의 세계를 기대하세요~
노상훈 2004.10.26

댓글 없음:

댓글 쓰기