Back to the talks Previous by track: Exploring shared philosophies in Julia and Emacs Next by track: Committing secrets with git using sops-mode Track: Development

Beguiling Emacs: Guile-Emacs relaunched!

Robin Templeton (they/them)

IRC: robin on libera.chat; Fediverse: @lispwitch@octodon.social; Matrix: @terpri:matrix.org; website: http://terpri.org/; mail: robin@terpri.org

Format: 16-min talk ; Q&A: BigBlueButton conference room
Etherpad: https://pad.emacsconf.org/2024-guile
Status: TO_CAPTION_QA

Talk

Duration: 15:57 minutes

Q&A

03:01.480 Q: About fibers: My understanding is that the problem with making Elisp concurrent is that none of the data structures (buffer, cons, vector, window etc) are concurrency-safe.  How do fibers help with this? 04:28.080 Q: Do you have a rough idea of how much of Guile is written in C? 06:19.240 Q: A Common Lisp implementation for Guile sounds really cool! Is there already work on this underway? 08:34.480 Q: Did switching from guile 2 to 3 give any performance benefits? 10:46.440 Q: Do you know if the Emacs maintainers are interested in switching to Guile as the engine for Emacs Lisp? 12:30.000 Q: Do you think guile-emacs will be able to use or (collaborate with) some of the other awesome projects around Emacs Lisp? 15:04.200 Q: SBCL, ...You mentioned Robert Strandh's SICL along with SBCL---does that work help with the implementation of CL in Guile?

Description

The Guile-Emacs project seeks to develop new foundations for Emacs, building on forty years of development to prepare the way for the next forty. Guile-Emacs brings Emacs and Guile together by providing a new Elisp implementation based on Guile's compiler technology, serving as the basis for a more expressive and extensible version of Elisp. We envision Guile and Emacs being co-developed in a sort of mutualism, with Emacs becoming the heart of a "Lisp machine for the 21st century" and with Guile fulfilling the promised role of Lisp from the GNU Manifesto.

Guile-Emacs is now being developed by a democratic workers cooperative, focused on development of the project itself and related components of the GNU system.

In this talk, I'll cover:

  • What is Guile-Emacs, in terms of its goals and general architecture? Why is Guile well-suited to the goals of the project?
  • How did the Guile-Emacs project begin, and what is its status today?
  • What are the immediate tasks for Guile-Emacs development, and how will they improve Guile-Emacs itself as well as its component projects?
  • How are our long-term goals for Guile-Emacs connected to the spirit of Emacs and the GNU Project in general? What do we envision for the future of GNU Emacs?
  • How can you get involved with and support this effort?

Along the way, we'll show live demos of Guile-Emacs itself and its extensions to Emacs Lisp.

About the speaker:

Robin Templeton is a free software advocate who enjoys programming language design and exploring system architecture. Their fascination with Emacs and Lisp lead them to begin work on the then-hypothetical Guile-Emacs project during their university studies. If given the opportunity and interest, they will bless an interested listener with a treasure trove of obscure Lisp history.

Guile-Emacs seeks to provide new foundations for Emacs, integrating Emacs and Guile via a new Elisp implementation. We envision a significant role for Emacs within the GNU Project, becoming a central part of a "Lisp machine for the 21st century".

Discussion

Questions and answers

  • Q: About fibers: My understanding is that the problem with making Elisp concurrent is that none of the data structures (buffer, cons, vector, window etc) are concurrency-safe.  How do fibers help with this?
    • A: Fibers do not provide thread-safety for any of the existing data structures.  They are useful for building things that don\'t use Emacs data structures, like a network client that reads a \"stream\".  Fibers can introduce new data structures that are thread-safe, like \"thread-local buffers\".
  • Q: \<ramin> You mentnioned that Emacs is roughly 25% written in C. Do you have a rough idea of how much of Guile is written in C? Could it be an improvement to make libguile a dependency of Emacs?
    • A: The problem is not the quantity of C, but that there is C involved at every single level/layer of computation in Emacs.  This makes it difficult to use concepts like delimited continuations, that can make it easy to implement Emacs concepts more simply.
    • A: About guile: it\'s about 1/2 C.
  • Q: A Common Lisp implementation for Guile sounds really cool! Is there already work on this underway?
    • A: Yes, Robin is working on it, but focuses more on research on how to do a polyglot lisp environnement where elisp and common-lisp can work together (with lisp 1 vs lisp 2 issues with different name spaces, package and module system interaction, ...). If you are interested, the guile project will work on it.
  • Q: As someone who\'s kinda new to the concept of Guile, is the primary goal to transpile Emacs Lisp into Guile bytecode rather than primarily focusing on adding support for writing code in Guile\'s Scheme interface in particular? 
    • A:
  • Q: Did switching from guile 2 to 3 give any performance benefits?
    • A: Not benchmarking stuff here yet, because guile emacs has too much overhead involved in conforming to Emacs.  Have not noticed a perceptible change.  Based on the Gabriel benchmark results, it might have benefited a  bit, but for Emacs we don\'t know yet.  Lowering the overhead is the best place to focus on to optimize guile-emacs.
  • Q: Do you know if the Emacs maintainers are interested in switching to Guile as the engine for Emacs Lisp?
    • A: Previous maintainers were cautiously optimistic and interested. Issues might be cross-platform compatibility.
  • Q: Do you think guile-emacs will be able to use or (collaborate with) some of the other awesome projects around Emacs-Lisp, like the gypsum project presented earlier today, or Andrea Corallo\'s efforts to make Emacs-Lisp more suitable for native compilation? Or even something like the renewed PreScheme efforts?
    • A: Gypsum has a different focus. Guile tries to improve lisp instead of replacing lisp in any way. But some code can be shared, especially if some parts of emacs are rewritten in lisp
    • A: For libgccjit: it is accelerating the interpreter, which is not great in the first place. So no direct relationship.
    • A: For prescheme: it  is a useful tool to look at, making it easier to upstream one day.
  • Q: SBCL, ...You mentioned Robert Strandh\'s SICL along with SBCL---does that work help with the implementation of CL in Guile? 
    • A: Time consuming part are the DSL from common lisp. So they can be used. No plan on sharing code yet, as they are open-source.
  • Q: Can you comment more on relation with hoot project and advantages that might bring to guile-emacs?
    • A: Hoot is only tested on scheme decompilation. But it is a completely different project. One could image compile emacs to wasm and maybe with a different garbage collector.
  • Q:
    • A:

Notes

  • https://guile-emacs.org/
  • Some more motivation: avoid FFI to increase performance and allow for more optimizations (including type annotations)

Transcript

