Hacker News new | past | comments | ask | show | jobs | submit login
State of Emacs Lisp on Guile (emacsninja.com)
93 points by todsacerdoti on May 19, 2020 | hide | past | favorite | 65 comments

Honest question: what are the benefits of Guile Emacs in 2020 and after? Guile speed? I'm aware Guile (especially) later versions got really good VM and general optimizations, but with recent work in gccemacs [1] and having complete gcc optimization engine under the belt, can these two be even compared? Also, gccemacs showed you get visible speedups in some use cases only.

Have everything under Guile umbrella? Remember, Guile is getting trickier and trickier to build over the years and I don't want that from scripting language whose main idea was to embed it (presumably also ship the source alongside your program in some cases). I'm getting impression even python source & build is easier to ship and you can't go below that.

Also, modern Guile compilation time is abysmal. I recently ditched Guix [2] from my system because bootstraping on fairly modern laptop would take hours, mainly because Guile is trying to compile some helper scheme libraries needed for guix to work and recompile everything again with 2-3 different gcc versions (which are bootstraped too).

[1] http://akrl.sdf.org/gccemacs.html

[2] https://guix.gnu.org/

"what are the benefits of Guile Emacs in 2020 and after?"

Here is what Andy Wingo had to say on the subject[1]:

Guile can implement Emacs Lisp better than Emacs can.

We can compile Emacs Lisp to Guile's VM, and make C shims to present a suitably compatible C interface to the rest of Emacs' C primitives.

No one will notice! Except that after a switch, Emacs would be faster, more powerful, and have the ability to access all of Guile's facilities -- the Scheme language, other languages implemented for Guile (Javascript, Lua, ...), a proper ffi, dynamically loadable libraries, a module system, the numeric tower (rationals, bignums, etc), Guile's existing libraries, delimited continuations (!), fast bytevector access, native threads, etc.

On a language level, I am convinced that not only can Guile implement Emacs Lisp, but it can provide a coherent story for tight interaction between e.g. minor modes in Javascript and Scheme and Elisp, etc. More details will come later, though feel free to bring up specific points.

There have been some suggestions on the list that "Guile people want to rewrite Emacs in Scheme". Though Scheme does have some facilities to offer, personally I do not believe in rewriting software. I've failed enough times, thank-you-very-much -- and if we could retrofit a compiler into Guile in two years via correctness-preserving transformations, surely we can replace the implementation of Elisp without causing problems.

My goal is to make it the obvious decision for the Emacs maintainers to say, "yes, let's switch to Guile's implementation of elisp, because it will make Emacs better and have no drawbacks". We're not there yet -- and that's why I wanted to put off this mail -- but we'll get there.

[1] - https://lists.gnu.org/archive/html/emacs-devel/2010-04/msg00...

I think it's safe to say at this point -more than 10 years later- that Andy Wingo was very optimistic.

Absolutely nothing of what he described in that email materialized. And it's no wonder it didn't, since a lot of it is simply wishful thinking. In addition, he didn't address the fact that there are political and not technical reasons behind the absence of certain features (e.g. FFI). They could be done today, without Guile, assuming a consensus on the political front existed.

On the other hand, Emacs Lisp has gotten a lot better and not only knocked out some of the features mentioned by Andy (dynamic modules, native threads) but is also making progress towards new directions (GCCEmacs).

And as I described in my other comment, I completely disagree with his premise that having Emacs be extended in JavaScript, Lua etc would be a plus. The last thing you do with a cohesive ecosystem like Emacs Lisp's is to introduce needless fragmentation that takes away its core strengths.

"I completely disagree with his premise that having Emacs be extended in JavaScript, Lua etc would be a plus"

I also disagree, but that boat sailed long ago... For years now Emacs has allowed dynamic module loading, which lets Emacs be extended by C or anything that compiles down to C (which is pretty much any language). So it can already be done.

What Guile will offer is in some cases skipping the module compilation step, and allow more direct access to languages which can be used through the Guile interpreter.

Furthermore, whether you or I like the idea of extending Emacs through Javascript or Lua, there are plenty of other Emacs users who do, and I say let them at it!

Emacs needs more new users, and if some can be attracted through compatibility with their favorite language, I welcome them.

I'd personally like to keep Emacs pure and Lispy, but that's already not true and it's very unlikely we're going to go back.

That's not to mention that significant parts of core Emacs has been written in C for decades now. It'd be much nicer if some of that C code could be rewritten in Scheme.

I don't agree with your view either.

Going through C is not a counterargument, since it's doesn't compete with interactive development in Emacs Lisp. The technical drawbacks are many and for that very reason you see no fragmentation in the ecosystem today.

