[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Conditional binding and testing of `lexical-binding'
From: |
Drew Adams |
Subject: |
Conditional binding and testing of `lexical-binding' |
Date: |
Sat, 1 Jan 2022 22:24:36 +0000 |
What's the best way, or a reasonable way, of
setting `lexical-binding' conditionally, so a
library can be used with both Emacs versions
that support lexical binding and versions
that don't support it?
___
As a simple example of testing, consider
something like this, in some context that
defines variable `x'. (`x' could be a
function arg, a `let' var, or a `setq' var;
its binding could be lexical or dynamic.)
(if (and (boundp 'lexical-binding)
lexical-binding)
(lambda (y) (something x y))
`(lambda (y) (something ',x y)))
(Assume `x' doesn't occur in `y', etc. By
hypothesis, occurrences of `x' can just be
_replaced_ by its value. And the function
body could be any code, not necessarily a
single `something' function call, etc.)
That works. (Of course, it has the drawback
that without lexical binding the value's not
a function; it's a list with car `lambda'.
So, not known to the byte-compiler to be a
function, not optimal, not elegant, not too
clean, etc.)
There are no doubt other ways to do something
similar. (Feel free to suggest alternatives.)
___
But my question is really about conditionally
_setting_ `lexical-binding', so it can be tested.
Putting it in `Local Variables' at the end of
a file, and using `eval' to set its value (e.g.
conditionally, depending on Emacs version or
`boundp' or whatever), has no effect. As the
doc says, we must instead set it in the first
file line.
And trying to set it conditionally this way
in a file apparently has no effect either:
(ignore-errors (eval '(setq lexical-binding t)
t))
(That uses the 2-arg version of `eval', so it
raises an error in older Emacs versions; hence
the `ignore-errors'.)
___
It works to just put it in the first file line:
;;; ....... -*- lexical-binding:t -*-
In Emacs versions where that variable doesn't
exist, this apparently has no effect - the var
continues not to exist after the file's loaded.
[I don't see that the doc says that the var is
set only if it already exists (or whatever the
actual criterion is). I was expecting that
that declaration would set `local-variables' to
`t' in older Emacs versions also, so I didn't
try it till after (unsuccessfully) trying other
conditional approaches. Shouldn't something be
said about this in the doc?]
Anyway, that first-line non-nil declaration
seems to work OK, e.g. with a test such as this:
(and (boundp 'lexical-binding) lexical-binding)
___
Is this the thing to do? If not, what advice
do you have for adapting a library to use
lexical binding when available (Emacs 24+) but
to also work when it's unavailable (Emacs < 24)?
[The doc just tells you how to convert code to
use lexical binding. I see nothing about how
to code compatibly for old and new Emacs.]
Re: Conditional binding and testing of `lexical-binding', Stefan Monnier, 2022/01/02