posted by 아겔-_- 2010.11.05 23:38

Win32 + CLISP + SLIME

-*- org -*-

1 아겔 2010-11-05 금

2 필요성

  • Win32에서 쓸만한 커먼리습 구현/환경을 세팅하는게 나름대로 많은 사람들이 도전하고 나도 해봤는데 만만치도 않고, 만족스럽게 구현하는게 힘들었었다.
  • 나름 이번에 CLISP을 구현체로 사용하면서 느낀점과 노하우를 정리해보기.

3 어째서 CLISP?

3.1 장점

  • 윈도에서 별 문제없이 잘굴러간다. (CCL, SBCL, CMUCL이 좀 불안정하고 항상 베타인점과 비교해서 큰 장점이라고 생각함.) Viaweb의 경우에도 윈도환경에서 CLISP을 이용하여 개발하였다고.
  • 안정적이다. 윈도환경에서 다른 구현체들은 다운되거나 SWANK만 띄우다가도 죽는 Kitten of Death을 종종 보는데 CLISP/Win32에서는 그런 경우를 본적이없다.
  • 생각보다 정말 빠르다. 바이트코드를 이용하는 VM이라서 다른 네이티브 코드를 생성하는 컴파일러에 비해서 느릴거라는 생각을 했는데 그렇게 차이가 안나고 오히려 다른 언어들(자바, 파이썬…)등보다 빠르고 특히 수치연산과 같은 부분은 놀랄정도로 빠르다. 실제로 애플리케이션 개발해서 사용해도 성능에 무리가 없다.
  • 애플리케이션 개발하여 단독배포(Standalone Deployment)이 윈도에서도 현실적이고 잘되어있다. 단순히 EXT:SAVEINITMEM을 이용하여 실행화일과 함께 이미지를 떨굴수있도록 되있어서 편하게 배포할수있다.
  • 유니코드 지원이 좋다. 다른 구현체에 비해서 유니코드 구현 레벨도 높고 바로 적용해서 쓸만한 수준이다.
  • 구현노트에 정말 자세하게 문서화를 잘해놨고, 윈도환경에서 큰 사용자를 크게 놀래키지않고 안정적이고 멋진 성능으로 커먼리습을 경험하기에 좋은 구현체라고 생각한다. (다른 운영체제에서도 그렇긴하지만)

3.2 단점

  • 스레드 지원이 좀 거시기하다. CLISP 구현노트(implementation notes) 문서에는 CL:*FEATURES*에 :MT이 있고, MT 패키지를 통해서 구현하고, POSIX, Win32에서 지원한다는데 내 버젼에서는 지원이 꺼져있나보당. (CLISP 2.49, 2010/07/07, Win32)
  • "Bordeaux Threads"와 같은 de Facto 스레드 라이브러리에서도 CLISP은 아예 지원이 안되고있음.
  • 스레드 관련 때문인지 Hunchentoot와 같은 일반적으로 커먼리습 웹개발에 이용하는 웹서버/웹프레임웍이 지원안된다. (다른 대안도 많지만)
  • 내장 함수들은 docstring이 거의 없어서 slime-autodoc의 덕을 별로 못본다. 다른 구현체들은 docstring이 나름 붙을만큼 붙어있어서 HyperSpec 안봐도 대충 알수있지만 docstring도 안붙고 인자 이름도 그냥 arg1, arg2… 이렇게만 보여서 가끔 거시기함.

3.3 대안들

  • SBCL : 좋고 네이티브 컴파일러라 멋지긴한데, 리눅스/FreeBSD였다면 이를 쓰겠지만, 윈도에서는 정말 너무하다 싶을 정도로 뻗어버려서 안쓰고 만다는 생각밖엔 안든다. docstring이나 그런것들도 친절하게 잘해놨고, 배포도 쉽게 할수있도록 배려를 해놨지만 여전히 윈도지원이 거시기하다.
  • Clozure CL : 네이티브 컴파일러, docstring 모두 좋은데, 역시 무서울정도로 뻗어주고 윈도에서 배포도 좀 거시기해보인다.
  • ECL : 윈도에서도 빌드되고 바이트코드 방식이라고. 음 나름 평이 좋은거 같은데 시도해볼까.
  • MKCL : 아직 써본적없음. KCL계열이고, ECL에서 fork했다고. 윈도에서도 MingW을 이용해서 빌드가 가능하단다. 나중에 한번 시도해보고 싶음. 프로젝트 자체가 매우 새롭다.
  • 상용 구현체 (Franz, LispWorks) : 돈 있으면 사서 쓰고싶다. 트라이얼들은 사용시간 제한이 있거나, 힙크기 제한이나 이미지 저장이나 deploy을 못하게 막아놓았다. 결국 돈주고 사는게 제일 속편할거 같다.
  • ABCL : 특이하게 JVM위에서 굴러가는 구현체. 시도해보면 재밌을거 같다.

