unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
* Do we need C's extern in Emacs Lisp?
@ 2022-03-29 17:45 Alan Mackenzie
  2022-03-29 21:09 ` Stefan Monnier
  2022-03-31  4:26 ` Richard Stallman
  0 siblings, 2 replies; 5+ messages in thread
From: Alan Mackenzie @ 2022-03-29 17:45 UTC (permalink / raw)
  To: emacs-devel

Hello, Emacs.

This point came up in discussion with Lars over an old bug report.

In C, there is the keyword extern which means "defined somewhere else".
For a function, an example is

    extern foo (int bar);

, and for a variable, something like

    extern int foo;

..  This keyword has the property that the extern object can be defined
anywhere else in the program, and the object can be used in the current C
file without causing any errors or warnings.

Currently we do not have any equivalent in Lisp.  For example, if

    (defvar foo)

is in a Lisp file, then subsequent use of foo will generate an unknown
variable warning.

For example(2), if in the Lisp file there is

    (declare-function foo nil)

, this generates a warning when the function foo is later defined.

I think it would be useful to have some sort of "extern" facility in our
Lisp.

What do other people think?

-- 
Alan Mackenzie (Nuremberg, Germany).



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

* Re: Do we need C's extern in Emacs Lisp?
  2022-03-29 17:45 Do we need C's extern in Emacs Lisp? Alan Mackenzie
@ 2022-03-29 21:09 ` Stefan Monnier
  2022-03-31 20:59   ` Alan Mackenzie
  2022-03-31  4:26 ` Richard Stallman
  1 sibling, 1 reply; 5+ messages in thread
From: Stefan Monnier @ 2022-03-29 21:09 UTC (permalink / raw)
  To: Alan Mackenzie; +Cc: emacs-devel

> For example, if
>
>     (defvar foo)
>
> is in a Lisp file, then subsequent use of foo will generate an unknown
> variable warning.

That's not my experience.  Do you have a recipe?

> For example(2), if in the Lisp file there is
>
>     (declare-function foo nil)
>
> , this generates a warning when the function foo is later defined.

I haven't verified that it's indeed the case, but it sounds likely,
indeed.  We could consider silencing this warning, but I wonder why
you'd put such a `declare-function` in the same file where you define
`foo`, since it's redundant anyway.

Do you have a good use-case for it?


        Stefan




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

* Re: Do we need C's extern in Emacs Lisp?
  2022-03-29 17:45 Do we need C's extern in Emacs Lisp? Alan Mackenzie
  2022-03-29 21:09 ` Stefan Monnier
@ 2022-03-31  4:26 ` Richard Stallman
  1 sibling, 0 replies; 5+ messages in thread
From: Richard Stallman @ 2022-03-31  4:26 UTC (permalink / raw)
  To: Alan Mackenzie; +Cc: emacs-devel

[[[ To any NSA and FBI agents reading my email: please consider    ]]]
[[[ whether defending the US Constitution against all enemies,     ]]]
[[[ foreign or domestic, requires you to follow Snowden's example. ]]]

  > Currently we do not have any equivalent in Lisp.  For example, if

  >     (defvar foo)

  > is in a Lisp file, then subsequent use of foo will generate an unknown
  > variable warning.

Could you describe the scenario more clearly?  What sort of use, and where?
The reason I ask is that details would affect whether we judge
that the actual behavior is problematical or helpful.

  > I think it would be useful to have some sort of "extern" facility in our
  > Lisp.

This raises some questions:

1. How would you envision using it?

2. What would we do currently?

3. What would be the advantage of using the new construct instead?

W
-- 
Dr Richard Stallman (https://stallman.org)
Chief GNUisance of the GNU Project (https://gnu.org)
Founder, Free Software Foundation (https://fsf.org)
Internet Hall-of-Famer (https://internethalloffame.org)





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

* Re: Do we need C's extern in Emacs Lisp?
  2022-03-29 21:09 ` Stefan Monnier
@ 2022-03-31 20:59   ` Alan Mackenzie
  2022-03-31 21:16     ` Stefan Monnier
  0 siblings, 1 reply; 5+ messages in thread
From: Alan Mackenzie @ 2022-03-31 20:59 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: emacs-devel

Hello, Stefan.

On Tue, Mar 29, 2022 at 17:09:10 -0400, Stefan Monnier wrote:
> > For example, if

> >     (defvar foo)

