Reference 对cons单元格的引用

Reference 对cons单元格的引用,reference,lisp,common-lisp,cons,Reference,Lisp,Common Lisp,Cons,如何将变量设置为指向列表单元格 我试图编写一个宏,将列表中的所有值乘以一个值。这就是我目前拥有的: (defmacro scale (areas scale) `(dotimes (n (list-length ,areas)) (setf (nth n ,areas) (* (nth n ,areas) ,scale)))) 我担心这不是最有效的方法,因为我查找第n个单元格两次。我宁愿设置一个变量指向第n个单元格,这样setf可以修改该单元格的值,*可以在计算中使用该单元格的

如何将变量设置为指向列表单元格

我试图编写一个宏,将列表中的所有值乘以一个值。这就是我目前拥有的:

(defmacro scale (areas scale)
  `(dotimes (n (list-length ,areas))
     (setf (nth n ,areas) (* (nth n ,areas) ,scale)))) 
我担心这不是最有效的方法,因为我查找第n个单元格两次。我宁愿设置一个变量指向第n个单元格,这样
setf
可以修改该单元格的值,
*
可以在计算中使用该单元格的值

更好的方法是使用
dolist
,并将变量设置为单元格引用。这有可能吗

当我在这里时,当您有一个单元格时,是否也可以获取列表中的下一个单元格。有点像迭代器,因此我可以执行以下操作:

(let ((area (car areas))
  (loop while area do
    (setf area (* area scale))
    (setf area (next area))))
但我不知道如何区分设置指针还是设置引用单元格的值


我希望我讲得有道理:)

第一个代码示例的主要问题不是它找到了第n个单元格 两次,但它确实使用了
nth
。而不是获取第n个

单元格,获取下一个单元格,它是前一个单元格的
cdr

这不需要宏,所以让我们实现一个函数。那里 在列表的每个cons单元格上有多种方法:

(defun scale (areas scale)
  (do ((tail areas (cdr tail)))
      ((endp tail))
      (setf (car tail)
            (* (car tail) scale))))

(defun scale (areas scale)
  (loop for tail on areas
        do (setf (car tail)
                 (* (car tail) scale))))

(defun scale (areas scale)
  (mapl (lambda (cell)
          (setf (car cell)
                (* (car cell) scale)))
        areas))
有一种替代方法不涉及对的
car
的显式操作 每个单元格:

(defun scale (areas scale)
  (map-into areas
            (lambda (area)
              (* area scale))
            areas))
作为奖励,这里有一个类似于
dolist
的宏来修改 主体中的“变量”会传播到列表中:

(defmacro dolistref ((var list &optional result) &body body)
  (let ((tail (gensym "TAIL"))
        (head (gensym "HEAD")))
    `(let ((,head ,list))
       (symbol-macrolet ((,var (car ,tail)))
         (do ((,tail ,head (cdr ,tail)))
             ((endp ,tail) ,result)
           ,@body)))))

;; usage example
(let ((a (list 1 2 3)))
  (dolistref (item a a)
    (incf item))) ;; => (2 3 4)

谢谢,我知道一定有办法找到下一个手机。它没有点击表示它将是单元格的cdr,但现在这是非常有意义的。symbol macrolet的使用很好