[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Help with recursive destructive function
From: |
Eric Abrahamsen |
Subject: |
Re: Help with recursive destructive function |
Date: |
Mon, 04 Jun 2018 15:28:03 -0700 |
User-agent: |
Gnus/5.13 (Gnus v5.13) Emacs/27.0.50 (gnu/linux) |
On 05/14/18 16:27 PM, Michael Heerdegen wrote:
> Eric Abrahamsen <address@hidden> 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
- Re: Help with recursive destructive function,
Eric Abrahamsen <=
- Re: Help with recursive destructive function, Michael Heerdegen, 2018/06/04
- Re: Help with recursive destructive function, Eric Abrahamsen, 2018/06/06
- Re: Help with recursive destructive function, Michael Heerdegen, 2018/06/06
- Re: Help with recursive destructive function, Eric Abrahamsen, 2018/06/06
- Re: Help with recursive destructive function, Eric Abrahamsen, 2018/06/06
- Re: Help with recursive destructive function, Michael Heerdegen, 2018/06/06
- Re: Help with recursive destructive function, Eric Abrahamsen, 2018/06/06
- Re: Help with recursive destructive function, Michael Heerdegen, 2018/06/06
- Re: Help with recursive destructive function, Michael Heerdegen, 2018/06/06
- Re: Help with recursive destructive function, Stefan Monnier, 2018/06/07