CommonLisp 학습을 위한 책
책/OnLisp: 1993, PaulGraham, Prentice Hall
책/PracticalCommonLisp: 2005, PeterSeibel, Apress
책/LandOfLisp: 2010, ConradBarski, No Starch Press: 번역서 중고
책/CommonLispRecipes: 2016, Edmund Weitz, Apress
CL-USER> (ql:quickload :cl-project) CL-USER> (cl-project:make-project #p"~/myproject" :author "Jeongsoo Park" :email "toracle@gmail.com") CL-USER> (ql:quickload :myproject) CL-USER> (push #p"/home/toracle/myproject/" asdf:*central-registry*) CL-USER> (ql:quickload :myproject) CL-USER> (asdf:test-system :myproject)
Roswell을 사용하면 환경을 통합적으로 구축할 수 있다.
roswell 설치
- ros install sbcl-bin
- ros install quicklisp
- ros install slime (실행 마치고 출력으로 나오는 helper.el을 emacs init에 추가해준다)
Windows에서는 sbcl 버전이 낮은데, roswell에서 기본적으로 sbcl을 사용한다.
Lisp for the Web 책에서 추천한 책들
PracticalCommonLisp 이 시작하기에는 제일 좋은 책이다.
언어의 기본적인 내용을 익혔다면, 그 다음에는 PAIP를 읽으면 좋다. 특히 좋은 코딩 스타일을 익히는데는 더할나위 없이 좋다.
함수형 스타일을 익히려면 LittleSchemer 를 읽어라. 이 책은 어떤 특정한 언어나 문법에 대한 책이 아니다. 특히 책이 쓰여진 방식 - 소크라테스식 대화 방식이 독특하고, 교육 방식을 살펴보는 측면으로도 좋은 책이다.
- 읽어보니 진짜 특이하다. 처음부터 끝까지 짧은 문답식으로 이루어져 있다.
견고한 함수형 마인드셋을 익히려면 OCaml을 참고해보면 좋다. Ocaml from the Very Beginning by John Whitington은 좋은 책이다.
이 이후에, 더 중무장하려면, OnLisp 이나 LetOverLambda 를 읽어라.
QuickLisp 설치
QuickLisp는 CL에서 널리 사용되는 패키지 관리자이다. 일단 이걸 처음에 셋팅해놓아야 다른 패키지들 설치하기가 편리하다.
우선 아래 명령으로 quicklisp 부트스트래핑 스크립트를 다운로드 받는다.
$ curl -O https://beta.quicklisp.org/quicklisp.lisp
그리고 CL REPL을 실행하고, 해당 파일을 로드한다.
CL-USER> (load "~/quicklisp.lisp")
아래 명령으로 quicklisp을 설치한다.
CL-USER> (quicklisp-quickstart:install)
설치가 진행되고, ~/quicklisp 디렉토리가 생성된다.
아래 명령을 실행하여 quicklisp이 매 세션마다 자동적으로 로딩되도록 한다.
CL-USER> (ql:add-to-init-file)
Optimization
(declaim (optimize (speed 3) (safety 0) (debug 0)))
자주 쓰는 명령어
Land of Lisp에서 나온 명령
- (ash number shift-digits)
- 숫자를 bit만큼 shift.
- (1- number)
- 숫자를 1 감소하여 반환.
- (1+ number)
- 숫자를 1 증가하여 반환.
- (flet ...)
- let과 비슷하나 변수 대신 함수를 정의하는 용도.
- (labels ...)
- flet과 비슷하나, 내부에서 정의된 함수끼리 서로 호출할 수 있음. let과 let*의 차이와 비슷함.
- (princ str)
- 화면에 출력. 사용자 친화적으로 출력.
- (oddp number)
- 홀수인지 여부를 반환.
- (cond ...)
- 조건 분기의 일반화된 form.
- (case ...)
- 조건 대신 값을 기준으로 분기하는 form.
- (eq a b)
- symbol의 경우 동등성 비교에 사용.
- (equal a b)
- symbol 이외의 모든 경우 동등성 비교에 사용.
- (assoc key alst)
- alist에서 key에 해당하는 entry를 추출.
- (mapcar func lst)
- list 각 원소에 대해 func를 적용하고 그 결과를 list로 이어붙여 반환.
- (apply func args)
- args와 함께 func를 호출.
- (append args)
- args들을 이어붙여 하나의 list로 반환.
- (remove-if-not func lst)
- list의 각 원소 중, func가 nil인 원소만 제외하고 반환.
- (find key lst :key func)
- list에서 key를 찾아 반환. 각 원소에서 key를 찾는 방법을 지정할 수 있음.
- (member elem lst)
- elem이 lst에 속하는지 여부를 반환.
- (push elem lst)
- lst의 맨 앞에 elem을 추가하여 반환.
- (progn stmts)
- 여러 stmt들을 수행함.
- (print str)
- 화면에 출력. 개행을 덧붙임.
- (prin1 str)
- 화면에 출력하되 개행을 생략.
- (read)
- 입력값을 받음.
- (eval stmt)
- 구문을 평가하여 실행.
- (loop stmt)
- 구문을 반복하여 실행.
- (unless cond stmt)
- 조건이 참이 아닌 경우에만 실행
- (read-from-string str)
- 문자열로부터 입력값을 받음.
- (concatenate 'string args)
- args를 문자열로 간주하여 이어붙여 반환.
- (read-line)
- 한 행의 입력값을 받음.
- (if cond true-stmt false-stmt)
- if 구문
- (coerce str 'list)
- 문자열을 문자들의 list로 쪼개어 반환.
- (coerce lst 'string)
- 문자들의 list를 문자열로 붙여 반환.
- (substitute-if replace-val func lst)
- lst에서 func이 true일 때 해당 원소를 replace-val로 변경하여 반환.
- (complement func)
- ...
- (mapc func lst)
- lst의 각 원소에 대해 func를 실행. mapcar와는 달리 아무 값도 반환하지 않는다.
- (with-open-file (stream-name filename :direction :output :if-exists :supersede) stmt)
- 파일 스트림을 연다.
- thunk
- 인자가 0개인, 즉시 실행할 수 있는 상태의 함수
- *standard-output*
- 표준 출력 스트림
- (funcall func)
- func를 실행
- (ext:shell str)
- 쉘에서 str을 실행
- (maplist func lst)
- lst에서 원소 하나씩 뒤로 가면서 func에 인자로 전달. (A B C) (B C) (C)
- (random num)
- num 이하의 난수를 발생
- (loop repeat num collect val)
- num 횟수만큼 반복하면서 각 val을 원소로 하는 list를 반환.
- (loop for n from from-num to to-num collect val)
- from-num부터 to-num까지 각 값을 n에 할당하며 반복하면서 각 val을 원소로 하는 list를 반환.
- (remove-duplicates lst)
- 중복 원소를 제거하여 반환.
- (mapcan func lst)
- mapcar와 같지만, 각 결과값을 flatten하여 append한 결과를 반환.
- (pushnew elem lst)
- lst의 맨 앞에 elem을 추가. inplace 함수.
- (make-array num)
- num 크기의 배열을 생성.
- (aref arr pos)
- 배열 arr에서 pos 위치의 원소를 반환.
- (make-hash-table)
- 해시 테이블을 생성하여 반환.
- (gethash key hsh)
- hsh 해시 테이블에서 key에 해당하는 값을 반환.
- (values args)
- args를 하나의 값으로 합쳐서 반환. 별다른 조치를 하지 않으면 가장 앞의 값을 기본값으로 사용.
- (multiple-value-bind (var1 var2 ...) val stmt)
- multiple value인 val을 var1, var2로 분해하고 stmt를 실행.
- (setf var value)
- var에 value를 저장.
- (dotimes (var value) stmt)
- 반복 회차 값을 var에 할당하면서 value 만큼 stmt를 반복.
- (defstruct typename args)
- typename을 이름으로 하는 구조체를 선언.
- (make-typename)
- typename 구조체 인스턴스를 생성.
- (length obj)
- obj의 길이를 반환. obj는 리스트, 문자열, 배열 등이 올 수 있음.
- (find-if func lst)
- lst에서 func를 만족시키는 첫번째 원소를 반환.
- (count v lst)
- lst에서 v와 같은 원소의 갯수를 반환.
- (position v lst)
- lst에서 v가 처음 등장하는 위치를 반환.
- (some func lst)
- lst에서 func를 만족하는 원소가 있는지 여부를 반환.
- (every func lst)
- lst에서 모든 원소가 func를 만족하는지 여부를 반환.
- (reduce func lst)
- lst를 순회하면서, lst의 각 원소를 func에 대입하여 실행한 값을 반환.
- (reduce func lst :initial-value v)
- lst를 순회하면서, lst의 각 원소를 func에 대입하여 실행한 값을 반환하되, 처음을 v로 시작.
- (map type func lst)
- lst에서 각 원소에 대해 func를 실행하고, 그 값을 이어붙여 type 형태로 반환.
- (subseq lst start end)
- lst에서 start부터 end 사이의 값만 슬라이싱하여 반환.
- (sort lst cmp)
- lst를 cmp 함수에 따라 정렬한 값을 반환.
- (numberp v)
- v가 숫자인지 여부를 반환.
- (defmethod funcname ((v type) ...) stmt)
- funcname을 이름으로 하는 메소드를 정의.
- (integerp v)
- v가 정수인지 여부를 반환.
- (type-of obj)
- obj의 타입을 반환.
- (incf var val)
- var에서 val만큼을 더한 값을 inplace로 대치.
- (decf var val)
- var에서 val만큼을 뺀 값을 inplace로 대치.
- (defstruct (typename (:include typename2)) args)
- typename2를 상속받아 typename을 선언.
- (zerop v)
- v가 0인지 여부를 반환.