On Jul 30, 2009, at 16:18, Neil Jerram wrote:
The main thing I believe that makes a fluid different from a normal
variable is that a fluid can have a different value in each thread -
which is not relevant to Elisp.
Not yet, at least.
And maybe that's enough. There's other stuff in Emacs besides
variable bindings that would require dynamic-wind support, like flet,
save-excursion (preserves current buffer and position), with-output-to-
string and with-output-to-temp-buffer (preserve 'standard-output'), as
well as any number of explicit calls to unwind-protect from Elisp code
to alter and restore other global state of the program (e.g., with set-
default-file-modes or set-standard-case-table). The current
incarnation of these things assumes a single-threaded execution
model. So, since we can't make Emacs multithreaded by simply dropping
Guile Elisp into it, if Emacs is all we're concerned about, maybe
assuming single-threaded execution only is okay for now.
On the other hand, if we want users to be able to write code snippets
in Elisp and have them callable from a concurrently-multithreaded
Scheme program (no Emacs processes in sight), I think we'll want the
multithreaded support for the basic Elisp language sooner rather than
later, even if multithreaded Emacs needs much more work.
I also don't know how complicated a switch to stop using fluids would
be. If it's not too painful, the performance impact would be
interesting to see -- does it get us closer to the performance of
Emacs itself?
See above. I'm not sure why fluid access should be significantly
slower than non-fluid access, so I would guess that the performance
cost is coming from the dynamic-wind part.
For a program the size of Emacs, I'd be concerned about the numbers of
fluids and dynamic states created, especially since the space cost
(and run time cost for growing the vectors, every 20th new entry)
grows with the product of the two. The number of dynamic states may
shrink, but the size of each dynamic state -- the number of allocated
fluid slots -- doesn't shrink, it only grows.
While they don't really correlate to anything in Guile Elisp directly,
the default max_specpdl_size (the specpdl stack is where things are
tracked for unwinding -- previous bindings, unwind-protect calls,
previous location data for save-excursion, etc) was raised to 1000 a
few years ago, and the maximum lisp evaluation depth (limits calls to
eval, funcall, apply) to 400 just a couple years ago. I assume that's
because the previous limits (650 and 300 respectively) were
occasionally getting reached. That suggests to me rather a lot of
dynamic states, and probably a large number of fluids.
Ken