emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Incorporating caching into defgroup/defcustom/defvar for Emacs 25


From: Sean Allred
Subject: Incorporating caching into defgroup/defcustom/defvar for Emacs 25
Date: Sun, 1 Feb 2015 10:46:56 -0600

Hi all,

Since this is a long email (sorry!), an executive summary: many Emacs 
applications use data that is persistent from session-to-session. The mechanism 
for doing so varies from application-to-application, but there are a few 
packages on the ELPAs that promise this, notably cache, pcache, and the new 
stash.el (my own creation for sx.el, both on github). I’ve discovered a lot of 
overlap in the way I’ve designed stash.el and the way the defgroup/defcustom 
system already works, so I’m curious to see how open you all are about 
introducing caching functionality baked into Emacs. defgroup and defcustom 
aren’t so difficult, but defvar (being a C function) introduces concerns that 
I’ve yet to truly research / understand.

One of the reasons that makes Emacs so awesome (or at least interesting) is the 
variety and number of full-blown application written in/for Emacs. Gnus and Org 
are prime examples, and *nothing* would be the same (for me) without Ido. All 
of these applications use on-disk data to keep information from session to 
session. This need is hardly limited to Emacs internally, too; Artur and I have 
been at work on sx.el (on github), another moderately complex Emacs application 
that uses (and outright needs) on-disk data. Most veritable applications use 
on-disk data, and I can only guess that they all do so with an in-house 
mechanic. The use-case is there.

There are a few caching libraries on the ELPAs at this time: cache, pcache, and 
stash (my own creation for sx.el). In my honest opinion,

- `cache’ is too simple. For one, it doesn’t even save its data! It merely 
provides a means for cached data to expire - a necessary utility for full 
support.
- `pcache’ is too complex (for my taste). It’s not immediately apparent 
where/how the data is stored. (Disclaimer: I have absolutely zero experience 
with eieio, its sole dependency.) As an added :(, it’s not available on the GNU 
ELPA.
- `stash’ is, I think, a good compromise between the two, though some filling 
out has to be done on the featureset. For example, it currently does not 
support cache timeouts. SX hasn’t needed it yet, but I’m certain other 
applications would. I’m, uhhh, I’m working on it :)

Something I’ve noticed in writing stash.el (and discussing it with Artur a bit) 
is that I’m duplicating functionality. To see this, let me explain (briefly) 
how stash.el works:

- &optional Programmer defines an ‘application’. This application implies a 
subdirectory within the over-arching `stash-directory’ where data is saved at 
some programmer-defined interval.
- Programmer defines a `stash’, optionally belonging to an application, with an 
associated filename. This filename is where this `stash’ is saved to disk as 
interpreted by `prin1-to-string'. (A `stash’ is just a variable with a few 
symbol-properties as metadata.)
- ...
  From this point on, the programmer just sets the variable’s value normally 
(with set/setq/etc.). On an idle-timer (set up by defining the application - 
there is a ’null’ application set to a minute’s idle time), the entire 
application is written to disk.

There are a few flaws in this approach (for example, not every variable has 
changed from the time it was last saved), but it’s working out pretty well. The 
most glaring flaw in this design is the duplication of the group-variable 
association already available (or conceptually so) in the 
defgroup/defcustom/defvar system. Given its generally applicability, I think 
caching in this (or similar) fashion would be a good addition to the system via 
keyword arguments to those three macros:

    (defgroup sx nil
      "Customization group for the `sx' package."
      :prefix "sx-"
      :tag "SX"
      :group ‘applications)
     ; => Would prepare to create a folder called “sx” in 
`customize-cache-directory’
    
    (defcustom sx-init-hook nil
      "Hook run when SX initializes.
    Run after `sx-init--internal-hook'."
      :group 'sx
      :type ‘hook
      :cache “init-hook.el”)
     ; => Would prepare to create a file called “init-hook.el” in 
`customize-cache-directory’/sx
    
    (defvar sx-variable :group ’sx :cache t :expire 60)
     ; => same as above, but basename defaults to “sx-variable” set to expire 
after one minute of inactivity

It’s this last that I’m most concerned about: `defvar’ is defined in the C 
source code. I haven’t taken the slightest peek at Emacs’ C sources, but I’d 
reckon there wouldn’t be a simple analog from the approach I took in stash.el. 
I’m just not sure. Perhaps the functionality can be moved to a Lisp defvar*.

I see a conceptual overlap with Customize’s own managed `custom-set-variables’ 
form, but they aren’t quite the same thing. It’s worth pointing out the 
similarity, but I’m not sure what to make of it.

I know this is a long email, so many thanks for reading it through. I’d really 
like to know interested thoughts on the topic. I’m perfectly willing and able 
to implement the functionality (or at least do most of the legwork) pending the 
necessary FSF paperwork, but it would be a non-trivial undertaking in an 
already busy schedule. Moreover, I’m sure there are multiple considerations 
I’ve missed :)

Best,
Sean Allred


reply via email to

[Prev in Thread] Current Thread [Next in Thread]