2018年6月9日土曜日

packageってなんぞ

 とりあえず、昔、インストールしておいたSLIMEでREPLは立ち上がる。

 まず、CommonLispからDBアクセスはどうしたらよいのか。
 対象はPostgreSQL。ググったら「CommonLispとRaspberryPiでデータベース~その1~」がひっかかった。つらつら。なるほど「cl-dbi1というものがあるらしい。
 さっそく例題にしたがってやってみる。
 あっさりとデータが返ってきた2
 へえ。
 コードをながめる。

;; Quicklispで「cl-dbi」をロード
(ql:quickload :cl-dbi)

;; パッケージ定義
(defpackage psql-package
(:use :cl

:cl-dbi))

;; パッケージに入る
(in-package :psql-package)

;; データベースへ接続
(defvar connection
(dbi:connect :postgres

:database-name "test"

:username "nobody"

:password "1234"))

;; クエリを実行
(let* ((query (dbi:prepare connection "SELECT * FROM hello"))
(result (dbi:execute query)))
(loop for row = (dbi:fetch result)
while row
do (format t "~A~%" row)))

 ——packageってなんぞ?
 いや、そういうものがあるらしいということは知っていたけど、腑に落ちてはいなかった。「in-package」があるってことは「out-package」もあるのか?3
 elispにはそんなものないし。
 ここでようやく気づく。
 思ったより敷居が高いぞ、CommonLisp。
 オライリー本が必要だ。でもM.D. ConradBarsk「Land of Lisp」ぐらいしか、ないよなぁ。そういえば、ポール・グレアムの「ANSI CommonLisp」をもっていたっけ。package。package。ふむふむ。よくわからん。でもなんとなく、わかった。
 やってみたところ、packageの中にpackageをつくるようなことはできないようだった4。平面にぼこぼこと溜池があるようなイメージかな。「in-package」というより「change-package」?

 いずれにしても1ファイル1パッケージにした方がよさそうだ。

Footnotes:

1

作者は日本人でLispハッカーとして有名な人だった。

2

その直後、pg.elが動かなくなっていることに気づいてあひょひょひょ〜、となった。

3

なかった。

4
CL-USER> (defpackage abc
       (:use :cl))
#<PACKAGE "ABC">

CL-USER> (in-package :abc)
#<PACKAGE "ABC">

ABC> (defpackage def
  (:use :cl))
#<PACKAGE "DEF">

ABC> (in-package :def)
#<PACKAGE "DEF">

DEF> (defun wrk() 999)
WRK

DEF> (in-package :cl-user)
#<PACKAGE "COMMON-LISP-USER">

CL-USER> (def::wrk)
999

CL-USER> (abc::def::wrk)
; Evaluation aborted on #<SB-INT:SIMPLE-READER-ERROR "too many colons in ~S" {1005C4D243}>.
CL-USER>