all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
* Q on byte-compile problem
@ 2006-06-06 19:19 Drew Adams
  2006-06-06 20:18 ` Stuart D. Herring
  0 siblings, 1 reply; 3+ messages in thread
From: Drew Adams @ 2006-06-06 19:19 UTC (permalink / raw)


I'm not suggesting there is a bug here (I don't know). I'm asking for help
understanding what to do (recommendations).

I define a macro `foo' in library `foo.el'. This macro constructs and evals
a `defun' using its argument (`bar') as the function to be defined.

I have a library `bar.el' that has two alternative, top-level definitions of
function `bar', depending on whether macro `foo' has been defined:

 (when (fboundp 'foo) (foo bar)) ; use foo to define bar
 (unless (fboundp 'foo) (defun bar ...)) ; std defun of bar

In Emacs 20, I have no problem byte-compiling and using library bar.

In Emacs 22:

1. If I byte-compile `bar.el' in a session that does not have library `foo'
loaded, then  I get a warning about a reference to free variable `bar' when
it tries to compile (foo bar). Seems normal: the compiler can't figure out
that (foo bar) is a macro expression.

2. If I byte-compile `bar.el' in a session that has library `foo' loaded,
then I get a warning that `bar' is not known to be defined (`bar' is used
elsewhere in file `bar.el'). Is this normal? Shouldn't the compiler eval the
(foo bar) and define `bar', so then (bar...) wouldn't be unrecognized? The
(foo bar) occurs before the use of `bar' in `bar.el'.

I'm not too worried about the warnings, in any case, but it would be nice to
eliminate them somehow - recommendations?

However, in Emacs 22:

A. If I load `bar.elc' that was compiled via #1 (with `foo'):

 a1) in a session in which library `foo' was not loaded - `bar's
     definition is, as I expected, the straight `defun' version
     (byte-compiled) [Good]

 a2) in a session in which library `foo' was loaded - I get this error at
     load time: "Symbol's value as variable is void: bar" [Bad].
     Nevertheless, `bar.elc' seems to load OK, and `bar' is defined OK
     (straight `defun' version).

I want a2 to pick up the `foo'-defined version of `bar'. Obviously I'm not
doing the right thing. However, I don't understand why loading `bar.elc'
chokes in a2. I would expect the (when (fboundp 'foo)...) envelope to
protect the call to macro `foo' during the load.

B. If I load `bar.elc' that was compiled via #2 (without `foo'):

 b1) in a session in which library `foo' was not loaded - `bar's
     definition is, as I expected, the straight `defun' version
     (byte-compiled) [Good]

 b2) in a session in which library `foo' was loaded - `bar's
     definition is, as I expected, the `foo'-defined version
     (byte-compiled) [Good]

In terms of executing `bar', both cases of both A and B work fine, but in a2
the straight `defun' version of `bar' is used, and I want the `foo'-defined
version to be used. IOW, I want the (when (fboundp 'foo)...) to be eval'd
when `bar.elc' is loaded, not just when it is compiled.

I see this in Elisp-manual node Eval During Compile:

     If functions are defined programmatically (with `fset' say), then
     `eval-and-compile' can be used to have that done at compile-time
     as well as run-time, so calls to those functions are checked (and
     warnings about "not known to be defined" suppressed).

So, I also tried putting `eval-and-compile' around both definitions, at the
top level, but that didn't help. Suggestions? Thx.

Just in case there is a bug, here is the Emacs version I'm using:

In GNU Emacs 22.0.50.1 (i386-mingw-nt5.1.2600)
 of 2006-03-20 on W2ONE
X server distributor `Microsoft Corp.', version 5.1.2600
configured using `configure --with-gcc (3.4) --cflags -Id:/g/include'

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

* Re: Q on byte-compile problem
  2006-06-06 19:19 Q on byte-compile problem Drew Adams
@ 2006-06-06 20:18 ` Stuart D. Herring
  2006-06-07  1:57   ` Drew Adams
  0 siblings, 1 reply; 3+ messages in thread
From: Stuart D. Herring @ 2006-06-06 20:18 UTC (permalink / raw)
  Cc: emacs-devel

> 2. If I byte-compile `bar.el' in a session that has library `foo' loaded,
> then I get a warning that `bar' is not known to be defined (`bar' is used
> elsewhere in file `bar.el'). Is this normal? Shouldn't the compiler eval
> the
> (foo bar) and define `bar', so then (bar...) wouldn't be unrecognized? The
> (foo bar) occurs before the use of `bar' in `bar.el'.

The compiler macro-expanded the (foo bar) into something that presumably
began (defun bar ...) -- but it did not -evaluate- this.  When the
compiler encounters a normal `defun' at top level, it recognizes
thenceforth that the symbol named therein is a valid function.  But,
either because of the conditional nature of your (foo bar) or because of
its macro nature (someone who understands byte compilation better,
specify?), the compiler isn't aware that bar will (at load time!) actually
be defined as a function.

> I'm not too worried about the warnings, in any case, but it would be nice
> to
> eliminate them somehow - recommendations?

You could always put in an (eval-when-compile (unless (fboundp 'bar)
(defun bar ()))) to try to squelch the warning without doing any damage to
anything else.

> A. If I load `bar.elc' that was compiled via #1 (with `foo'):

Surely you mean without foo loaded for the compilation?

>  a2) in a session in which library `foo' was loaded - I get this error at
>      load time: "Symbol's value as variable is void: bar" [Bad].
>      Nevertheless, `bar.elc' seems to load OK, and `bar' is defined OK
>      (straight `defun' version).
>
> I want a2 to pick up the `foo'-defined version of `bar'. Obviously I'm not
> doing the right thing. However, I don't understand why loading `bar.elc'
> chokes in a2. I would expect the (when (fboundp 'foo)...) envelope to
> protect the call to macro `foo' during the load.

The byte-compiled file contains a call to the function `foo', which of
course involves evaluation of its argument bar.  The fact that the symbol
'foo now has a macro definition is irrelevant; the compiled code still
wants to call a function, and in fact dies before it even gets to the
point of discovering that (symbol-function 'foo) is now a macro.  The
result is that by the time the second form executes, `bar' is still
unfbound, so the defun runs.

> B. If I load `bar.elc' that was compiled via #2 (without `foo'):

Again -- you mean compiled with foo's macro definition available, yes?

>  b1) in a session in which library `foo' was not loaded - `bar's
>      definition is, as I expected, the straight `defun' version
>      (byte-compiled) [Good]

Here's the thing -- unless defining a function with the macro `foo'
involves the run-time use of other things from the foo library, why not
just have this case use the foo definition as well?  Part of the point of
byte-compiling is that macros can be expanded and then later used in an
Emacs which does not know about them.

Hope this helps,
Davis

-- 
This product is sold by volume, not by mass.  If it appears too dense or
too sparse, it is because mass-energy conversion has occurred during
shipping.

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

* RE: Q on byte-compile problem
  2006-06-06 20:18 ` Stuart D. Herring
@ 2006-06-07  1:57   ` Drew Adams
  0 siblings, 0 replies; 3+ messages in thread
From: Drew Adams @ 2006-06-07  1:57 UTC (permalink / raw)


    The compiler macro-expanded the (foo bar) into something that presumably
    began (defun bar ...) -- but it did not -evaluate- this.  When the
    compiler encounters a normal `defun' at top level, it recognizes
    thenceforth that the symbol named therein is a valid function.  But,
    either because of the conditional nature of your (foo bar) or because of
    its macro nature (someone who understands byte compilation better,
    specify?), the compiler isn't aware that bar will (at load
    time!) actually be defined as a function.

Right. Actually, I thought of providing, first, a phony `defun', to quiet
the byte compiler. But I would just end up with multiple-definitions
warnings in that case.

Could the compiler perhaps be made to recognize that a top-level `defun' was
being added to the byte-compiled file, and treat it as a top-level `defun'
is treated? Not a complaint - just wondering if such an enhancement would be
straightforward or tricky.

    Here's the thing -- unless defining a function with the macro `foo'
    involves the run-time use of other things from the foo library, why not
    just have this case use the foo definition as well?

Macro `foo' doesn't just define `bar' using the same `defun' expression. The
point of macro `foo' is that it constructs a different `defun' for its
argument - the body of function `bar' is entirely different, to be able to
take advantage of features in library `foo'. Macro `foo' and the `foo'
functionalities need not be defined in the same library (in fact, they are
not). What's important is that to take advantage of `foo' functionality,
`bar' must be defined with macro `foo'.

    Part of the point of byte-compiling is that macros can be expanded and
    then later used in an Emacs which does not know about them.

No problem there. Use of library `foo', which the `foo' definition of `bar'
permits, does not mean use of the macro `foo' (at run time). The macro is
only used to construct the proper `defun' to make `bar' be `foo'-enabled.

Thanks for your suggestions and reminders.

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

end of thread, other threads:[~2006-06-07  1:57 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-06-06 19:19 Q on byte-compile problem Drew Adams
2006-06-06 20:18 ` Stuart D. Herring
2006-06-07  1:57   ` Drew Adams

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.