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: Eric Abrahamsen
Subject: Re: Help with recursive destructive function
Date: Mon, 07 May 2018 09:52:49 -0700
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/27.0.50 (gnu/linux)

Stefan Monnier <address@hidden> writes:

>>     (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.

All this went very rapidly over my head, but I guess that's what I was
hoping for! I'll wait and see if you all work this through any further,
then play around with the results, and update bug #29541 with a new patch.

Thanks!

Eric




reply via email to

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