find-symbol
(find-symbol string [package])
intern と似ていますが新しく作りません。package(省略時はカレントパッケージ)がその名前でアクセス可能にしているシンボルを返し、なければ nil を返します。アクセス可能とは、パッケージに存在するシンボル(intern・export・import・shadowing-import・shadow がメンバーテーブルに記録したもの、あるいはそのパッケージの下で行われた定義 -- defun はインターンです)、use しているパッケージから継承したシンボル(そのパッケージのエクスポート)、cl を通じて届く標準名、キーワードのいずれかです。ソース中でそのパッケージの下に読まれただけのシンボルは記録されず、unintern が取り除いた名前はもはやパッケージ自身のものではありません。パッケージを指さない指定子(nil を含む)は、Common Lisp と同じく package-error-package が指定子である package-error を通知します -- オプションのシステムを調べるときは先に find-package で確かめます。
Common Lisp との差異: コンパイルバックエンド(JVM/WASM)で読み込み/コンパイル時パッケージについて nil を返せるのはリテラル文字列のときだけです -- 判定はコンパイル時の視界(cl シンボルとプログラム自身の defun)に対して畳み込まれるため、実行時に定義された変数やマクロはそこからは見えません(インタプリタはグローバル変数や defmacro マクロを含む生きたイメージを調べます)。計算された名前は代わりに intern されるので常にシンボルが返り、そのステータスもイメージではなく生成された綴り(修飾付きなら :external、修飾なしなら :internal)から決まります。パッケージ自身が記録しているもの、および他のパッケージから届くものは、リテラルでも計算された値でもインタプリタと同じ答えになります: インポートしたシンボル(:import-from、再エクスポート)、:use で継承したシンボル(use しているパッケージのシンボル、:inherited)、defpackage が記録したメンバー(:shadow、:intern)です。パッケージが cl を通じて届く標準名も、名前やパッケージがリテラルでも計算された値でも cl のシンボル(:inherited)を返します: そうした探索を持つプログラムは標準名の表を持ちます。生成された答えのままになるのは 2 つの場合です: 計算された指定子が事前登録のシムパッケージ(uiop、bordeaux-threads、closer-common-lisp)を指すときは PKG:NAME を作り、1 引数形式で計算された標準名のステータスは、多値フォームがその場で読むか、プログラムが別の理由で表を持つかしない限り :internal のままです。プログラムが make-package で作ったパッケージは例外で、そのメンバーテーブルはすべてのバックエンドで参照されるため、引数が何であれ intern 前は nil、後はそのシンボル、が成り立ちます。関数オブジェクト #'find-symbol も同じ 2 つの値を返します。コンパイルバックエンドではその引数は計算された値として扱われます。
パッケージに common-lisp(または cl)を渡した場合、答えは標準の名前一覧になります。CLHS 11.1.2.1 によりこのパッケージは 978 個の標準名すべてをエクスポートするので、rontolisp がその演算子を実装しているかどうかに関わらず名前は見つかります。エクスポートされていることと定義されていることは別の話です -- そうした名前に対して fboundp・macro-function・special-operator-p は依然として nil を返し、呼び出せば undefined-function が通知され、プログラム側で defun することもできます。cl を use するパッケージはそれらの名前を同じように継承し(:inherited)、t と nil はそれ自身として返ります。
第 2 の値はそのパッケージにおける ANSI のアクセス可能性ステータス — :external、:inherited、:internal、あるいはパッケージがその名前を提供しないときは nil — を返します。2 つの値は同時に nil になります: