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