4 Emacs+SLIME 기본세팅

  • 딱 필요한 설정만 하는게 취향.

4.1 이맥스 설치

4.2 SLIME 패키지 수동 설치

  • 그냥 cvs snapshot 받아서 압축 풀어서 바로 적용.

4.3 ~/.emacs

(setq slime-net-coding-system 'utf-8-unix)
(add-to-list 'load-path "c:/lisp/slime-2010-10-29/")
(require 'slime)
(setq inferior-lisp-program "c:/lisp/clisp/clisp.exe")
(slime-setup '(slime-fancy))
(setq slime-header-line-p nil)

5 mk-defsystem? ASDF? libCL? QuickLisp? clbuild?

  • 의존성, 외부 라이브러리.
  • 커먼리습에도 다양한 시도가 있구낭.
  • 그 이외에도 어떤 '시스템(system)'을 컴파일하고, 이미지에 적재하는데 좀 자동화하는 필요성도 있긴함. 어떤 시스템을 만들어서 배포하는데 이런거 일일이 적어주기도 그렇고 스크립트로 작성하기도 마땅한건 아니니까.
  • '시스템' : 패키지는 이름공간을 나누는데 이용하고, 자바와 같은 플랫폼과는 다르게 단순히 한 소스파일이 꼭 하나의 패키지 항목이라고 말할수도 없고, 하나의 소스에도 여러 패키지를 만들수도 있고… 차라리 C/C++처럼 여러개로 분할하여 컴파일도 가능하고… 커먼리습은 파일기반이라기보다는 이미지 기반이기 때문에 좀 다른 접근법이 필요함. 이런 상황에서 다수개의 패키지, 다수개의 소스파일을 일괄, 자동화하여 빌드/로딩할 방법이 필요함. 이런 집합을 '시스템'이라고 부르는듯함.
  • 어떻게 생각하면 C/C++의 make이랑도 비슷하다고 생각하면됨.
  • 의외로 "quicklisp user survey"(http://xach.livejournal.com/271794.html)의 결과에서 재밌는 부분을 찾았다. 나 이외에도 대부분의 CL이용자들이 직접 그냥 손으로 다운로드하여 시스템을 설치하는구나…

5.1 mk-defsystem

  • CLOCC(the CommonLisp Open Code Collection)에 포함된 'defsystem'
  • 좀 오래된 방법인거 같음.
  • 더 대중적으로 인기도 많고 대세인 'asdf'의 'asdf-install'을 통해 설치가 가능하단다.
  • C/C++의 make이랑 비슷한 위상인듯.

5.2 ASDF

  • ".asd" 파일을 통해서 정의한 시스템을 그와 딸린 소스코드를 컴파일/로딩하는데 이용하는 de Facto.
  • 현재 오픈소스 리습 커뮤니티의 거의 대부분의 라이브러리나 애플리케이션은 asdf을 통해 패키징하고 배포하는게 대세인듯.
  • 네트웍을 통해 자동으로 패키지를 다운로드하고 설치하고, 의존성도 자동으로 설치해주는 asdf-install 같은 확장도 있어서 편리하다.
  • 윈도 환경에선 asdf-install이 마땅치 않으나 그래도 asdf을 손으로 설치해도 나쁘지 않으므로 이렇게 이용하는게 차라리 속편하다.

5.3 libCL

  • 리눅스 배포판처럼 아예 자주 쓰는 커먼리습 라이브러리들을 한번에 묶어서 설치해 사용하도록 하는 방법.
  • 그럭저럭 쓸만한데 업데이트도 느리고 윈도7에서 잘 굴러가지도 않아서 편하긴 하지만 안쓰게됨.

5.4 QuickLisp

  • asdf-install처럼 원격의 시스템을 받아다 의존성까지 풀어서 설치하는 새로운 방식.
  • 좋긴한데 중앙집중적으로 또 다른 저장소에서 메타데이터들을 관리하고 좀 마음에 안들때도 있음. 어차피 정말 그래도 써야겠다면 어차피 손으로 로딩해도 되긴하지만. 무엇보다 윈7에서 잘 안맞는거 같아서 이것도 접었음.

5.5 clbuild

  • asdf-install처럼 라이브러리를 다운로드/컴파일/로드하는 방식.
  • jhbuild을 모델로해서 만들었다고 하는구낭. 쉘스크립트 방식이라 윈도에선 좀 거시기할듯. 그리고 QuickLisp처럼 중앙 저장소에서 관리를 하는구나.

6 ASDF 이용

6.1 ~/.clisprc.lisp을 이용하여 asdf 로딩/설정

  • 단순히 "asdf.lisp" 파일을 시작시 CL:LOAD 하도록 지정해주면됨.
    ;; c:/lisp/lisp/asdf/asdf.lisp 있어야겠죠?
    (load #P"c:/lisp/asdf/asdf")
    

6.2 시스템 컴파일/로딩

  • 시스템의 이름을 지정할때는 예를 들어, 시스템 이름이 "puri"인 경우 키워드나 문자열, 심볼 모두 가능.
  • ASDF:*CENTRAL-REGISTRY*에 ".asd" 파일과 소스코드가 위치한 디렉토리를 CL:PUSH해주고서 실행하는게 윈도에선 속편함.
    • 단점으로는 의존성들에 대해서도 일일이 CL:PUSH ^^;
  • 컴파일 : ASDF:COMPILE-SYSTEM이나 ASDF:OPERATE, ASDF:OOS와 ASDF:COMPILE-OP 이용.
    > (ASDF:COMPILE-SYSTEM :puri)
    ;; ..or
    > (ASDF:OPERATE 'ASDF:COMPILE-OP :puri)
    ;; ..
    > (ASDF:OOS 'ASDF:COMPILE-OP :puri)
    
  • 로딩 : 컴파일과 같으나, ASDF:LOAD-SYSTEM, ASDF:LOAD-OP인점만 다름. 컴파일은 자동으로 적용.

6.3 기타…

  • 윈도에서 "바로가기"를 이용하여 유닉스의 심볼릭 링크처럼 ASDF:*CENTRAL-REGISTRY*에 지정한 디렉토리에 ".asd" 파일만 링크하면 매번 시스템 적재할때마다 ASDF:*CENTRAL-REGISTRY*에 경로를 지정안해도 된다고 하는데 난 왜 안되지;;;
  • "NTFS Symbolic Link"을 이용하여 시도해보면될까
  • 아님 ASDF:*SYSTEM-DEFINITION-SEARCH-FUNCTIONS*에 하위 디렉토리를 검색하여 로딩하도록 함수를 추가해서도 해결이 가능해보인다.
    • http://en.wikibooks.org/wiki/Common_Lisp/External_libraries/ASDF/Configuring_ASDF#Alternative_to_symlinks.2C_search_directories_recursively
      ;; An alternative to the standard sysdef search can be defined.  This                
      ;; code below can be dropped into your Lisp init files and customized.               
      ;; It will search for all ASDF systems in subdirectories of the                      
      ;; specified directories.  That lets you simply "drop-in" new packages               
      ;; into one of the specified directories, and it will be available for               
      ;; loading without any further steps.                                                
      (in-package #:asdf)
      (defvar *subdir-search-registry* '(#p"/my/lisp/libraries/")
        "List of directories to search subdirectories within.")
      (defvar *subdir-search-wildcard* :wild
        "Value of :wild means search only one level of subdirectories; value of :wild-inferiors means search
       all levels of subdirectories (I don't advise using this in big directories!)")
      (defun sysdef-subdir-search (system)
        (let ((latter-path (make-pathname :name (coerce-name system)
                                          :directory (list :relative
                                                           *subdir-search-wildcard*)
                                          :type "asd"
                                          :version :newest
                                          :case :local)))
          (dolist (d *subdir-search-registry*)
            (let* ((wild-path (merge-pathnames latter-path d))
                   (files (directory wild-path)))
              (when files
                (return (first files)))))))
      (pushnew 'sysdef-subdir-search *system-definition-search-functions*)
      

Author: Jonghyouk Yun <ageldama@gmail.com>

Date: 2010-11-05 23:34:01 KST

HTML generated by org-mode 6.21b in emacs 23

신고
posted by 아겔-_- 2010.03.27 23:25
신고
posted by 아겔-_- 2009.03.30 23:21
팩터에서 튜플 클래스를 선언하고 속성을 붙이는것까지 설명했다.
이제는 객체에 메서드를 붙여줄 시간이다. (객체지향에서 객체는 속성과 행위로 표현하니까.)

팩터의 타입시스템 자체는 하스켈이나 OCaml의 그것들과 유사한데, 메서드나 슬롯에 대한 부분은 커먼리습의 CLOS와 유사하다.

무슨말인가하면, 어떤 객체에 대해서 메서드를 붙이는것과는 조금 다르다는말이다.
예를 들어서 우리는 메서드의 polymorphism에 대해서 다음에 익숙해있다.

someCircle.area();
someRectangle.area();
단순히 이름이 같다는것정도.

팩터는 그 언어의 특색(nature)에 따라 객체의 메서드도 사실은 그냥 일반적인 워드와 같다.
리습에서 객체의 메서드는 그냥 일반적인 함수호출과 같고, 하스켈에서 어떤 타입에 대한 함수는 일반적인 함수와 같다.
단지 그 인자중 하나가 그 클래스/타입에 속할때 원하는 메서드의 코드를 선택하는것이 다르다.

팩터에는 별도로 연산자가 없다. 모두 워드다. 마찬가지로 메서드를 만드는것만으로 기존의 연산자를 재정의하는것이 가능하다.

팩터나 CLOS에서 이런 "메서드의 이름"을 규정하는것을 제네릭(generic)이라고한다. 그리고 다음처럼 선언한다.

( scratchpad ) GENERIC: area
( scratchpad ) GENERIC: perimeter ( obj -- perimeter )
단순히 제네릭의 이름을 주거나, 제네릭의 stack effect declaration을 적어줘도 좋다.

이렇게하면, 객체별로 이 제네릭에 대한 메서드를 붙일 준비가 끝났다.

일단 넓이를 구하는 메서드들은 다음처럼 붙여봤다.

( scratchpad ) USE: math.constants
( scratchpad ) pi .
3.141592653589793
( scratchpad ) pi sq .
9.869604401089358
( scratchpad ) M: circle area r>> sq pi * ;
( scratchpad ) 9 <circle> area .
254.4690049407732
( scratchpad ) M: rectangle area [ w>> ] [ h>> ] bi * ;
( scratchpad ) 3 4 <rectangle> area .
12

"M: 클래스 제네릭 ..." 이렇게 시작해서 일반적인 워드와 같이 그 구현을 하는것을 알 수 있다.

다수개의 인자에 대해서도 제네릭을 다르게 만들어놓고서 하면 되는데, 이때 주의점은 GENERIC: 선언은 반드시 스택의 맨 위가 해당 클래스의 인스턴스여야 한다는것이다. 특정 클래스를 다른 위치에 두고자 한다면 "GENERIC#" 선언을 이용한다.

또한, HOOK:을 통해서 multiple dispatch에서처럼 다수의 인자의 타입에 따른 메서드 dispatch을 구현이 가능하다.
(그 이외에도 MATH:등을 통해서 수학연산자에서처럼 양변의 타입에 따른 dispatch도 가능하다)

또한 상속 받은 클래스의 메서드에서 상위 메서드를 호출하려면 super등을 통하지 않고 단순히 "call-next-method"을 호출한다.
(circle의 area에서 shape의 area을 호출하고자 한다던지...)

마지막으로 메서드의 인자가 많거나 할때도, locals의 M::을 이용하여 "::"와 같이 인자들에 이름을 붙이거나 할수있다.

( scratchpad ) M: circle perimeter r>> pi * 2 * ;
( scratchpad ) 9 <circle> perimeter .
56.54866776461628
( scratchpad ) M: rectangle perimeter [ w>> 2 * ] [ h>> 2 * ] bi + ;
( scratchpad ) 3 4 <rectangle> perimeter .
14








신고
posted by 아겔-_- 2009.03.18 17:59

하악하악...

SBCL에서 기본적으로 유니코드를 지원하지만, 뭔가 부족했음. (사실 전 커먼리습 요즘엔 다 까먹;;;)

중국어도, 일본어도 기본적으로 native encodings을 지원하는데...

그래서 그냥 감기로 병가내고 쉬면서 작업해서 만들어봤음.


sbcl-devel에 코드 보내야징...
신고
posted by 아겔-_- 2009.01.31 23:04
저는 FactorLanguage을 좋아합니다. (http://en.wikipedia.org/wiki/Factor_(programming_language))

실용적이고 제가 원하는것을 모두 갖춘것 같은 언어라고 생각해요. 커먼리습은 너무 오래되고 커지기만 한 느낌이고(물론, 언어자체의 설계를 뒤집을 필요가 전혀없으니까 그렇긴해도, 구현이나 개발환경이 그런게 사실 윈도나 런곳에서는 좀 제한적이잖아요?), 스킴은 뭔가 구현마다 너무 큰 갭이 있는것 같고요. (다른분들보다 제가 아둔해서 그렇게 느끼는걸수도 있겠죠. ^^;)

커먼리습 같은 네이티브 컴파일러, 파일/이미지기반의 개발, ffi도 괜찮고, 이미 다른 언어에서 구현하기 힘들정도로 멋진 도구들을 많이 갖추고 있고, 그리고 무엇보다 심플하고 완전한 언어 그자체로부터 나오는 강력한 표현력은 리습의 s-expression에서 느낀것보다 훨씬 신선하게 저에게 충격을 줬었습니다. 제게 있어서 리습은 제 생각하는 방법을 바꿔버린 언어이고, Factor은 생각하는 방법을 다시 바꾼 언어죠.

하여튼 제게 있어서는 다른 리습해커들에게 커먼리습이 갖는것처럼 뭔가 완전하고 아름다운 제 도구인 FactorLanguage에서 좀 싫어하는건 사실 개발환경이었어요.

익숙해지기 힘들고, 거추장스럽고, 마우스에 손이 자주가야하고, 그리고 무엇보다 아직은 한글입력/출력이 안되는! ㅜ.ㅜ




그런데 좋은 소식이 있었더라구요.
언제나 팩터쪽은 그런식(!!!)이듯이 순식간에 엄청난 물건이!

FUEL(Factor's Ultimate Emacs Library)이라는 겸손한 이름(;;;)의 Emacs모드였어요.

원래 팩터를 개발한 슬라바 아저씨(Slava Pestov, http://factor-language.blogspot.com/)가 jEdit을 개발한 사람이어서 그런지 jEdit쪽 바인딩이나 그런건 나름 괜찮았었는데, jEdit자체가 요즘엔 좀 거시기한 에디터가 되고 그랬던 와중에, 기존에 팩터에서 사용가능한 vim, emacs 모드에서 이맥스 모드였던 "factor.el"이 발전하여 SLIME(http://common-lisp.net/project/slime/)처럼 막강한 개발환경이 되었어요!

관련 블로그 포스팅 : http://factor-language.blogspot.com/2009/01/screencast-editing-factor-code-with.html


하악하악... 설정도 그냥 이맥스랑 팩터만 설치하고, 이맥스에서 fu.el을 load-file하면 끝!

;;; ~/.emacs에서...
(load-file "d:/tools/factor/misc/fuel/fu.el")

그리고 "M-x run-factor"하고 잠시 (처음 시작할때는 좀 많이 기둘려야 해용 ㅜ.ㅜ) SLIME-REPL처럼 사랑스러운 scratchpad을 만날수있답니다!

팩터 파일을 편집하고, 바로 REPL측에 컴파일/적재하고, 이를 테스트하고, 작성하면서 관련된 레퍼런스를 즉시 검색하고(팩터은 코드와 함께 문서도 적재되서 언제나 실행시간에 관련 문서를 바로바로 찾아볼수있답니다. ^^), 코드를 "리-팩터링"한다던지 하는 개발환경으로서 SLIME 못지 않은 환경을 간단히 갖출수있었어요.
(심지어 이클립스와 같은 자바IDE에서나 보던 'Organize Imports'와 같은 "fuel-update-usings"같은것까지 있더라구요.)

자세한 /뽀대/는 다음 스크린캐스트 : http://blip.tv/file/1658806


저에게는 FUEL이 참 설레이는 환경이 되었어요. *^^*




ps. 처음 "M-x run-factor"하면 많이 느린데요, 이유는 필요한 vocab(모듈이랑 비슷한 개념이에요)을 vm에 적재하고, 최적화 컴파일러를 거쳐서 컴파일하기 때문인데요, 빠르게 하시려면 한번 그렇게 적재하신 다음에 scratchpad에서 "save"을 쳐서, 이미지를 업데이트 하시면 다음번 "run-factor'부터는 빠르게 올라온답니다. 스몰톡이나 커먼리습처럼 파일기반으로 개발이 가능하면서도, vm의 현재 상태를 이미지로 만들어서 deploy하거나 개발할때 편리하게 이용할수있어요. ^^
신고

'삽질+돈되는짓 > FactorLanguage' 카테고리의 다른 글

팩터는 어떤 언어임까?  (0) 2009.02.13
Why "Factor"?  (0) 2009.02.13
io.encodings.korean을 완성했습니다.  (2) 2009.02.12
factor-kr을 시작했습니다.  (0) 2009.02.08
ProjectEuler 풀면서 한컷!  (0) 2009.02.01
FactorLanguage을 위한 SLIME?  (2) 2009.01.31
posted by 아겔-_- 2009.01.18 19:22
나름 세상은 static/dynamic typing에 관한 문제로 격변기인것도 같아요.

그러는 와중에 또 하나 나름의 미래의 이슈는 dispatch에 관한게 아닐까 생각해봅니다.

스몰톡, 루비와 같은 언어들처럼 message-passing 메타포를 통해서 실제 수행할 메서드를 찾는 방식과
하스켈, CLOS처럼 인자의 타입쌍에 따라서 코드를 수행하는 방식의 대립이 되지 않을까는 생각이죠.

일단 메시지전달 진영을 살펴보면, Io, Ruby, Smalltalk, Objective-C 대표적이겠네요,객체가 receiver가 되서 전달하는 메시지에 따라서 해당 메시지를 받을 수 있는 메서드를 실행하는 방식이죠.

그리고 multimethod(정확한 정의라고는 하기 힘들겠지만, 편의상 이렇게 부를게요.)진영은 Haskell, Factor, Clojure, CLOS등이 여기에 속하겠죠. 특징이라면, generic-function등을 선언해놓고 여기에 이후에 추가하는 타입(클래스)에 따라 method을 등록하는 방식이죠. 어떤 하나의 객체에 메서드를 붙이는 것이 아니라 여러가지 타입쌍에 따라서 어떤 메서드를 실행할지를 결정해요. 보통 하스켈과 같은 pattern-matching을 지원하는 언어들에서 인자의 타입이나 값의 구조에 따라서 하나의 함수에서 적절한 코드를 평가하는것과 같은 방식이죠.

메시지전달 방식은 대단히 유연하다고 생각하지만, "Haskell: School of Expression"과 같은 책의 맨 처음에서 설명하는 '도형 그리기/면적구하기'와 같은 전형적인 문제에서 혼란스러운 코드를 만들어줍니다.(심지어 오래전 Objective-C 문서에서는 '도형 그리기' 문제를 던져만 놓고 답은 제시하지 못하는 웃기는 문서도 있었죠-_-;;) 대부분의 이러한 언어들은 객체의 타입에 따라서 메서드를 결정하는것이 아니라, 거의 첫번째 인자의 타입(즉, receiver)만을 살펴서 실행할 메서드를 결정하며, 이러한 문제를 표현하기에 적합하지 않습니다. (그리고 더 슬픈건 '객체지향'을 통해서 '모델링'하거나 '시뮬레이션'하는 세계는 거의 대부분 이런 문제라는것이죠.)

거기에 전자의 경우에는 단순히 '복잡함'을 해결한다는 명목으로 단일상속하여 수직적인 관계를 단순화하려고 노력하죠. 수평적인 공유는 mix-ins, traits/roles와 같은 방식으로 해결하려하죠. 그리고 RoR의 어떤 클래스를 보듯이 정말 단순히 어떤 클래스가 소스의 내용과 실제 실행시간의 모습이 예측하기 힘들다는 문제를 만들어내죠. (스몰톡의 경우엔 차라리 문제가 단순할지도 모르겠지만, 루비, Io와 같은 언어에서는 실행시간과 단순한 클래스의 문서가 서로 갭이 큰 경우가 있죠.)

반대로 multimethod진영은 객체에 대해서 훨씬 우아한 해법을 제시하고 있습니다. Haskell의 class, instance의 관계는 좀 복잡하긴 하지만, Clojure에서 struct을 통한 타입의 선언과(이름만 '구조체'이지 Haskell의 그것과 유사하죠. Factor에서 객체모델도 사실 Tuple타입에서 시작하고요.) 상속관계의 표현, 그리고 이 타입과 연관된 메서드의 정의들로 객체 정의를 끝내죠. 단순히 어떤 인터페이스를 구현하거나 하는 피곤한 방법에서 진짜 polymorphic하게 객체를 만드는것이죠. 정말 단순하고, OO에 경도된 개발자들은 그럴거 뭐하러 그런 언어를 쓰느냐고 속이 꼬일지도 모르겠지만, 조금만 생각해보면 '객체지향의 이름으로' 행했던 수많은 뻘짓들을 할 필요가 없게됨을 알게된답니다.



그래서 뭐냐구요? 아. 결론은 없는결요. ^^;
신고
posted by 아겔-_- 2009.01.11 14:58
[Paul Graham] 아저씨의 "ANSI CommonLisp"을 어떻게 어떻게 PDF로 얻어서 읽었습니다.

아직 "해커와 화가"도 제대로 읽어보지 못했고, 그냥 YCombinator라던지 Arc의 소식, 그리고 그의 [홈페이지]에 간간히 올라오는 에세이를 읽으며 막연히만 알던 분이었는데, ACL(ANSI CommonLisp)을 읽으며 멋지다는 생각을 했습니다.

Peter Seibel의 "Practical CommonLisp"이 뭔가 좀 장황하고 아기자기하면서 "우와~"스러운 예제들을 만들어가면서 커먼리습, 리습의 세계에 맛을 들이게 하는 반면, ACL은 간결하면서 명확한(정말 PCL에 비해서 ACL의 코드나 설명은 간결하고 명확하죠.) 문체로 정확히 개념을 잡아주는 요점정리 같은 느낌이었습니다.

솔직히 PCL도 좋은 책이지만, 뭔가 리습에 대해 조금이라도 알고, 그 느낌을 명쾌하게 정리하는것에 있어서는 ACL이 더 좋은 책이라는 생각을 했습니다.

게으르고 뭔가 설정하기 참 싫어하는 탓에 LispInABox을 대충 깔고 갖고 놀았는데 재밌었어요.

아... CLOS에 대해서도 나쁘지 않게 잘 설명한 좋은 책이라는 생각을 했습니다.

기본적으로 리습에 대한 이해가 약간 있고, 익숙한 사용자라면, 그리고 CLOS와 같은 객체시스템이나 그런것에 대해서 약간의 지식이 있는 편이라면 ACL은 금방 내용을 읽어내려갈 좋은책인것 같습니다. (전 토, 일 이틀간 정말 재밌게 읽었네요. ^^)




ps. 아... '해커와 화가' 질러야겠어요^^;
ps2. 그래도 DrScheme이 편해요. ^^;

신고

티스토리 툴바