为xor定义方案宏

时间:2016-08-14 17:49:31

标签: macros scheme lisp mit-scheme

请注意以下宏正在运行。

apt-get install

但是,如果我在一般情况的参数列表中省略(define-syntax xor (syntax-rules () ((xor a1 a2) (if a1 (false? a2) (true? a2))) ((xor a1 a2 a3 ...) (let ((a (xor a1 a2))) (xor a a3 ...))))) ,它似乎无法正常工作。

a3

因此,我想知道第二种情况下省略号究竟发生了什么。

Q1。这是否意味着除省略号之外的每个参数列表都应该是唯一的才能正常运行?

例如,给定输入(define-syntax xor (syntax-rules () ((xor a1 a2) (if a1 (false? a2) (true? a2))) ((xor a1 a2 ...) (let ((a (xor a1 a2))) (xor a ...))))) ,第一个将生成(xor #t #t #t),而第二个将生成#t

我使用的翻译是#f

Q2。是否有可能使其短路?

谢谢,

1 个答案:

答案 0 :(得分:1)

省略号告诉你关于第二个符号的事情。 a2 ...可以是零个或多个元素,您需要在重复的内容中使用a2才能使其正常工作。在第二个宏中,a2的结果缺少重复元素的省略号,而ellipsis之后的a不是匹配模式的一部分,也没有省略号。这两个事实都使宏无效。

第一个宏是正确的,因为您有一个匹配两个元素的术语。你的第二个术语也匹配两个术语,但是由于第一个匹配的模式是运行的,你确定你的第二个模式有两个以上的参数,因为它匹配两个a3 ...至少有一个元素。

我不确定true?的用途。略有简化:

(define-syntax xor
  (syntax-rules ()
    ((xor a1 a2)
     (if a1 (not a2) a2))
    ((xor a1 a2 a3 ...)
     (xor (xor a1 a2) a3 ...))))

(xor 1 2 3 4 5)  ; ==> 5  (odd number of true values)
(xor 1 2 3 4)    ; ==> #f (even number of true values)
(xor 1 2 3 4 #f) ; ==> #f (even number of true values)
(xor 1 #f #f #f) ; ==> #t (odd number of true values)

现在这将计算参数表达式的奇校验。因为触发器不能短路。 (xor #t #t #f #f #t) ; ==> #t因为它有一些奇怪的真实参数。关于它的作用以及它的菊花链xor逻辑,它并没有真正留下唯一的真正逻辑。既然你永远不能将它短路,你也可以使用完全相同的程序:

(define (xor . args)
  (= (remainder (count values args) 2) 1))

(xor 1 2 3 4 5)  ; ==> #t (odd number of true values)
(xor 1 2 3 4)    ; ==> #f (even number of true values)
(xor 1 2 3 4 #f) ; ==> #f (even number of true values)
(xor 1 #f #f #f) ; ==> #t (odd number of true values)

可以在SRFI-1 list library

中找到计数

xor有另一种解释,这是我读到这个问题时的第一个解释,因为它是短路工作的唯一情况。如果一个表达式为真,则为true,否则结果为false。在这里,当遇到第二个假值时,您可以短路到#f而不评估其余的参数。

(define-syntax xor
  (syntax-rules ()
    ((_) #f)
    ((_ a) a)
    ((_ a b ...)
     (if a
         (not (or b ...))
         (xor b ...)))))

(xor 1 2 3 4 5)  ; ==> #f (more than one true value)
(xor 1 2 3 4)    ; ==> #f (more than one true value)
(xor 1 2 3 4 #f) ; ==> #f (more than one true value)
(xor 1 #f #f #f) ; ==> #t (only one true value)

;; Slightly more complex version where 
;; the result is always the one true value or #f
(define-syntax xor
  (syntax-rules ()
    ((_) #f)
    ((_ a) a)
    ((_ a b ...)
     (let ((tmp a))
       (if tmp 
           (and (not (or b ...)) tmp)
           (xor b ...))))))

(xor 1 2 3 4 5)  ; ==> #f
(xor 1 2 3 4)    ; ==> #f
(xor 1 2 3 4 #f) ; ==> #f
(xor 1 #f #f #f) ; ==> 1 (the actual true value, consistent)

大多数算法都没有因使用过程而受到任何速度惩罚,但我猜可能会有一些情况,这个宏可能会像宏一样派上用场。不保留该值的过程版本与另一个版本的过程版本非常相似:

(define (xor . args)
  (= (count values args) 1))