2016-05-03 10 views
5

最近、私はcl-mysqlについてのコードを読もうとしましたが、#+で立ち往生しました。cl-mysqlのコードで "#+"の意味は何ですか?

はそれをグーグルが、動作しないので、ここで

(defun make-lock (name) 
    #+sb-thread (sb-thread:make-mutex :name name) 
    #+ecl (mp:make-lock :name name) 
    #+armedbear (ext:make-thread-lock) 
    #+ (and clisp mt) (mt:make-mutex :name name) 
    #+allegro (mp:make-process-lock :name name)) 

に向けるしようとしましたが、それは別のバックエンドのLispコンパイラのためであるように見えます。しかし、なぜこのようなことを書くのかはまだ分かりません。 誰でも私がそれを明確にするのを助けることができます。

+0

[Common Lisp:#+ nilとは何ですか?](http://stackoverflow.com/q/29849954/1281433)、[#+#は何ですか? lispでの平均?](http://stackoverflow.com/q/5785755/1281433)、[演算子#+と# - in .sbclrc](http://stackoverflow.com/q/8651695/1281433) –

+1

私は閉じたこれは重複しているので、それは他の質問で答えられているので、私はそれを上書きしました。これは、この構造がどのように使われているかの良い例であり、あなたが指摘したように、 (あなたは通常、それ以上検索する必要はありません)。 –

答えて

9

#+は、キーワードが特殊変数*FEATURES*にあるかどうかを確認するリーダ/マクロです。存在しない場合、次のフォームはスキップされます(読者はコンパイラには表示されません)。反対のことをする#-もあります。

Common Lisp標準には含まれていないものがいくつかありますが、すべての(またはほとんどの)実装で非標準の拡張が提供されるほど重要です。複数の実装で動作する必要があるコードでそれらを使用するには、現在の実装に正しいコードを提供するために読み取り時条件を使用する必要があります。ミューテックス(一般的にスレッド)は、これらのものの1つです。

もちろん、サードパーティのライブラリによって提供される機能もあります。あなたが例えばQuicklispに依存したコードを書きたいならば、あなたは#+quicklispを使用することができるように

(:SWANK :QUICKLISP :SB-BSD-SOCKETS-ADDRINFO :ASDF-PACKAGE-SYSTEM :ASDF3.1 
:ASDF3 :ASDF2 :ASDF :OS-UNIX :NON-BASE-CHARS-EXIST-P :ASDF-UNICODE :64-BIT 
:64-BIT-REGISTERS :ALIEN-CALLBACKS :ANSI-CL :ASH-RIGHT-VOPS 
:C-STACK-IS-CONTROL-STACK :COMMON-LISP :COMPARE-AND-SWAP-VOPS 
:COMPLEX-FLOAT-VOPS :CYCLE-COUNTER :ELF :FLOAT-EQL-VOPS 
:FP-AND-PC-STANDARD-SAVE :GENCGC :IEEE-FLOATING-POINT :INLINE-CONSTANTS 
:INTEGER-EQL-VOP :INTERLEAVED-RAW-SLOTS :LARGEFILE :LINKAGE-TABLE :LINUX 
:LITTLE-ENDIAN :MEMORY-BARRIER-VOPS :MULTIPLY-HIGH-VOPS :OS-PROVIDES-DLADDR 
:OS-PROVIDES-DLOPEN :OS-PROVIDES-GETPROTOBY-R :OS-PROVIDES-POLL 
:OS-PROVIDES-PUTWC :OS-PROVIDES-SUSECONDS-T :PACKAGE-LOCAL-NICKNAMES 
:PRECISE-ARG-COUNT-ERROR :RAW-INSTANCE-INIT-VOPS :SB-DOC :SB-EVAL :SB-FUTEX 
:SB-LDB :SB-PACKAGE-LOCKS :SB-SIMD-PACK :SB-SOURCE-LOCATIONS :SB-TEST 
:SB-THREAD :SB-UNICODE :SBCL :STACK-ALLOCATABLE-CLOSURES 
:STACK-ALLOCATABLE-FIXED-OBJECTS :STACK-ALLOCATABLE-LISTS 
:STACK-ALLOCATABLE-VECTORS :STACK-GROWS-DOWNWARD-NOT-UPWARD :SYMBOL-INFO-VOPS 
:UNIX :UNWIND-TO-FRAME-AND-CALL-VOP :X86-64) 

*FEATURES*の内容は次のようになります。 Quicklispが利用できない場合にのみ実行されるコードが必要な場合は、#-quicklispを使用します。

機能のブール式を使用することもできます。例えば、

#+(or sbcl ecl) (format t "Foo!") 

はSBCLまたはECLのいずれかにFoo!を印刷します。

#+(and sbcl quicklisp) (format t "Bar!") 

のみQuicklispが利用できていSBCLにBar!を印刷します。

(defun make-lock (name) 
    (cond ((member :sb-thread *features) 
     (sb-thread:make-mutex :name name)) 
     ((member :ecl *features*) 
     (mp:make-lock :name name)) 
    ...)) 

をしかし、我々は彼らのパッケージが存在されていないシンボルを読み取ることができませんし、いくつかのパッケージは、特定の実装/ライブラリ/アプリケーションであるため、それは通常、動作しません:

+0

あなたのコメントをありがとう、本当にありがとう – c0rehe110

4

一つは、私たちが書くことができることを想像できます。パッケージはではなく、読み込み時にレイジー/自動で作成されたです。あなたの例では

CL-USER 1 > (read-from-string "foo:bar") 

Error: Reader cannot find package FOO. 
    1 (continue) Create the FOO package. 
    2 Use another package instead of FOO. 
    3 Try finding package FOO again. 
    4 (abort) Return to level 0. 
    5 Return to top loop level 0. 

sb-thread:make-mutexはSBCLに理にかなっているシンボルですが、ないアレグロCLで:存在しないパッケージのシンボルを読んCommon Lispでは

、エラーにつながります。さらに、パッケージSB-THREADはAllegro CLには存在しません。したがって、Allegro CLはそれを読み取ることから保護する必要があります。この場合、記号sb-thread:make-mutexは、というフィーチャーがcl:*features*リストにある場合にのみ読み取られます。これはおそらくSBCL、またはsb-threadsが利用可能であると主張しているLispのためだけであろう。

ここの特徴表現は、Lispが未知のパッケージのシンボルを読み込めないようにします。パッケージは不明です。それぞれのソフトウェアがロードされていないか、利用できないためです。

関連する問題