unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
* New package: resist!
@ 2021-12-08 20:55 Qiantan Hong
  2021-12-09  2:48 ` Karl Fogel
  2021-12-09 13:56 ` Stefan Kangas
  0 siblings, 2 replies; 50+ messages in thread
From: Qiantan Hong @ 2021-12-08 20:55 UTC (permalink / raw)
  To: emacs-devel@gnu.org

[-- Attachment #1: Type: text/plain, Size: 814 bytes --]

This package implements persistence facility.
It provides two level of interfaces:
- A high-level persistent variable facility
- A low-level persistent key-value store facility

The persistent variable facility detects changes of values
persistent variables in an idle timer and persist the changes
into a persistent key-value store.
Multiple methods for detecting and computing the changes are
provided. See `make-persistent-variable' for details.

The persistent key-value store provides the following functions:
- Creating and compressing store: `make-kv-store', `compact-kv-store'
- Put, remove and look up key value pairs: `kv-put', `kv-rem', `kv-get',
- List operations: `kv-push', `kv-delete'
See their docstrings for details.
All changes are persisted immediately into external storage.


[-- Attachment #2: resist!.el --]
[-- Type: application/octet-stream, Size: 10405 bytes --]

;;; resist! --- Against SQLite3!  -*- lexical-binding: t; -*-

;; Copyright (C) 2021 Free Software Foundation, Inc.

;; Author: Qiantan Hong <qhong@alum.mit.edu>
;; Maintainer: Qiantan Hong <qhong@alum.mit.edu>
;; Keywords: persistence database
;; Version: 0.0.1

;; This file is part of GNU Emacs.

;; GNU Emacs is free software: you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation, either version 3 of the License, or
;; (at your option) any later version.

;; GNU Emacs is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;; GNU General Public License for more details.

;; You should have received a copy of the GNU General Public License
;; along with GNU Emacs.  If not, see <https://www.gnu.org/licenses/>.

;;; Commentary:
;; This package implements persistence facility.
;; It provides two level of interfaces:
;; - A high-level persistent variable facility
;; - A low-level persistent key-value store facility

;; The persistent variable facility detects changes of values
;; persistent variables in an idle timer and persist the changes
;; into a persistent key-value store.
;; Multiple methods for detecting and computing the changes are
;; provided. See `make-persistent-variable' for details.

;; The persistent key-value store provides the following functions:
;; - Creating and compressing store: `make-kv-store', `compact-kv-store'
;; - Put, remove and look up key value pairs: `kv-put', `kv-rem', `kv-get',
;; - List operations: `kv-push', `kv-delete'
;; See their docstrings for details.
;; All changes are persisted immediately into external storage.

;;; Code:

(require 'cl-lib)

(defcustom persistent-variable-idle-time 1
  "Time in seconds to wait before writing out persistent variables.

The effect normally takes place after restarting Emacs, or
restarting `persistent-variable-idle-timer' manually."
  :type 'number)

(defcustom persistent-variable-store-filename (concat user-emacs-directory ".persistent-variables")
  "Filename of the key value store that backs up persistent variables."
  :type 'file)

(cl-defstruct (kv-store (:constructor make-kv-store-1)) path table)
(defun make-kv-store (path)
  "Create a key value store backed by file PATH.
If file PATH does not exist, create it and return an empty key value store.
If file PATH exists, load its content into a key value store and return it."
  (let* ((kv-store (make-kv-store-1 :path path))
         (kv-store-table (make-hash-table :test 'equal))
         need-compactification)
    (when (file-exists-p path)
      (condition-case nil
          (with-temp-buffer
            (insert-file-contents path)
            (while (< (point) (1- (point-max))) ; exclude trailing newline
              (let ((entry (read (current-buffer))))
                (pcase (car entry)
                  ('++ (puthash (cadr entry) (caddr entry) kv-store-table))
                  ('-- (remhash (cadr entry) kv-store-table))
                  ('l+ (push (caddr entry) (gethash (cadr entry) kv-store-table)))
                  ('l- (puthash (cadr entry)
                                (delete (caddr entry) (gethash (cadr entry) kv-store-table))
                                kv-store-table))))))
        (end-of-file
         ;; We might encounter trailing unbalanced form if Emacs
         ;; crashed in the middle of `kv-put'.  We compact the file
         ;; and fix unbalanced form as a side effect
         (setq need-compactification t)))
      (setf (kv-store-table kv-store) kv-store-table))
    (when need-compactification
      (compact-kv-store kv-store))
    kv-store))
(defsubst kv--log (form)
  (let ((print-length nil) (print-level nil))
    (prin1 form (current-buffer)))
  (insert "\n"))