Being able to write a Lua or JavaScript function on the fly, inside Emacs, and having Guile execute it would make these languages direct competitors to Emacs Lisp. You would expect to see newcomers take the easy way out and never bother with Emacs Lisp. Fragmentation. Dilution. That is the core issue.

You seem to think that these sort of sacrifices should be made in the interest of popularity. I don't agree at all. Emacs has no reason to make populist compromises. It has certain qualities that have stood the test of time and have kept it extremely powerful. To go on the populist road would ensure that Emacs becomes just like everything else out there. A mediocrity.

I would firmly oppose switching the entirety of the Emacs ecosystem to JS, Lua, Rust or any other non-Lispy language, but that's not what we're talking about here. If an occasionaly JS or Lua package becomes available through Guile, what's the harm?

Anyway, I don't see this as the primary benefit of Guile Emacs.. the rest benefits that Andy Wingo mentions are much more interesting and valuable to me, not JS/Lua compatibility.

I'd also much prefer to write my own Emacs code in Scheme than eLisp (though, again, Guile Emacs does not entail replacing eLisp packages with Scheme -- you can still use eLisp if you want, and existing eLisp packages will still work).

I don't think you'll be able to control occasional or not. This is a Pandora's box [1] situation. Either you open it or you don't. And having alternative languages as direct competitors to Emacs Lisp, available for interactive development, would certainly be blowing the box apart.

I wouldn't mind Scheme as an alternative, the only alternative, except I don't think I'd use it myself since I would still see Emacs Lisp as domain-superior.

Agreed on the rest, except as I said, none of that materialized from the Guile camp whilst we had plenty of that goodness emerge in core Emacs.

[1] https://en.wikipedia.org/wiki/Pandora%27s_box

The problem with your point of view is that if it came to pass, then anyone who wanted to work on Emacs packages would have to learn multiple programming languages when before they only needed one, Elisp.

Having packages in multiple languages hurts the ability of people to help contribute to each others' work (especially if they don't have time or space to learn multiple languages).

Agreed, and I was disappointed about xi-editor's approach of using an RPC so any language can be used for extension. For all its issues at least elisp is ubiquitous, and contributes to feature discoverability.

This smacks of the https://en.wikipedia.org/wiki/The_Innovator%27s_Dilemma. If we're afraid that people will want to write packages in Blub for some reason, and we refuse to accommodate Blub at all, we're just driving everyone to some other editor that embraces it.

I think the difference is that Emacs isn't a company, and it doesn't need to beat others in a competition, it just needs enough contributors to keep moving forward. Not everyone needs to use Emacs for Emacs to succeed in its goals.

True, I was thinking of http://www.paulgraham.com/avg.html (where Lisp was Viaweb's "secret weapon"). And I'm worried about Emacs ending up with too small an audience of package maintainers to cover mainstream workplace use cases.

It might be the case that being able to use Emacs Lisp outside of the Emacs editor in a (potentially) more robust environment designed for general purpose programming could potentially give Emacs Lisp more legitimacy as a programming language in its own right (not just "a scripting language for an editor").

However, it seems that some people have another goal in mind with the Guile-based Elisp: actually replacing Emacs Lisp, or phasing it out, or whatever. I think that is a terrible idea. I also think their goal of mixing languages inside of Emacs would have the negative consequences you describe.

FWIW I think you could say FFI is possible. I've written a Golang module for emacs and build using -buildmode=c-shared and loaded it into emacs. I think for generic FFI you could probably wrap some sort of libffi.so using elisp.

There exist multiple Emacs FFI implementations [1], [2]. None of them are included in Emacs though and that's the main issue. For something like FFI to be maximally useful, you do want it to be part of Emacs and not an additional -compiled- add-on.

The problem is not technical, but political. For years, RMS has opposed an Emacs FFI due to his belief that it could be used to subvert Emacs goals by making it possible to do proprietary extensions.

[1] https://github.com/tromey/emacs-ffi

[2] https://github.com/skeeto/elisp-ffi

The are no benefits. In fact, what few folks consider benefits -be able to extend Emacs with JavaScript or Scheme- I think are major issues that have the potential to destroy Emacs.

Emacs Lisp fits the problem domain like a glove. Someone in this thread called it 'the worst Lisp' but that's a mischaracterization. It's actually a good, practical, Lisp and far from the worst. In short, there is enormous value in the current Emacs Lisp ecosystem, and every heavy Emacs user knows it.

Guile doesn't really have much to offer, given its terrible performance, lack of interest from developers (and some would say users), platform-compatibility issues and strong potential for diluting a very valuable, very cohesive ecosystem.