> > is in a Lisp file, then subsequent use of foo will generate an unknown
> > variable warning.

> That's not my experience.  Do you have a recipe?

This happened in an attempt to fix bug #21466, a bug you opened in 2015
proposing to replace cc-bytecomp-defun and cc-bytecomp-defvar by
(declare-function foo nil) and (defvar foo).

I was wrong about the "subsequent use ... generate an unknown variable
warning.".  Sorry.  The problem happened during a more unusual
compilation situation best explained by the following comment from
cc-fonts.el:

    ;; Need to declare these local symbols during compilation since
    ;; they're referenced from lambdas in `byte-compile' calls that are
    ;; executed at compile time.  They don't need to have the proper
    ;; definitions, though, since the generated functions aren't called
    ;; during compilation.

The "need to declare" means "need to give the value/function cell of the
symbol a binding", because the byte compiler seems to use boundp and
fboundp to check whether to emit "not known" warnings.

> > For example(2), if in the Lisp file there is

> >     (declare-function foo nil)

> > , this generates a warning when the function foo is later defined.

> I haven't verified that it's indeed the case, but it sounds likely,
> indeed.  We could consider silencing this warning, but I wonder why
> you'd put such a `declare-function` in the same file where you define
> `foo`, since it's redundant anyway.

In the above cc-fonts.el scenario, foo needs a function binding at the
time the `byte-compile' form processes it, which happens to be before it
gets defined in the file.

> Do you have a good use-case for it?

See above.  ;-)  It may well be that such facilities would enable me to
dismantle large parts of cc-bytecomp.el sooner rather than later.

"This variable/function is defined somewhere" is a natural thing to want
to say.  The (defvar foo) and (declare-function foo nil) don't say this,
exactly.

>         Stefan

-- 
Alan Mackenzie (Nuremberg, Germany).



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

* Re: Do we need C's extern in Emacs Lisp?
  2022-03-31 20:59   ` Alan Mackenzie
@ 2022-03-31 21:16     ` Stefan Monnier
  0 siblings, 0 replies; 5+ messages in thread
From: Stefan Monnier @ 2022-03-31 21:16 UTC (permalink / raw)
  To: Alan Mackenzie; +Cc: emacs-devel

> I was wrong about the "subsequent use ... generate an unknown variable
> warning.".  Sorry.  The problem happened during a more unusual
> compilation situation best explained by the following comment from
> cc-fonts.el:
>
>     ;; Need to declare these local symbols during compilation since
>     ;; they're referenced from lambdas in `byte-compile' calls that are
>     ;; executed at compile time.  They don't need to have the proper
>     ;; definitions, though, since the generated functions aren't called
>     ;; during compilation.
>
> The "need to declare" means "need to give the value/function cell of the
> symbol a binding", because the byte compiler seems to use boundp and
> fboundp to check whether to emit "not known" warnings.

Explicit calls to `byte-compile` are rather unusual, indeed, and since
declarations like (defvar FOO) are supposed to affect the code only in
the current lexical scope they can't be applied to this use case since
calls to `byte-compile` are dynamic and thus not easily associated with
a particular lexical scope.

Arguably we should be able to provide some kind of "environment"
argument to `byte-compile`, but for your use case, maybe the better
option is to wrap the code that you pass to `byte-compile` along the
lines of

    (defun my-byte-compile (form vars funs)
      (eval
       (byte-compile
        `(progn
          ,@(mapcar (lambda (v) `(defvar ,v)) vars)
          ,@(mapcar (lambda (f) `(declare-function ,f nil)) funs)
          ,form))))

> "This variable/function is defined somewhere" is a natural thing to want
> to say.  The (defvar foo) and (declare-function foo nil) don't say this,
> exactly.

Those declarations don't just say "defined somewhere" but something
closer to "will be defined somehow by the time we get here" (tho
admittedly, it's a lot more murky).  This is usually more useful since
it justifies removal of the warning by promising that the corresponding
runtime error won't happen.

It's less clear what we can do with just "this variable/function is
defined somewhere" since it doesn't do us much good if it's defined in
a file that never gets loaded.


        Stefan




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

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

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-03-29 17:45 Do we need C's extern in Emacs Lisp? Alan Mackenzie
2022-03-29 21:09 ` Stefan Monnier
2022-03-31 20:59   ` Alan Mackenzie
2022-03-31 21:16     ` Stefan Monnier
2022-03-31  4:26 ` Richard Stallman

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