unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
From: Eric Abrahamsen <eric@ericabrahamsen.net>
To: Michael Heerdegen <michael_heerdegen@web.de>
Cc: emacs-devel@gnu.org
Subject: Re: Help with recursive destructive function
Date: Sat, 28 Jul 2018 13:52:40 -0700	[thread overview]
Message-ID: <87fu03gk13.fsf@ericabrahamsen.net> (raw)
In-Reply-To: <87y3glomjm.fsf@web.de> (Michael Heerdegen's message of "Tue, 15 May 2018 01:16:45 +0200")


On 05/15/18 01:16 AM, Michael Heerdegen wrote:
> Eric Abrahamsen <eric@ericabrahamsen.net> writes:
>
>> For backwards compatibility, we need to be able to handle lists that are
>> quoted, or that start with the symbol `list'. This will sound familiar
>> to you... In the non-destructive version, it was easy enough just to
>> return (cdr thing) instead of thing.
>
> What will this code do when the saved list was really quoted, or was a
> list with the symbol list as first element?  Wouldn't the backward
> compatible version cause errors?

After weeks of avoiding this, I'm nearly there. This version does
everything I need it to, EXCEPT I have somehow lost the ability to
handle single-atom data, which was the whole point of passing in a
gv-ref. I don't understand why, it seemed to be working fine, but I
switched to cl-labels and maybe changed some other things (I didn't keep
the intermediate version), and now it just doesn't do it. Would you help
me take one more look at this?

It also doesn't handle '(list), but those cases are rare and occur at
top-level, so I can take care of them in pre-processing.

#+BEGIN_SRC elisp

(defun deep-edit (data edit-p traverse-p)
  (let ((stack (list (gv-deref data))))
    (cl-labels ((handle-refs
                 (refs)
                 (dolist (ref refs)
                   (let* ((val (gv-deref ref))
                          (edit (when val (funcall edit-p val))))
                     (when (car edit)
                       (cl-callf (lambda (x) (funcall (car edit) x))
                           (gv-deref ref))
                       (when (cdr edit)
                         (handle-refs (list ref))))
                     (when (funcall traverse-p (gv-deref ref))
                       (push (gv-deref ref) stack))))))
      (while stack
        (let ((current (pop stack)))
          (cond
           ((consp current)
            (handle-refs `(,(gv-ref (car current))
                           ,(gv-ref (cdr current)))))
           ((and (arrayp current) (not (stringp current)))
            (handle-refs
             (mapcar (lambda (idx) (gv-ref (aref current idx)))
                     (number-sequence 0 (1- (length current))))))
           ((hash-table-p current)
            (let ((refs '()))
              (maphash (lambda (key _val)
                         ;; Order matters here!
                         (push (gv-ref (gethash key current)) refs)
                         (push (gv-ref (deep-edit-hash-key key current))
                               refs))
                       current)
              (handle-refs (nreverse refs))))))))))

(let ((tree '("one" two ''(three "four" (list "five")))))
 (deep-edit
  (gv-ref tree)
  (lambda (thing)
    (cond ((consp thing)
           (pcase (car thing)
             ('list (cons #'cdr t))
             ('quote (cons #'cadr t))))
          ((stringp thing)
           (cons #'upcase nil))))
  (lambda (thing)
    (consp thing)))
 tree)

#+END_SRC

The above works, yet if I change `tree' to be a plain string "one", it
isn't transformed. I just can't see why.

Eric



  parent reply	other threads:[~2018-07-28 20:52 UTC|newest]

Thread overview: 41+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-05-05  1:04 Help with recursive destructive function Eric Abrahamsen
2018-05-05  1:18 ` Stefan Monnier
2018-05-05  1:37   ` Michael Heerdegen
2018-05-05 15:41     ` Michael Heerdegen
2018-05-06 17:29       ` Eric Abrahamsen
2018-05-06 19:29         ` Michael Heerdegen
2018-05-06 19:34           ` Eric Abrahamsen
2018-05-06 18:27       ` Eric Abrahamsen
2018-05-07  2:01         ` Michael Heerdegen
2018-05-07  3:01           ` Eric Abrahamsen
2018-05-07  4:16             ` Clément Pit-Claudel
2018-05-07 14:14               ` Michael Heerdegen
2018-05-07 16:26               ` Stefan Monnier
2018-05-07 16:52                 ` Eric Abrahamsen
2018-05-08 13:15                   ` Michael Heerdegen
2018-05-08 18:42                     ` Eric Abrahamsen
2018-05-08 19:03                       ` Clément Pit-Claudel
2018-05-08 19:41                         ` Eric Abrahamsen
2018-05-10  1:52                       ` Michael Heerdegen
2018-05-10 17:08                         ` Michael Heerdegen
2018-05-11  2:12                           ` Eric Abrahamsen
2018-05-14 14:27                             ` Michael Heerdegen
2018-05-14 16:57                               ` Eric Abrahamsen
2018-05-14 23:16                                 ` Michael Heerdegen
2018-05-15  0:28                                   ` Eric Abrahamsen
2018-07-28 20:52                                   ` Eric Abrahamsen [this message]
2018-07-28 23:46                                     ` Michael Heerdegen
2018-07-28 23:59                                       ` Eric Abrahamsen
2018-07-29  0:09                                         ` Michael Heerdegen
2018-06-04 22:28                               ` Eric Abrahamsen
2018-06-05  0:23                                 ` Michael Heerdegen
2018-06-06 21:04                                   ` Eric Abrahamsen
2018-06-06 21:58                                     ` Michael Heerdegen
2018-06-06 22:10                                       ` Eric Abrahamsen
2018-06-06 23:10                                         ` Eric Abrahamsen
2018-06-06 23:30                                           ` Michael Heerdegen
2018-06-07  0:49                                             ` Eric Abrahamsen
2018-06-07  1:13                                               ` Michael Heerdegen
2018-06-06 23:18                                         ` Michael Heerdegen
2018-06-07 13:59                                     ` Stefan Monnier
2018-06-07 16:51                                       ` Eric Abrahamsen

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.gnu.org/software/emacs/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=87fu03gk13.fsf@ericabrahamsen.net \
    --to=eric@ericabrahamsen.net \
    --cc=emacs-devel@gnu.org \
    --cc=michael_heerdegen@web.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).