Hello everyone. I'm Robin Templeton, and I'm going to talk about Emacs Beguiled and recent progress on the Guile-Emacs project. First of all, if you're not familiar with Guile, it's an implementation of the Scheme programming language, which is a dialect of Lisp, and in the same family as Emacs Lisp, and Guile is GNU's official extension language. The goal of the Guile-Emacs project is to use Guile as the basis for Emacs's Lisp support. It has two main components: a new Emacs Lisp compiler built on top of Guile, and a variant of Emacs in which the built-in Lisp implementation is entirely replaced with Guile Elisp. We expect the combination of these two projects to have several benefits. One is improved performance. Another is increased expressiveness for Elisp and making it easier to extend and experiment with the language. Finally, it will reduce Emacs's reliance on C for two reasons. Guile will be responsible for the language implementation, so Emacs will no longer have to include a Lisp interpreter. It will also become possible to implement much more of Emacs in Lisp than is currently feasible. Of course, this raises the question of why Guile is suitable for this project. And we chose Guile for a few reasons. Guile is primarily a Scheme implementation, but it also has built-in support for multiple languages using its compiler tower. To add support for a new language to Guile, you only have to write a compiler from the source language to Tree-IL, which is essentially a low-level, minimal representation of Scheme. All of Guile's compiler optimizations occur at the Tree-IL layer or lower, so you don't need to worry about the lower-level details of the compiler when initially implementing your language. Guile also has some Lisp features that are very rare in Scheme implementations. For example, it has a nil value that counts as both false and an empty list, just like in Elisp, and it also has a version of the Common Lisp Object System and its metaobject protocol, which is called GOOPS. The idea of Guile-Emacs has a pretty long history, going back at least three decades. There have been about half a dozen previous implementation attempts. But the current iteration began with a series of six Summer of Code internships: Daniel Kraft's in 2009, and then my internships from 2010 to 2014. My basic implementation strategy was pretty straightforward. I implemented a core subset of Elisp, which was enough to run some batch mode programs outside of Emacs. In Emacs, I modified the garbage collector and the data structures for Lisp objects to use their libguile equivalents. I replaced Emacs' Lisp evaluator with the one provided by Guile Elisp. After a little over a year of work, at the end of the 2014 internship, I ended up with a fully functional prototype of Guile-Emacs. It used Guile Elisp alone as its Lisp implementation and was completely compatible with Emacs functionality and with external extensions. One caveat was that performance was pretty bad, because I was focused on correctness, as well as ease of integration with the Emacs C code. But it was nonetheless a major milestone for the project. Let's take just a moment to look at Guile-Elisp. For starters, we have access to Guile modules. If we call Guile's version function, we can see that we're running under Guile 3.0. We have access to some of the numeric tower via the arithmetic functions. We also have multiple values. We have to be careful to use Guile's values procedure here, not the CL library's, but you can see that this works properly rather than being an emulation. Finally, we have tail call elimination. Naturally, we're going to use factorial to demonstrate it. If n is zero, return the answer, else recurse with n less one and n times a. Of course, this definition works correctly, but it gets more interesting if we communicate the answer with an error, in order to look at a backtrace. You can see here that there are no calls to fact visible in between the request to evaluate and the error communicating the answer. That's because this tail call has been optimized into effectively a goto. This is essential for any kind of serious functional programming. That's a peek at Guile-Elisp. In 2015, I left university to go work on web technologies, and the project was dormant for a very long time. But that's been changing recently. During the last few months, I've been working with Larry Valkama to rebase Guile-Emacs onto the development branch of upstream Emacs, including the past decade's worth of upstream development. What we've ended up with is a series of rebases onto different versions of Emacs. The older ones tend to work pretty well. The newer ones have increasingly bad problems where they haven't been properly adjusted for changes in the Emacs implementation. But we do have by now a version of Emacs 30 which boots correctly and can be used for interactive debugging, as well as the ability to bisect the revisions of Emacs and find out where regressions were introduced. Our immediate goal is of course to complete the rebase. At the same time, we want to improve Guile Elisp's performance to at least be competitive with ordinary Emacs Lisp. Just to characterize the performance situation, Guile Elisp is usually about half as fast as ordinary Elisp, while Guile Scheme is quite often an order of magnitude faster than ordinary Elisp, and that's based on micro benchmarks like the Gabriel benchmarks. But there's clearly a lot of room to improve our compiler's output. If you want to mark your calendars, we're expecting to have a usable version of Guile-Emacs 30 out sometime next spring. We're also going to put some effort into either extracting old work or doing new work that could be contributed upstream. On the Guile side, we'll probably start out with optimizing the dynamic binding facilities, which are used very seldom in Scheme, but are used all the time in traditional Lisp dialects. On the Emacs side, we'll be working initially on abstracting away the details of the Lisp implementation where they're not relevant. And that will clean up the Emacs code base a bit. It'll make it easier to integrate Emacs and Guile Elisp. It will probably be helpful for anyone who is working on ordinary Elisp on their own. We're also going to be adding new features to Emacs Lisp. We've seen a few of them already. The numeric tower, tail call optimization, Common Lisp compatibility. We're also going to provide access to Fibers, which is a Guile library based on ideas from Concurrent ML that provides much more powerful facilities for concurrent and parallel programming than what Emacs currently offers. This plan meets Guile-Emacs' basic goals, and it's work that we could maybe get integrated upstream in a reasonable amount of time. But it's also worth considering what more we can do, and what effect Guile-Emacs might have on Emacs if it becomes simply Emacs. For context, the amount of C code in Emacs has increased by around 50% in the last decade, and now it constitutes around a quarter of the code base. C can be a bit of a barrier to customizing and extending Emacs. For example, there are about 1500 C subroutines. Around 500 are used in C code, as well as available to Lisp code, and being written in C means that they can't be practically redefined. The use of C can become a barrier to extending Emacs or customizing its behavior. We might consider writing as much of Emacs as possible in Lisp. One way to speed up this process would be to provide a Common Lisp implementation for Guile. Note that between Guile Elisp and Guile Scheme, we have all of the essential ingredients for a Common Lisp environment. We can also share code with other Common Lisp implementations such as SBCL and SICL. Overall, the duration of the project will be better measured in months rather than years, despite Common Lisp's reputation for being a large language. This could have multiple uses, of course. It could be a model for future improvements to Elisp, because Elisp and CL can interact directly without problems. And it would be very easy for Elisp to borrow language features from Common Lisp. But for the purpose of a C to Lisp transition, it would also provide us with instant access to a huge number of high-quality libraries for things that Guile is not necessarily equipped to deal with, such as access to low-level Windows APIs, as well as lots of other libraries, such as interfaces to GUI toolkits for a variety of operating systems. At a certain point, this has technical advantages. If most of Emacs is written in Lisp, then we could consider using Guile Hoot to compile Emacs to WebAssembly, making it available perhaps in web browsers or on systems with the WebAssembly System Interface. But it would also be a great victory for practical software freedom. That's the idea that Freedom One, the freedom to study and modify programs, should not just be legally and technically possible, but should be actively encouraged by our computing environments. Emacs is really one of the archetypal examples of this, but we can and should go further. When Emacs is implemented primarily in Lisp, the entirety of the system will be transparent to examination and open to modification. Every part of Emacs will be instantaneously inspectable, redefinable, and debuggable. This will be a fundamental change in what is possible to do with Emacs extensions. For example, one experiment I'd be interested in is using the Common Lisp Interface Manager as the basis for Emacs's user interface. Screwlisp is giving a talk about McCLIM later today, but for present purposes, just think of it as a super-powered version of Emacs's concept of interactive functions. It would be a pretty long-term project in Emacs as it currently exists, but it would be almost trivial if Emacs were customizable at the lowest layers via Lisp. We'll certainly be looking at the practicality of these kinds of changes as we continue developing Guile-Emacs. Finally, how can you get involved with and support Guile Emacs? One way to help is just by trying it out and letting us know what your experiences are like. There will be a snapshot available on the Codeberg project site of the version that I'm using to give this presentation. It will be available both as a Guix package and as a portable tarball. This will be more interesting as we get closer to a complete rebase. We're also always happy to talk to potential contributors or potential collaborators from other projects. We can always use bug reports, and we're interested in what kind of features people actually want to see in Guile-Emacs. Guile-Emacs is also being developed by a small worker cooperative, so donations are a pretty direct way to support the project. If you do nothing else, I recommend going to the website and subscribing to our mailing lists so that you can keep up with news on the project. If you're watching this at EmacsConf, there will be a Q&A session immediately following this, and thanks for watching!

