2009년 4월 23일 목요일

haskell 잠깐 둘러보면서 느낀것들 횡설수설

haskell 이 실용적인 언어는 아니라고 생각되서 앞으로 더 haskell 문서를 보게될지 모르겠네. 어쨌건 haskell 을 배우면서(배웠다기 보다는 정말 구경한거.. 그냥 지하철에서 문서좀 읽다 자다가.. 간단히 샘플몇개 코딩해본게 전부지) 내 코딩스타일을 바꿔야 할점들을 몇개 더 알게됐는데 정리해두자.

아 그전에 망할 모나드 트랜스포머.. 모나드 스택 은 킹왕짱좋은 개념이란건 알겠는데 결국 이산을 못넘은게 좀 아쉽긴 하다. 뭐 대강 왜 이친구들이 모나드를 스택식으로 쌓아올렸는지 뭐 그 필요성? 그걸로 얻은 것들? 뭐 그런것들에 대해서 냄새는 맡았지만.. 뭐 그걸로 얻는게 많다는것도 알게 됐지만 내눈엔 가까운길 놔두고 멀리 돌아가는 길로밖에 안보인다. 코딩을 이렇게 까지 복잡하게 해야 하는것에 납득할수가 없었다.

뭐 순수함수형 언어라는게 그렇더라. 순수함을 지키기 위해서 희생이 너무큰데 글쎄.. 그렇게 까지 지킬 필요가 있을까. 어차피 컴퓨터 라는 기계 자체가 펑셔널 하질 않은것을.


어쨌건 몇가지 적어둔다.
  • 먼저 pure functional 이란 말부터.. 가장 중요한것은 값이 일단 정해지면 절대 변하지 않는다는게 기본 개념이다. 물론 이게 되면 여러가지로 장점이 많지. 보통 함수형언어 책들 앞대가리들 읽어보면 이런 내용이 줄줄이 나온다. 그런데 내 결론은 그거 죄다 헛소리. 꿈꾸는 소리. 그러고 보면 haskell 이 여기까지 발전한게.. 정말 haskell 커뮤니티 애들은 천재들의 집단인거다.
  • 모나드.. 음 이게 정말 뭐랄까 대단하다. 모나드 자체는 정말 별거 아닌데 응용이 무지막지하게 나온다. 처음 이개념을 도입한놈은 천재중의 천재라고 할수 있겠네.. 어쨌건 실체는 뭐랄까.. 만들기 졸라 불편하면서 동시에 오사용을 막을수있는 매크로 랄까. 현재 언어스펙으로 나타내기 어려운 개념을 표현한다는 점에선 lisp macro 와 유사하지만.. lisp macro 가 만들고 쓰는게 상당히 자유로운것에 비해 monad 는 아주 번거롭게 틀에 같힌 형태?(좀더 좋게 표현하면 그 monad 가 나타내는 world 에 안전하게 격리된 상태 낄낄) 대신에 macro 를 많이 쓰는 경우 스파게티가 나오지만 monad 는 계층형태로 이쁘게 쌓아올리는 식의 코딩이 가능하다.( 모나드 트랜스포머.. ) 뭐 이렇게만 쓰면 monad 개념이 아주 좋은게 맞는데.. 뭐 자세히 지금 내 기분을 적기가 어렵지만 어쨌건 monad 는 코딩이 아주 번거롭다.. 이건 내가 C 식의 사고를 하기 때문인건데.. 뭐 어쨌건 monad 는 존나 좋은 개념. 하지만 나한텐(대부분의 다른 개발자들도 마찬가지라고 생각되는데) 아주 불편한 개념.

헐.. 글을 막쓰다 보니 주제를 벗어났네. 요점만 적자. 앞으로 내가 코딩하면서 몇가지 신경써줄것들이다.
  • pure code 와 impure code 의 분리. 이건 사실 굳이 함수형 언어 개발자가 아니더라도 몸으로 알고있는 사실. 하지만 haskell 의 경우 언어가 이런면을 강요하다 보니 좀더 분리에 신경을 쓰게 됐는데 이런식으로 철저히 분리를 하고 나니 코드가 좀더 유연해지더라. 이건 사실 모듈화를 잘하라는 진리와 상통하는 말이다.
  • typeclass 의 사용.  이건 결국 템플릿 메타 프로그래밍으로 이어지겠지. 그리고 데이타모델링에 OOP 를 피하는 좋은 수단이기도 하고. 이런류의 내용은 C++ 쪽 문서들에도 몇번 강조되고있는 글인데 haskell 로 좀 코딩하다 보니 감이 잡히더라. 단 글로 나타낼정도로 명확히 정리하지 못해서 좀 아쉽다. 뭐 내가 하는게 다 그렇지.
  • 위험한 코드는 아예 빌드가 안되도록. 이것도 당연히 이미 여러 C++ 문서에서 다루고 있는 것이지만 다시한번 느낀점이다. 컴파일러가 잡아주는게 가능한 문제라면 무조건 컴파일러가 잡아줘야 한다. 또는 컴파일러가 잡아주도록 만들어야 한다. 그냥 읽고 지나갔던 static assert 나.. 여러 템플릿 기법을 다시 둘러봐야 겠다.  난 static assert 를 잡느니 main 앞에 assert 를 모아두는걸 좋아하는 편인데.. 앞으론 좀 적극적으로 써봐야 겠다. 이미 boost 의 경우 유명해져서 이것저것 써도 태클 들어올일은 적을테고 말이지. 코드를 짤때 위험하게 쓰일 경우를 대비해서 주석한줄 달랑 적지 말고 최대한의 방어를 하자. 특히 C++ 클래스는 컴파일러가 말없이 만드는 코드들이 많고.. 또 타입캐스팅이 말없이 일어나는 경우가 많으니 주의 또 주의.
  • 최소한의 함수들을 만들어서 조립. haskell 의 compose 는 정말 쇼크였다. 일단 문법이 편히 받쳐주니 여러가지를 composing 해서, 또는 compose 를 염두에 두고 만들어봤는데 정말 그리 좋을수가 없더라. 아직 C++ 이 이런식으로 사용하기는 적절하지 않은데 뭐 다른 편법을 쓰더라도 이놈은 좀더 공부해둘 필요가 있다. 흠 그런데 이런식으로 코딩하려면 제네릭한 함수가 있어야 하고.. 결국 템플릿 메타 프로그래밍(evil)으로 빠진다.

