Common Lispの関数やマクロと対応する機能を持つSchemeの手続きや構文を表にまとめる.
随時更新.
| Common Lisp |
Scheme |
備考 |
| atom |
なし |
(not (pair? obj))を使う |
| consp |
pair? |
|
| dolist |
for-each |
記法は異なる |
| mapcan |
append-map! |
SRFI 1 |
| mapcar |
map |
|
| multiple-value-bind |
receive |
SRFI 8, library syntax |
| null |
null? |
|
| nth |
list-ref |
|
| nthcdr |
list-tail |
SRFI 1ではdrop |
| progn |
begin |
|
| rplaca |
set-car! |
|
| rplacd |
set-cdr! |
|
| setq |
set! |
|
Common Lisp では
1
2
| CL-USER> (let (a b c) c)
NIL |
のように let で束縛する値を省略できる.
省略された変数は nil に束縛される.
しかし,Scheme にはそのような省略記法はない.
そこで,マクロを使い Common Lisp のような略記法を導入する.
次のように書く.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
| (define-syntax old-let let)
(define-syntax %let
(syntax-rules ()
((_ (te ...) () body ...)
(old-let (te ...)
body ...))
((_ (te ...) ((id e) be ...) body ...)
(%let (te ... (id e)) (be ...) body ...))
((_ (te ...) (id be ...) body ...)
(%let (te ... (id '())) (be ...) body ...))))
(define-syntax let
(syntax-rules ()
((_ e1 e2 ...)
(%let () e1 e2 ...)))) |
Common Lisp と同様に束縛する値を省略した変数は空リストに束縛されるようにしている.
cl-indent.el を導入すると特別な字下げをする形式や関数を簡単に追加できる。
site-lisp などの path の通った場所に cl-indent.el を置き,.emacs に
(require 'cl-indent)
(setq lisp-indent-function (function common-lisp-indent-function))
と書くと導入できる。
字下げする形式を追加するには define-cl-indent 関数を使う。
例えば, sunless を追加するには .emacs 内に,
(define-cl-indent '(sunless . unless))
のように書く。
(x . y) と書くと x が y の別名になるよう。
cl-indent.el 内には (unless 1) と書いてある。
これは unless 内は1 字下げという意味らしい。
よって,次のようにも書ける。
(define-cl-indent '(sunless 1))
Windows 版 Allegro Common Lisp で SLIME から使う場合など IDE を起動したくない場合は, IDE を起動しないイメージファイルを用意する。
イメージファイルは build-lisp-image 関数で作成する。トップレベルから,
CG-USER(1): (require :build)
NIL
CG-USER(2): (build-lisp-image "no-ide.dxl" :include-ide nil :restart-init-function nil)
done.
T
とすると no-ide.dxl という名前のイメージファイルが作成される。 :restart-init-function パラメータには起動時に初期化のために呼び出す関数名を指定する。 これに, cg:start-ide が指定されていたので, IDE が起動していた。 よって, nil を指定して IDE を起動しないようにする。ついでに, :include-ide を nil にして ide 機能を読み込まないようにしておく。
SLIME 側からは -I オプションで作成したイメージファイル no-ide.dxl を指定して起動する。
> allegro-express.exe -I no-ide.dxl
参考:
Building Images – Allegro CL version 7.0 documentation
シンボルに対応する関数が定義されているかは fboundp 関数で調べる。
CL-USER> (defun foo (x y) (+ x y))
FOO
CL-USER> (fboundp 'foo)
T
CL-USER> (fboundp 'bar)
NIL
intern は印字名に対応するシンボルを得る関数。
逆に、シンボルの印字名を得るには symbol-name 関数を用いる。
下の concat-symbol は「2つのシンボルの各印字名を連結した印字名をもつシンボル」を返す関数。
(defun concat-symbol (x y)
(intern (concatenate 'string (symbol-name x) (symbol-name y))))
CL-USER> (concat-symbol 'x 'y)
XY
NIL
毎回忘れて再発明しそうになるが、Common Lisp にはリストを複製する関数 copy-tree がある。
CL-USER> (let ((lst '(a b c)))
(eq lst (copy-tree lst)))
NIL
Common Lisp ではコマンドライン引数を取得する方法は処理系依存らしい。
Steel Bank Common Lisp (SBCL) の場合は *posix-argv* に文字列のリストの形で代入されている。
Allegro Common Lisp (ACL) の場合は system パッケージの command-line-arguments 関数で取得できる。
『KMRCLを眺める(184) COMMAND-LINE-ARGUMENTS』
によると、(apropos ‘argv) として ‘argv で関数の説明文を検索すれば処理系毎の方法が見つかることが多いとのこと。
最近のコメント