Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's the meaning of "#+" in the code of cl-mysql? [duplicate]

Recently I tried to read code about cl-mysql, but got stuck with the #+.

Tried to google it, but not work, so turn to 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 looks like it is for different backend lisp compiler. But still no idea why write something like this. Anyone can help me make it clear, thx.

like image 300
c0rehe110 Avatar asked May 03 '16 07:05

c0rehe110


People also ask

What's the meaning of UwU?

Uwu is an emoticon depicting a cute face. It is used to express various warm, happy, or affectionate feelings. A closely related emoticon is owo, which can more specifically show surprise and excitement. There are many variations of uwu and owo, including and OwO, UwU, and OwU, among others.

What's the meaning of 3?

1 : a number that is one more than 2 — see Table of Numbers. 2 : the third in a set or series the three of hearts. 3a : something having three units or members. b : three-pointer. Other Words from three More Example Sentences Phrases Containing three Learn More About three.

Whats a means of?

: a way to pay for the things that one needs to live : source of income.

What is the meaning of 2?

1 : being one more than one in number. 2 : being the second —used postpositively section two of the instructions. two. pronoun. plural in construction.


2 Answers

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

There are some things that aren't part of the Common Lisp standard, but are important enough that all (or most) implementations provide a non-standard extension for them. When you want to use them in code that needs to work on multiple implementations, you have to use read-time conditionals to provide the correct code for the current implementation. Mutexes (and threads in general) are one of those things.

Of course there may be features provided by third party libraries as well. 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 wanted to write code that depends on Quicklisp for example, you could use #+quicklisp. If you wanted code that is only run if Quicklisp is not available, you'd use #-quicklisp.

You can also use a boolean expression of features. For example,

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

would print Foo! on either SBCL or ECL.

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

would only print Bar! on SBCL that has Quicklisp available.

like image 109
jkiiski Avatar answered Sep 23 '22 16:09

jkiiski


One could 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 that does usually not work, because we can't read symbols when their package is not existing and some packages are implementation/library/application specific. Packages are not created at read time in a lazy/automatic fashion.

In Common Lisp, reading a symbol of a package, which does not exist, leads to 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 symbol which makes sense in SBCL, but not in Allegro CL. Additionally the package SB-THREAD does not exist in Allegro CL. Thus Allegro CL needs to be protected from reading it. In this case, the symbol sb-thread:make-mutex will only be read, if the the feature sb-thread is present on the cl:*features* list. Which is likely only for SBCL, or a Lisp which claims to have sb-threads available.

The feature expressions here prevents the Lisp from trying to read symbols with unknown packages - the packages are unknown, because the respective software is not loaded or not available.

like image 20
Rainer Joswig Avatar answered Sep 20 '22 16:09

Rainer Joswig