It is a project that is slowly languishing while Emacs Lisp is slowly but surely getting better.

The benefit is not in extending Emacs with different languages (though there would be nothing stopping people from doing so since Guile is a multi-language platform, like Racket) but in separating the concerns of text editing software from programming language implementation. Emacs is great at the text editing part, but has to reinvent the wheel over and over when it comes to the compiler/VM part.

It is wrong to say that Guile has terrible performance. Guile Scheme is more performant than the standard implementations of elisp, python, ruby, and other so-called scripting languages. Each major release of Guile has had significant performance improvements, most recently a JIT compiler. It is true that the elisp implementation on Guile is slow, but that's a reflection of the project being a prototype and not production-ready. It could be fast if there was interest in developing it, but there isn't so it's just another interesting but dead project.

I called it "probably" the worst lisp. I enjoy very much working with elisp, and almost 100% agree with your characterization of it.

But it is a fairly clunky language with all it's let, letstar, letdash, letstardash... You know what I mean. I am no elisp history expert, but I believe that is due to it's age and how easy it is to extend.

And just to reiterate, I have never felt limited by it, I really like it, I would not change it and it solves the domain problem just fine.

There are Lisps out there that are actually bad. For example, I find every Clojure-inspired neoLisp to be bad. Or something like newLISP. These are bad Lisps because they suffer from fundamental design errors that go against the concept of Lisp itself.

On the other hand languages like TXR Lisp and Emacs Lisp have made certain compromises in order to better fit their problem domains, but are fully aligned with the core ideas of Lisp as defined through its historical evolution.

I also don't see let, letstar, etc as clunky but I've also been using them for more than a decade (and am firmly in the Lisp Machine Lisp -> Common Lisp camp).

You seem to be a more experienced lisper than me (I mostly do elisp scripts and a bit of Clojure) and I have learned a bit from your answer. Thanks.

> These are bad Lisps because they suffer from fundamental design errors that go against the concept of Lisp itself.

So can you elaborate on what those design errors might be? And what exactly is the "concept of lisp"?

One example: https://www.gnu.org/software/emacs/manual/html_node/elisp/Co...

The concept of Lisp through its historic evolution refers to the set of ideas and implementation details that allows one to read a book about Lisp written 40 years ago and apply the same concepts through a language called Lisp today without any -major- changes.

If that's not possible or involves substantial programming logic rewriting, the language should not be viewed as Lisp.

Does Guix's remote build caching help avoid every Guix user having to build the full bootstrap?


It's not uncommon to have to build things because you've updated earlier than some others. I remember waiting hours for Rust, webkitgtk, or cataclysm-dda to build on multiple occasions. Sometimes just waiting another day would mean a substitute was available. You could also update your current profile with the exclusion of a few packages, such as the ones that have no substitutes. This is nice, but because it updates your current profile, then you can't remove something you were planning to remove via your package declarations, you're introducing your state then. A temporary issue that gets fixed when you can next apply your package manifest, though.

I can understand why following the master branch can result in massive rebuilds.

Does Guix offer a branch that contains code that has been built by the CI builders? In which case, when a user grabs a package they'll be able to grab the compiled version rather than have to compile it themselves.

Yes, I'm not sure why they are doing a full bootstrap. A full bootstrap takes ages for any distro and Guix goes even further than other distros by constantly reducing the size of their binary seed as they work towards a human auditable seed which comes at the expense of increased bootstrapping time.

At least on nix, I often cache miss the Hydra builds because I'm running unstable. Maybe they set something that's making them bootstrap?

Guile is almost 30 years old. It’s GNU’s Scheme implementation. People wanted to replace the nonstandard Emacs Lisp with Scheme but since so much code was written in elisp, they didn’t want to throw it out.

At this point someone should abstract out the Emacs definition so others could build it with Scheme or Clojure.

Emacs is basically a Lisp interpreter. They wrote the parts that needed to be fast in C and the rest is elisp.

45 years ago Emacs needed to be built in C. Today the entire thing could be built with a standard Lisp.

I suppose if someone wrote an Emacs in Scheme, the projects could converge once Guile is integrated into Emacs

I sometimes feel that someone needs to declare "elisp bankruptcy" in the same vein as one declares inbox bankruptcy, accept that implementing all of elisp in another superior lisp is too much work, write a better emacs-alike from the ground up in a proper, performant lisp, and let the package authors do the work of porting their packages.

> let the package authors do the work of porting their packages.

Unfortunately that will never happen, and since packages are the reason anyone uses anything, no one will use the newmacs.