(defun compact-kv-store (kv-store)
  "Compress the log for KV-STORE.
Do this by dumping the full content of (kv-store-table KV-STORE) at once."
  ;; dump the full content of kv-store-table at once
  ;; to compress the log
  (with-temp-buffer
    (maphash (lambda (key value) (kv--log (list '++ key value)))
             (kv-store-table kv-store))
    (let ((file-precious-flag t))
      (write-file (kv-store-path kv-store)))))

(defsubst kv-put-1 (key value kv-store)
  (kv--log (list '++ key value))
  (puthash key value (kv-store-table kv-store)))
(defsubst kv-rem-1 (key kv-store)
  (kv--log (list '-- key))
  (remhash key (kv-store-table kv-store)))
(defsubst kv-push-1 (key value kv-store)
  (kv--log (list 'l+ key value))
  (push value (gethash key (kv-store-table kv-store))))
(defsubst kv-delete-1 (key value kv-store)
  (kv--log (list 'l- key value))
  (puthash key (delete value (gethash key (kv-store-table kv-store))) (kv-store-table kv-store)))
(defmacro kv--persist-now (kv-store &rest body)
  (declare (indent 1) (debug ([&rest form] body)))
  `(with-temp-buffer
     ,@body
     (let ((inhibit-message t))
       (write-region nil nil (kv-store-path ,kv-store) t 'silence))))

(defun kv-put (key value kv-store)
  "Associate KEY with VALUE in KV-STORE.
The operation is immediately persisted."
  (kv--persist-now kv-store
    (kv-put-1 key value kv-store)))
(defun kv-rem (key kv-store)
  "Remove KEY from KV-STORE.
The operation is immediately persisted."
  (kv--persist-now kv-store
    (kv-rem-1 key kv-store)))
(defun kv-push (key value kv-store)
  "Add VALUE to the list associated with KEY in KV-STORE.
The operation is immediately persisted."
  (kv--persist-now kv-store
    (kv-push-1 key value kv-store)))
(defun kv-delete (key value kv-store)
  "Remove VALUE from the list associated with KEY in KV-STORE.
The operation is immediately persisted."
  (kv--persist-now kv-store
    (kv-delete-1 key value kv-store)))
(defun kv-get (key kv-store &optional dflt)
  "Look up KEY in KV-STORE and return its associated value.
If KEY is not found, return DFLT which defaults to nil."
  (gethash key (kv-store-table kv-store) dflt))

(defvar inhibit-ask-user-about-lock nil)
(defun inhibit-ask-user-about-lock-advice (orig-func file opponent)
  (if inhibit-ask-user-about-lock
      (signal 'file-locked (list file opponent))
    (funcall orig-func file opponent)))
(advice-add 'ask-user-about-lock :around #'inhibit-ask-user-about-lock-advice)

(defvar persistent-variable-list nil "List of persistent variables.")
(defvar persistent-variable-kv-store (make-kv-store persistent-variable-store-filename))
(defvar persistent-variable-idle-timer (run-with-idle-timer persistent-variable-idle-time t 'persistent-variable-demon))

(defvar persistent-variable-unbound-marker (gensym))
(defun persistent-variable-demon ()
  "Persist any changes of variables in `persistent-variable-list'.

The operation may fail if `persistent-variable-store-filename' is locked.
In such cases, return nil.  If the operation succeeds, return t."
  (dolist (variable persistent-variable-list)
    (with-temp-buffer
      (setq buffer-file-truename (kv-store-path persistent-variable-kv-store))
      (condition-case nil
          (progn
            (setf (buffer-modified-p (current-buffer)) t) ; otherwise `lock-buffer' would do nothing
            (let ((create-lockfiles t)
                  (inhibit-ask-user-about-lock t))
              (lock-buffer))
            (condition-case nil
              (pcase (get variable 'persistence-method)
                ('eql
                 (unless (eql (kv-get variable persistent-variable-kv-store) (symbol-value variable))
                   (kv-put-1 variable (symbol-value variable) persistent-variable-kv-store)))
                ('equal
                 (unless (equal (kv-get variable persistent-variable-kv-store) (symbol-value variable))
                   (kv-put-1 variable (copy-tree (symbol-value variable) t) persistent-variable-kv-store)))
                ('set
                 (let ((old-list (kv-get variable persistent-variable-kv-store))
                       (new-list (symbol-value variable)))
                   (let ((deleted-items (cl-set-difference old-list new-list))
                         (added-items (cl-set-difference new-list old-list)))
                     (mapc (lambda (value) (kv-delete-1 variable value persistent-variable-kv-store)) deleted-items)
                     (mapc (lambda (value) (kv-push-1 variable value persistent-variable-kv-store)) added-items)))))
              (void-variable
               (unless (eq (kv-get variable persistent-variable-kv-store persistent-variable-unbound-marker)
                           persistent-variable-unbound-marker)
                 (kv-rem variable persistent-variable-kv-store))))
            (write-region nil nil buffer-file-truename t 'silent)
            t)
        (file-locked
         (message "Giving up storing persistent variables this time, because %s is locked."
                  (kv-store-path persistent-variable-kv-store))
         nil)))))
(add-hook 'kill-emacs-hook #'persistent-variable-demon)

(cl-defun make-persistent-variable (variable &optional (method 'eql))
  "Make VARIABLE persistent.

If there is an existing entry in `persistent-variable-kv-store',
set the value of VARIABLE to the value in the key value store.

METHOD specifies how VARIABLE is saved and restored,
and can be one of the following:
- `eql': saves the value of VARIABLE if it is not `eql' to last saved value.
- `equal': saves the value of VARIABLE if it is not `equal' to last saved value.
- `set': saves the set difference of the value of VARIABLE compared to last saved value.
Membership test is done using `eql'."
  (cl-pushnew variable persistent-variable-list)
  (let ((persistent-value (kv-get variable persistent-variable-kv-store persistent-variable-unbound-marker)))
    (unless (eq persistent-value persistent-variable-unbound-marker)
      (set variable persistent-value)))
  (setf (get variable 'persistence-method) method))
(defun kill-persistent-variable (variable)
  "Make VARIABLE no longer persistent."
  (setq persistent-variable-list (delq variable persistent-variable-list))
  variable)

(provide 'resist!)
;;; resist!.el ends here

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

* Re: New package: resist!
  2021-12-08 20:55 New package: resist! Qiantan Hong
@ 2021-12-09  2:48 ` Karl Fogel
  2021-12-09  6:59   ` Qiantan Hong
  2021-12-09  9:15   ` Tassilo Horn
  2021-12-09 13:56 ` Stefan Kangas
  1 sibling, 2 replies; 50+ messages in thread
From: Karl Fogel @ 2021-12-09  2:48 UTC (permalink / raw)
  To: Qiantan Hong; +Cc: emacs-devel@gnu.org

On 08 Dec 2021, Qiantan Hong wrote:
> This package implements persistence facility.
> It provides two level of interfaces:
> - A high-level persistent variable facility
> - A low-level persistent key-value store facility
>
> The persistent variable facility detects changes of values
> persistent variables in an idle timer and persist the changes
> into a persistent key-value store.
> Multiple methods for detecting and computing the changes are
> provided. See `make-persistent-variable' for details.
>
> The persistent key-value store provides the following functions:
> - Creating and compressing store: `make-kv-store', 
> `compact-kv-store'
> - Put, remove and look up key value pairs: `kv-put', `kv-rem', 
> `kv-get',
> - List operations: `kv-push', `kv-delete'
> See their docstrings for details.
> All changes are persisted immediately into external storage.

Does this package require the entire store to be loaded into 
memory in order for a single value to be looked up or stored?

It looks like it does (based on reading `kv-get', etc), but I 
might be missing something.

Best regards,
-Karl



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

* Re: New package: resist!
  2021-12-09  2:48 ` Karl Fogel
@ 2021-12-09  6:59   ` Qiantan Hong
  2021-12-09  7:57     ` Óscar Fuentes
  2021-12-09  9:15   ` Tassilo Horn
  1 sibling, 1 reply; 50+ messages in thread
From: Qiantan Hong @ 2021-12-09  6:59 UTC (permalink / raw)
  To: emacs-devel@gnu.org

> Does this package require the entire store to be loaded into memory in order for a single value to be looked up or stored?
> 
> It looks like it does (based on reading `kv-get', etc), but I might be missing something.

It is. According to my benchmark I don’t think this is a problem
for most Emacs use cases (it loads 10k entry within 0.03s,
I’ve tested longer list).

I do have an idea how to do it without loading the entire store,
by dividing the store into several “buckets” based on hash value
of they keys (and each bucket can be dynamically splitted,
essentially forming a trie). But I don’t know if it’s worth it.

Maybe let’s put the package in use first and see if that’s
necessary? It can be added (mostly) without changing
the interface. The only change I can see is, we may want
kv-store-filename to become kv-store-directory so
those bucket files are stored under it. Or we can retain
the current interface and add suffix to kv-store-filename.
Which one is more preferable?

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

* Re: New package: resist!
  2021-12-09  6:59   ` Qiantan Hong
@ 2021-12-09  7:57     ` Óscar Fuentes
  2021-12-09  8:05       ` Qiantan Hong
                         ` (2 more replies)
  0 siblings, 3 replies; 50+ messages in thread
From: Óscar Fuentes @ 2021-12-09  7:57 UTC (permalink / raw)
  To: emacs-devel

Qiantan Hong <qhong@mit.edu> writes:

>> Does this package require the entire store to be loaded into memory in order for a single value to be looked up or stored?
>> 
>> It looks like it does (based on reading `kv-get', etc), but I might be missing something.
>
> It is. According to my benchmark I don’t think this is a problem
> for most Emacs use cases (it loads 10k entry within 0.03s,
> I’ve tested longer list).

Was it with a cold disk cache? SSD or HDD? :-)

I'm afraid that you are focusing too much on a single metric.

You don't mention how large is each record, but anyway 10k records is a
tiny number for any serious database application. And then we have
memory pressure: apart from raw RAM usage, IIRC Emacs' garbage collector
traverses live objects, which means that Emacs becomes slower as the
info it holds grows. Then we have the persistence requirement: if we
want frequent, persistent updates to the database, having to write the
database's entire content each time we want to persist a change is
unacceptable. Then, if we want concurrent access from multiple sessions
(which itself requires some level of support for atomic operations) your
approach of reading and saving a big file becomes unfeasible in
practice, unless for tiny databases.

Don't get me wrong, I'm also worried about introducing sqlite support in
core. I'm afraid that it will be misused, a solution that creates
problems, so to speak, but it is undeniable that there are reasonable
uses for a proper database on Emacs.




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

* Re: New package: resist!
  2021-12-09  7:57     ` Óscar Fuentes
@ 2021-12-09  8:05       ` Qiantan Hong
  2021-12-09  8:09       ` Qiantan Hong
  2021-12-09 13:24       ` Stefan Monnier
  2 siblings, 0 replies; 50+ messages in thread
From: Qiantan Hong @ 2021-12-09  8:05 UTC (permalink / raw)
  To: Óscar Fuentes; +Cc: emacs-devel@gnu.org

> 
> Was it with a cold disk cache? SSD or HDD? :-)
> 
> I'm afraid that you are focusing too much on a single metric.
> 
> You don't mention how large is each record, but anyway 10k records is a
> tiny number for any serious database application. And then we have
> memory pressure: apart from raw RAM usage, IIRC Emacs' garbage collector
> traverses live objects, which means that Emacs becomes slower as the
> info it holds grows.
10k is tiny for business records, but IMO big for Emacs packages.
About the size dependency on record, the takeaway is that the speed
is almost exactly the READ speed, so for loading Lisp values,
it’s basically impossible to beat because you always need to convert
from string to Lisp values even using other database.

Instead, database will benefit from loading lazily, but I can do it too.
It’s unclear to me whether it’s necessary, but if it’s proven to be true,
I could add it.

> Then we have the persistence requirement: if we
> want frequent, persistent updates to the database, having to write the
> database's entire content each time we want to persist a change is
> unacceptable.
This is a common misunderstanding. Resist! is a log structured store
and only writes out increments. It’s even probably “cleverer” than 
stock databases because it understands some Lisp (e.g. list operations)
and you can teach it to understand more.

Maybe to avoid future confusion I should mention this in package header?

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

* Re: New package: resist!
  2021-12-09  7:57     ` Óscar Fuentes
  2021-12-09  8:05       ` Qiantan Hong
@ 2021-12-09  8:09       ` Qiantan Hong
  2021-12-09 13:24       ` Stefan Monnier
  2 siblings, 0 replies; 50+ messages in thread
From: Qiantan Hong @ 2021-12-09  8:09 UTC (permalink / raw)
  To: Óscar Fuentes; +Cc: emacs-devel@gnu.org

> Then, if we want concurrent access from multiple sessions
> (which itself requires some level of support for atomic operations) your
> approach of reading and saving a big file becomes unfeasible in
> practice, unless for tiny databases.
It is not doing that. Currently it has LWW semantics for “basic”
kv, and set semantics for “list” kv.

Emacs lock file is slow so kv-* is not doing locking and leave the
responsibility to caller. persistent-value-* does locking.

Writes from other instances is not immediately visible, but I could
make that happen. Not sure if it’s useful though, unless someone
want to (ab)use it as an IPC channel.

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

* Re: New package: resist!
  2021-12-09  2:48 ` Karl Fogel
  2021-12-09  6:59   ` Qiantan Hong
@ 2021-12-09  9:15   ` Tassilo Horn
  2021-12-09  9:25     ` Qiantan Hong
  1 sibling, 1 reply; 50+ messages in thread
From: Tassilo Horn @ 2021-12-09  9:15 UTC (permalink / raw)
  To: Karl Fogel; +Cc: Qiantan Hong, emacs-devel

Karl Fogel <kfogel@red-bean.com> writes:

> Does this package require the entire store to be loaded into memory in
> order for a single value to be looked up or stored?
>
> It looks like it does (based on reading `kv-get', etc), but I might be
> missing something.

It does, but I think usually every package/component would have its own
store.  So I don't think that the foobar package loads its complete
store when accessing foobar-value-1 is no big deal.

Bye,
Tassilo



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

* Re: New package: resist!
  2021-12-09  9:15   ` Tassilo Horn
@ 2021-12-09  9:25     ` Qiantan Hong
  2021-12-09  9:36       ` Tassilo Horn
  0 siblings, 1 reply; 50+ messages in thread
From: Qiantan Hong @ 2021-12-09  9:25 UTC (permalink / raw)
  To: Tassilo Horn; +Cc: Karl Fogel, emacs-devel@gnu.org

> On Dec 9, 2021, at 1:15 AM, Tassilo Horn <tsdh@gnu.org> wrote:
> 
> Karl Fogel <kfogel@red-bean.com> writes:
> 
>> Does this package require the entire store to be loaded into memory in
>> order for a single value to be looked up or stored?
>> 
>> It looks like it does (based on reading `kv-get', etc), but I might be
>> missing something.
> 
> It does, but I think usually every package/component would have its own
> store.  So I don't think that the foobar package loads its complete
> store when accessing foobar-value-1 is no big deal.

The persistent-variables facility I added however maintains a global store.

Will this turns out to be a problem?
If so, I can either implement general bucket-splitting, or
for the persistent-variable-*, use one store for each package.
Which one makes more sense?




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

* Re: New package: resist!
  2021-12-09  9:25     ` Qiantan Hong
@ 2021-12-09  9:36       ` Tassilo Horn
  2021-12-09 20:37         ` Qiantan Hong
  0 siblings, 1 reply; 50+ messages in thread
From: Tassilo Horn @ 2021-12-09  9:36 UTC (permalink / raw)
  To: Qiantan Hong; +Cc: Karl Fogel, emacs-devel

Qiantan Hong <qhong@mit.edu> writes:

>> It does, but I think usually every package/component would have its
>> own store.  So I don't think that the foobar package loads its
>> complete store when accessing foobar-value-1 is no big deal.
>
> The persistent-variables facility I added however maintains a global
> store.

Oh, I haven't checked the new version.

> Will this turns out to be a problem?

Possibly, I don't know.  But what's wrong with simply having
`make-persistent-variable' receive the store as an argument?  That would
allow me to have a foo--store where all my persistent foo-variables of
my foo package reside.  If all of them get loaded at once, that's
totally ok.

Bye,
Tassilo



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

* Re: New package: resist!
  2021-12-09  7:57     ` Óscar Fuentes
  2021-12-09  8:05       ` Qiantan Hong
  2021-12-09  8:09       ` Qiantan Hong
@ 2021-12-09 13:24       ` Stefan Monnier
  2 siblings, 0 replies; 50+ messages in thread
From: Stefan Monnier @ 2021-12-09 13:24 UTC (permalink / raw)
  To: Óscar Fuentes; +Cc: emacs-devel

> You don't mention how large is each record, but anyway 10k records is a
> tiny number for any serious database application.

`resist!` is designed to make persistent data that is usually stored in
Emacs's heap.  If you database is too large that you clearly don't want
to use that.  So far, all the examples I've seen mentioned here (Gnus
registry, savehist, ...) are databases which are currently happily kept
in the Lisp heap, so they should do fine with `resist!`.


        Stefan





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

* Re: New package: resist!
  2021-12-08 20:55 New package: resist! Qiantan Hong
  2021-12-09  2:48 ` Karl Fogel
@ 2021-12-09 13:56 ` Stefan Kangas
  1 sibling, 0 replies; 50+ messages in thread
From: Stefan Kangas @ 2021-12-09 13:56 UTC (permalink / raw)
  To: Qiantan Hong; +Cc: emacs-devel@gnu.org

Qiantan Hong <qhong@mit.edu> writes:

> This package implements persistence facility

Any chance for a more descriptive name than "resist!.el"?  Thanks.



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

* Re: New package: resist!
  2021-12-09  9:36       ` Tassilo Horn
@ 2021-12-09 20:37         ` Qiantan Hong
  2021-12-10 18:25           ` Qiantan Hong
  0 siblings, 1 reply; 50+ messages in thread
From: Qiantan Hong @ 2021-12-09 20:37 UTC (permalink / raw)
  To: Tassilo Horn, Stefan Kangas; +Cc: Karl Fogel, emacs-devel@gnu.org

> Possibly, I don't know.  But what's wrong with simply having
> `make-persistent-variable' receive the store as an argument?  That would
> allow me to have a foo--store where all my persistent foo-variables of
> my foo package reside.  If all of them get loaded at once, that's
> totally ok.
Good idea, I’ll add that in the next revision.

>> This package implements persistence facility
> 
> Any chance for a more descriptive name than "resist!.el"?  Thanks.
Resist! seems very descriptive to me:
It’s the recursive acronym of Resist! pErSISTs!

Jokes aside, persist.el or persistent.el or persistence.el might be
a few candidates, but not sure if they’re used, or reserved
because these are quite broad terms.


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

* Re: New package: resist!
  2021-12-09 20:37         ` Qiantan Hong
@ 2021-12-10 18:25           ` Qiantan Hong
  2021-12-10 18:59             ` Stefan Monnier
  0 siblings, 1 reply; 50+ messages in thread
From: Qiantan Hong @ 2021-12-10 18:25 UTC (permalink / raw)
  To: Tassilo Horn; +Cc: Karl Fogel, Stefan Monnier, emacs-devel@gnu.org

The package is now hosted at https://code.librehq.com/qhong/resist/

I think it will be useful to have this package either on GNU Elpa
or Emacs core, or maybe both (for forward compatibility).
Shall we push forward?

>  But what's wrong with simply having
> `make-persistent-variable' receive the store as an argument?
Added.

I’ve also added an automatic compacting daemon.

There’s some remaining technical question:
- What’s the right group to put the customizations?
- currently I ask user to invoke kv-compact-demon-start
  and persistent-variable-demon-start explicitly to
  start/restart the services.
  Are there better way?
  Not sure if those makes sense as minor modes.

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

* Re: New package: resist!
  2021-12-10 18:25           ` Qiantan Hong
@ 2021-12-10 18:59             ` Stefan Monnier
  2021-12-10 19:15               ` Qiantan Hong
  0 siblings, 1 reply; 50+ messages in thread
From: Stefan Monnier @ 2021-12-10 18:59 UTC (permalink / raw)
  To: Qiantan Hong; +Cc: Tassilo Horn, Karl Fogel, emacs-devel@gnu.org

> The package is now hosted at https://code.librehq.com/qhong/resist/
>
> I think it will be useful to have this package either on GNU Elpa
> or Emacs core, or maybe both (for forward compatibility).
> Shall we push forward?

Do you have write access so you can add it yourself?
If not, let me know.

I just looked at the code and I think it should be cleaner w.r.t its use
of namespace: the file is `resist!.el` and it defines macros and
functions using the `kv-` prefix as well as the `persistent-` prefix; we
should unify those 3 names.

[ Also the advice functions should have a name that starts with the
  package's namespace prefix.  ]

> There’s some remaining technical question:
> - What’s the right group to put the customizations?
> - currently I ask user to invoke kv-compact-demon-start
>   and persistent-variable-demon-start explicitly to
>   start/restart the services.
>   Are there better way?
>   Not sure if those makes sense as minor modes.

Why not start them lazily when the data is changed (e.g. within
`kv--ensure-transaction`)?


        Stefan




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

* Re: New package: resist!
  2021-12-10 18:59             ` Stefan Monnier
@ 2021-12-10 19:15               ` Qiantan Hong
  2021-12-10 19:24                 ` Philip Kaludercic
  2021-12-10 19:53                 ` Stefan Monnier
  0 siblings, 2 replies; 50+ messages in thread
From: Qiantan Hong @ 2021-12-10 19:15 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: Karl Fogel, emacs-devel@gnu.org, Tassilo Horn

> I just looked at the code and I think it should be cleaner w.r.t its use
> of namespace: the file is `resist!.el` and it defines macros and
> functions using the `kv-` prefix as well as the `persistent-` prefix; we
> should unify those 3 names.
> 
> [ Also the advice functions should have a name that starts with the
>  package's namespace prefix.  ]
I’m thinking the “package” as an extension to Elisp language itself,
so I didn’t have package prefix in mind. Thus the name like `compact-kv-store`.

Maybe the file should be named `persistence.el`?

>> There’s some remaining technical question:
>> - What’s the right group to put the customizations?
>> - currently I ask user to invoke kv-compact-demon-start
>>  and persistent-variable-demon-start explicitly to
>>  start/restart the services.
>>  Are there better way?
>>  Not sure if those makes sense as minor modes.
> 
> Why not start them lazily when the data is changed (e.g. within
> `kv--ensure-transaction`)?
Sure, that will work, thanks.

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

* Re: New package: resist!
  2021-12-10 19:15               ` Qiantan Hong
@ 2021-12-10 19:24                 ` Philip Kaludercic
  2021-12-10 19:27                   ` [External] : " Drew Adams
  2021-12-10 19:57                   ` Eli Zaretskii
  2021-12-10 19:53                 ` Stefan Monnier
  1 sibling, 2 replies; 50+ messages in thread
From: Philip Kaludercic @ 2021-12-10 19:24 UTC (permalink / raw)
  To: Qiantan Hong
  Cc: Karl Fogel, Tassilo Horn, Stefan Monnier, emacs-devel@gnu.org

Qiantan Hong <qhong@mit.edu> writes:

> I’m thinking the “package” as an extension to Elisp language itself,
> so I didn’t have package prefix in mind. Thus the name like `compact-kv-store`.
>
> Maybe the file should be named `persistence.el`?

I like this name better!

-- 
	Philip Kaludercic



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

* RE: [External] : Re: New package: resist!
  2021-12-10 19:24                 ` Philip Kaludercic
@ 2021-12-10 19:27                   ` Drew Adams
  2021-12-10 19:57                   ` Eli Zaretskii
  1 sibling, 0 replies; 50+ messages in thread
From: Drew Adams @ 2021-12-10 19:27 UTC (permalink / raw)
  To: Philip Kaludercic, Qiantan Hong
  Cc: Karl Fogel, emacs-devel@gnu.org, Stefan Monnier, Tassilo Horn

> > Maybe the file should be named `persistence.el`?
> I like this name better!

andyetshepersisted.el ;-)

https://en.wikipedia.org/wiki/Nevertheless,_she_persisted

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

* Re: New package: resist!
  2021-12-10 19:15               ` Qiantan Hong
  2021-12-10 19:24                 ` Philip Kaludercic
@ 2021-12-10 19:53                 ` Stefan Monnier
  2021-12-10 21:08                   ` [External] : " Drew Adams
  1 sibling, 1 reply; 50+ messages in thread
From: Stefan Monnier @ 2021-12-10 19:53 UTC (permalink / raw)
  To: Qiantan Hong; +Cc: Tassilo Horn, Karl Fogel, emacs-devel@gnu.org

> I’m thinking the “package” as an extension to Elisp language itself,
> so I didn’t have package prefix in mind. Thus the name like `compact-kv-store`.

IMO, *very* few things deserve to be in the "global" namespace beside
`setq`, `lambda`, ...

> Maybe the file should be named `persistence.el`?

I don't have an opinion on the name, as long as you pick one and use it
for both the filename and all the definitions therein ;-)

>> Why not start them lazily when the data is changed (e.g. within
>> `kv--ensure-transaction`)?
> Sure, that will work, thanks.

If you do that, then you can even use a timer that's not repeated, and
instead just make sure subsequent changes will re-start the timer.


        Stefan




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

* Re: New package: resist!
  2021-12-10 19:24                 ` Philip Kaludercic
  2021-12-10 19:27                   ` [External] : " Drew Adams
@ 2021-12-10 19:57                   ` Eli Zaretskii
  2021-12-10 20:19                     ` Alexandre Garreau
  2021-12-10 21:04                     ` Dmitry Gutov
  1 sibling, 2 replies; 50+ messages in thread
From: Eli Zaretskii @ 2021-12-10 19:57 UTC (permalink / raw)
  To: Philip Kaludercic; +Cc: kfogel, qhong, emacs-devel, monnier, tsdh

> From: Philip Kaludercic <philipk@posteo.net>
> Date: Fri, 10 Dec 2021 19:24:36 +0000
> Cc: Karl Fogel <kfogel@red-bean.com>, Tassilo Horn <tsdh@gnu.org>,
>  Stefan Monnier <monnier@iro.umontreal.ca>,
>  "emacs-devel@gnu.org" <emacs-devel@gnu.org>
> 
> Qiantan Hong <qhong@mit.edu> writes:
> 
> > I’m thinking the “package” as an extension to Elisp language itself,
> > so I didn’t have package prefix in mind. Thus the name like `compact-kv-store`.
> >
> > Maybe the file should be named `persistence.el`?
> 
> I like this name better!

I suggest 'against-persistence.el'.



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

* Re: New package: resist!
  2021-12-10 19:57                   ` Eli Zaretskii
@ 2021-12-10 20:19                     ` Alexandre Garreau
  2021-12-10 20:28                       ` Qiantan Hong
  2021-12-10 22:17                       ` Joost Kremers
  2021-12-10 21:04                     ` Dmitry Gutov
  1 sibling, 2 replies; 50+ messages in thread
From: Alexandre Garreau @ 2021-12-10 20:19 UTC (permalink / raw)
  To: Philip Kaludercic, emacs-devel
  Cc: qhong, emacs-devel, kfogel, monnier, tsdh, Eli Zaretskii

Le vendredo, 10-a de decembro 2021, 20-a horo kaj 57:21 CET Eli Zaretskii 
a écrit :
> > From: Philip Kaludercic <philipk@posteo.net>
> > Date: Fri, 10 Dec 2021 19:24:36 +0000
> > Cc: Karl Fogel <kfogel@red-bean.com>, Tassilo Horn <tsdh@gnu.org>,
> > 
> >  Stefan Monnier <monnier@iro.umontreal.ca>,
> >  "emacs-devel@gnu.org" <emacs-devel@gnu.org>
> > 
> > Qiantan Hong <qhong@mit.edu> writes:
> > > I’m thinking the “package” as an extension to Elisp language itself,
> > > so I didn’t have package prefix in mind. Thus the name like
> > > `compact-kv-store`.
> > > 
> > > Maybe the file should be named `persistence.el`?
> > 
> > I like this name better!
> 
> I suggest 'against-persistence.el'.

persist: it’s shorter, so shorter identifiers

maybe even prsist




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

* Re: New package: resist!
  2021-12-10 20:19                     ` Alexandre Garreau
@ 2021-12-10 20:28                       ` Qiantan Hong
  2021-12-10 20:34                         ` Philip Kaludercic
  2021-12-10 22:17                       ` Joost Kremers
  1 sibling, 1 reply; 50+ messages in thread
From: Qiantan Hong @ 2021-12-10 20:28 UTC (permalink / raw)
  To: Alexandre Garreau
  Cc: Philip Kaludercic, emacs-devel@gnu.org, kfogel@red-bean.com,
	monnier@iro.umontreal.ca, tsdh@gnu.org, Eli Zaretskii

> persist: it’s shorter, so shorter identifiers
> 
> maybe even prsist
Sounds good. I’ll do prsist then.

Best,
Qiantan


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

* Re: New package: resist!
  2021-12-10 20:28                       ` Qiantan Hong
@ 2021-12-10 20:34                         ` Philip Kaludercic
  2021-12-10 20:44                           ` Qiantan Hong
                                             ` (2 more replies)
  0 siblings, 3 replies; 50+ messages in thread
From: Philip Kaludercic @ 2021-12-10 20:34 UTC (permalink / raw)
  To: Qiantan Hong
  Cc: emacs-devel@gnu.org, kfogel@red-bean.com,
	monnier@iro.umontreal.ca, Alexandre Garreau, tsdh@gnu.org,
	Eli Zaretskii

Qiantan Hong <qhong@mit.edu> writes:

>> persist: it’s shorter, so shorter identifiers
>> 
>> maybe even prsist
> Sounds good. I’ll do prsist then.

(I know this is bike-shedding, but...) What is the point of leaving out
a single vowel?  Doesn't using a "real" or at least pronounceable word
avoid typos and make it easier to remember?

> Best,
> Qiantan
>

-- 
	Philip Kaludercic



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

* Re: New package: resist!
  2021-12-10 20:34                         ` Philip Kaludercic
@ 2021-12-10 20:44                           ` Qiantan Hong
  2021-12-10 20:54                           ` Alexandre Garreau
  2021-12-10 21:11                           ` [External] : " Drew Adams
  2 siblings, 0 replies; 50+ messages in thread
From: Qiantan Hong @ 2021-12-10 20:44 UTC (permalink / raw)
  To: Philip Kaludercic
  Cc: emacs-devel@gnu.org, kfogel@red-bean.com,
	monnier@iro.umontreal.ca, Alexandre Garreau, tsdh@gnu.org,
	Eli Zaretskii



> On Dec 10, 2021, at 12:34 PM, Philip Kaludercic <philipk@posteo.net> wrote:
> 
> Qiantan Hong <qhong@mit.edu> writes:
> 
>>> persist: it’s shorter, so shorter identifiers
>>> 
>>> maybe even prsist
>> Sounds good. I’ll do prsist then.
> 
> (I know this is bike-shedding, but...) What is the point of leaving out
> a single vowel?  Doesn't using a "real" or at least pronounceable word
> avoid typos and make it easier to remember?
With completion there’re no other package starting with `prs`, but
there is `perl-mode` that also starts with `per`, so `prs` save 25%
of the key strokes in this case. But maybe it doesn’t worth it.

Another factor: prsist is obviously a fake word, but persist is a real *verb*.
persist-variable-* looks stranger to me (it’s obviously grammatically incorrect)
than prsist-variable-*.

Being said that, your argument is also sound and I don’t really have a strong 
opinion on either of them. I’ll wait to see if there’s more comments. If not,
I’ll decide it using a random number generator.

Best,
Qiantan


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

* Re: New package: resist!
  2021-12-10 20:34                         ` Philip Kaludercic
  2021-12-10 20:44                           ` Qiantan Hong
@ 2021-12-10 20:54                           ` Alexandre Garreau
  2021-12-10 21:11                           ` [External] : " Drew Adams
  2 siblings, 0 replies; 50+ messages in thread
From: Alexandre Garreau @ 2021-12-10 20:54 UTC (permalink / raw)
  To: Qiantan Hong, Philip Kaludercic
  Cc: kfogel@red-bean.com, Eli Zaretskii, tsdh@gnu.org,
	monnier@iro.umontreal.ca, emacs-devel@gnu.org

Le vendredo, 10-a de decembro 2021, 21-a horo kaj 34:38 CET Philip 
Kaludercic a écrit :
> Qiantan Hong <qhong@mit.edu> writes:
> >> persist: it’s shorter, so shorter identifiers
> >> 
> >> maybe even prsist
> > 
> > Sounds good. I’ll do prsist then.
> 
> (I know this is bike-shedding, but...) What is the point of leaving out
> a single vowel?  Doesn't using a "real" or at least pronounceable word
> avoid typos and make it easier to remember?

if you spell out the R like p’R-sist, you get the pronounciation of 
persist.  Plus it’s a common tradition to leave out some vowels to make 
identifiers smaller, such as cnt, ptr, itr (notice there’s still a vowel), 
etc.

prsst could be possible, but the double s is weird, it’s less 
recognizable, and prsist looks more like “resist” than “persist” (there’s 
no “e” in the “wrong” place).

I didn’t think of what Qiantan said about completion and verb meaning, but 
it looks sound to me.  Originally I wasn’t so convinced because “persist” 
looked at least a little more beautiful, I proposed it because I thought 
it since “resist” was suggested to be change into something more 
meaningful.



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

* Re: New package: resist!
  2021-12-10 19:57                   ` Eli Zaretskii
  2021-12-10 20:19                     ` Alexandre Garreau
@ 2021-12-10 21:04                     ` Dmitry Gutov
  1 sibling, 0 replies; 50+ messages in thread
From: Dmitry Gutov @ 2021-12-10 21:04 UTC (permalink / raw)
  To: Eli Zaretskii, Philip Kaludercic
  Cc: kfogel, qhong, tsdh, monnier, emacs-devel

On 10.12.2021 22:57, Eli Zaretskii wrote:
> I suggest 'against-persistence.el'.

Viva la Persistance!



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

* RE: [External] : Re: New package: resist!
  2021-12-10 19:53                 ` Stefan Monnier
@ 2021-12-10 21:08                   ` Drew Adams
  0 siblings, 0 replies; 50+ messages in thread
From: Drew Adams @ 2021-12-10 21:08 UTC (permalink / raw)
  To: Stefan Monnier, Qiantan Hong
  Cc: Karl Fogel, emacs-devel@gnu.org, Tassilo Horn

> > Maybe the file should be named `persistence.el`?
> 
> I don't have an opinion on the name, as long as you
> pick one and use it for both the filename and all
> the definitions therein ;-)

Use the same name for the file and its definitions?

I don't think so.  Did you perhaps mean use the same
name for the file and as a _prefix_ for the names of
the things it defines?

Even then, I don't think so.  AFAIK, there's no stated
convention regarding Lisp file names.  But there is a
convention regarding a library's prefix.

So a file name such as `persist.el', in combination
with a prefix such as `pers-', or `kv-, or `xyz-', or
anything else not already taken, would be conventional.

On the other hand, a prefix that in some way reflects
the library (its name or something else) is generally
helpful for users, mnemonically.

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

* RE: [External] : Re: New package: resist!
  2021-12-10 20:34                         ` Philip Kaludercic
  2021-12-10 20:44                           ` Qiantan Hong
  2021-12-10 20:54                           ` Alexandre Garreau
@ 2021-12-10 21:11                           ` Drew Adams
  2021-12-11  4:08                             ` Richard Stallman
  2 siblings, 1 reply; 50+ messages in thread
From: Drew Adams @ 2021-12-10 21:11 UTC (permalink / raw)
  To: Philip Kaludercic, Qiantan Hong
  Cc: emacs-devel@gnu.org, kfogel@red-bean.com,
	monnier@iro.umontreal.ca, Alexandre Garreau, tsdh@gnu.org,
	Eli Zaretskii

> >> maybe even prsist
> > Sounds good. I’ll do prsist then.
> 
> (I know this is bike-shedding, but...) What is the point of leaving out
> a single vowel?  Doesn't using a "real" or at least pronounceable word
> avoid typos and make it easier to remember?

One person's bike-shedding is another's
matter of helpfulness and convenience.

But yes, +1.

If you're looking for a library that persists
things, your search is more likely to find
"persist" than "prsist".  MUCH more.

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

* Re: New package: resist!
  2021-12-10 20:19                     ` Alexandre Garreau
  2021-12-10 20:28                       ` Qiantan Hong
@ 2021-12-10 22:17                       ` Joost Kremers
  2021-12-11  9:33                         ` Qiantan Hong
  1 sibling, 1 reply; 50+ messages in thread
From: Joost Kremers @ 2021-12-10 22:17 UTC (permalink / raw)
  To: Alexandre Garreau
  Cc: Philip Kaludercic, qhong, emacs-devel, kfogel, monnier, tsdh,
	Eli Zaretskii


On Fri, Dec 10 2021, Alexandre Garreau wrote:
>> > Qiantan Hong <qhong@mit.edu> writes:
>> > > I’m thinking the “package” as an extension to Elisp language itself,
>> > > so I didn’t have package prefix in mind. Thus the name like
>> > > `compact-kv-store`.
>> > > 
>> > > Maybe the file should be named `persistence.el`?
[...]
> persist: it’s shorter, so shorter identifiers

Note, though, there's already a package on GNU ELPA called "persist":

https://elpa.gnu.org/packages/persist.html

-- 
Joost Kremers
Life has its moments



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

* Re: [External] : Re: New package: resist!
  2021-12-10 21:11                           ` [External] : " Drew Adams
@ 2021-12-11  4:08                             ` Richard Stallman
  0 siblings, 0 replies; 50+ messages in thread
From: Richard Stallman @ 2021-12-11  4:08 UTC (permalink / raw)
  To: Drew Adams
  Cc: philipk, qhong, emacs-devel, kfogel, monnier, galex-713, tsdh,
	eliz

[[[ To any NSA and FBI agents reading my email: please consider    ]]]
[[[ whether defending the US Constitution against all enemies,     ]]]
[[[ foreign or domestic, requires you to follow Snowden's example. ]]]

Before we add this package to Emacs in any way, we should look at its
interface and think about whether to change the details.

-- 
Dr Richard Stallman (https://stallman.org)
Chief GNUisance of the GNU Project (https://gnu.org)
Founder, Free Software Foundation (https://fsf.org)
Internet Hall-of-Famer (https://internethalloffame.org)





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

* Re: New package: resist!
  2021-12-10 22:17                       ` Joost Kremers
@ 2021-12-11  9:33                         ` Qiantan Hong
  2021-12-11 11:16                           ` Tassilo Horn
  2021-12-11 14:06                           ` Stefan Monnier
  0 siblings, 2 replies; 50+ messages in thread
From: Qiantan Hong @ 2021-12-11  9:33 UTC (permalink / raw)
  To: Joost Kremers, Stefan Monnier
  Cc: Philip Kaludercic, emacs-devel@gnu.org, Karl Fogel,
	Alexandre Garreau, Tassilo Horn, Eli Zaretskii

> Note, though, there's already a package on GNU ELPA called "persist":
> 
> https://elpa.gnu.org/packages/persist.html
Oops, now I have no good idea for name.

> I just looked at the code and I think it should be cleaner w.r.t its use
> of namespace: the file is `resist!.el` and it defines macros and
> functions using the `kv-` prefix as well as the `persistent-` prefix; we
> should unify those 3 names.
After second thought, I think it’s quite hard to reconcile them in a descriptive
way. Does that mean I should split the file into a kv.el and persistent.el?

Is it acceptable that there’re some slight deviation from the
prefix tradition, like make-persistent-variable and kill-persistent-variable?

If to put the package on ELPA, should we also split into two packages?
I think it’s logically one suite of persistence facility though, in that
case, is it good to have two file named kv.el and persistent.el
in a package called Persistence (or to avoid confusion with Persist,
screw it and still call it Resist!)?


Best,
Qiantan


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

* Re: New package: resist!
  2021-12-11  9:33                         ` Qiantan Hong
@ 2021-12-11 11:16                           ` Tassilo Horn
  2021-12-11 14:06                           ` Stefan Monnier
  1 sibling, 0 replies; 50+ messages in thread
From: Tassilo Horn @ 2021-12-11 11:16 UTC (permalink / raw)
  To: Qiantan Hong
  Cc: Philip Kaludercic, Joost Kremers, emacs-devel, Karl Fogel,
	Stefan Monnier, Alexandre Garreau, Eli Zaretskii

Qiantan Hong <qhong@mit.edu> writes:

>> Note, though, there's already a package on GNU ELPA called "persist":
>> 
>> https://elpa.gnu.org/packages/persist.html
> Oops, now I have no good idea for name.

Maybe pkv or pkvs for persistent key-value store?

Bye,
Tassilo



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

* Re: New package: resist!
  2021-12-11  9:33                         ` Qiantan Hong
  2021-12-11 11:16                           ` Tassilo Horn
@ 2021-12-11 14:06                           ` Stefan Monnier
  2021-12-11 14:27                             ` Qiantan Hong
  2021-12-11 21:01                             ` Alexandre Garreau
  1 sibling, 2 replies; 50+ messages in thread
From: Stefan Monnier @ 2021-12-11 14:06 UTC (permalink / raw)
  To: Qiantan Hong
  Cc: Joost Kremers, Alexandre Garreau, Philip Kaludercic, Karl Fogel,
	Tassilo Horn, Eli Zaretskii, emacs-devel@gnu.org

Qiantan Hong [2021-12-11 09:33:04] wrote:
>> Note, though, there's already a package on GNU ELPA called "persist":
>> https://elpa.gnu.org/packages/persist.html
> Oops, now I have no good idea for name.

If you look at persist.el (always a good idea when a package by the
same name shows up), you'll see it has very similar aims.
`org-persist.el` as well.

So it looks like a good opportunity to see if/how you can improve your
package such that it can be either build on top of those packages, or
completely replace some of those packages, or replace some part of
those packages.

> Is it acceptable that there’re some slight deviation from the
> prefix tradition, like make-persistent-variable and kill-persistent-variable?

I hate those deviations, to be honest.  And they're incompatible with
the new symbol shorthand feature.


        Stefan




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

* Re: New package: resist!
  2021-12-11 14:06                           ` Stefan Monnier
@ 2021-12-11 14:27                             ` Qiantan Hong
  2021-12-11 21:01                             ` Alexandre Garreau
  1 sibling, 0 replies; 50+ messages in thread
From: Qiantan Hong @ 2021-12-11 14:27 UTC (permalink / raw)
  To: Stefan Monnier, phillip.lord@russet.org.uk
  Cc: Philip Kaludercic, Joost Kremers, emacs-devel@gnu.org, Karl Fogel,
	Alexandre Garreau, Tassilo Horn, Eli Zaretskii

> If you look at persist.el (always a good idea when a package by the
> same name shows up), you'll see it has very similar aims.
> `org-persist.el` as well.
> 
> So it looks like a good opportunity to see if/how you can improve your
> package such that it can be either build on top of those packages, or
> completely replace some of those packages, or replace some part of
> those packages.
My current plan is to split what’s in resist!.el into two packages
- kv.el, which provides persistent key value store, and should
  support multiple backends. My log store would be one,
  what’s in persist.el already would be one, and potentially
  SQLite3/gdbm/recutils... ones in the future.
- My persistent variable stuff is of different flavor from those
  already in persist.el, mine being more transparent.
  I hope I can let my stuff join persist-* namespace,
  and replace what’s already in persist.el with wrappers
  for backward compatibility.
  But I would need to hear back from author of persist.el
  first.

Best,
Qiantan


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

* Re: New package: resist!
  2021-12-11 14:06                           ` Stefan Monnier
  2021-12-11 14:27                             ` Qiantan Hong
@ 2021-12-11 21:01                             ` Alexandre Garreau
  2021-12-11 21:13                               ` Qiantan Hong
  1 sibling, 1 reply; 50+ messages in thread
From: Alexandre Garreau @ 2021-12-11 21:01 UTC (permalink / raw)
  To: Qiantan Hong, emacs-devel
  Cc: Philip Kaludercic, Joost Kremers, emacs-devel@gnu.org, Karl Fogel,
	Stefan Monnier, Tassilo Horn, Eli Zaretskii

Le sabato, 11-a de decembro 2021, 15-a horo kaj 6:14 CET Stefan Monnier a 
écrit :
> Qiantan Hong [2021-12-11 09:33:04] wrote:
> >> Note, though, there's already a package on GNU ELPA called "persist":
> >> https://elpa.gnu.org/packages/persist.html
> > 
> > Oops, now I have no good idea for name.
> 
> If you look at persist.el (always a good idea when a package by the
> same name shows up), you'll see it has very similar aims.
> `org-persist.el` as well.
> 
> So it looks like a good opportunity to see if/how you can improve your
> package such that it can be either build on top of those packages, or
> completely replace some of those packages, or replace some part of
> those packages.

Btw, eieio-persistent (which you didn’t cite in this mail) also stores one 
value per file, just as persist.el, so they’re technically compatible.

I don’t know how org-persist stores data, however.

But it would be nice if they all shared a common implementation, so it 
would be possible to configure a single backend for all of them at will 
(possible, you could still accept that eieio uses something different from 
org-persist, since they’re on different levels, and you could also configure 
per package, I guess), without for the user to have to multiply its 
internal knowledge of more and more software.



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

* Re: New package: resist!
  2021-12-11 21:01                             ` Alexandre Garreau
@ 2021-12-11 21:13                               ` Qiantan Hong
  2021-12-11 21:26                                 ` Alexandre Garreau
  2021-12-12  1:05                                 ` Michael Heerdegen
  0 siblings, 2 replies; 50+ messages in thread
From: Qiantan Hong @ 2021-12-11 21:13 UTC (permalink / raw)
  To: Alexandre Garreau
  Cc: Philip Kaludercic, Joost Kremers, emacs-devel@gnu.org, Karl Fogel,
	Stefan Monnier, Tassilo Horn, Eli Zaretskii

> Btw, eieio-persistent (which you didn’t cite in this mail) also stores one 
> value per file, just as persist.el, so they’re technically compatible.
I think eieio-persistent occupies a weird position here.
It’s not really an implementation of a persistent (key value) store,
it’s more like an object oriented prin1.
I’m not sure how to incorporate eieio-persistent into our program yet.


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

* Re: New package: resist!
  2021-12-11 21:13                               ` Qiantan Hong
@ 2021-12-11 21:26                                 ` Alexandre Garreau
  2021-12-11 21:53                                   ` Alexandre Garreau
  2021-12-12  1:05                                 ` Michael Heerdegen
  1 sibling, 1 reply; 50+ messages in thread
From: Alexandre Garreau @ 2021-12-11 21:26 UTC (permalink / raw)
  To: Qiantan Hong
  Cc: Philip Kaludercic, Joost Kremers, emacs-devel@gnu.org, Karl Fogel,
	Stefan Monnier, Tassilo Horn, Eli Zaretskii

Le sabato, 11-a de decembro 2021 22-a horo kaj 13:04 CET, vous avez écrit 
:
> > Btw, eieio-persistent (which you didn’t cite in this mail) also stores
> > one value per file, just as persist.el, so they’re technically
> > compatible.
> I think eieio-persistent occupies a weird position here.
> It’s not really an implementation of a persistent (key value) store,
> it’s more like an object oriented prin1.
> I’m not sure how to incorporate eieio-persistent into our program yet.

It’s very weird because you define one file per object… so yeah it’s not a 
store at all, it just makes objects persist.  But if anyone wants objects 
to persist all in a single store, instead of taking up a lot of different 
spare files (or at least to a predefined directory), they might want to use 
your logging kv, sqlite, gdbm, etc.

What should be implemented in eieio-persistent is a way to define a default 
place to store objects.  By default it would be, for instance, a 
directory, which would be not an object slot but a class attribute.  It 
would make so that when you create an object without specifying a “file” 
slot, the “directory” slot would be used to automatically generate a file 
in it.  And then the directory would be used to restore objects at 
startup.  There would be a global default directory defined for the class 
eieio-persistent, inherited by all persistent objects, and customizable 
through customize.  But you could define child class to eieio-persistent 
with other directories (or subdirectories, if it’s a relative path).  
Possibly, if we want to be strictly compatible with the current (by 
default, if we don’t specify a “file” slot, non-working) behavior, we could 
define a eieio-stored subclass to eieio-persistent, and only this one would 
act as I said.

Then, we could also make customizable the fact that it wouldn’t use one 
file per object, just as persist.el, but also use another backend.

But we should hack eieio-base so that eieio-persistent functions use 
persist.el



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

* Re: New package: resist!
  2021-12-11 21:26                                 ` Alexandre Garreau
@ 2021-12-11 21:53                                   ` Alexandre Garreau
  0 siblings, 0 replies; 50+ messages in thread
From: Alexandre Garreau @ 2021-12-11 21:53 UTC (permalink / raw)
  To: Qiantan Hong, emacs-devel
  Cc: Philip Kaludercic, Joost Kremers, emacs-devel@gnu.org, Karl Fogel,
	Stefan Monnier, Alexandre Garreau, Tassilo Horn, Eli Zaretskii

Le sabato, 11-a de decembro 2021, 22-a horo kaj 26:13 CET Alexandre 
Garreau a écrit :
> Le sabato, 11-a de decembro 2021 22-a horo kaj 13:04 CET, vous avez
> écrit
> > > Btw, eieio-persistent (which you didn’t cite in this mail) also
> > > stores
> > > one value per file, just as persist.el, so they’re technically
> > > compatible.
> > 
> > I think eieio-persistent occupies a weird position here.
> > It’s not really an implementation of a persistent (key value) store,
> > it’s more like an object oriented prin1.
> > I’m not sure how to incorporate eieio-persistent into our program yet.
> 
> It’s very weird because you define one file per object… so yeah it’s not
> a store at all, it just makes objects persist.  But if anyone wants
> objects to persist all in a single store, instead of taking up a lot of
> different spare files (or at least to a predefined directory), they
> might want to use your logging kv, sqlite, gdbm, etc.

Moreover, eieio persistence mechanism doesn’t allow to *automatically* 
restore objects.  So you have to manually restore the file name somewhere 
else (wait what’s the point of saving if you still have something else to 
save (necessarily by another mean) in order to be able to restore?).  A 
such mechanism should, for instance, take the filename and use that as a 
variable name to put the object into.



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

* Re: New package: resist!
  2021-12-11 21:13                               ` Qiantan Hong
  2021-12-11 21:26                                 ` Alexandre Garreau
@ 2021-12-12  1:05                                 ` Michael Heerdegen
  2021-12-12  1:18                                   ` Alexandre Garreau
  2021-12-12  1:30                                   ` Qiantan Hong
  1 sibling, 2 replies; 50+ messages in thread
From: Michael Heerdegen @ 2021-12-12  1:05 UTC (permalink / raw)
  To: emacs-devel

Qiantan Hong <qhong@mit.edu> writes:

> It’s not really an implementation of a persistent (key value) store,
> it’s more like an object oriented prin1.

How does your package handle values whose print syntax can't just be
`read' to recreate the value?

Michael.




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

* Re: New package: resist!
  2021-12-12  1:05                                 ` Michael Heerdegen
@ 2021-12-12  1:18                                   ` Alexandre Garreau
  2021-12-12  1:35                                     ` Michael Heerdegen
  2021-12-12  1:30                                   ` Qiantan Hong
  1 sibling, 1 reply; 50+ messages in thread
From: Alexandre Garreau @ 2021-12-12  1:18 UTC (permalink / raw)
  To: emacs-devel

Le dimanĉo, 12-a de decembro 2021, 2-a horo kaj 5:52 CET Michael Heerdegen 
a écrit :
> Qiantan Hong <qhong@mit.edu> writes:
> 
> 
> 
> > It’s not really an implementation of a persistent (key value) store,
> > it’s more like an object oriented prin1.
> 
> How does your package handle values whose print syntax can't just be
> `read' to recreate the value?

that’s an issue for pretty much any persistence package, and it would just 
as well be while using sqlite, persist, eieio-persistent or anything else.

You must for each of these edge cases make a special condition to invent 
some sort of print value, and recognize it back when reading it…  That is, 
you must invent a way to prin1 it anyway.  I mean storing data necessarily 
requires some sort of serialization (be it native dumping).  It’s part of 
the philosophy of lisp anyway to make anything readable and printable.

Now we could try to see what would happen concretely: what kind of values 
are you thinking to?



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

* Re: New package: resist!
  2021-12-12  1:05                                 ` Michael Heerdegen
  2021-12-12  1:18                                   ` Alexandre Garreau
@ 2021-12-12  1:30                                   ` Qiantan Hong
  2021-12-12  1:33                                     ` Qiantan Hong
  1 sibling, 1 reply; 50+ messages in thread
From: Qiantan Hong @ 2021-12-12  1:30 UTC (permalink / raw)
  To: Michael Heerdegen; +Cc: Alexandre Garreau, emacs-devel@gnu.org

>> It’s not really an implementation of a persistent (key value) store,
>> it’s more like an object oriented prin1.
> 
> How does your package handle values whose print syntax can't just be
> `read' to recreate the value?
Currently I haven’t account for it, it will prob — it’s easy to add
a `condition-case` that catches error and warns in the next revision.
Do you have any better suggestions?

> You must for each of these edge cases make a special condition to invent 
> some sort of print value, and recognize it back when reading it…  That is, 
> you must invent a way to prin1 it anyway. 
AFAIU, eieio-persistent looks almost like a generic prin1.
However it doesn’t work on native Lisp objects —
it basically does the thing what we need but with a very weird interface
(e.g. it expect the object itself to remember where it should write to,
which makes it basically impossible to define sensible method on native objects).
An interface like 
(object-write THIS &optional PRINTCHARFUN) makes much more sense to me.

How can we fix this? If this is fixed, we could use such extensible prin1 for all
persistence operation.

Also another namespace problem: the extensible prin1 probably shouldn’t live
in persist-*, because kv-* will depend on this extensible prin1. 
But it now becomes unclear what namespace it should lives in (kv-* doesn’t make
much sense IMO).

I’m now more convinced that this whole matter is more of an Elisp language
extension rather than a package. If we insist to not utilize global namespace,
it probably would need to be divided into lots of namespace.
Is it agreed that each file should use only one namespaces?
Then we would also need to scatter code into quite a few files.

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

* Re: New package: resist!
  2021-12-12  1:30                                   ` Qiantan Hong
@ 2021-12-12  1:33                                     ` Qiantan Hong
  0 siblings, 0 replies; 50+ messages in thread
From: Qiantan Hong @ 2021-12-12  1:33 UTC (permalink / raw)
  To: Michael Heerdegen; +Cc: Alexandre Garreau, emacs-devel@gnu.org

>> It’s not really an implementation of a persistent (key value) store,
>>> it’s more like an object oriented prin1.
>> 
>> How does your package handle values whose print syntax can't just be
>> `read' to recreate the value?
> Currently I haven’t account for it, it will prob 
* it will probably just error when loading the store.

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

* Re: New package: resist!
  2021-12-12  1:18                                   ` Alexandre Garreau
@ 2021-12-12  1:35                                     ` Michael Heerdegen
  2021-12-12  1:38                                       ` Qiantan Hong
  2021-12-12  1:59                                       ` Alexandre Garreau
  0 siblings, 2 replies; 50+ messages in thread
From: Michael Heerdegen @ 2021-12-12  1:35 UTC (permalink / raw)
  To: emacs-devel

Alexandre Garreau <galex-713@galex-713.eu> writes:

> > > It’s not really an implementation of a persistent (key value) store,
> > > it’s more like an object oriented prin1.
> > 
> > How does your package handle values whose print syntax can't just be
> > `read' to recreate the value?
>
> that’s an issue for pretty much any persistence package, and it would just 
> as well be while using sqlite, persist, eieio-persistent or anything
> else.

Yes, but it's the hard part.  It is what makes saving the Gnus registry
slow, and it is what makes eieio-persistent look "like an object
oriented prin1".

> Now we could try to see what would happen concretely: what kind of values 
> are you thinking to?

The Gnus registry is one example.  Apart from that: most values,
actually, apart from trivial ones: lists, hash-tables, structs.  Most
applications will not just need to save integers and strings.

Michael.




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

* Re: New package: resist!
  2021-12-12  1:35                                     ` Michael Heerdegen
@ 2021-12-12  1:38                                       ` Qiantan Hong
  2021-12-12  1:52                                         ` Michael Heerdegen
  2021-12-12  1:59                                       ` Alexandre Garreau
  1 sibling, 1 reply; 50+ messages in thread
From: Qiantan Hong @ 2021-12-12  1:38 UTC (permalink / raw)
  To: Michael Heerdegen; +Cc: emacs-devel@gnu.org


> actually, apart from trivial ones: lists, hash-tables, structs.  Most
> applications will not just need to save integers and strings.
Lists have readable print syntax in almost every Lisps,
and hash-tables and structs both have readable print syntax
in Emacs Lisp

— that’s one aspect where Emacs Lisp is better than Common Lisp.

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

* Re: New package: resist!
  2021-12-12  1:38                                       ` Qiantan Hong
@ 2021-12-12  1:52                                         ` Michael Heerdegen
  2021-12-12  2:02                                           ` Alexandre Garreau
  0 siblings, 1 reply; 50+ messages in thread
From: Michael Heerdegen @ 2021-12-12  1:52 UTC (permalink / raw)
  To: emacs-devel

Qiantan Hong <qhong@mit.edu> writes:

> Lists have readable print syntax in almost every Lisps,
> and hash-tables and structs both have readable print syntax
> in Emacs Lisp

It's onyl that you can't use it if one of the elements does not have
readable print syntax.  So you have to traverse the list, and you end up
doing the same as eieio-persistent needs to.

Michael.




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

* Re: New package: resist!
  2021-12-12  1:35                                     ` Michael Heerdegen
  2021-12-12  1:38                                       ` Qiantan Hong
@ 2021-12-12  1:59                                       ` Alexandre Garreau
  2021-12-12  2:56                                         ` Qiantan Hong
  2021-12-12  6:42                                         ` Michael Heerdegen
  1 sibling, 2 replies; 50+ messages in thread
From: Alexandre Garreau @ 2021-12-12  1:59 UTC (permalink / raw)
  To: emacs-devel

Le dimanĉo, 12-a de decembro 2021, 2-a horo kaj 35:48 CET Michael 
Heerdegen a écrit :
> Alexandre Garreau <galex-713@galex-713.eu> writes:
> 
> 
> 
> 
> > > How does your package handle values whose print syntax can't just be
> > > `read' to recreate the value?
> 
> 
> 
> > that’s an issue for pretty much any persistence package, and it would
> > just as well be while using sqlite, persist, eieio-persistent or
> > anything else.
> 
> Yes, but it's the hard part.  It is what makes saving the Gnus registry
> slow, and it is what makes eieio-persistent look "like an object
> oriented prin1".

No, as said before you’re conflating two separated issues: variable 
persistence, and element-by-element retrieving (from a kv store).  We use 
a kv-store for variable persistence, but that feature is different from the 
later one because you save each value once in its entirety, and then fetch 
it back once in its entirety.  So reading or printing it is actually 
necessary, you cannot make it faster, and it’s not a bottleneck (I/O is 
the bottleneck then), you have to serialize anyway.  When you want to 
fetch individual elements without restoring the whole value in its 
entirety (or perhaps doing just as if it was, in a lazy way, but that’s 
yet again a new feature which has not been discussed yet, and which enters 
in competition with the kernel’s paging/swaping features), you need to 
destructure it manually, you don’t do that automatically, and you want its 
restoration to be coordinated in some determined way… that’s not variable 
persistence.  So the problem you’re talking about, where “read” and 
“write” are slow, is not variable persistence.

I feel like the features we came to discuss are so abstract people keep 
confusing and conflating them together.  They all in some way slightly 
overtake one onto the other, so it makes it understanding overall even 
more difficult…

> > Now we could try to see what would happen concretely: what kind of
> > values are you thinking to?
> 
> The Gnus registry is one example.  Apart from that: most values,
> actually, apart from trivial ones: lists, hash-tables, structs.  Most
> applications will not just need to save integers and strings.

That’s a separate problem, again.  These value are perfectly printable.  
You just claim we can store them so that they’re more efficient to 
(partially) retrieve.  And that’s not a problem solveable by variable 
persistence (since the concept of variable persistence is you restore back 
the entire variable into memory), so it’s not even related to the current 
feature being discussed.

If you want to solve that, you have to use the lower level feature we 
discussed before, a kv storage mechanism, to store your hashtable or 
alist.  A struct is by definition limited so there’s little interest in 
storing it strangely (but you store an array of them you may want a 
relational database, indeed… except until now we only discussed about 
needs of a simple kv storage, which is lower level than a relational 
database).  A *general* list, or an array, may be amenable to a hashtable/
alist with succesive increments as keys, but if you have any more adapted 
idea I’d like to hear it (because otherwise it looks a little overkill).

But you then have to *manually* prepare a store for that, and manually 
split up your sequence into that store.

We cannot apply that to the issue discussed now, variable persistence, 
hence any variable, because that would mean simply recursively make all 
lisp objects which are sequences stored into kv stores (because, as you 
know, a hashtable can contain another hashtable, and two sequences can 
share elements), that’s just overkill, it consists in changing the entire 
elisp runtime, and in the end you just replace every variable with a query 
to a relational database… which is interesting, but has not been discussed 
until now.  You would make one table for each type, and pointers would be 
replaced by foreign keys.  Is that what you want? is that what you’re 
talking about?  That would be the “most efficient way” if we wanted to store 
all emacs ram to disk, and yet be able to retrieve it while being sure to 
do it most efficiently wrt what a relational database can do, with the least 
reading from disk and the least stuff kept into memory.

The ideas in this discussion start getting very weird… now I’m wondering 
if it would be possible, in a perfect world, to at the same time describe 
perfectly the native way of storing variables/(PI/repositionable)pointers/
number in memory so it can directly be dumped to disk and portably be 
decoded at will, and design a relational database format so that it can be 
mmaped to memory and be used to represent variables and complex objects 
directly (or the otherway around: encode, and defragment/fragment/group 
(through action of a special garbage collector) objects into memory so 
that if it’s dumped to disk it gives a most efficient relational database 
data, and yet be effecient to read (like data often used together would be 
near each other)), and use that to represent all data on a computer, for 
every programming language/runtime/software…



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

* Re: New package: resist!
  2021-12-12  1:52                                         ` Michael Heerdegen
@ 2021-12-12  2:02                                           ` Alexandre Garreau
  2021-12-12  2:11                                             ` Michael Heerdegen
  0 siblings, 1 reply; 50+ messages in thread
From: Alexandre Garreau @ 2021-12-12  2:02 UTC (permalink / raw)
  To: emacs-devel

Le dimanĉo, 12-a de decembro 2021, 2-a horo kaj 52:56 CET Michael 
Heerdegen a écrit :
> Qiantan Hong <qhong@mit.edu> writes:
> 
> 
> 
> > Lists have readable print syntax in almost every Lisps,
> > and hash-tables and structs both have readable print syntax
> > in Emacs Lisp
> 
> It's onyl that you can't use it if one of the elements does not have
> readable print syntax.  So you have to traverse the list, and you end up
> doing the same as eieio-persistent needs to.

But then lists are not the “elements which do not have readable print 
syntax”, while we asked you example of such elements.

Yes, you need to traverse the list, but to print a list you traverse it 
anyway.  The idea of an “extensible print” is that during that recursive 
traversing that print already does, if it encounters a “object that it 
doesn’t know how to print”, we teach it to use a function that knows how 
to print it in a such way that it can be read again.




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

* Re: New package: resist!
  2021-12-12  2:02                                           ` Alexandre Garreau
@ 2021-12-12  2:11                                             ` Michael Heerdegen
  2021-12-12  2:18                                               ` Alexandre Garreau
  0 siblings, 1 reply; 50+ messages in thread
From: Michael Heerdegen @ 2021-12-12  2:11 UTC (permalink / raw)
  To: emacs-devel

Alexandre Garreau <galex-713@galex-713.eu> writes:

> Yes, you need to traverse the list, but to print a list you traverse it 
> anyway.  The idea of an “extensible print” is that during that recursive 
> traversing that print already does, if it encounters a “object that it 
> doesn’t know how to print”, we teach it to use a function that knows how 
> to print it in a such way that it can be read again.

This is what eieio-persistent does and what makes it slow.  What would
your package would have to offer then?

Michael.




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

* Re: New package: resist!
  2021-12-12  2:11                                             ` Michael Heerdegen
@ 2021-12-12  2:18                                               ` Alexandre Garreau
  0 siblings, 0 replies; 50+ messages in thread
From: Alexandre Garreau @ 2021-12-12  2:18 UTC (permalink / raw)
  To: emacs-devel

Le dimanĉo, 12-a de decembro 2021, 3-a horo kaj 11:29 CET Michael 
Heerdegen a écrit :
> Alexandre Garreau <galex-713@galex-713.eu> writes:
> 
> 
> 
> > Yes, you need to traverse the list, but to print a list you traverse
> > it
> > anyway.  The idea of an “extensible print” is that during that
> > recursive traversing that print already does, if it encounters a
> > “object that it doesn’t know how to print”, we teach it to use a
> > function that knows how to print it in a such way that it can be read
> > again.
> 
> This is what eieio-persistent does and what makes it slow.  What would
> your package would have to offer then?

That’s what any serialisation method do.  It’s necessary.  Unless your 
data is compacted adjacently into memory (some garbage collectors do that, 
not all of them) so you can “serialize” by directly dumping a block of 
memory onto disk.  But nobody do that, because it’s unportable.

So my question is: compared to what?

Our package (actually there would likely be between 2 and 4 packages, with 
between 3 and 4 layers of abstraction, but we’re talking about the highest 
one) offer an interface so that some chosen variable are saved and restored 
between emacs’ sessions.  It’s not even a question of rapidity.  And 
there’s no “faster competitor”.

If you want not to have to access objects, which are all recursive, and 
all of arbitrary dimension, and since they’re lisp, all able to contain 
arbitrary type of data, there’s not even *one* relational database that 
can handle it correctly now (or maybe is that what nosql is about? dunno).  
You are talking about an inexistent feature nobody ever talked about, and 
which has not been implemented before by anybody.



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

* Re: New package: resist!
  2021-12-12  1:59                                       ` Alexandre Garreau
@ 2021-12-12  2:56                                         ` Qiantan Hong
  2021-12-12  6:42                                         ` Michael Heerdegen
  1 sibling, 0 replies; 50+ messages in thread
From: Qiantan Hong @ 2021-12-12  2:56 UTC (permalink / raw)
  To: Alexandre Garreau; +Cc: Michael Heerdegen, emacs-devel@gnu.org


> On Dec 11, 2021, at 5:59 PM, Alexandre Garreau <galex-713@galex-713.eu> wrote:
> 
> If you want to solve that, you have to use the lower level feature we 
> discussed before, a kv storage mechanism, to store your hashtable or 
> alist.  A struct is by definition limited so there’s little interest in 
> storing it strangely (but you store an array of them you may want a 
> relational database, indeed… except until now we only discussed about 
> needs of a simple kv storage, which is lower level than a relational 
> database).  A *general* list, or an array, may be amenable to a hashtable/
> alist with succesive increments as keys, but if you have any more adapted 
> idea I’d like to hear it (because otherwise it looks a little overkill).
> 
> But you then have to *manually* prepare a store for that, and manually 
> split up your sequence into that store.
In fact I think I can do better for these “second-level” key-value mapping
pattern, e.g. a persistent variable bound to a hash-table/alist.
I can translate them to a list key in the .persistent-variables store,
e.g. (variable-symbol key-in-the-hash-table). We can even support more 
indirections.

> This is what eieio-persistent does and what makes it slow.  What would
> your package would have to offer then?
Please read the package description.


Best,
Qiantan


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

* Re: New package: resist!
  2021-12-12  1:59                                       ` Alexandre Garreau
  2021-12-12  2:56                                         ` Qiantan Hong
@ 2021-12-12  6:42                                         ` Michael Heerdegen
  1 sibling, 0 replies; 50+ messages in thread
From: Michael Heerdegen @ 2021-12-12  6:42 UTC (permalink / raw)
  To: emacs-devel

Alexandre Garreau <galex-713@galex-713.eu> writes:

>  and in the end you just replace every variable with a query to a
> relational database… which is interesting, but has not been discussed
> until now.  You would make one table for each type, and pointers would
> be replaced by foreign keys.  Is that what you want? is that what
> you’re talking about?

No, not really.  I wanted to point to the problems of saving Elisp data
I know from eieio-persistent, but I see you are aware of them.  Since I
did not really understand the purpose of your package yet let me have a
look now.

Michael.




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

end of thread, other threads:[~2021-12-12  6:42 UTC | newest]

Thread overview: 50+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-12-08 20:55 New package: resist! Qiantan Hong
2021-12-09  2:48 ` Karl Fogel
2021-12-09  6:59   ` Qiantan Hong
2021-12-09  7:57     ` Óscar Fuentes
2021-12-09  8:05       ` Qiantan Hong
2021-12-09  8:09       ` Qiantan Hong
2021-12-09 13:24       ` Stefan Monnier
2021-12-09  9:15   ` Tassilo Horn
2021-12-09  9:25     ` Qiantan Hong
2021-12-09  9:36       ` Tassilo Horn
2021-12-09 20:37         ` Qiantan Hong
2021-12-10 18:25           ` Qiantan Hong
2021-12-10 18:59             ` Stefan Monnier
2021-12-10 19:15               ` Qiantan Hong
2021-12-10 19:24                 ` Philip Kaludercic
2021-12-10 19:27                   ` [External] : " Drew Adams
2021-12-10 19:57                   ` Eli Zaretskii
2021-12-10 20:19                     ` Alexandre Garreau
2021-12-10 20:28                       ` Qiantan Hong
2021-12-10 20:34                         ` Philip Kaludercic
2021-12-10 20:44                           ` Qiantan Hong
2021-12-10 20:54                           ` Alexandre Garreau
2021-12-10 21:11                           ` [External] : " Drew Adams
2021-12-11  4:08                             ` Richard Stallman
2021-12-10 22:17                       ` Joost Kremers
2021-12-11  9:33                         ` Qiantan Hong
2021-12-11 11:16                           ` Tassilo Horn
2021-12-11 14:06                           ` Stefan Monnier
2021-12-11 14:27                             ` Qiantan Hong
2021-12-11 21:01                             ` Alexandre Garreau
2021-12-11 21:13                               ` Qiantan Hong
2021-12-11 21:26                                 ` Alexandre Garreau
2021-12-11 21:53                                   ` Alexandre Garreau
2021-12-12  1:05                                 ` Michael Heerdegen
2021-12-12  1:18                                   ` Alexandre Garreau
2021-12-12  1:35                                     ` Michael Heerdegen
2021-12-12  1:38                                       ` Qiantan Hong
2021-12-12  1:52                                         ` Michael Heerdegen
2021-12-12  2:02                                           ` Alexandre Garreau
2021-12-12  2:11                                             ` Michael Heerdegen
2021-12-12  2:18                                               ` Alexandre Garreau
2021-12-12  1:59                                       ` Alexandre Garreau
2021-12-12  2:56                                         ` Qiantan Hong
2021-12-12  6:42                                         ` Michael Heerdegen
2021-12-12  1:30                                   ` Qiantan Hong
2021-12-12  1:33                                     ` Qiantan Hong
2021-12-10 21:04                     ` Dmitry Gutov
2021-12-10 19:53                 ` Stefan Monnier
2021-12-10 21:08                   ` [External] : " Drew Adams
2021-12-09 13:56 ` Stefan Kangas

Code repositories for project(s) associated with this public inbox

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

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).