You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Elisp has a lot of mutable global state. Some of it is highly shared. And it is very easy to modify global, highly shared state inadvertently. This includes point, mark, narrowing, match data, current buffer, selected window, selected frame, and who knows what else.
For example, calling (looking-at "[ \t]") to check if we are on whitespace clobbers match data. If this is done in a function, the caller has to wrap its invocation in a (save-match-data) if match data is important.
Proposal:
If your function is not specifically intended to modify global shared state, preserve it by wrapping your function body in the appropriate (save-*) or (with-*) macros.
If you do modify global shared state, at a minimum, document the fact; ideally, document how you modify it.
If you accept function arguments and expect them to modify global shared state, document your expectations. If they are called in a modified shared state context, document that context.
The text was updated successfully, but these errors were encountered:
If your function is not specifically intended to modify global shared state, preserve it by wrapping your function body in the appropriate (save-) or (with-) macros.
For the match data, at least, that goes against the current advice on emacs-devel: any function A when calling function B should assume that B can modify the match data. And it should itself wrap the call to B in save-match-data, if it needs it preserved. We could document when a function preserves the match data, however.
As far as moving point or changing buffers go, yes, I think those should be generally documented.
As an analogy, processor/OS/compiler ABIs document certain registers as “must be preserved across calls” and certain other registers as “may be destroyed by any call”.
We could have a (n incomplete) list of parts of global state which should or need not be preserved.
Elisp has a lot of mutable global state. Some of it is highly shared. And it is very easy to modify global, highly shared state inadvertently. This includes point, mark, narrowing, match data, current buffer, selected window, selected frame, and who knows what else.
For example, calling
(looking-at "[ \t]")
to check if we are on whitespace clobbers match data. If this is done in a function, the caller has to wrap its invocation in a(save-match-data)
if match data is important.Proposal:
(save-*)
or(with-*)
macros.The text was updated successfully, but these errors were encountered: