2

I've been looking through some elisp libraries and most calls to provide happen at the end of the file. In clojure the ns is quite similar to provide.

I've noticed that putting provide at the top of the file makes no difference. Is there a reason for putting it at the end vs at the top?

  • 1
  • i'm talking about 'provide, not 'require – zcaudate Sep 26 '18 at 13:18
  • 1
    Ah, so based on your edit you are not asking why libraries contain (provide <package>), but why they contain it at the bottom rather than at the top? – phils Sep 26 '18 at 13:35
  • Well I've nominated this to be re-opened, as it turned out not to be the duplicate that it had originally sounded like -- none of the other Q&As address the actual question of "why at the bottom and not the top?" – phils Sep 26 '18 at 22:36
4

The reason for putting the provide at the end rather than the beginning is the same as the reason for including the comment ;;; <library.el> ends here at the end of the file:

If it's not there, then you know that you don't have the complete file.

The comment is the human-readable version of that, and (provide 'FEATURE) is the machine-readable version.

Imagine if you had a truncated copy of foo.el with (provide 'foo) at the top, and loading it caused errors -- but due to the provide Emacs believed it was now fully-loaded, and so subsequent (require 'foo) did nothing to fix the problem in that session, even after you installed a corrected copy of the file.

Conversely, if (provide 'foo) is the very last form in the file and Emacs processes it, then it is guaranteed that the entire file has been loaded as intended.

4

Because it's in the coding conventions, would be one answer. :)

The provide/require/features design is quite simple. When a package requires a feature it is loaded, but only if it isn't already loaded. That is determined by checking the list of features found in features.

Packages only add their features only once they have finished loading, i.e. only once their features become available to use. So, they do it last.

More specifically, if the provide call is at the beginning you can get unexpected failures where you've done (require 'foo) and indeed (featurep 'foo) says that foo is loaded, yet (foo-mode 1) fails saying that foo-mode is not defined (because we're still in the process of loading foo, actually).

The value of the variable features stores the list. Mine currently has ~300 symbols in it.

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