그외.. 꼭 haskell 이라서 라기 보단.. haskell 쪽에 몇가지 굉장히 매력적인 라이브러리들(QuickCheck, STM, Parsec 등등)이 있는데 내방식대로 써먹을 방법을 찾아봐야겠다. 또 FRP 란놈도 좀 흥미가 생기던데 아직 구경도 안해봤다. 이건 좀 아쉽군..

아.. 그리고 순수함수형 데이타구조에 대한 글들도 좋은게 많던데 이건 좀 읽어봐야겠더라. 이친구들은 이게 성능이 나쁘지 않다고 말을 하던데 흠.. 사실 믿어지질 않네.

어.. 하나 더. haskell 의 중요한 특성중에 lazy 가 있는데 흠. 글쎄 난 이놈에겐 별 매력을 못느겼다. lazy 특성때문에 얻은 장점이 아주 많다는걸 알겠는데 ( 무한 자료구조 같은경우는 정말 깨더라. 여기에 리커시브까지 끼면 후럴... ) 이 코드가 실제로 어떻게 돌아가는지 상상이 잘 안되더라. 이것도 뭐 숙련도 문제이긴 헌데 나한테는 넘을수없는 벽이었다. strict 가 기반이고 lazy 는 선택적으로 쉽게 지원해주면 좋았을텐데.. 참고로 clojure 가 strict 가 기본에 lazy-cons 라는 적절한 놈을 지원하더라. 우왕ㅋ굳ㅋ
(사실 언어가 돌아가는 모양을 알아야 되겠다는게 선언적 언어인 haskell 에는 좀 안어울릴수도 있는데 알고싶은걸 어쩌랴? 적어도 메모리가 얼마나 쌓이는지는 알아야지)

추가로.. 맘에 안들던점. 망할 언어확장. haskell 98 이 오래된 스펙이라 몇가지 추가기능들을 확장이란식으로 제공하던데 이건뭐.. haskell 의 발전을 옆에서 지켜본 사람이 아니면 그런 확장이 있는것도 모를테고.. 아니 사실 이건 haskell 의 문서부족에 대한 불평이네. haskell 문서들은 그냥 레퍼런스거나 아니면 거창한 내용을 담고있는 논문레벨의 문서(확장가능한 익셉션.. 이건뭐 정말 깨더군. 글쎄 다른언어같았다면 그냥 언어차원에서 구현하고 이리쓰셈. 하거나 확장가능한 언어라면 라이브러리단에서 붙이고 친절한 튜터리얼을 줬을텐데 haskell 은 이게 부족해서 문서를 찾다보면 논문까지 도달하게 되더라. 꽥 아니 뭐 이게 더 나은 모양이긴 하지만...)..

윗문단 다시 정리하면 튜터리얼의 부재가 상당히 짜증났다. 몇몇 문서들은 이게 프로그래머(haskell 구현자가 아닌 haskell 유저) 보라고 쓴건지 수학자 보라고 쓴건지.. 용어는 다른 언어와 미묘하게 다르고 뭐 생소한 학문에서 따온 용어를 언어에 붙여넣은것도 있고 어쨌건 haskell 은 그들만의 언어라는 느낌이 강하다.

엇 그리고 보니 haskell 의 장점중 하나가 병렬성인데 이쪽은 전혀 안봤네. 이건 나중에 다시 한번 둘러보자..


음. currying 에 대해서도. 이것도 킹왕짱. 아주 끌리는 언어적 기능. 전에 ocaml 구경할때는 그냥 그런갑다 했는데 이번에 이게 얼마나 좋은지 느꼈다. 뭐 lisp 애들은 매크로로 만들어 쓰는거 같던데 헐. 어쨌거나 함수를 받아서 함수를 내놓는다는 그야말로 고차원적 코딩이 자연스럽게 이루어지는 기반이라고도 할수있는데 아쉽게도 현재 C++ 에서는 쓰기가 좀 애매하다. boost::bind 를 써서 흉내가 가능하긴 한데... 흠. 다음 표준에 람다가 어느정도까지 들어가는지 좀 확인해보고 고민해보자.













댓글 없음: