標準の共通-lisp関数/マクロを使ってパッケージから現在のパッケージにいくつかの関数を一時的にインポートする方法はありますか?Common Lisp:パッケージからいくつかの関数を一時的にインポートするための最良の方法
私は1つを見つけることができず、自分自身をロールバックしなければならなかった。標準が既にそのような機能を提供しているならば、何かをコード化する必要はなく、別の言語構造を導入する必要はありません。
(defmacro with-functions (functions the-package &body body)
"Allows functions in the-package to be visible only for body.
Does this by creating local lexical function bindings that redirect calls
to functions defined in the-package"
`(labels
,(mapcar (lambda (x) `(,x (&rest args)
(apply (find-symbol ,(format nil "~:@(~a~)" x)
,the-package)
args)))
functions)
,@body))
使用例:
(defclass-default test-class()
((a 5 "doc")
(b 4 "doc")))
#<STANDARD-CLASS TEST-CLASS>
CL-USER>
(with-functions (class-direct-slots slot-definition-name) 'sb-mop
(with-functions (slot-definition-initform) 'sb-mop
(slot-definition-initform
(car (class-direct-slots (find-class 'test-class))))))
5
CL-USER>
EDITは:マクロにライナーの提案の一部を組み込みました。
私は、パッケージ内の関数を見つけるために、実行時のルックアップの時間コストで、実行時のルックアップ機能を維持することを決めました。
私はシャドウイングインポートおよびuninternを使用して、インポートマクロを書き込もうとしましたが、私はそれが仕事を得ることができませんでした。私は読者に、関数をインポートしたコードが評価される前に、インポートされた関数が(読み込み時に)まだ存在していないと言う問題がありました。
シャドウイングとアンインンターンで動作させる方が良い方法だと思います。これははるかにクリーンで速く(実行時ルックアップ機能はありません)、パッケージ内の関数とシンボルで動作します。
誰かがuninternとshadowing-importを使ってimport-withマクロをコード化できるかどうかを知りたいと思うでしょう。
このAPPLYは記号を名前として使用して呼び出すことができないため、字句関数では機能しません。 –
マクロを展開する前にシンボルが読者によって解決されているので、これはマクロでは可能ではないと思いますが、私は間違っているかもしれません。 – Daimrod
@Daimrodこのようなマクロを構築することは可能ですが、初期のシンボル解決戦略に起因する名前の競合を処理する必要があるため、非常に扱いにくい(おそらく、移植性がない)場合があります。 –