all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
* Help with recursive destructive function
@ 2018-05-05  1:04 Eric Abrahamsen
  2018-05-05  1:18 ` Stefan Monnier
  0 siblings, 1 reply; 41+ messages in thread
From: Eric Abrahamsen @ 2018-05-05  1:04 UTC (permalink / raw)
  To: emacs-devel

So I'm revisiting my nemesis, eieio-persistent, and trying to write a
function for serializing data to disk in a generalized, data-agnostic
way.

The function needs to take a totally arbitrary list of data, and run a
function over it so that each element in the (possibly very nested) list
is tested and, if the test is positive, destructively replaced by a new
value.

I'd like to make it destructive because there could potentially be a
very large amount of data, and very few of the elements will actually
need to be altered, and I'm afraid copying enormous structures will be
slow.

I'm pretending that the job is to walk an arbitrary tree, and upcase any
and all strings in that tree. That's not the job, but I'm confident that
if I can make this work, it will be relatively simple to translate into
the actual job. (It will also have to handle hash-tables and vectors,
again I think that's all relatively straightforward.)

So here's my test data:

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

And the result I want (the destructive alteration of `test-data') is:

("A" 1 "B" ("C" (2 ("D" . 3)) (4 . "E") "F"))

The function I came up with always operates at one higher level of
nesting, because that's the only way to get a setf-able handle to
internal elements of the data structure: if you `mapc' a function over a
list, you can't use the resulting lambda argument symbol to set
anything. So I stay a level "up", in order to use setf, setcar, setcdr,
etc.

I did briefly consider `cl-symbol-macrolet', since it seems to be made
to address these sorts of problems, but this other solution more or less
came clear before I got a clear mental grasp of symbol-macrolet.

I'm hoping that someone might be willing to lend me some brain, and tell
me if I've done something conceptually wrong. Will this function do what
I expect it to do?

(defun walk (thing)
  (cond ((listp (cdr thing))
	 (dotimes (i (length thing))
	   (cond ((stringp (nth i thing))
		  (setf (nth i thing) (upcase (nth i thing))))
		 ((listp (nth i thing))
		  (walk (nth i thing))))))
	((consp thing)
	 (when (stringp (car thing))
	   (setcar thing (upcase (car thing))))
	 (when (stringp (cdr thing))
	   (setcdr thing (upcase (cdr thing)))))))




^ permalink raw reply	[flat|nested] 41+ messages in thread

end of thread, other threads:[~2018-07-29  0:09 UTC | newest]

Thread overview: 41+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
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
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

Code repositories for project(s) associated with this external index

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

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.