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 Btw, I don't like the slurp macro idea. There is no advantage of making this a macro - you would only lose. If slurp would exist as a function you could simply write (eval-when-compile (slurp file)). This is also a bit of a dogmatic rule: If something can be written as a macro or a function, write it as a function. But I guess many Lisp hackers agree with it.
@minad @oantolin @jameshowell There are a few advantages: It could get accepted as I presented a counter-argument based on Eli's comments in reference to a real in-core use-case, and it continues the discussion which might result in something like what you propose (which would have to be accompanied by another function that would simplify the expansion of file names relative to the current compiled file).
@pkal Sure, I see. I am very much against this kind of artifical maneuvering (or should I say manipulation) in order to achieve something. This is one thing which bothers me about emacs-devel. I would rather present my case in a clear and direct way and get a clear response. Instead of adding a slurp macro I would rather not add anything.
@oantolin
@jameshowell
@pkal And if you want to find real use cases for slurp as a function, simply grep the Emacs code base and look for potential call sites. I looked for a minute and found for example treesit-generic-mode-font-lock-query, and I am sure there are plenty of other similar potential call sites, where we could avoid repeating the with-temp-buffer/insert-file-contents/buffer-string pattern.
@oantolin @jameshowell
@minad @oantolin @jameshowell I did so yesterday, and didn't find any convincing places. In practice, most of the time I have seen packages need such a function comes from APIs that made the "mistake" of being string- instead of buffer-oriented.
@pkal @oantolin @jameshowell Oh okay. I did not expect that, and as I said, I found some places where the pattern is used. Furthermore it somehow contradicts my own experience and I've wanted a file to string function multiple times, and I claim to know enough Elisp that I can judge if it is okay to use it or if I should resort to inserting in a buffer and buffer manipulation.
@pkal @oantolin @jameshowell Also if you search around and do not find "convincing places", you are already starting with your preformed opinion. What I said or meant was different - I suggested to look around for places where the insert-file-contents/buffer-string pattern is used, just to see how often this pattern occurs, without judging if the code is perfect or not. Think about your ensure-proper-list function, which has almost no applications in Emacs and yet it ended up in subr.el.
@pkal @oantolin @jameshowell I have never missed an ensure-proper-list function while I have missed a file-to-string function, repeatedly!
@minad @oantolin @jameshowell FTR I have invested more time in this discussion than in the discussion behind ensure-proper-list. If I had know that beforehand, I would not have added the function.
@pkal To be clear, ensure-proper-list has little relevance. My point is that you are judging by a double standard. Sometimes functions with little relevance are added to subr.el, while practically relevant functions like file-to-string don't make it in since they presumably violate some higher dogmas, even if they have been requested multiple times and already exist in separate libraries. I disagree with such development principles.
@oantolin @jameshowell
@minad @oantolin @jameshowell I don't see it as a double-standard. The rationale against file-to-string is like when you don't want to add functions that operate on global state in concurrent languages to the standard library (note this is a simile, I am not saying this is the same!). Such a function could be convenient at times, but that is not a reason to serve as a bad example and can lead to more APIs being string instead of buffer-oriented. But again, this is a matter of principles.
@minad @oantolin @jameshowell I looked again, and did find a few instances. I think I misremembered, that most instances where this pattern appears to have been used were tests. So yes it is used, but I don't want to disregard that it isn't necessary/idiomatic most of the time.
@pkal @oantolin @jameshowell Once again, I disagree with the judgmental nature of your statement. This is exactly the patronizing stance I criticized a while ago. My assumption is that the authors of the code knew what they were doing - after all the code made it in. It is not that I don't understand the buffer first principle, but I think the principle is applied too rigidly.
@minad For this particular case I think the performance pitfalls would be adequately dealt with by mentioning them in the docstring. @pkal @jameshowell
@oantolin Yes, I think providing such "bad" examples (not that it is, really) can even be educational if documented with proper disclaimers. From my experience more extensive standard libraries are better than minimal ones for practical languages like Elisp. Otherwise it is like programming Scheme without SRFIs. @pkal @jameshowell

@minad @oantolin @jameshowell There is a big gap between Scheme-like minimalism and Elisp's preference to not include a single function that would go against perhaps the only design princple of the language...

If you have all this energy to discuss the question, please redirect it to emacs-devel. I don't think that it would be well spent, since your attitude is non-constructive and feels infantalising. I'd recommend just accepting that there are differences in preferences and leave it at that

@minad @oantolin @jameshowell I am sorry to put it this way, but with all personal respect I really don't want to continue having this conversation, especially here because it just feels like running around in a circle of misunderstandings. I hope you can understand that that, and forgive me if I mentally mute the thead.
@pkal @oantolin @jameshowell @yantar92 Philip, you don't get it. You are the one who is patronizing repeatedly. I am not in a strong position, while you are in happy disagreement with the existing principles. My goal is not to convince you that we should add/remove file-to-string/ensure-proper-list. Maybe you can understand why it is difficult to contribute if principles are invoked quickly for rejection, instead of finding compromises, and if no alternative resolutions are considered?
@pkal There are multiple people who have made similar experiences as I made with emacs-devel, but of course it is always clear who is at fault. Words like "misunderstanding" or "confusion" are typical emacs-devel language which mean that the other person is not taken seriously. From my side, I don't see any misunderstanding. The arguments you made are perfectly clear, and as I wrote a while ago, it is a matter of weighing the arguments. @oantolin @jameshowell @yantar92
@minad @oantolin @jameshowell I don't see it as "artifical maneuvering", quite on the contrary it is an open-ended investigation into the different and related options we could consider. This is what I am trying to get at to explain the differences in attitude that determine the differences in impression. IMO the key to it is not to go in with a fixed mindset and treat the suggestions of others with open, respectful curiosity.

@pkal @oantolin @jameshowell

> IMO the key to it is not to go in with a fixed mindset and treat the suggestions of others with open, respectful curiosity.

Yes, exactly. From my experience this is not what happens on emacs-devel often enough.

Nevertheless, regarding the technical question if a slurp macro makes sense - it does not, and I doubt that I can be convinced otherwise given what I know about Lisp and macros.