9

Common idiom to workaround macro expansion or resolve warning about undefined variables during byte-compilation:

(eval-when-compile
  (require 'cl-lib))

But this require ... compiled into .elc file! I found that cl-eval-when have proper semantic (according to name).

Normally we don't need for require as site file and package.el

For example I want to byte-compile my .emacs which uses some external macros, but silently pass through if there are no such package:

(cl-eval-when 'compile
  (condition-case err
      (require 'w3m-util)
    (error (byte-compile-warn "Failed by: %S" err))))
(w3m-util-DEPENDENT-CODE ...)

Another way to do this is:

(ignore-error
   (require 'w3m-util)
   (w3m-util-DEPENDENT-CODE ...))

But now we are not a top level form...

Do I properly fill that eval-when-compile name do something that is not expected from its name?

  • FWIW, the latter two snippets do not have the same behavior. The former does not protect w3m-DEPENDENT-CODE from a missing w3m-util. – Drew Oct 13 '15 at 15:27
  • (when (require 'w3m-util nil t) (w3m-util-DEPENDENT-CODE...)) – Drew Oct 13 '15 at 15:29
  • (when (require 'w3m-util nil t) ...) is nice idiom! But I try to make perfect .emacs file, not a library. So have in mind delayed (on-request) code loading with help of auto-loading. For this reason I extensively use eval-after-load, asked require needs only to make byte-compilation success with macro expansion. – gavenkoa Oct 14 '15 at 21:20
9

Did you ask Emacs what eval-when-compile is supposed to do?

C-h f eval-when-compile tells you that it evaluates the arg also at load time:

eval-when-compile is a Lisp macro in `byte-run.el'.

(eval-when-compile &rest BODY)

Like ‘progn’, but evaluates the body at compile time if you’re compiling.
Thus, the result of the body appears to the compiler as a quoted
constant.  In interpreted code, this is entirely equivalent to
‘progn’, except that the value of the expression may be (but is
not necessarily) computed at load time if eager macro expansion
is enabled.

It says that if interpreted it is like progn. And it explicitly repeats this.

A function or macro name seldom reflects the behavior perfectly. But in this case it sounds like you are looking for a different behavior, which might be called eval-only-when-compile.

  • 1
    eval-only-when-compile name help me understand point to name eval-when-compile, thanks! – gavenkoa Oct 13 '15 at 15:25
3

To evaluate code only on compilation stage use eval-when macros which is dated by RMS in 1993-07-30.

cl-eval-when appeared in 2012-06-03 from Stefan Monnier and it is not available for Emacs 22.x (if you care, I do).

For example you like to get rid of Warning: assignment to free variable in:

(setq auto-revert-interval 2)

just add above that line:

(eval-when 'compile (require 'autorevert))

Note that this is useful only for byte compilation of .emacs file. If you develop a library you should do require or split library file into separate and load only required features.

  • To avoid variable warnings, you just need (defvar auto-revert-interval) – npostavs Apr 2 '16 at 22:59
  • 1
    I use defvar solution in many cases but also look for stronger solution. I can mistype name or package can remove definition and compilation checker would be silent in such cases. – gavenkoa Apr 4 '16 at 19:03

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.