A while ago, I was trying to work around the emacs maintainers’ curious decision to always load a .elc file in preference to a .el file, even if the .el file is newer.

I didn’t want to settle for that. My solution was to recompile my emacs lisp files prior to running emacs.

I see now that there is a better alternative: replace the built-in require with my own version. And it is not just because it is open source that I can do this. I can fix it as a user too.

(require feature &optional filename noerror)

require performs the following steps:

do nothing if the feature has already been loaded (this protects against recursive loads)

finds the appropriate file in load-path

loads either the .el or .elc file

throws an error if the required feature is not provided

provides a mechanism for supressing errors

provides a mechanism to load a feature from a specific file

If I wanted a drop-in replacement, I should do all of those things, and replicate the function signature. However, I don’t need the error suppression or loading from a specific file. I also like to be able to force a load even if a library has been loaded previously. If this doesn’t match your requirements, it should be easy to adapt the code below.

( defun require* (feature &optional force) ( when (or force (not ( featurep feature ))) (setq feature (symbol-name feature)) ( let ((path load-path) (found-filename nil) head el-attribs elc-attribs) ( while (and (not found-filename) path) (setq head (pop path)) ( let ((el-filename (format "%s/%s.el" head feature)) (elc-filename (format "%s/%s.elc" head feature))) ;; if .el and .elc both exist, pick the newest ;; otherwise pick the one that exists if any ( cond ((and (file-exists-p el-filename) (file-exists-p elc-filename)) ( if (file-newer-than-file-p el-filename elc-filename) (setq found-filename el-filename) (setq found-filename elc-filename))) ((file-exists-p el-filename) (setq found-filename el-filename)) ((file-exists-p elc-filename) (setq found-filename elc-filename))) ;; load file if found ( when found-filename (message (format "Found: [%s]" found-filename)) ( let ((load-suffixes ())) (load found-filename))))) ( unless found-filename ( error "Unable to find %s" feature)))))

The brave might choose to do (defun require ...) instead of (defun require* ...)