'삽질+돈되는짓/Clojure/Lisp/Scheme'에 해당되는 글 9건

  1. 2010.11.05 Win32 + CLISP + SLIME (5)
  2. 2010.07.18 Windows에 Leiningen 설치하기 (3)
  3. 2010.07.18 Leiningen 이용하여 Clojure 개발하기 (1)
  4. 2010.07.15 독후감 "프로그래밍 클로져" (4)
  5. 2010.03.27 CFFI로 Hello MsgBox (2)
  6. 2009.11.28 [간략 리시피] 21세기적으로 Clojure 개발하기 (5)
  7. 2009.10.04 Emacs로 전향하기 (5)
  8. 2009.03.18 SBCL컴파일러 한글인코딩지원추가 (4)
  9. 2009.01.11 Paul Graham 아저씨의 ANSI CommonLisp. (7)
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.07.18 04:06
클로져 개발을 하려면 clojure.jar을 설치하는것도 아니고 이맥스랑 연동하는것도 아니고 오히려 leiningen을 설치하여 쓰는게 가장 좋은 방법이라고 생각한다.

편집기 연동은 솔직히 vim에 문법강조만 깔아서 써도 나쁘지않다. 어차피 'lein repl'로 테스트해볼수도 있고 될거는 다 되니까, 자동완성이나 실시간 docstring 표시같은건 되면 좋지만 사실 필수는 아니라고 생각한다. 기존의 파이썬이라 루비 개발을 할때에도 이들이 지원되면 좋았지만 안된다고 개발이 안되거나 어렵진 않았으니까.