If there were a translation layer for backwards compatibility then that could work, but the one with more packages wins, so I don't think it could work without it.

Neovim is getting good traction in the vim space. It turns out that developers are also annoyed by these issues on legacy platforms and are motivated to support the new system.

I'm not familiar with the vim world. How different is the neovim API? Do the developers maintain two versions of their plugins?

I'm not that familiar with the details. My understanding is that neovim at least mostly supports the vim language, but also offers other APIs (not clear about whether these APIs are extensions of the VIM language or altogether different) that allow developers to work around common VIM issues. My crude impression is that developers actively prefer to interface with the new APIs, and many packages aren't even backwards compatible with VIM.

Honest question. What's wrong with elisp?

I have never been limited by it. Granted, it's probably the worst lisp. But it works just fine for it's intended use. It could be argued that is one of the most used lisps.

As for porting packages, some are old and will never get ported and packages are the spice of emacs.

The language itself I don't really have a problem with, but it's slow.

This has happened, and the result is VSCode.

Of course, ES6 is less powerful than Scheme, but the speed and the mindshare outweighed the homoiconicity and the macros :-\

Anecdata: I switched from VSCode to Emacs because VSCode kept freezing, have not once regretted that decision.

This is especially funny given ES6's allegedly superior concurrency story.

30 years in development do help avoid some pitfalls, though.

I got the feeling that Atom might be a better analogy. For example, you can get a Spacemacs like environment if you use the Proton extension (https://discuss.atom.io/t/announce-proton-vim-focused-spacem...), which itself is written in ClojureScript, which is live-reloadable...

Speed and mindshare don’t make up for a lack of flexibility and power. No one’s gonna be running a window manager based on VS Code, and that should tell you something (see EXWM)

Why a mere WM; I can imagine booting into VS as some people boot into Emacs.

VSCode is a M$ initiative. Give it a couple years.

This comparison is laughable and ignorant.

It's true that Guile is a Scheme implementation, but it is also a platform to host any other language. The Guile-Emacs project wasn't about removing Elisp, it was about making Elisp run on the Guile VM.

Yes, that’s what I meant. They don’t want to throw away the Elisp but they want to support a Scheme.

Someday in the far far future long after Scheme is supported and millions of lines is rewritten in Scheme, I could imagine dropping support for Elisp.

Then Emacs will be nothing more than a large Scheme program that could run on any implementation of Scheme

I think it's easier to port everything elisp to Scheme (with some help by automation perhaps), than having an Emacs implementation in a Scheme that runs in all implementation of Scheme. I've worked many years in Scheme and the differences between compilers and interpreters are too large, especially when it comes to low-level functionality necessary for good performance.

You are assuming many things that are simply not true. There is no goal or will to integrate Guile in Emacs. It was a failed experiment taken up by volunteers outside of the core Emacs development team.

Most of the value in the Emacs ecosystem lies in Emacs Lisp and not in an "abstracted out" Emacs definition. Plenty of folks have implemented Emacs in various languages (using the same "abstracted out" definition) and guess what, all of them went nowhere. Because they were missing the point, just like you do.

"Plenty of folks have implemented Emacs in various languages (using the same "abstracted out" definition) and guess what, all of them went nowhere."

If they were:

1 - Lispy

2 - Faster

3 - Fully compatible with existing eLisp packages.

I think people would switch.

Guile Emacs is all of those except (at this point) faster.. when I tried it, it was unfortunately way slower.

If the speed could be improved a lot and the remaining bugs ironed out, it would be a very strong contender.

> Guile Emacs is all of those except (at this point) faster.

Guile Emacs is not at all compatible with Emacs Lisp, it only implements a tiny subset of Emacs Lisp.

It's right there in OP's article.

So the only thing it has going for it is being .. Lispy. Not enough.

In my own testing from Nov 2017, I got GUI Emacs to run.. it was slow, but it ran.

Vanilla GUI Emacs runs a non-trivial amount of eLisp code, so at least then with the version of Emacs I used (24.4.50) the compatibility situation could not have been dire than what the OP reported.

Also, you have to bear in mind that Guile Emacs was the work of one single (very talented) person over a single summer.

If there was actually a team of people working on it, I expect a lot more progress towards compatibility could be made.

Here is a list of outstanding items that still need to be worked on Guile Emacs:


That is because op didn't run it in Emacs. Guile-emacs uses the same Emacs c functions that Emacs elisp does, and running the Emacs tests against guiles elisp-without Emacs is like taking away a huge part of the standard functionality and expecting things to run.

The points it makes about speed are not wrong, but that the author fails to understand even the most basic relations between Guile-emacs and guile-elisp makes it hard for me to take it seriously.

Well, one of the major points of Guile (speed) is becoming obsolete as people are working in native-compiling elisp with libgccjit[0]. It provides great speed benefits: an average of x3~4 and up to ~x20 on recursive functions. With type annotations we can speed it up more — no need for a Guile JIT for speed anymore.

[0]: https://akrl.sdf.org/gccemacs.html

Guile-Emacs was making a larger point about GNU: What if instead of each application being its own island, there was more of a shared infrastructure? A text editor (or any other GNU application) shouldn't have to concern itself with programming language implementation, they should be able to focus on their problem domain. GNU devs could use Guile as a solid base for user-extensible programs (something GNU as a whole is supposed to value, but in practice mostly doesn't except for Emacs and a few others.) I don't think this will ever happen because GNU lacks cohesive vision and leadership, but Guile-Emacs was a worthy experiment anyway. There is one success story in GNU, though: Guix. That project has demonstrated the mutually beneficial relationship that other GNU projects could have with Guile if they ever wanted to go that route.