Captioner: sachac and robin

Q&A transcript (unedited)

All right. Hey, thanks for bearing with us there. We had a couple of bumps in the road, a cross between a couple of different versions of our program that we deliver here, different ways that we bring this stream together between the recorded content that that speakers are putting together in advance in the live content, such as what you're seeing right here. So thanks go to Sacha and Leo, and everybody behind the stages gluing it all together. And we're back here now, and I'm speaking with Robin, who us ready to take on some of your questions and address some of the comments over here on the etherpad. If you want to jump in there, there's links in the chat. And thanks so much, Robin, for your talk. And it's also been a pleasure chatting with you just a little bit over the last couple of months on IRC. Yeah, absolutely. Great meeting you. All right. All right, everyone. I think I am streaming now. So let's look at it. Let's see. I see the IRC scrolling. So let's see where that's going. Yes, the Common Lisp is what I thought would piss people off. And because it's not part of either community, but I think it would be a good compromise for building a Lisp into a language that's more suitable for building large systems like the kind that we are building in Emacs today. I also left out an important part of the talk, which is part of the motivation for transitioning from C to Lisp. And that's the performance characteristics fundamentally change when you get a modern and high performance Lisp system involved. it starts getting less practical to just call out to C to speed up every operation. Among other things, you lose the ability to use more advanced control structures, like the limited continuations. And you also have to pay the overhead of calling out to our foreign function. So it gets to be an increasingly better deal to optimize your list implementation and provide ways for building faster list programs, such as type annotations, once you've gotten over a certain threshold of performance.
[00:03:01.480] Q: About fibers: My understanding is that the problem with making Elisp concurrent is that none of the data structures (buffer, cons, vector, window etc) are concurrency-safe.  How do fibers help with this?
I'm going to look at the pad. Here we go. The first question is about fibers and whether they help with making Elisp concurrent in terms of its data structures. Yes, that's absolutely correct. Fibers by themselves do not provide thread safety for any of the existing Emacs data structures. What they are useful for is building things that don't use Emacs data structures, say a network client that reads input from a stream or in scheme, a port or a stream instead of a buffer. And we can also take a look at options for making more Emacs features concurrency safe or thread safe. For example, we could introduce the idea of a thread local buffer that didn't require locks for sharing between different threads. And I'm not sure how that would develop, but I'm sure the Emacs maintainers already have some ideas in this direction. Fibers will basically provide a high-performance system that you can use apart from ordinary Emacs-less constructs.
[00:04:28.080] Q: Do you have a rough idea of how much of Guile is written in C?
Let's see. We have another question. Emacs is roughly 25% C. How much of Guile is in C? Well, part of my point about C is not so much that there, well, obviously, I phrased it a little provocatively, but the problem is not so much that there is C, but that there is so much C involved in every single layer of the application. So, for example, we're limited in our ability to use tools like limit continuations, which can be used to express buffer local variable binding in a few dozen lines, because Emacs has so much calling back and forth between guile and C, due to so much basic functionality being in primitive C subroutines. So that's one issue apart from the question of how much is in a particular language. To answer the question about Guile, Guile has about 165,000 lines of scheme code and about 160,000 lines of C code, so it's about half and half. And that shouldn't really be surprising given that it is actually focused on low-level things like building a high-performance bytecode compiler, and a just-in-time compiler, and so on, as well as providing its own fairly rich, but still far less complete than Emacs's standard library, in terms of Ice9 and other system libraries
[00:06:19.240] Q: A Common Lisp implementation for Guile sounds really cool! Is there already work on this underway?
shipped with Guile. The next question is on a Common Lisp implementation for Guile, and whether work on it is underway. In fact, work on it is already underway. I've been working on it on and off in my spare time for a couple of years now. I've gotten, I think, a couple of chapters of the hyperspectin, if you want to measure it that way. But I've been focusing my work more on research and on what we need to do to have a LISP environment, a polyglot LISP environment, wherein the features of Common Lisp and Scheme and Emacs Lisp can all work easily and ergonomically together. So this involves things like the question of Lisps having Lisp1s versus Lisp2s. That is, a Lisp1-like scheme has one namespace, like every variable is a single name that can refer to one value, whereas in Lisp2s like EmacsLisp, symbols can have different definitions as functions and as variables, as well as other namespaces like property lists. So Kent Pittman has some interesting thoughts on this that I've been looking into. Another issue is the interaction between package and module systems. So I don't have really anything ready to publish just yet on this, but I have been looking into the background issues of integrating this into Guile in a useful way. And let's see, one other thing I was going to mention. Okay, I've lost it. But yeah, there is some work already. And if people are interested in moving Emacs in this direction, then we'll certainly start working on it in earnest.
[00:08:34.480] Q: Did switching from guile 2 to 3 give any performance benefits?
Another question, did switching from Guile 2 to 3 give any performance benefits? Well, honestly, we're not really benchmarking stuff here because Guile Emacs has so much overhead from structuring the compiler to closely conform to Emacs in terms of like even things as simple as metadata layout for variable information. So I haven't actually noticed a perceptual change. I would guess based on the Gabriel benchmark results that is benefited from what somewhat from Gal 3's performance improvements but for Emacs I just don't know yet and working on the compiler's code generation and lowering the overhead is going to be the thing that provides the most return for improving that aspect of Gal Emacs. Let's see, I see SICL mentioned here, as well as SPCL. And it could certainly help with the implementation of Commonwealth and Guile, because a lot of the basic stuff is just providing a new interface to some bit of functionality. Like the sequence library, it's mostly stuff that we already have through SR5 and so on. The difficult, well, not the difficult but the time consuming parts are going to be all the little DSL sitcom on this path packed up inside it like pretty printing format loop and so on. It's for those high-level features that I think we could potentially share code with other Common Lisp implementations. And Common Lisp implementations do tend to be permissively licensed, SPCL's public domain, for example, so there's no barrier to sharing code with them.
[00:10:46.440] Q: Do you know if the Emacs maintainers are interested in switching to Guile as the engine for Emacs Lisp?
There's another question about whether the Emacs maintainers are interested in switching to Guile as the engine for Emacs Lisp. I can't speak for the current maintainers. I can say that people have talked to previous Emacs maintainers about the whole idea, and their attitude was generally cautiously optimistic. As in, it's not something they, it's somewhat political, they didn't want to get into it, but they didn't think that it was a bad idea, and they wanted to know more about how it might evolve in the future. I can comment that Eli Zaretsky, who I believe is the current Emacs maintainer, is very concerned about cross-platform compatibility. And so if I can guess at his priorities correctly, I think that that's something that we'll have to make sure is rock solid before we propose any kind of upstreaming of Gala Emacs. but in general maintainers have been cautious but curious. So I just wanted to break in and note at this point that as lives I didn't sorry I couldn't do so more gracefully while we were still on stream but I wanted to let you know that just as of 10 seconds ago or so we've had to cut away into our next talk but we can keep going here as long as we like. Okay, let's wrap up. There's only a couple questions left on the pad, so I'll answer those, and then I'll be available on IRC. So, the next
[00:12:30.000] Q: Do you think guile-emacs will be able to use or (collaborate with) some of the other awesome projects around Emacs Lisp?
question is whether Guile Emacs will be able to collaborate with projects like Gypsum and the native compilation projects or the pre-scheme efforts. Oh, yes, that is one of the things I forgot to bring up in my talk. So, first of all, Gypsum is approaching a similar idea from a different direction. And we clearly have a different focus. My focus is on improving Emacs Lisp and making Emacs itself better by integrating Guile Elisp and Emacs, rather than replacing eLisp or deprecating it in any way. But given gypsum's requirements, I do think that we could share a lot of code required for emulating basic Emacs functionality. And this could even become interesting if we get to the point of rewriting parts of Emacs in Lisp. With respect to the native compilation effort, I'm familiar with it. I'm not that impressed with the results of it. It's a very impressive effort, but as far as I can tell, it's accelerating a bytecode interpreter that just simply has an out-of-date design, to be quite blunt. It's possible that Emacs's JIT has ideas that Guile should adopt, like perhaps libgccjit might perhaps be better than GNU Lightning, which is a relatively simple JIT that Guile uses. But it doesn't have to have a direct relationship to Guile Emacs. And as far as pre-scheme goes, I have been watching Flat Watson's work on pre-scheme with great interest because Scheme 48 used to be my favorite implementation. And I do think that it could be, it's a tool that we should look at when we're thinking about moving functionality into Lisp and could certainly make it easier to upstream some of the work we may end up doing. All right, do we have more questions?
[00:15:04.200] Q: SBCL, ...You mentioned Robert Strandh's SICL along with SBCL---does that work help with the implementation of CL in Guile?
There's a question about SICL and SBCL. I think I answered that earlier. It should help us implement Common Lisp when it comes to high-level features and the various large subcomponents of Common Lisp. Another important factor is that Guile already has decent support for the Common Lisp object system. Without that, it would be far more difficult. But I do expect that we can share code with other Common Lisp implementations. I've personally rated Common Lisp compiler code when working on Guile Hoot, for example. So there are definitely places where they can contribute. Regarding the Hoot project and its relationship to Galimax, it's a purely speculative thing. First of all, Hoot is only tested on Scheme-to-WebAssembly compilations. I've heard some suggestions that some uses of Tree.io may not be compatible with the Hoot compiler. I'm not sure if that's the case or not. But it is a complete enough project that if Emacs is, say, 90% Lisp, there's only a few thousand lines of C code to implement, then it would be entirely practical to compile Emacs WebAssembly, as long as we had a back end, like one based on the browser's document object model, or some sort of graphical interface through WASI. And that may have some interesting applications for portability to unusual platforms. It may even bring performance advantages in cases where the WebAssembly implementation is connected to a tracing just-in-time compiler, because that may be more appropriate to the high level of dynamism the Emacs list has than the kind of simple template JITs that both Emacs and Guile are using. What a fascinating point. Just to break into active listening a little so this doesn't, to you, feel like you're talking to yourself. I can see from chat and the questions still coming in, you know, comments. You know, it isn't, but I just want you to be able to hear and feel that. Yeah, great, great point there. All right. Thank you. And yes, if there are more questions, keep throwing them at me. I should probably also mention I will have to jump out myself, but the recording will automatically end when we all jump out or just drop a note anywhere, ping me, whatever. And I'll come along and shut off the recording and we'll trim it up before we publish it. I'm looking forward to reading through anything I do miss. Thank you. Sounds good. All right, I'm not seeing changes in the etherpad. So I'm going to close this in maybe 30 seconds if there are no more additions. Thanks, everyone, for the interesting and very pointed questions on some of the most significant areas. I appreciate everyone's feedback. I'm glad this provoked so much curiosity in people. Thank you, janneke. All right, I think we are done with the Q&A session, so I'm going to close this BBB and we can continue with the rest of EmacsConf. You are currently the only person in this conference.

Questions or comments? Please e-mail robin@terpri.org

Back to the talks Previous by track: Exploring shared philosophies in Julia and Emacs Next by track: Committing secrets with git using sops-mode Track: Development