특히 윈도에서 leiningen을 설치해 쓰는게 좋다고 생각한다.
윈도에서는 swank-clojure(<http://github.com/jochu/swank-clojure>)을 설치해도 이맥스에서 잘 연동이 안될수도 있고, 이클립스의 counterclockwise등의 IDE을 사용해도 없으면 많이 불편한게 사실이니까.

기존에 파이썬으로 lein을 다시 작성해서 메일링에도 올려보고 윈도에서 bash이 없어도 leiningen이 잘 굴러가게 하려고 삽질을 좀 해봤지만(<http://www.mail-archive.com/clojure@googlegroups.com/msg21473.html>) 맘에 들진 않았고, 호응도 좋았는데, 아이디어만 주고 말려고 했는데 자꾸 요구사항 반영해 달라고해서 귀찮을거 같아서 그만뒀다;;;
(돌 날아온다;;;)

여튼, 현재는 도스 배치파일 버젼도 배포한다. (<http://github.com/technomancy/leiningen/blob/master/bin/lein.bat>)

위의 배치파일을 다운로드하여 PATH 걸린 위치에 넣어준다.

보통 리눅스/유닉스에서는 이렇게 스크립트만 넣고 'self-install'하면 설치가 끝나지만 윈도에서는 그렇지 않아서 직접 clojure.jar, lein.jar을 찾아 넣어준다.

lein.bat을 열어보면 다음과 같은 부분이 있다.
rem this script works after downloading Leiningen standalone jar
rem and copying it on %LEIN_JAR% path

rem optionally can be downloaded also Clojure jar
rem (stable release, 1.1.0 or newer is recommended)
rem and copied on %CLOJURE_JAR% path
rem this step is not necessary, because Leiningen standalone jar
rem contains Clojure as well

set CLOJURE_VERSION=1.1.0
set LEIN_VERSION=1.1.0
일단 필요한 clojure.jar, lein.jar의 버젼을 확인한다. (set CLOJURE_VERSION=..., set LEIN_VERSION=...). 위의 URL을 방문하여 해당 버젼의 jar 파일을 다운로드한다.

그리고 이 저장한 파일의 절대경로를 환경변수로 세팅해주면 된다. 이는 lein.bat의 다음의 부분을 수정한다.

rem uncomment this and set paths explicitly
rem set LEIN_JAR=C:\Documents and Settings\wojcirob\.m2\repository\leiningen\leiningen\%LEIN_VERSION%\leiningen-%LEIN_VERSION%-standalone.jar
rem set CLOJURE_JAR=C:\Documents and Settings\wojcirob\.m2\repository\org\clojure\clojure\%CLOJURE_VERSION%\clojure-%CLOJURE_VERSION%.jar

굵게 표시한 set LEIN_JAR, set CLOJURE_JAR 두행의 맨 앞 rem을 지우고, 그 값에 저장한 clojure.jar, lein.jar의 절대경로를 지정한다.

그리고 "lein version"을 콘솔에서 실행하여 설치가 잘되었는지 확인한다. :-)

신고
posted by 아겔-_- 2010.07.18 03:49


 이 문서에서는 간략히 leiningen이 무엇인지 설명하고, 이를 이용하여 기본적인 클로져 개발 사이클에 필요한 내용을 HOWTO형식으로 정리한다. 그리고 실용적으로 개발하기위한 TDD, REPL, 이클립스 연동과 같은 부분들 또한 설명하도록 한다.





leiningen?

 leiningen은 클로져 프로젝트 관리도구다.

 자바의 Apache Maven와 같은 위상의 도구로서 다음과 같은 작업을 기본적으로 지원한다.

 * 초기 스켈레톤 생성
 * Maven, Clojars등의 원격저장소를 통한 외부라이브러리 의존성관리
 * 빌드, 테스트, 패키징 등 일반적인 개발사이클에서 필요한 작업의 자동화
 * ...그밖에 다양한 기능들을 플러그인을 통하여 지원

 Maven의 pom.xml와 같이 project.clj을 통하여 훨씬 간결하고 선언적으로 프로젝트를 관리하도록 지원한다.


 Leiningen은 단일한 스크립트로서 시스템에 설치하며, 유닉스/리눅스/OSX에서의 설치는 단순히 'lein' 쉘 스크립트를 받아 'lein self-install'로 완료하며, 윈도의 경우에는 별도의 문서를 참고하여 'self-install' 대신 직접 두세단계의 절차를 진행하여 설치한다.
 
 Leiningen은 어떤 GUI 도구나 IDE이 아니라 CMD.exe이나 유닉스쉘을 통해 접근하는 스크립트이므로 이 문서에는 쉘이나 콘솔에서 명령을 실행하는것을 기준으로 설명하겠다.

 
 * Leiningen : <http://github.com/technomancy/leiningen>
 * Apache Maven : <http://maven.apache.org/>
 * Clojars : <http://clojars.org/>









프로젝트 시작

 프로젝트는 new명령으로 다음처럼 생성한다.
 
 > lein new net.adaltan/foobar


 
 new명령은 현재 디렉토리에 프로젝트 스켈레톤을 생성하고, 'net.adaltan'은 그룹ID, 'foobar'은 프로젝트ID이다.
 결과적으로 'net.adaltan.foobar'을 최상위 네임스페이스로하는 프로젝트를 생성한다.
 
 
 
 
 
 




의존성

 개발을 하면서 외부 라이브러리를 참조하여야 할 경우, .jar 파일을 classpath에 추가하거나 Maven의 경우 pom.xml에 이를 기재하였다. 이와 같이, project.clj에 외부 의존성을 지정할수있다.
 
 기본적으로 생성한 프로젝트의 project.clj은 보통 다음과 같다.

(defproject net.adaltan/foobar "1.0.0-SNAPSHOT"
  :description "FIXME: write"
  :dependencies [[org.clojure/clojure "1.1.0"]
                 [org.clojure/clojure-contrib "1.1.0"]])


 :dependencies 벡터에 원하는 의존성을 추가하여준다. 여기에 적는 방법은 "group-id/artifact-id version"와 같은 형식으로 적는다. 예를 들어, 다음과 같은 형태로 지정한 pom.xml은...
 
    <dependency>
        <groupId>com.lowagie</groupId>
        <artifactId>itext</artifactId>
        <version>2.1.3</version>
    </dependency>

 다음의 project.clj의 의존성 벡터로 표현한다.
 
    [ ... [com.lowagie/itext "2.1.3"] ... ]

 매우 간단하다. :dependecies은 애플리케이션의 실행시간에 참조할 classpath에 추가하는 의존성이다.
 
 leiningen 자체도 의존성을 표현하는데, 이는 leiningen의 플러그인을 지정할때 사용한다. 이때는 :dev-dependencies을 키로 하며, dependecies와 같은 형식으로 지정한다. SLIME연동, 이클립스 프로젝트 연동, ...등과 같이 leiningen의 기능을 플러그인을 통해 확장할때 :dev-dependencies을 이용한다.
 
 Clojars이나 Maven repository에서 검색하여 의존성을 지정하면된다.
 
 의존성을 project.clj에 지정하였다면 "lein deps" 명령으로 이를 다운로드 받아와 적용한다.
 
 > lein deps
 ...

 추가적인 jar 저장소를 지정이 가능한데, 이들에 대해서는 이후 보일 예제 project.clj을 참고하라.

 
 
 



빌드, 패키징...

 일반적인 애플리케이션 빌드 과정에 속하는 단계들이므로 별도의 설명없이 명령들을 나열하겠다.

 프로젝트를 컴파일
 > lein compile
 
 프로젝트 클린
 
> lein clean

 프로젝트 jar로 패키징
 > lein jar
 
 프로젝트 jar로 패키징 (모든 의존성을 포함한 하나의 uberjar로 생성)
 > lein uberjar


 jar, uberjar의 경우 생성할 결과 파일이름, 디렉토리를 지정할수있으며, uberjar의 경우 standalone jar으로 만들수있으므로 메인 클래스를 지정 가능하다. 이들 키워드에 대해서는 이후에 설명할 예제 project.clj을 참고하라.
 
 프로젝트를 빌드하여 시스템 로컬 저장소에 설치
 > lein install


 프로젝트 빌드시에 소스파일 이외에도 classpath으로 복사하는 리소스 파일등이 있다면 :resources-path을 통해 해당 경로를 지정 가능하다.

 또한, .java 파일들을 프로젝트에 함께 포함하여 클로져+자바로 프로젝트를 개발한다면 lein-javac을 이용하여 이를 함께 컴파일하도록 한다.

 * lein-javac : <http://github.com/antoniogarrote/lein-javac>






REPL, 테스트

 코딩을 하고 자신이 작성한 모듈을 점진적으로 테스트하고 디버깅하려면 REPL을 이용하는게 바람직하다.
 이를 위해 다음처럼 실행한다.

 > lein repl


 위와 같이 한 다음 use을 이용하여 자신이 개발한 네임스페이스를 불러와 테스트하면된다.

 user> (use 'net.adaltan.foobar.core)


 또한, leiningen 기본 프로젝트는 항상 단위테스트 파일을 생성하는데 이들 파일은 src의 레이아웃과 같이 test 디렉토리에 위치한다. 예를 들어, src/net/adaltan/foobar/core.clj을 위한 테스트 파일인 test/net/adaltan/foobar/core_test.clj 파일은 다음과 같이 생성해준다.

(ns net.adaltan.foobar.core-test
  (:use [net.adaltan.foobar.core] :reload-all)
  (:use [clojure.test]))

(deftest replace-me ;; FIXME: write
  (is false))

 이는 clojure.test(<http://richhickey.github.com/clojure/clojure.test-api.html>)을 이용한 단위테스트다.

 함수를 작성하고 이에 대한 테스트를 적용하려면 이렇게 단위테스트를 작성하고 다음의 명령으로 테스트해본다.

 > lein test






예제 project.clj

 이 섹션에서는 예제 project.clj을 보여 어떠한 키워드들을 기본적으로 지원하는지 보여 설정가능한 기능을 파악하도록한다.

<http://github.com/technomancy/leiningen/blob/master/sample.project.clj>

;; 프로젝트 이름 "sample", group-id은 "org.example".
(defproject org.example/sample "1.0.0-SNAPSHOT" ; 버젼은 "1.0.0-SNAPSHOT"
  ;; Clojars에 업로드하였을때 설명으로 표시될 내용, 이를 통해 검색이 가능함
  :description "A sample project"
  ;; Clojars에서 표시할 프로젝트 URL
  :url "http://example.org/sample-clojure-project"
  ;; 프로젝트 메일링리스트. 혹시 다수개라면 리스트로 묶어서 여러개를 나열하도록한다.
  :mailing-list {:name "sample mailing list"
                 :archive "http://example.org/sample-mailing-list-archives"
                 :other-archives ["http://example.org/sample-list-archive2"
                                  "http://example.org/sample-list-archive3"]
                 :post "list@example.org"
                 :subscribe "list-subscribe@example.org"
                 :unsubscribe "list-unsubscribe@example.org"}
  ;; 프로젝트 라이센스 및 배포정보.
  ;;   다수개의 라이센스를 채택할경우 :license 키 대신에 :licenses을 이용해 나열한다.
  ;;   :distribution은 :repo이거나 :manual인데 공개 저장소에 올려도 좋다면 :repo을 선택한다.
  :license {:name "Eclipse Public License - v 1.0"
            :url "http://www.eclipse.org/legal/epl-v10.html"
            :distribution :repo
            :comments "same as Clojure"}
  ;; 의존성
  :dependencies [[org.clojure/clojure "1.1.0"]
                 [org.clojure/clojure-contrib "1.1.0"]
                                 ;; :exclusions 키를 이용하여 포함하지 않을 네임스페이스를 지정함
                 [log4j "1.2.15" :exclusions [javax.mail/mail
                                              javax.jms/jms
                                              com.sun.jdmk/jmxtools
                                              com.sun.jmx/jmxri]]]
  ;; 의존성을 다운로드할때 lib/ 디렉토리를 묵시적으로 삭제하고 다시 받을지 지정.
  :disable-implicit-clean false
  ;; 개발시 필요한 의존성을 나열. uberjar으로 jar로 묶었을때 이들은 포함하지 않는다.
  :dev-dependencies [[org.clojure/swank-clojure "1.2.1"]]
  ;; 자바연동과 :gen-class을 위해 AOT 컴파일할 클래스를 나열. :namespaces은 :aot와 같다.
  :aot [org.example.sample.SampleClass]
  ;; uberjar로 묶었을때 "main"으로 적용할 네임스페이스
  :main [org.example.sample]
  ;; reflection call에 대한 경고?
  :warn-on-reflection true
  ;; 기본 저장소를 사용할지?
  :omit-default-repositories true
  ;; 추가적인 저장소를 지정
  :repositories { "java.net" "http://download.java.net/maven/2"
                  "jboss" "http://repository.jboss.com/maven2/"}
  ;; 기본적인 프로젝트 파일 경로와 다르게 설정하려면 다음의 경로들을 설정할것
  :source-path "src/main/clojure"
  :library-path "target/dependency"
  :test-path "src/test/clojure"
  :resources-path "src/main/resources"
  :native-path "src/native" ; JNI, Native 의존성 파일들의 위치
  :jar-dir "target/" ; 프로젝트 jar 파일 생성 디렉토리
  :jar-name "sample.jar" ; 'lein jar'로 생성한 파일의 이름
  :uberjar-name "sample-standalone.jar" ; 'uberjar'로 생성할 파일의 이름
  ;; JVM에 전달할 인자
  :jvm-opts "-Xmx1g")

 기본설정이 있으므로 위에 나타난 키워드들을 모든 project.clj에 적을 필요는 없지만, 필요한 경우에는 이를 오버라이드하여 설정가능하므로 알아두는게 좋다.






Apache Maven, 이클립스(counterclockwise)와의 연동

 'pom' 명령으로 쉽게 pom.xml을 생성하여 Apache Maven 프로젝트로 전환이 가능하다.
 클로져 프로젝트는 Apache Maven을 통해 Leiningen을 통해 관리하듯이 관리가 가능하다.

 * Clojure Maven Plugin : <http://github.com/talios/clojure-maven-plugin>

 하지만, Leiningen만큼 많은 플러그인을 통한 기능을 지원하지는 않는것으로 보인다.

 마지막으로 가장 많이 사용하는 자바 개발도구인 이클립스와 이클립스를 위한 클로져 플러그인인 counterclockwise을 위한 프로젝트 파일을 생성하는 lein-eclipse을 소개한다.

 다음의 URL을 참고하여 :dev-dependencies에 lein-eclipse을 추가한 다음 다음처럼 하여 이클립스 프로젝트 파일을 생성한다.

 * counterclockwise : <http://code.google.com/p/counterclockwise/>
 * lein-eclipse : <http://clojars.org/lein-eclipse>

 > lein deps
 > lein eclipse

 이렇게 프로젝트를 생성한 다음엔 Import하여 바로 이클립스에서 개발이 가능하다.







신고
posted by 아겔-_- 2010.07.15 17:38

이번에 읽은책은 덕스러운 책들을 즐겨 출판하샤 세간의 찬사를 받고 계신 '도서출판 인사이트'에서 우리글로 내어놓은  "프로그래밍 클로져".
클로저 표지
 


http://pragprog.com/images/covers/original/shcloj.jpg 사실은 영문판으로 개인적으로 구입해서 "커먼리습 덕질이 우선"와 "남자라면 네이티브 컴파일러?!"라는 생각으로 한 세 챕터정도만 조금 읽어두고 썩히고 있었읍죠. (맛만 봐두고 정작 중요한 functional programming, laziness, concurrency와 관련한 부분은 읽지도 않았던게죠^^;)


Clojure 언어 자체는 최근에 들어서 GitHub, BitBucket등의 오픈소스 프로젝트 피드들을 살펴볼때마다 느끼지만 오픈소스 커뮤니티 안에서 급성장했다고 생각합니다. 정말 기존의 수많은 lisp-clone이나 이러한 시도를 했던 스킴 환경들과 달리 급성장하고있고, 충분히 성숙하고 멋진 프로젝트/라이브러리들이 이미 세상에 나와있다고 생각합니다. 그리고 JVM에서 굴러갈
무언가를 개발 하기에도 더없이 매력적인 환경이라고 생각하구요. 제가 생각하는 요인, 혹은 현재의 현상은...

  • 언어자체가 리습이지만, 기존의 리습의 역사적이고 약간은 고리타분한 모습을 벗고 non-Lisper들에게조차 idiomatic하려 매우 노력한게 곳곳에서 느껴진다.
  • 자바언어, 그리고 수많은 자바 라이브러리에 별다른 레이어나 추가적인 작업없이 직관적이고 직접적으로 접근
  • 클로져로 작성하더라도 자바측에 이를 노출하여 상호호환이 자유로움
  • 커먼리습의 매크로(defmacro), 하스켈의 지연평가(lazy evaluation)와 같은 멋진 기능들을 적절히 융합
  • 쉽고 직관적으로 고수준의 동시성 제어가 가능하도록하여 멀티코어, JVM을 최대한 활용하도록.
  • Leiningen 그리고 Clojars
    • Apache Maven처럼 프로젝트 자체의 의존성, 형태의 선언적 기술이 가능하도록 했고
    • 빌드, 테스트, 배포 등의 일반적인 작업을 Leiningen을 통해서 쉽고, 선언적으로.
    • 의존성 관리도 메이븐의 jar뿐만 아니라 Clojars을 통해서 RubyGems와 같이 사용자간의 쉬운 공유가 가능
    • Apache Maven처럼 단순히 Leiningen에 내장된 기능만이 아니라 수많은 플러그인을 통해서 Leiningen이 지원하는 기능을 확장/개발이 가능
    • 이미 수많은 라이브러리, 애플리케이션, 플러그인이 개발되어 공유하고 있음

뭐 이런것들이 생각나는 지금의 급성장하는 요인인거 같음.

책을 읽으며 많은 부분을 새로이 생각하거나 느꼈다. 특히나 이책에서는 그간 실용성이랑은 좀 안친해보이고 심지어 고리타분하게 느낄정도의 함수형 프로그래밍을 실용적인 의미로서 다시 접근해 보이는데 크게 놀랐다.

클로져에서 제공하는 동시성 제어(책에서는 '병행성'이라고하셨음. 병행성이 더 적절한 말일듯)에 대한 설명이나 늦은 평가나 무한한 리스트/시퀀스에 대한 소개, 다중메서드라고 표현한 multiple dispatch에 관한 부분은 사실 다른 언어에서 없거나, 찾기 힘들거나 모호한 개념으로 설명을 그냥 빙 돌아가는게 일반적이라고 생각했는데 이들에 대해서 처음 접하는 이들도 명확하게 개념을 잡고 이들을 어떤때 어떻게 적용할지를 생각해보게 해준다고 생각한다.


그럼에도 약간 아쉬운점도 못되는점들은...
  • 어쩔수없이 책이 나올 시점에는 세상에 없었던것들에 대한 설명이 있었으면 했다.
    • Leiningen을 이용한 개발 방법
    • deftype, defprotocol 같은 타입정의


어쨌든 좋은책을 세상에 내주고 우리말판까지 내주신 모든분들에게 감사드리고 싶은 책이었다. :-)










ps. 오늘도 말투는 이랬다 저랬다 일관성없음;;; (고치기 귀찮;;;)

ps2. 저번 "프로그래밍 루아" 독후감도 그렇고 인사이트에서 뭐 떡고물이라도 주셔야 되는거 아닌지 깊이 생각해볼일;;;

신고
posted by 아겔-_- 2010.03.27 23:25
신고
posted by 아겔-_- 2009.11.28 19:26

세줄요약:
  • clojure.jar, clojure-contrib.jar 절대 (직접) 설치하지마라!!!
  • 개발하려면 emacs + (elpa) + swank-clojure 써라!!!
  • lein을 활용해라!!!


1. emacs에 elpa을 설치한다 : http://tromey.com/elpa/

  방문해서 install elisp코드 이맥스 scratch 버퍼에 붙여넣고 C-j




2. swank-clojure 설치하여 slime + clojure 설치를 한방에

  이맥스에서 "M-x package-list-packages"한 다음 "swank-clojure"에서 "I"로 체크하고 "X"로 설치... 


3. ~/.emacs에 다음을 추가하여 유니코드 사용가능하게
(setq slime-net-coding-system 'utf-8-unix)

4. 이맥스에서 "M-x slime"하여 테스트!


5. leiningen을 설치 : http://github.com/technomancy/leiningen/

"lein" 쉘스크립트를 다운 받아 적당히 PATH에 걸고 실행가능으로.
그리고 다음을 쉘에서 실행하여 clojure, clojure-contrib등을 설치...
lein self-install

이렇게 하면 간략한 clojure 개발환경 세팅 끝.

project.clj을 만들고 lein compile, jar, uberjar, test등을 바로 적용이 가능해졌고, clojars에서 제공하는 외부 라이브러리를 다운 받아 적용이 가능해졌고 pom을 만들어 clojars에 배포하거나 apache-maven에 적용도 가능해지는 멋진 환경에 되었심...

이맥스에서는 "M-x swank-clojure-project"로 해당 project.clj의 경로를 지정하면 프로젝트를 바로 인식해서 열어준다능... (클래스패스등...)

하악하악... 


신고
posted by 아겔-_- 2009.10.04 18:02

 

2009/10/03 23:57:43

 

나같은 vimpire도 결국엔... 하악거리게 되었;;;

은근 사용해 보는데 이클립스에 익숙해져서 그런지 완전 좋게 느껴지는... vim이라는 구속구를 벗어버린 느낌이랄까...

 

 

ELPA

  • CPAN처럼 네트웍을 통해 elisp을 설치하는 하악... 2009/10/03 23:57:58
  • clojure-mode설치하고 M-x clojure-install해보고 나서 바로 반해버렸음

 

 

ParEdit

  • http://www.emacswiki.org/emacs/ParEdit
  • "괄호"을 위한 에디터! 2009/10/04 00:00:34
  • 리습코드를 편집하는데 이젠 없으면 안되게 나를 만들어버린 ㅜ.ㅜ

    • 괄호 자동 붙이기, M-)이라던지 C-k등을 느껴보아요...
  1. ;;; paredit.el
  2. (autoload 'paredit-mode "paredit" "Minor mode for pseudo-structurally editing Lisp code." t)
  3. (add-hook 'emacs-lisp-mode-hook       (lambda () (paredit-mode +1)))
  4. (add-hook 'lisp-mode-hook             (lambda () (paredit-mode +1)))
  5. (add-hook 'lisp-interaction-mode-hook (lambda () (paredit-mode +1)))
  6. (add-hook 'slime-repl-mode-hook       (lambda () (paredit-mode +1)))
  7. (add-hook 'slime-mode-hook            (lambda () (paredit-mode +1)))

 

http://www.emacswiki.org/emacs/ParEdit

 

http://www.emacswiki.org/emacs/PareditCheatsheet

 

SLIME + ElDoc

  • SLIME은 뭐 말할거 없잖수... 2009/10/04 00:02:12
  • ElDoc은 뭔가 입력할때(함수호출...) 메시지 버퍼에 인자목록등을 뿌려주는 하악하악...
  • (slime-setup '(slime-fancy))

    • 요렇게 초기화하면 대략 기타 contrib등을 같이 로딩함.
    • slime/contrib이하를 참고
    • 기타 원하는거 로딩해도 좋은데 정말 강력해지는 slime!
  • (setq slime-net-coding-system 'utf-8-unix)

    • 인코딩 지정해야지 심볼등을 정상적으로 한글입력!

 

 

 

 

 

이 글은 스프링노트에서 작성되었습니다.

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

하악하악...

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

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

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


sbcl-devel에 코드 보내야징...
신고
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이 편해요. ^^;

신고

티스토리 툴바