Subject: Re: bug#29220: 26.0.90; eieio-persistent-read fail to restore saved object.

From: Eric Abrahamsen <[email-masked]>
Date: Wed, 20 Dec 2017 18:21:36 -0800

On 12/20/17 15:54 PM, Stefan Monnier wrote:
>> As for the quoting thing, my current idea is to not add quotes to lists
>> when writing, then strip quotes on restore, if the car of the list is a
>> valid class symbol then try to restore an object, but wrap in
>> `condition-case' and return the plain list if an error is raised.
>
> I recommend you ask the opinion of Eric M. Ludlam <[email-masked]>
> (the original author of that code).

Okay!

Eric, I'm dragging you into this because we're having a little trouble
with the eieio persistence functionality. Sorry...

In Emacs 26 objects are implemented using records, which (long story
short) means that their representations from `prin1' are no longer
reconstructable using `read', which is causing problems for
eieio-persistent.

The current persistence read/write process basically only handles
top-level slot values. It looks at the value, does one of the following:

1. Writes an object using `object-write'
2. Writes a list of objects using a "list" plus `object-write'
3. Quotes a list and prints it
4. Prints value directly

If objects are inside lists, hash tables, or vectors (or anything else),
they are not written using `object-write'. This used to not be a problem
because their `prin1' representation was still readable.

This is no longer the case, which leads to failure for libraries that
put objects inside other data structures.

In this bug report I tried to do a simple fix for pcache, by looking for
objects inside hash tables and vectors, and using `object-write' for
them, too. That works (though it only goes one layer deeper), but it
caused new bugs in the Gnus registry, because now lists inside hash
tables are quoted, but not un-quoted during the restore process.

The persistence process is fundamentally only set up to do single-layer
processing of objects and their slot values. Probably, people are going
to continue to use eieio-persistent for more complex things (it's only
luck that I didn't run into trouble with EBDB), and I think
eieio-persistent should be able to handle whatever gets thrown at it.

My feeling is that both the write and restore process should walk the
entire tree of whatever object is being written. The write process
should turn objects into list representations, nothing more. The restore
process should restore objects, and strip strings of properties (I've
got the outline of this in bug#29541), and nothing more. If the restore
process was destructive, it would save some consing.

Three items for consideration:

1. What do you think about the above proposal? Have you had some ideas in
   this direction already?
2. Stefan pointed out that, if we don't quote lists, there's a potential
   ambiguity during restore time between lists that are lists, and lists
   that represent an object. Do you have any thoughts about this?
3. Emacs 26 is looming, and our current solutions either break pcache,
   or break the Gnus registry. We might want to do a stop-gap for Emacs
   26, and a more complete fix for master/27.

Sorry if I've over-explained, I'm using this opportunity to continue
thinking about the problem.

Eric