2008년 1월 9일 수요일

Emacs에서 Common Lisp Hyperspec 보기

리습 코드를 읽다보면 아무래도 모르는 함수나 매크로에 대한 레퍼런스를 찾아볼 필요가 생긴다. Common Lisp Hyperspec이 웹에 있고 HTML 파일을 내려받아 로컬에 저장해 놓고 볼 수도 있지만 인덱스를 일일이 클릭해가며 모르는 심볼을 찾아보는 것은 귀찮은 일이다.

보다 나은 방법은 커서가 심볼 위에 있을 때 ctrl+c ctrl+d h 를 입력하는 것이다(slime이 실행되어 있는 상태여야 한다). 그러면 해당 심볼에 해당하는 Hyperspec 웹 페이지가 뜨게 된다. 하지만 웹 페이지를 띄우는 방법은 느리고, Emacs를 벗어나야 한다는 게 불편하다. 그래서 Emacs 내에서 Hyperspec을 보는 방법을 적어보려고 한다.

Reference:
http://www.foldr.org/~michaelw/log/programming/lisp/dpans-texinfo-edition
http://www.phys.au.dk/~harder/dpans.html

1. Texinfo가 필요하다. 최신 버전을 다운로드 받아서 설치한다. 설치는 내려받은 소스의 압축을 푼 폴더에서 다음과 같이 입력하면 된다.

./configure
make
sudo make install

그런데 소스 폴더에 있는 INSTALL 파일을 읽어보면 위와 같은 일반적인 설치 과정만으로는 texinfo.tex 와 *.tex 파일들은 설치되지 않으니 추가적인 설치 명령이 필요하다고 하는데, 파일에서 말하는 TEXMF라는 게 무엇인지 모르겠다. 일단 위와 같은 일반적인 설치만으로도 목적을 달성하는 데는 별 문제가 없었으니 넘어가자.

2. dpans2texi-1.03.tar.gz를 다운 받아 압축을 푼 후 압축이 풀린 디렉토리에서 다음과 같이 입력한다.

./configure
wget ftp://parcftp.xerox.com/pub/cl/dpANS3/*
wget ftp://parcftp.xerox.com/pub/cl/dpANS3R/*
make
sudo make install

만일 wget이 없다면 설치하도록 하자. 소스 파일을 다운로드해서 압축을 푼 후 디렉토리에서 다음과 같이 입력하면 된다.

./configure
make
sudo make install

3. .emacs 파일(emacs startup file)에 다음과 같이 추가한다.

