[Top][All Lists]

[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)
     (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)

(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.]

reply via email to

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