all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
From: Drew Adams <drew.adams@oracle.com>
To: "emacs-devel@gnu.org" <emacs-devel@gnu.org>
Subject: Conditional binding and testing of `lexical-binding'
Date: Sat, 1 Jan 2022 22:24:36 +0000	[thread overview]
Message-ID: <SJ0PR10MB5488D4372A6BCE46CF82D0E1F3479@SJ0PR10MB5488.namprd10.prod.outlook.com> (raw)

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



             reply	other threads:[~2022-01-01 22:24 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-01-01 22:24 Drew Adams [this message]
2022-01-02 12:36 ` Conditional binding and testing of `lexical-binding' 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

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=SJ0PR10MB5488D4372A6BCE46CF82D0E1F3479@SJ0PR10MB5488.namprd10.prod.outlook.com \
    --to=drew.adams@oracle.com \
    --cc=emacs-devel@gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this external index

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

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.