From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!.POSTED!not-for-mail From: Michael Heerdegen Newsgroups: gmane.emacs.devel Subject: Re: Help with recursive destructive function Date: Thu, 10 May 2018 03:52:07 +0200 Message-ID: <87tvrgqnug.fsf@web.de> References: <87efiqzzd2.fsf@ericabrahamsen.net> <87bmdu3mtf.fsf@web.de> <87zi1e9kju.fsf@web.de> <87o9hs3aht.fsf@ericabrahamsen.net> <87bmds9qcg.fsf@web.de> <87k1sg185t.fsf@ericabrahamsen.net> <044bdbf1-39a2-0e71-ec79-3d375d9109c8@gmail.com> <877eof1k7y.fsf@ericabrahamsen.net> <87wowe2sql.fsf@web.de> <877eoe2dma.fsf@ericabrahamsen.net> NNTP-Posting-Host: blaine.gmane.org Mime-Version: 1.0 Content-Type: text/plain X-Trace: blaine.gmane.org 1525917060 12337 195.159.176.226 (10 May 2018 01:51:00 GMT) X-Complaints-To: usenet@blaine.gmane.org NNTP-Posting-Date: Thu, 10 May 2018 01:51:00 +0000 (UTC) User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/27.0.50 (gnu/linux) Cc: emacs-devel@gnu.org To: Eric Abrahamsen Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Thu May 10 03:50:55 2018 Return-path: Envelope-to: ged-emacs-devel@m.gmane.org Original-Received: from lists.gnu.org ([208.118.235.17]) by blaine.gmane.org with esmtp (Exim 4.84_2) (envelope-from ) id 1fGajP-00036Y-4h for ged-emacs-devel@m.gmane.org; Thu, 10 May 2018 03:50:55 +0200 Original-Received: from localhost ([::1]:59732 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fGalV-0003Va-RA for ged-emacs-devel@m.gmane.org; Wed, 09 May 2018 21:53:05 -0400 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:34552) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fGakp-0003UA-P0 for emacs-devel@gnu.org; Wed, 09 May 2018 21:52:24 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1fGakm-000277-Lk for emacs-devel@gnu.org; Wed, 09 May 2018 21:52:23 -0400 Original-Received: from mout.web.de ([212.227.15.14]:37299) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1fGakm-00026q-Bk for emacs-devel@gnu.org; Wed, 09 May 2018 21:52:20 -0400 Original-Received: from drachen.dragon ([188.110.196.170]) by smtp.web.de (mrweb003 [213.165.67.108]) with ESMTPSA (Nemesis) id 0MYevq-1elIV90geQ-00VU4k; Thu, 10 May 2018 03:52:09 +0200 In-Reply-To: <877eoe2dma.fsf@ericabrahamsen.net> (Eric Abrahamsen's message of "Tue, 08 May 2018 11:42:21 -0700") X-Provags-ID: V03:K1:HTXDv+l2MbPpm6mrbO4bAuaPjWBx4t0A0iZSwrsX562RNUfPIrh Xkdr5fWFwODjy8uMciN1C1vmonm7u6LHBIixyx6+ik5Je2OxGbCKqGeQMyperzaHx1QschM Jz7062ITa0HdL3hqKQybQyDgSbu/XeAyeEISRD3K6jTZCcWst1NlMkkNG8rj2sDkPTp4RS1 B4hQBDnurPqv41Xcl9jeA== X-UI-Out-Filterresults: notjunk:1;V01:K0:+TT29XR1/jI=:XCO78SUdRy5a4DS0mr9dBa dS140cDRe34LYpMwvUawHbKOGNfZLWsw49ePWruMbGfGF8Ec0GosHWx6ANP+Xu6avzCfMUOV2 1s9fs+Xobfocf1mN/g3wEAZXikvy13gzqk/7rr9+6Wagc3sket+V+lCbkfYwEPyrZaVM6X4Kc TAgZsTDtpsB7tE6F7egNtnD44OB/VIMKcs6UyYpTR2nInYyphkWlcvjYyKKUiYiHyD0lBVPek +VYmrV5obAwEievNsnkHFoe34sBwyn3coQrDU2eWERAMnjUH9Sul+q/zYYpDN9iDFWcaK8jzt peoS6pSM5o9/uVUFTmCpEqjy9olcBFqKX640m7EaX7jTwHNxan823/uOy+FAs6eU/kyNHczEn WzJkNKMJsreZwCdaar7iCGVSFBZZQrqqZJ0crNuxjrEVLsAQxUe2W9dWADNSM7ZdBwjv+I0/F W9GW0gaNCxcSHiBMmL3XTGD2pGrtdFS6rQ3gLLylPqpCUPZRl4T1GyTFfY5eAujJf63uvhD79 TntS9S8D2kd7v2bhXPCamHytCpr9MXU2CljJVjVuJ4cn3EIinnjiO8gI5KRoPB2KOA4Xple7c D/b63xaj2btiLXMmXnE6niHQzzK6CjQrR8h/beWboXrax6V0fjOQx2+MQefPgyYpYFrqQGZxE 6s6cYGGLSiM43j7BmhJBJTmoHuQzSSuEGp2IUa0yS3jF86yb3RIWYndk0p+hg02HPVpMVB7O7 TeqwJVSTtAsJEzhEt+Cngq/Qoqj1mF/ij3c2DspKISxGcCuQj0c3TO/qgBj2njJu9y2UdjgU X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 212.227.15.14 X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Original-Sender: "Emacs-devel" Xref: news.gmane.org gmane.emacs.devel:225182 Archived-At: Eric Abrahamsen writes: > These are the sorts of things I can typically handle (sometimes even > without bugs!), whereas Clement's (or your, or Stefan's) function > isn't... I tweaked it a bit and extended the idea for arrays. Hope the comments are helpful. Uses seq.el and cl-lib. #+begin_src emacs-lisp ;; -*- lexical-binding: t -*- (defun deep-edit (edit-fun data) ;; DATA is the structure to process. ;; ;; EDIT-FUN is a function accepting one argument THING that returns ;; non-nil when THING is something to be replaced. The non-nil ;; return value should be a function that when called with the THING as ;; argument returns the replacement for THING. ;; Example: (lambda (thing) (and (stringp thing) #'upcase)) as ;; EDIT-FUN would cause all strings being replaced with their upcased ;; version. (let ((stack `((identity ignore ,data)))) (while stack (pcase-let* ((`(,getter ,setter ,cell) (pop stack)) (current (funcall getter cell)) (modify-fun (funcall edit-fun current))) (cond ;; 1. When we should replace CURRENT, do it (modify-fun (funcall setter cell (funcall modify-fun current))) ;; FIXME: Do hash-tables fit here? ;; 2. Check whether we need to traverse CURRENT ((consp current) (cl-callf2 append `((car setcar ,current) (cdr setcdr ,current)) stack)) ((and (arrayp current) (not (stringp current))) (cl-callf2 append (let ((i -1)) (seq-map (lambda (_) (let ((j (cl-incf i))) `(,(lambda (x) (aref x j)) ,(lambda (x v) (aset x j v)) ,current))) current)) stack))))))) ;; Example to try: (let ((tree '("a" "b" "c" (2 ("d" . 3)) (4 . "e") "f" (("g" . "h") (["i" "j" ("k" "l") nil []]))))) (deep-edit (lambda (thing) (and (stringp thing) #'upcase)) tree) tree) #+end_src Michael.