Let over Lambda 书中的 sortf 中的 'a1' 绑定在哪里?

Where is 'a1' bound in sortf from the book Let over Lambda?

Doug Hoyte 的书 "Let over Lambda" 通过 sorting networks 描述了固定大小输入的快速排序功能:

(defmacro! sortf (comperator &rest places)
  (if places
    `(tagbody
      ,@(mapcar
        #`(let ((,g!a #1=,(nth (car a1) places))
                (,g!b #2=,(nth (cadr a1) places)))
            (if (,comperator ,g!b ,g!a)
              (setf #1# ,g!b
                    #2# ,g!a)))
        (build-batcher-sn (length places))))))

表达式'(car a1)'和'(cadr a1)'中的符号'a1'从何而来?

顺便说一句。 'defmacro!' 是一个定义宏的宏,它引入了 'g!{symbol}' 语法来通过 'gensym' 创建一个新的符号。 'build-batcher-sn' 构建一个 sorting network using Batcher's algorithm.

我觉得很奇怪,还有mapcar只会带一个函数而let不合格。因此必须有别的东西,令人惊讶的是 #` 是一个 reader-macro,它围绕以下表达式创建一个函数:

'#`(list a b c) 
; ==> (lambda (a1) `(list a b c))

请注意,我引用了它,因为它是一个读取宏,它仍然会扩展,但结果会被引用。所以 a1 来自 reader 宏。这是它的定义和激活:

(defun |#`-reader| (stream sub-char numarg)
  (declare (ignore sub-char))
  (unless numarg (setq numarg 1))
  `(lambda ,(loop for i from 1 to numarg
                  collect (symb 'a i))
     ,(funcall
        (get-macro-character #\`) stream nil)))

(set-dispatch-macro-character
  #\# #\` #'|#`-reader|)

有问题的代码:

'#`(let ((,g!a #1=,(nth (car a1) places))
                (,g!b #2=,(nth (cadr a1) places)))
            (if (,comperator ,g!b ,g!a)
              (setf #1# ,g!b
                    #2# ,g!a)))
; ==>
(lambda (a1)
 `(let ((,g!a ,(nth (car a1) places)) 
        (,g!b ,(nth (cadr a1) places)))
   (if (,comperator ,g!b ,g!a) 
       (setf ,(nth (car a1) places) ,g!b ,(nth (cadr a1) places) ,g!a))))

要使用更多参数,请在前面添加数字:

'#2`(list ,a1 ,a2)
; ==> (lambda (a1 a2) `(list ,a1 ,a2))