Feeling gratitude towards this community. Just wrote my first #emacslisp advice ever.

(advice-add #'package-function-has-no-hook :before #'my-little-hook-function)

A small thing, but it removes friction from my org-static-blog (recommended!) workflow.

These little steps forward are what make this hobby so much fun. And—you'll just have to believe me—the confidence to bork around like this comes from being part of this community.

[EDIT: broken link removed; see thread]

#emacs #mastodon #fediverse

@jameshowell FYI if you wrote "my-little-hook-function", you could also be interested in `define-advice', which combines a defun and a advice-add into a single form. Here are two example from my init.el:

(define-advice eval-last-sexp (:before (&rest _) eval-last-sexp-pulse)
(save-excursion
(forward-sexp -1)
(let ((start (point)))
(forward-sexp 1)
(pulse-momentary-highlight-region start (point)))))

@jameshowell Also, what function from package.el did you want to modify? Your sourcehut link points to a 404 page.

@pkal Sorry! Let's try it this way. NEW BLOG POST: "My first advice! (in Emacs Lisp)"

https://jamesendreshowell.com/2026-04-04-my-first-advice-in-emacs-lisp.html

#emacs #emacslisp

My first advice! (in Emacs Lisp)

@jameshowell You ask in the blog post why Emacs Lisp doesn't have a function to return the contents of a file as a string. It kind of makes sense to me, let's see if I can explain it.

Emacs has two data structures to store text in: strings and buffers. You may think of buffers as just for showing to the user in a window to edit, but buffers also have an extensive collection of functions to work on them programatically (obviously, since every thing the user can do to edit a buffer just calls some command). I feel like Emacs in general pushes you towards using strings only for small amounts of temporary text and buffers for longer text or longer-lived pieces of text. From that point of view it makes perfect sense to me that Emacs has a function to insert the content of a file into a buffer, but not one to return it as a string: a file is likely to long and to stick around a while for you to work on it, it belongs most likely in a buffer rather than a string. The existence of `insert-file-contents` and the non-existence of a corresponding string-returning function is meant to nudge towards buffers for file processing.

@pkal

@oantolin No, I get it, in fact slinging HTML lines around in buffers and concatenating them together in buffers makes more sense—in the Emacs context. But you can see how someone (like perhaps the author of org-static-blog, and certainly naive me) would cling to string-oriented habits.

Thank you for the thoughtful, patient, illuminating answer to my snarky rhetorical question!

@pkal

@jameshowell Well, having given that answer, I should say that lots of people have probably had to write that function to get the contents of a file as a string, it probably should be included with Emacs. 😅 @pkal

@oantolin The "s" package has a function to do that, and the consequence is that people keep on reading an entire function in as a string and then doing GC-heavy list processing on the function, where using a buffer would have been more idiomatic.

I am not sure if I submitted a patch for this once, but a compromise of having a `slurp` macro could be interesting, since it would read in the file once at macroexpansion time, without making it a general replacement for buffers.

@jameshowell

@pkal @oantolin @jameshowell I vote that Emacs gets a read-file-to-string function! This has been requested so often by many people and there are valid use cases, despite the small performance risk if used incorrectly. I find these concerns exaggerated. Think about your recent addition ensure-proper-list, which is so far not even used in the Emacs code, and which is O(n) in contrast to ensure-list - another risk for incorrect use. Even worse there is almost no need for this function.
@pkal @oantolin @jameshowell I argue that API design should better be guided by actual demand, and not only by theoretical concerns. Emacs is first and foremost a practical tool. One could take a look at functions which are often used from the s.el or f.el packages and then add them to Emacs. Now we have Compat to port the functions back. This is a missed opportunity and my hope for Compat was specifically to close this gap.
@pkal @oantolin @jameshowell Another indication for demand is to just look at the code of Emacs and some packages and check if we could replace common patterns. It does not look like this in the case of ensure-proper-list, but I think I have seen places where a file to string function would have come handy, for instance if the file is small or the content of the file is used unchanged, or if the performance overhead is acceptable despite string manipulation. Buffers are not without cost either.
@pkal @oantolin @jameshowell So to conclude I think API design in Emacs could be informed better, by taking into account all the information that we have, theoretical considerations, inspiration from other "modern" Lisps, inspiration from popular ELPA libraries, actual use in Emacs or packages, and users asking for a feature. And again - Compat is there to distribute the new functionality as soon as possible such that it can be used even on old Emacs versions.

@minad @oantolin @jameshowell I don't want to stop you from suggesting it on the proper channels, but it is my experience that a `read-file` function is almost always abused, especially by people with a background in functional programming with lazy evaluation. So for me this is not a theoretical concern, but practical experience that makes me skeptical.

And in general: Something being common is a bad sign that it is the right thing to do, let alone should be encouraged.

@pkal Instead of protecting these poor pure functional programmers from themselves, I think we should treat Emacs users as adults. 🙄@minad @jameshowell
@oantolin @pkal @jameshowell Yes and the example of lazy IO is not a realistic reason for skepticism and not related to Elisp. There are not many Haskell users actually. I've also written a bit of Haskell a few years ago with some packages on Hackage. But if we are talking about edge cases, I have a special case where I think a file to string function would be legitimate. A while ago I wanted to read small files from the /proc fs and use the content either directly, or convert it to a number.
@oantolin @pkal @jameshowell When reading such small files, only a small string is going to be allocated, and we will likely end up with less pressure on the Elisp runtime system and garbage collector. In contrast, buffers are relatively fat objects in Elisp, and their creation leads to manipulation of the buffer list and hook calls. To be fair, we have with-work-buffer to mitigate the costs.