(require 'info-look)
(info-lookup-add-help
:mode 'lisp-mode
:regexp "[^][()'\" \t\n]+"
:ignore-case t
:doc-spec '(("(ansicl)Symbol Index" nil nil nil)))

이제 리습 코드의 심볼 위에 커서가 있을 때 ctrl+h S 를 입력하고 엔터를 치면 해당 심볼에 대한 레퍼런스가 바로 뜰 것이다.(글의 시작 부분에 링크한 Reference에는 ctrl+h ctrl+i 라고 써 있지만 최근 버전의 Emacs에서 키 바인딩이 바뀌면서 기존 단축키가 먹지 않는다. ctrl+h 대문자S 를 눌러야 한다.) 그리고 ctrl+h i 를 눌러서 info 페이지로 들어가면 Programming 카테고리에 ANSI Common Lisp이 생긴 것을 볼 수 있다.

다른 방법을 소개하고 있는 페이지들도 링크해본다.
http://www.newartisans.com/blog_files/hyperspec.info.for.emacs.php
http://bc.tech.coop/blog/031002.html
http://lemonodor.com/archives/2002/02/living_in_emacs.html

2008년 1월 8일 화요일

Emacs에서 정규식 테스트하기

Reference:
http://www.newartisans.com/blog_files/regex.tool.for.emacs.php

1. regex-tool.el 파일을 받는다. emacs가 위치한 디렉토리 아래의 site-lisp 디렉토리 또는 /usr/local/share/emacs/site-lisp 디렉토리에 넣으면 된다.
2. .emacs 파일(emacs 시작시에 읽어들이게 되는 설정 파일. 없으면 홈폴더에 만들면 된다.)에 다음 코드를 추가한다.
(load "regex-tool" t) ; load regex-tool if it's available
3. meta+x load-file을 입력해 regex-tool.el 파일을 수동으로 로드해준다. 한 번 그렇게 해 주고 난 뒤에는 meta+x regex-tool 을 치면 정규식 테스트가 가능한 것을 볼 수 있다.

2008년 1월 4일 금요일

맥에서 SBCL이 thread를 지원하도록 만들기

SBCL은 맥에서 experimental threading을 지원한다고 되어있지만, 그런 식으로 발표된지가 1년이 훨씬 넘었기 때문에 더 이상 experimental한 것이 아니라고 보는 사람들이 많다. 어쨋건, 맥에서 SBCL로 웹 프로그래밍을 해보려면 threading support는 필수적이기 때문에 SBCL을 어떤 식으로 인스톨해야 스레드를 지원하도록 만들 수 있는지 알아보도록 하겠다. 요점은 특정한 설정을 주고 소스를 직접 컴파일해야 되는데, 컴파일하려면 리습 구현이 필요하기 때문에 일단 바이너리 버전의 SBCL을 설치한 다음, 소스코드를 컴파일해서 바이너리를 만들고 그 바이너리로 인스톨하면 된다. 구체적인 설치 과정은 다음과 같다.

1. 바이너리 버전의 SBCL을 다운받아 인스톨한다.
바이너리 파일을 다운받아 압축을 푼 폴더에서 sudo sh install.sh

2. SBCL의 소스 코드를 내려받아 압축을 푼다.
예를 들어 압축을 푼 폴더가 /Users/chanwoo/Downloads/sbcl-1.0.13 라고 하자.

3. 내려받은 소스 코드 디렉토리의 최상단(/Users/chanwoo/Downloads/sbcl-1.0.13 폴더)에 customize-target-features.lisp 파일을 다음과 같은 내용으로 만들어 저장한다.

(lambda (features)
(flet ((enable (x)
(pushnew x features))
(disable (x)
(setf features (remove x features))))
;; Threading support, available only on x86/x86-64 Linux, x86 Solaris
;; and x86 Mac OS X (experimental).
(enable :sb-thread)))

4. 소스를 컴파일한다.
sudo sh make.sh

5. 기존에 설치된 SBCL을 지운다.
/usr/local/bin/sbcl 과 /usr/local/lib/sbcl 을 삭제

6. 소스 디렉토리(/Users/chanwoo/Downloads/sbcl-1.0.13)에서 바이너리 파일을 인스톨하듯이 인스톨하면 된다.
sudo sh install.sh

Hunchentoot를 돌려보면 스레드를 지원하는 것을 볼 수 있다! :)

2008년 1월 2일 수요일

ASDF (Another System Definition Facility)

커먼 리습 프로그래밍을 하다보면 홈 폴더가 아닌 다른 폴더에 저장된 .lisp 파일을 로드해 올 수는 없을까 하는 의문이 생기게 된다. load가 파일을 읽어들여오는 path 설정은 도대체 어디서 하는거지? 라고 고민할 수 있다. 결론적으로 말하면 load는 파일을 로드하기 위해서 복수의 디렉토리를 살펴볼 능력이 없다. 하지만 방법이 없는 것은 아니다. asdf를 사용하면 원하는 일을 할 수 있다. SBCL이나 OpenMCL 같은 경우에는 asdf가 기본적으로 포함되어 있기 때문에 별도의 설치가 필요 없다. asdf를 사용할 때 다음과 같이 해주기만 하면 된다.

(require 'asdf)

asdf는 사실 프로그램이 복수의 파일들로 나뉘어서 짜여질 때 파일들 사이의 의존관계를 지켜가며 컴파일하도록 도와주는 C의 make와 비슷한 것이라 보면 된다. 이러한 의존관계는 .asd 파일로 만들어진다. 다음 cow.asd 파일의 예를 보면 tail.lisp 파일은 legs.lisp 파일에 의존적이다.

;;;; -*- Mode: Lisp; Syntax: ANSI-Common-Lisp; Base: 10 -*-

(defpackage #:cow-asd
(:use :cl :asdf))

(in-package :cow-asd)

(defsystem cow
:name "cow"
:version "0.0.0"
:maintainer "T. God"
:author "Desmon Table"
:licence "BSD sans advertising clause (see file COPYING for details)"
:description "Cow"
:long-description "Lisp implementation of our favorite ruminant"
:components ((:file "tail"
:depends-on ("package" "legs"))
(:file "legs"
:depends-on ("package"))
(:file "head"
:depends-on ("package"))
(:file "package")))

cow.asd 및 tail.lisp, legs.lisp 등의 파일이 ~/work/cow 폴더에 저장되어 있다고 하자. 그러면 이 시스템을 사용하기 위해서는 자신이 사용하는 리습의 스타트업 파일(홈폴더 아래에 만들면 되며 SBCL은 .sbclrc OpenMCL은 openmcl-init.lisp)에 다음과 같이 추가하면 된다.

(require 'asdf)
(push #p"~/work/cow" asdf:*central-registry*)

이렇게 추가한 뒤에는 SBCL에서는 그저 (require 'cow)라고 하는 것만으로 파일들이 차례대로 로드된다. 다른 리습 구현에서는 (asdf:operate 'asdf:load-op 'cow)라고 해야 하지만.

따라서 asdf를 이용하게 되면 홈 폴더가 아닌 곳에 리습 파일을 놓고 로드할 수가 있다. 리습 파일을 원하는 폴더에 위치시키고 그 폴더를 asdf:*central-registry*에 등록시킨 다음, 폴더 안에 있는 .lisp 파일들을 어떤 식으로 로드할 것인지를 .asd 파일로 만들어 역시 같은 폴더 안에 위치시키면 된다. 만일 로드하고자 하는 리습 파일이 lisp-unit.lisp파일 하나뿐이라면 lisp-unit.asd 파일은 다음과 같은 것으로 충분할 것이다.

(defpackage #:lisp-unit-asd
(:use :cl :asdf))

(in-package :lisp-unit-asd)

(defsystem lisp-unit
:name "lisp-unit"
:components ((:file "lisp-unit")))

아무튼, 여기서 다 설명할 수는 없지만, asdf는 현재 Common Lisp에서 시스템을 구성하는 일반적인 방법이다. 그리고 asdf-install은 Common Lisp 라이브러리를 설치하는데 가장 널리 사용되는 도구다. 둘 다 Common Lisp의 교과서들을 끝내고 실제 세상으로 나갈 때 반드시 사용하게 되는 도구라고 할 수 있다.

2008년 1월 1일 화요일

Common Lisp Testing Framework

어떤 프로그래밍 언어를 사용해서 프로그램을 하든 테스팅 프레임워크와 프로파일러는 필요하다. 커먼 리습의 테스팅 프레임워크들을 잘 정리해놓은 글이 있어 링크해본다. Common Lisp Testing Framework

lisp-unit은 사용법이 아주 간단할 뿐더러 문서화도 잘 되어 있다. 하지만 테스트를 조직화 할 수 있는 방법이 마땅치 않아서 간단한 테스트만을 필요로 할 때 적합하다고 한다. FiveAMStefil은 좀 더 스케일이 크고 조직화된 테스트에 적합하다고 한다.

1. lisp-unit 설치

lisp-unit은 원래 파일 하나로 배포되었지만, 2007년 1월 11일자로 asdf-install 가능하게 바뀌었다. 설치하려면 슬라임에서 다음과 같이 한다.

(require 'asdf-install)
(asdf-install:install 'lisp-unit)

2. FiveAM과 Stefil 설치

FiveAM과 Stefil을 설치하기 전에 해야 할 것이 두 가지 있다.

1. 다음과 같이 최신의 slime을 받아서 사용하는 것이 좋다.

cvs -d :pserver:anonymous:anonymous@common-lisp.net:/project/slime/cvsroot co slime

slime-2.0을 사용하면 컴파일이 제대로 되지 않는다.

2. slime이 위치한 디렉토리를 asdf:*central-registry*에 추가한다.
추가하지 않고 컴파일하면, FiveAM과 Stefil 둘 다 swank라는 것을 요구하는 것을 볼 수 있다. swank는 slime의 다른 이름이다. 리습구현의 스타트업 파일에(SBCL의 경우에는 홈 폴더의 .sbclrc 파일) 다음과 같이 slime이 위치한 디렉토리를 추가해주면 된다.

(push #p"/Users/chanwoo/cl-library/slime/" asdf:*central-registry*)

이제 준비가 되었으면 두 테스팅 프레임워크를 설치해보자.

1. FiveAM 설치
FiveAM은 asdf로 설치 가능하다. 다음과 같이 하면 설치 끝.

(require 'asdf-install) ;GPG체크 때문에 디버거로 떨어지면 0번을 눌러서 진행하면 된다.
(asdf:install-install 'fiveam)

2. Stefil 설치
먼저 iterate, alexandria, defclass-star를 설치해야 한다.
(require 'asdf-install)
(asdf-install:install 'iterate)
(asdf-install:install 'alexandria)

defclass-star는 다음과 같이 darcs로 내려받은 후,
darcs get http://common-lisp.net/project/defclass-star/darcs/defclass-star
폴더를 asdf:*central-registry*에 추가하면 설치 끝이다.

세 가지를 다 설치했다면, 이제 Stefil을 다음과 같이 내려받은 후,

darcs get http://common-lisp.net/project/stefil/darcs/stefil

해당 디렉토리를 asdf:*central-registry*에 추가하면 설치 끝.

설치가 끝나고 FiveAM이나 Stefil을 사용하려면 SBCL에서는 단순히,
(require 'fiveam) 또는 (require 'stefil) 로 충분하다.
SBCL외의 다른 구현을 사용한다면,
(asdf:operate 'asdf:load-op 'fiveam) 또는 (asdf:operate 'asdf:load-op 'stefil) 라고 하면 된다.