Andrzej Pronobis
Andrzej Pronobis

Reputation: 36096

with-eval-after-load and order of evaluation in Emacs Lisp

Given the situation below:

(with-eval-after-load 'python
  exp1
  )

(with-eval-after-load 'python
  exp2
  )

Is exp2 guaranteed to be evaluated after exp1 when python mode is loaded?

How about if those two with-eval-after-load are in different files, and file2 containing exp2 requires file1 containing exp1?

Upvotes: 1

Views: 643

Answers (1)

phils
phils

Reputation: 73274

The short answer is that they are evaluated in the same order in which the eval-after-load forms are evaluated.

If each eval-after-load is evaluated only once, then that's all you need to know. Otherwise some additional detail may be of interest...

If 'python has not yet been provided then the order in which exp1 and exp2 will be evaluated is (again) strictly the order in which their enclosing eval-after-load forms are evaluated; but more specifically, it is the order in which they are first evaluated. If either of those eval-after-load forms were evaluated multiple times (but still prior to the library in question being loaded), that fact would have no effect on the eventual evaluations of exp1 and exp2 -- each of which would be evaluated once, and in that order.

If 'python has been provided already, then the behaviour is different: instead of deferred evaluation, the child expression is evaluated immediately (i.e. the form is effectively equivalent to progn), which means that should any of the eval-after-load forms be evaluated multiple times, their child forms will also be evaluated multiple times.

How about if those two with-eval-after-load are in different files, and file2 containing exp2 requires file1 containing exp1?

If file2 is loaded first, and file2 loads file1, then it depends on whether the eval-after-load in file2 happens before it loads file1 (in which case exp2 happens first), or after it loads file1 (in which case exp1 happens first).

One minor curiosity in all of this is that the location of the provide expression in a library does not seem to affect matters. For the purposes of eval-after-load, things seem to work as if the provide were always at the very end of the library (as indeed it usually is), even if that isn't actually true. I suppose this ensures consistency between using a feature symbol or a library name as the eval-after-load argument, but I'm unsure of the details of why it works that way (because a cursory look at the code for provide suggests that it can directly invoke the after-load functionality).

n.b. with-eval-after-load is defined in terms of eval-after-load, which is why I have used the latter in this answer. The answer applies equally, regardless of which you use.

And in case it makes a difference, I am presently using Emacs 24.5.1.

Upvotes: 2

Related Questions