Shammer's Philosophy

My private adversaria

わかっているようでわかっていないかもしれないパッケージ

背景

Lisp のパッケージで苦戦というか、ハマってしまった。理解が不十分なのかもしれないが、defpackage の use で common-lisp-user や common-lisp を定義しているのに、独自に用意した某関数を別パッケージからうまく呼出しできない状態に。原因はわかったが、ちょっと意外だったので内容をメモ。

準備

まず、以下のような関数を用意。

(defun hello (name)
  (format t "Hello, ~A~%" name))

という内容で、myfunc.lisp を定義。これを、Clozure CL の初期化ファイル($HOME/.ccl-init.lisp)にロードするように書いておく。

myfunc.lisp を別パッケージから呼び出す

呼び出す側のファイルは main.lisp とする。内容は以下のような感じ。

(defpackage "TEST"
  (:use "COMMON-LISP" "CCL" "COMMON-LISP-USER"))

(in-package test)

(defun aaa (name)
  (hello name))

(aaa "Taro")

結果

以下のようにエラーになる。

$ ccl64 -l main.lisp
> Error: Undefined function HELLO called with arguments ("Taro") .
> While executing: AAA, in process listener(1).
> Type :GO to continue, :POP to abort, :R for a list of available restarts.
> If continued: Retry applying HELLO to ("Taro").
> Type :? for other options.
1 >

まったくわけがわからなかった。defpackage の use で "COMMON-LISP-USER" や "COMMON-LISP" を指定しているのに hello にアクセスできないとはどういうことかと。

原因

myfunc.lisp で export していないのが原因だった。COMMON-LISP-USER パッケージにあるとしても、export していないとアクセスできない。myfunc.lisp を以下のようにすることで解決する。

(defun hello (name)
  (format t "Hello, ~A~%" name))

(export 'hello)

うーむ、、、なんか、前も同じことをやったかもしれない。何度やれば身になるのだろうか。。。