unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
* Conditional binding and testing of `lexical-binding'
@ 2022-01-01 22:24 Drew Adams
  2022-01-02 12:36 ` LdBeth
  2022-01-02 18:27 ` Stefan Monnier
  0 siblings, 2 replies; 12+ messages in thread
From: Drew Adams @ 2022-01-01 22:24 UTC (permalink / raw)
  To: emacs-devel@gnu.org

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



^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2022-01-03  3:31 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2022-01-01 22:24 Conditional binding and testing of `lexical-binding' Drew Adams
2022-01-02 12:36 ` LdBeth
2022-01-02 12:41   ` Po Lu
2022-01-02 18:29     ` Stefan Monnier
2022-01-02 23:01       ` [External] : " Drew Adams
2022-01-02 23:01     ` Drew Adams
2022-01-03  0:49       ` Po Lu
2022-01-02 23:01   ` Drew Adams
2022-01-03  3:09     ` LdBeth
2022-01-03  3:31       ` Drew Adams
2022-01-02 18:27 ` Stefan Monnier
2022-01-02 23:01   ` [External] : " Drew Adams

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).