7

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?

Drew
  • 75,699
  • 9
  • 109
  • 225
zcaudate
  • 637
  • 4
  • 14
  • 1
    or https://emacs.stackexchange.com/q/8288 or https://emacs.stackexchange.com/q/18638 – phils Sep 26 '18 at 13:11
  • 1
    i'm talking about 'provide, not 'require – zcaudate Sep 26 '18 at 13:18
  • 2
    Ah, so based on your edit you are not asking why libraries contain `(provide )`, but why they contain it *at the bottom* rather than at the top? – phils Sep 26 '18 at 13:35
  • 1
    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
  • This question ought to be re-opened. The linked question isn't even close to being a duplicate. – JBentley Apr 04 '22 at 14:24

2 Answers2

6

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.

Stefan
  • 26,154
  • 3
  • 46
  • 84
Ben Hyde
  • 574
  • 3
  • 9
5

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.

phils
  • 48,657
  • 3
  • 76
  • 115
  • 2
    FWIW, the purpose of the "ends here" heading is documented under [`(elisp) Library Headers`](https://www.gnu.org/software/emacs/manual/html_node/elisp/Library-Headers.html). – Basil Sep 26 '18 at 13:51