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: Clément Pit-Claudel
Subject: Re: Help with recursive destructive function
Date: Mon, 7 May 2018 00:16:12 -0400
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Thunderbird/52.7.0

On 2018-05-06 23:01, Eric Abrahamsen wrote:
> I'd like to have an iterative approach to work with as well

Here's a quick attempt:

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

    (setq test-data '("a" 1 "b" ("c" (2 ("d" . 3)) (4 . "e") "f")))

    (defun f (subtree)
      (if (stringp subtree)
          (upcase subtree)
        subtree))

    (deep-edit #'f test-data)

… I'd actually tend to write it like this, if pcase is OK:

    (defun deep-edit (f data)
      (let ((cur `(car setcar ,data))
            (stack `((cdr setcdr ,data))))
        (while (or cur stack)
          (pcase-let* ((`(,getter ,setter ,cell) cur)
                       (subtree (funcall getter cell)))
            (funcall setter cell (funcall f subtree))
            (cond
             ((consp subtree)
              (push `(cdr setcdr ,subtree) stack)
              (setq cur `(car setcar ,subtree)))
             (t (setq cur (pop stack))))))))

Let me know if it needs clarification.  I haven't tested it much, either.

Clément.



reply via email to

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