#+
— это макрос чтения, который проверяет, находится ли ключевое слово в специальной переменной *FEATURES*
. Если его нет, следующая форма будет пропущена (читателем; компилятор ее никогда не увидит). Существует также #-
, который делает обратное.
Есть некоторые вещи, которые не являются частью стандарта Common Lisp, но достаточно важны, чтобы все (или большинство) реализации предоставили для них нестандартное расширение. Если вы хотите использовать их в коде, который должен работать с несколькими реализациями, вы должны использовать условные выражения времени чтения, чтобы предоставить правильный код для текущей реализации. Мьютексы (и потоки в целом) — одна из таких вещей.
Конечно, могут быть функции, предоставляемые сторонними библиотеками. Содержимое *FEATURES*
будет выглядеть примерно так:
(: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)
Поэтому, если вы хотите написать код, который зависит, например, от Quicklisp, вы можете использовать #+quicklisp
. Если вам нужен код, который запускается только в том случае, если Quicklisp недоступен, вы должны использовать #-quicklisp
.
Вы также можете использовать логическое выражение признаков. Например,
#+(or sbcl ecl) (format t "Foo!")
напечатает Foo!
либо на SBCL, либо на ECL.
#+(and sbcl quicklisp) (format t "Bar!")
будет печатать Bar!
только на SBCL, для которого доступен Quicklisp.
person
jkiiski
schedule
03.05.2016