[implementations-list] Why can't I byte-compile (all of) Vimpulse?

Štěpán Němec stepnem at gmail.com
Wed Apr 28 16:06:35 CEST 2010


On Wed, Apr 28, 2010 at 12:52:43PM +0000, Vegard Øye wrote:
> When a file is compiled, it is /not/ evaluated, except for `defmacro'
> calls and `require' statements. However, if the compiled file requires
> other files, those files /are/ evaluated. This means, amongst other
> things, that if you compile a file which defines some variables with
> `defvar' and /uses/ those variables, you will get warnings about free
> variables. Those `defvar' declarations are not evaluated. The
> preferred way to handle this seems to be to place all the declarations
> in a separate file and then require it, forcing evaluation. (In
> Viper's case, that file is viper-init.el.)

No; when a file is compiled, *all* the macros are expanded (i.e.
evaluated); that's one of the points of macros, after all -- to be
expanded at compile time, not run time. And `defvar's are recognized by
the compiler, too, so you definitely should *not* get any warnings, as
long as all the `defvar's are put before the variables are first used.

> vimpulse-big.el can't do that, of course, since it's a single file. So
> there's another and uglier way to force evaluation during compilation:
> wrap the code in (eval-and-compile ...). Of course, you still have to
> do this /before/ you actually use the variables.
> 
> (Interestingly, `defmacro' calls are evaluated regardless. This is so
> the compiler can substitute the macro expansion for subsequent macro
> calls. Why couldn't it make the same exception for `defvar'? According
> to the Reference, section 16.6,
> 
>     [Y]ou can tell the compiler that a variable is defined using
>     `defvar' with no initial value.
> 
> But it doesn't mention the need for using `eval-and-compile' in the
> compiled file! Way confusing.)

Yeah, it doesn't mention that because it is not the case AFAIK, see above.

> 
> So, yeah, vimpulse-big.el. If I got this right, I'll have to define
> all variables at the beginning of the code, wrapped in
> (eval-and-compile ...), to silence the compiler completely. Right now
> it complains a lot (warnings), although it does produce the .elc.
> 
> > I don't think it makes sense to have multiple features (i.e.
> > `provide' forms) in a single file (this issue was mentioned before).
> > If you want to compile the single file version, shouldn't you
> > instead remove all the provides except `vimpulse' (and reorder the
> > code so it will work, if needed)?
> 
> If it could be automated, sure. All the makefile would have to do is
> remove the last two lines of every file (one `provide' statement and
> one blank line) before concatenating them. Do you think that's
> possible as stated, or would one have to use awk or sed and search for
> "(provide "? (I've never used awk or sed.)

I don't think `make' can do that on its own -- `cat' is an external
program, too ;-).

You could e.g. just replace `cat' in the makefile with

sed "/^(\(provide\|require\) 'vimpulse-/d" 

That would do what `cat' does, except for all lines providing or
requiring 'vimpulse-something, i.e. it would leave `(provide 'vimpulse)'
in.

Štěpán



More information about the implementations-list mailing list