了解循环宏扩展 [英] Understanding loop macro expansion

查看:66
本文介绍了了解循环宏扩展的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在下面扩展了宏,以查看其工作原理,并发现自己有些困惑.

I expanded the macro below to see how it worked and found myself a little confused.

(loop for i below 4 collect i)

扩展到(为了便于阅读,我对其进行了一些清理)

expands to (I have cleaned it up a little for readability)

(block nil
  (let ((i 0))
    (declare (type (and number real) i))
    (let* ((list-head (list nil))
           (list-tail list-head))
      (tagbody
       sb-loop::next-loop
         (when (>= i 4) (go sb-loop::end-loop))
         (rplacd list-tail (setq list-tail (list i)))
         (setq i (1+ i))

         (print "-------") ;; added so I could see the lists grow
         (print list-head)
         (print list-tail)
         (print "-------")

         (go sb-loop::next-loop)
       sb-loop::end-loop
         (return-from nil (cdr list-head))))))

..这是运行上述命令的结果.

..and here is the output from running the above..

;; "-------" 
;; (NIL 0) 
;; (0) 
;; "-------" 
;; "-------" 
;; (NIL 0 1) 
;; (1) 
;; "-------" 
;; "-------" 
;; (NIL 0 1 2) 
;; (2) 
;; "-------" 
;; "-------" 
;; (NIL 0 1 2 3) 
;; (3) 
;; "-------"

我只是看不到列表头在哪里修改,我不得不假设头和尾是eq,因此修改一个就是在修改另一个,但是有人可以分解一下rplacd行上发生的事情?

I just can't see where list-head is modified, I have to assume head and tail are eq and thus modifying one is modifying the other but could someone please break down what is happening on the rplacd line?

推荐答案

list-headlist-tail最初是 相同 (在eq意义上). list-head是一个缺点,cdr是要收集的列表. list-tail指向列表中的最后一个弊端(最初除外,请参见下文).

list-head and list-tail are initially the same (in the eq sense). list-head is a cons which cdr is the list being collected. list-tail points to the last cons in the list (except initially, see below).

要将元素添加到列表的末尾,replacd修改list-tail的cdr以添加新的缺点,并且list-tail被更新以指向新的缺点.

To add an element to the end of the list, replacd modifies the cdr of list-tail to add a new cons, and list-tail is updated to point to the new cons.

当循环终止时,结果为list-head的cdr.

When the loop terminates, the result is the cdr of list-head.

为什么这项复杂的业务有额外的弊端?因为当list-tail始终是指向列表的最后一个缺点的指针时,列表附加算法变得更加容易.但一开始,空列表没有缺点.因此,诀窍是使列表变长一些.

Why this complicated business with an extra cons? Because the list appending algorithm becomes easier when list-tail is always a pointer to the last cons of the list. But in the beginning, the empty list has no cons. So the trick is to make the list one cons longer.

这篇关于了解循环宏扩展的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