What does "# +" mean in cl-mysql code?

I recently tried to read cl-mysql code, but stuck with #+ .

I tried to do this, but it doesn’t work, so go here

 (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)) 

And it looks like this is for another backend lisp compiler. But I still don’t know why to write something like that. Anyone can help me make this clear, thanks.

+5
source share
2 answers

#+ is a reader macro that checks if the keyword is in the special *FEATURES* variable. If it is not there, the next form will be skipped (by the reader, the compiler will never see it). There is also #- which does the opposite.

There are some things that are not part of the standard Lisp standard, but important enough that all (or most) implementations provide a custom extension for them. If you want to use them in code that should work with multiple implementations, you need to use conditional expressions to read to provide the correct code for the current implementation. Mutexes (and themes in general) are one of those things.

Of course, there may be functions of third-party libraries. The contents of *FEATURES* will look something like this:

 (: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) 

So, if you want to write code that depends on Quicklisp, for example, you can use #+quicklisp . If you need code that runs only if Quicklisp is not available, you should use #-quicklisp .

You can also use a logical expression of functions. For instance,

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

will print Foo! on SBCL or ECL.

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

only Bar! will print Bar! on SBCL, which has Quicklisp.

+9
source

You can imagine that we can write:

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

But this usually does not work, because we cannot read characters when their package does not exist, and some packages are an implementation of / library / application. Packages are not created while reading in a lazy / automatic way.

In Common Lisp, reading a package symbol that does not exist results in an error:

 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. 

In your example, sb-thread:make-mutex is a character that makes sense in SBCL, but not in Allegro CL. In addition, the SB-THREAD package does not exist in Allegro CL. Therefore, Allegro CL needs to be protected from reading it. In this case, the sb-thread:make-mutex character will only be read if the SB-THREAD function is present in the cl:*features* list. Most likely only for SBCL or Lisp, which claims to have sb-threads .

Function expressions here prevent Lisp from trying to read characters with unknown packages - packages are unknown because the corresponding software is not loaded or is not available.

+4
source

All Articles