Integrating a compiler into a text editor to speed it up is a bit of an overkill imo. What if a lisp source changes and needs to be recompiled? What if several lisp files change? Does it mean that it also needs a sort of a build system? This brings the joke about an "operating system that lacks a decent editor" closer to reality (or reality closer to the joke).

I came here to post this as well. I've been running the feature/native-comp branch as my main Emacs and it's really impressive. I'm not sure when it will be ready for consideration for merging (there's still a lot of active development) but this branch is definitely the future of Emacs.

This project looks very promising!

This article is pretty biased against Guile. Guile-Emacs was a very neat experiment and the fact that it worked at all was remarkable but the prototype didn't get traction with the Emacs devs. It should be no surprise that it has issues because it was never completed! That's not an indictment of Guile or Emacs (both are wonderful), there just wasn't the necessary desire to make it happen so it fizzled out.

Guile-emacs also used a lot of Emacs functions for elisp functionality. The author is trying to draw conclusions from the test suite failing, but forgot to include a large chunk of the run-time.

Unfortunately, this comparison uses Guile 2.2. Guile 3 is out and has greatly improved the performance via Wingo‘s JIT.

AFAIK the biggest point that brought Guile-Emacs to a standstill is the internal string representation of Emacs that is different from Guile’s native format.

I am not sure that would help. Guile elisp is slow. I don't think there is anything stopping it from being as fast as guile sche, except for maybe man-hours.

The author updated the post with benchmarks for Guile 3.

One cool thing I'm doing with Guile Elisp is writing code that can be called by both Guix and Emacs to deal with the packages required by my Guix and Emacs configurations. Mind you it isn't much code, but it's really fun and I find myself sometimes writing Elisp with the intention that I can later call it from my Scheme projects. However, I would prefer to do it the other way around. I would NEVER write my Emacs config in Scheme, but I'd love to write portable libraries that could be called from any Guile supported project in whatever language makes sense for the problem domain.

I think a lot of people miss the point of Guile Emacs. Making Emacs faster or having access to all of Guile's features and libraries is not what the project intends - they are just possible free perks. The purpose of Guile was to allow any project to be extensible like Emacs with an independent module. That means instead of the Emacs folk implementing a native compiler just for themselves, some GNU project that uses Lua to rewrite existing Emacs Lisp libraries, or awesome small projects like Lilypond or Gnucash to have to deal with Guile Scheme all by themselves, all these projects can pool resources and improve their performance and features together. Guile Emacs is not about Emacs, it's about bringing more unity across all the islands of GNU projects.

If I had the know how / the time I would be less talk.

Guile elisp is very slow. There are almost no optimization work done whatsoever, and the dynamic state stuff is very slow still. I don't know what the author expected, really.

I think Guile-emacs defers a lot of the core functionality to Emacs C functions as well, which would explain the failed tests.

> Most surprising is the abysmal speed of the test[4], I’m looking forward to anyone being able to explain that part to me.

Just a shot in the dark, but I think since so many tests are failing, all bets are off as to their performance. For example, I could see a test getting into a loop that normally only runs ten times and succeeds, but here gets to run a million times before the test aborts and gives up. Not sure that's what's at work here, but... tests typically have timeouts for a reason (and typically finish significantly sooner than their timeouts, for obvious reasons). :-)

The tests don’t do anything interesting. You can see the code to generate the tests in the article. All the tests do is see whether each symbol (from whatever symbols the author had when they started emacs) is defined in the environment and, if so, that’s a pass.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact