Posted 2019-08-15 15:25:34 GMT
Common Lispのdefpackage
というかパッケージ関係の関数全般ですが、intern
やexport
するシンボルの名前の表記にstring designator
が使えるので、
(defpackage "FOO"
(:use "CL")
(:export "FOO" "BAR" "BAZ"))
とシンボル名を文字列で書かずにシンボルで書くことも可能です。
(defpackage foo
(:use cl)
(:export foo bar baz))
この場合、シンボル名が使われるので、
(defpackage #.(string 'foo)
(:use #.(string :cl))
(:export . #.(mapcar #'string '(foo #:bar baz))))
のようなことになっていると考えれば良いでしょう。
このstring designator
でのシンボルの表記に各人割とこだわりがみられるので考察してみることにしました。
"FOO"
、"BAR"
等とそのまま書く流儀です。たまに通な人がこの方式で書いてることがあります。
しかし、そんな特殊な状況のことを考えてコーディングする必要ってあるんですかね?
foo
、bar
等とそのまま書く流儀です。
一番すっきりしてて良さそうですが、案外少ないです
defpackage
したパッケージに余計なシンボルがインターンされるdefpackage
は、大抵cl-user
でされることが多いですが、cl-user
は作業用パッケージなので、多少汚染されても良いんじゃないかという気もしますね。
:foo
、:bar
等と書く流儀です。
よく見かける流儀です。
(defpackage :foo)
、(make-package :foo)
vs (defpackage #:foo)
、(make-package '#:foo)
等々キーワードパッケージが汚染されると開発環境のキーワード補完でゴミが補完されることが多くなるので、案外cl-user
が汚染されるより嫌かもしれないですね。
#:foo
、#:bar
等と書く流儀です。
これも割と見かける流儀です。
#:
がウザい見た目がウザいのでdefpackage
すれば良いでしょう。
(defpackage "FOO-META" (:use))(in-package "FOO-META")
(cl:defpackage foo
(:use cl)
(:export foo bar baz))
(cl:in-package "CL-USER")
(delete-package "FOO-META")
SBCLならこんな風に書けたりもします。
foo-meta::
(cl:defpackage foo
(:use cl)
(:export foo bar baz))
まあ、でもめんどくさいですね。
ファイルをロードする時に、暗黙のうちに*package*
をcl-user
、*readtable*
を標準のリードテーブルであると仮定しているコードは、Quicklispの大半を占めますが、それに起因するバグも思いの外多いです(Quicklispのパッケージを1000パッケージ位ロードしてみると体験できます)
作業用パッケージ(とリードテーブル)を作成して、そこでdefpackage
するのが吉なのかなあ等々考えていますが、作業用パッケージを作成するなら、余計なシンボルのインターンについても考えなくて良さそうですね。
ちなみにこの記事を書くにあたって、文字列、シンボル、キーワード、
読み取りスピード的にも普通のシンボルで書くのが有利っぽいですが、極端なことをしない限りは有意な差にはならないでしょう。
以上、特にまとまりもない記事でした。
■
HTML generated by 3bmd in LispWorks 7.0.0