emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Help with recursive destructive function


From: Stefan Monnier
Subject: Re: Help with recursive destructive function
Date: Mon, 07 May 2018 12:26:45 -0400
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/27.0.50 (gnu/linux)

>     (defun deep-edit (f data)
>       (let ((cur (list #'car #'setcar data))
>             (stack (list (list #'cdr #'setcdr data))))
>         (while cur
>           (let* ((getter (car cur))
>                  (setter (cadr cur))
>                  (tree (caddr cur))
>                  (subtree (funcall getter tree)))
>             (funcall setter tree (funcall f subtree))
>             (cond
>              ((consp subtree)
>               (push (list #'cdr #'setcdr subtree) stack)
>               (setq cur (list #'car #'setcar subtree)))
>              (t (setq cur (pop stack))))))))

BTW, a "cleaner" (tho less efficient) way uses gv-ref:

    (defun deep-edit (f data)
      (let ((cur (gv-ref (car data)))
            (stack (list (gv-ref (cdr data)))))
        (while (or cur stack)
          ;; Probably should use (cl-callf f (gv-deref cell)).
          (pcase (setf (gv-deref cur) (funcall f (gv-deref cell)))
            ((and (pred consp) subtree)
              (push (gv-ref (cdr subtree)) stack)
              (setq cur (gv-ref (car subtree))))
            (t (setq cur (pop stack)))))))

tho the above has a bug when cur is nil, so it won't work as is.


        Stefan "it'd be great to be able to represent a gv-ref as
                a 3-element tuple so as to make it as efficient as your
                code, tho"




reply via email to

[Prev in Thread] Current Thread [Next in Thread]