From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!.POSTED!not-for-mail From: Eric Abrahamsen Newsgroups: gmane.emacs.devel Subject: Re: Help with recursive destructive function Date: Mon, 04 Jun 2018 15:28:03 -0700 Message-ID: <87vaayp4p8.fsf@ericabrahamsen.net> 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> <87tvrgqnug.fsf@web.de> <87vabvbfrj.fsf@web.de> <87d0y30wkn.fsf@ericabrahamsen.net> <878t8mtiqz.fsf@web.de> NNTP-Posting-Host: blaine.gmane.org Mime-Version: 1.0 Content-Type: text/plain X-Trace: blaine.gmane.org 1528151355 25369 195.159.176.226 (4 Jun 2018 22:29:15 GMT) X-Complaints-To: usenet@blaine.gmane.org NNTP-Posting-Date: Mon, 4 Jun 2018 22:29:15 +0000 (UTC) User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/27.0.50 (gnu/linux) Cc: emacs-devel@gnu.org To: Michael Heerdegen Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Tue Jun 05 00:29:11 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 1fPxyQ-0006QW-WE for ged-emacs-devel@m.gmane.org; Tue, 05 Jun 2018 00:29:11 +0200 Original-Received: from localhost ([::1]:42201 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fPy0W-0001qF-Fu for ged-emacs-devel@m.gmane.org; Mon, 04 Jun 2018 18:31:20 -0400 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:53946) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fPy0K-0001py-N8 for emacs-devel@gnu.org; Mon, 04 Jun 2018 18:31:09 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1fPy0H-0001vy-J0 for emacs-devel@gnu.org; Mon, 04 Jun 2018 18:31:08 -0400 Original-Received: from mail.ericabrahamsen.net ([50.56.99.223]:34077) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1fPy0H-0001pI-DB for emacs-devel@gnu.org; Mon, 04 Jun 2018 18:31:05 -0400 Original-Received: from localhost (unknown [207.109.85.82]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) (Authenticated sender: eric@ericabrahamsen.net) by mail.ericabrahamsen.net (Postfix) with ESMTPSA id 1B36AC2F36; Mon, 4 Jun 2018 22:30:57 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=mail.ericabrahamsen.net; s=mail; t=1528151457; bh=6S9+m5qeYtOXeme2p9uXPulId4DEsWu5wUAR3DL6+cw=; h=From:To:Cc:Subject:References:Date:In-Reply-To:From; b=j9Y2vEl/pLY0zQMyeSvCZcdyhnHbb8gpzR04X8FJ6b4LElIdnUEz2xbtv9yawnfSs p83BVjoUFH23tqRrfduIsJMkmE35C5TYBjY9ETkWDxWFV/clXrlklkjtvA1SYkObNK /ffG4Yckh+PjrPbemx5c1KhGBsysO2KN4SoodMG8= In-Reply-To: <878t8mtiqz.fsf@web.de> (Michael Heerdegen's message of "Mon, 14 May 2018 16:27:32 +0200") X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 50.56.99.223 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:226012 Archived-At: On 05/14/18 16:27 PM, Michael Heerdegen wrote: > Eric Abrahamsen writes: > >> This is great, and I really like the use of gv -- morally it seems like >> the right tool. > > Didn't profile speed, however - hope it's good enough. > >> I will have time this weekend to apply all this to eieio-persistent. > > Where can I have a look at your work? This is progressing terribly slowly, in part because of business trips, and in part because obviously I fundamentally don't understand how values work in elisp. I wanted to tweak the process a bit: object slots look like: '(:slot1 "val1" :slot2 "val2"), and instead of dumping that whole list into deep-edit, I want to call `deep-edit' once per *value*. In part that would reduce the total number of iterations, but mostly it would make the process more robust, avoiding a bug I hit while testing on an EBDB database. #+BORING_BACKGROUND One of the slots in an EBDB database is :record-class, which defaults to 'ebdb-person-record. Let's pretend a database is created with the slots '(:file "foo.txt" :record-class ebdb-person-record :state broken). As `deep-edit' cdr's down the slot list, it eventually ends up with '(ebdb-person-record :state broken), and tries to make an object out of that, which fails. The real solution is to have a more explicit tag saying "this should be an object", but we don't have that now, and more importantly we won't when it comes to reading older persistence files in a backwards-compatible fashion. #+END I can't for the life of me pass values to `deep-edit' so that the changes are reliably reflected in the original structure of "slots". Here's a simple baseline that works correctly: #+BEGIN src elisp (let ((lst '(:one "one" :two ("some" "strings") :three "three"))) (deep-edit (lambda (x) (and (stringp x) #'upcase)) #'consp lst) lst) #+END => (:one "ONE" :two ("SOME" "STRINGS") :three "THREE") Then, naively, I call `deep-edit' on every other list item: #+BEGIN src elisp (let* ((lst '(:one "one" :two ("some" "strings") :three "three")) (len (length lst)) (idx 1)) (while (< idx len) (deep-edit (lambda (x) (and (stringp x) #'upcase)) #'consp (nth idx lst)) (cl-incf idx 2)) lst) #+END => (:one "one" :two ("SOME" "STRINGS") :three "three") That only worked for consp values. I don't understand this: `nth' is implemented in C as (car (nthcdr)), and nthcdr looks to me like it's producing a chunk of the underlying list structure. So does car of nthcdr return a simple value (ie something un-setf-able) if car is an atom, but something still connected to the original list structure (setf-able) if car is a cons cell? If that's the case, I'm not sure how to reliably pass a settable value in to `deep-edit'. We could pass gv-refs into `deep-edit', in which case it would have to check values to see if they're already references or not (or gv-ref itself could do that check). I can't think of anything else. But more importantly, I'd like to know why I'm wrong about `nth' here... Thanks, Eric