Remacs is a fork of Emacs that aims to reimplement the Emacs core. Although most Emacs code is written in a dialect of Lisp, the interpreter for that Lisp (along with low-level stuff like IO) is written in C. The goal of Remacs is to rewrite the C code in Rust while maintaining “bug-for-bug compatibility” with Emacs.
Certain recurring questions seem to come up whenever Remacs is discussed, so here is a handy FAQ to address them. (Disclaimer: I’ve made nonnegligible contributions to Remacs. The opinions contained in this FAQ are not necesssarily those of the Remacs project or any of its contributors, including me.)
Table of Contents
- Rewriting interpreted Elisp in compiled Rust is a bad idea.
- What do I need to do to make my config work with Remacs?
- What are the end-user benefits of switching from Emacs to Remacs?
- So there are no new features?
- That sounds like a lot of work for nothing. What’s the point?
- Rewrites are a bad idea. This will never work.
- What version of Rust does Remacs use?
- When will the port be finished?
- Will Remacs replace Emacs?
- Rust is a language for hipsters. What’s wrong with good old-fashioned C, like Mom used to make?
- Will Remacs include Guile integration?
- What if Remacs causes a schism among Emacs users? Nobody wants another XEmacs.
- This will drain mindshare and effort from core Emacs development.
- To what extent do the Rust implementations of Lisp functions match their C counterparts?
- What are
- It would be better to work on improving Elisp itself instead of messing with the underlying implementation.
- It would better to replace Elisp with [Common Lisp / Scheme / Python / other].
- Will this fix Emacs’s long-standing long-lines problem?
- Will the Rust code get upstreamed?
- You’re using the word port wrong. It means extending existing code to a new platform, not rewriting code in a new language.
- How can I contribute?
- Strawberries don’t grow on trees.
- How many Remacs contributors are there?
- Where has Remacs been discussed?
- Where has this FAQ been discussed?
Rewriting interpreted Elisp in compiled Rust is a bad idea.
No, you’ve misunderstood. The underlying C code is being rewritten, and the goal is to leave the Elisp undisturbed.
What do I need to do to make my config work with Remacs?
Nothing, ideally. Remacs is intended to be a drop-in replacement for Emacs. Any differences in behavior are considered bugs, and filing an issue would be appreciated. (Small changes might be required if you have Lisp code that interacts directly with the low-level code.)
What are the end-user benefits of switching from Emacs to Remacs?
The main benefit is the thrill of using cutting-edge technology.
So there are no new features?
That’s right. There has been vague talk of doing something with concurrency or multithreading in the future, as well as speculation that Remacs might end up with speed improvements in areas like JSON parsing, but nothing concrete has come.
That sounds like a lot of work for nothing. What’s the point?
I don’t know that the Remacs developers have a common motivation, but I would guess that most of them are in it for at least one of the following:
- Exploring Emacs internals
- Playing with Rust
Personally I’m more interested in 1 than 2, but I’ve certainly come to a better understanding of some Rust concepts along the way (I still don’t get lifetimes or iterators though).
That’s the point from the individual contributor perspective. From the point of view of Emacs itself, work on Remacs led to the discovery of at least two bugs, one in the interpreter and one in the test suite. Remacs has also developed a large test suite of its own, mostly smoke tests for low-level functions. These could potentially be contributed upstream. I mean, I don’t know if anyone needs tests for
memory-use-count, but why not?.
Rewrites are a bad idea. This will never work.
The rewrite is incremental, so in a sense it already works. Rust and C are able to talk to each other, so much of the code can be ported function by function, with the editor remaining fully functional the whole time (modulo bugs).
What version of Rust does Remacs use?
According to one of the lead maintainers, Remacs “leans HEAVILY into nightly”.
When will the port be finished?
A meaningful estimate is not possible at this point. Personally I’m skeptical that it will ever be completely finished. Will anyone port the garbarge collector? Or the bytecode interpreter? Maybe, but progress might stall out before anyone figures out the hairy stuff.
Will Remacs replace Emacs?
No. I don’t know of anyone, including the Remacs developers, who has switched completely from using Emacs to using Remacs, and I don’t see that changing.
Rust is a language for hipsters. What’s wrong with good old-fashioned C, like Mom used to make?
Don’t ask me, I just work here.
Will Remacs include Guile integration?
There are no plans to include Guile integration in Remacs. Including an experimental, unfinished interpreter would dramatically increase the complexity of the project.
What if Remacs causes a schism among Emacs users? Nobody wants another XEmacs.
XEmacs was a fork of Emacs with cutting-edge new features, developed commercially by some of the best Lisp hackers in the world. In contrast, Remacs is a fork of Emacs with no new features at all, developed for fun by whoever shows up. I think the community is safe.
This will drain mindshare and effort from core Emacs development.
On the contrary, working on Remacs is a great onboarding exercise for the Emacs codebase. Someone who has successfully ported a handful of low-level Lisp functions from C to Rust is in a position to go on to make changes to the existing C code. I myself recently made a small contribution to core Emacs, and that certainly would not have happened had it not been for Remacs.
To what extent do the Rust implementations of Lisp functions match their C counterparts?
Most of the ported functions follow their original implementations pretty closely. The most divergent one that I know of is
byteorder, a function of no arguments that returns 66 (ASCII uppercase B) for big endian machines or 108 (ASCII lowercase l) for small endian machines:
Which implementation is nicer? You be the judge.
lisp_fn are macros in C and Rust, respectively, for defining exposed Lisp functions (that is, functions that can be called from within Emacs).
DEFUN is great, but
lisp_fn is truly a marvel. Whereas
DEFUN requires all inputs and outputs to be of the union type
lisp_fn allows functions to defined with native Rust types. This gives greater compile-time guarantees of type-correctness.
It would be better to work on improving Elisp itself instead of messing with the underlying implementation.
Why not both?
It would better to replace Elisp with [Common Lisp / Scheme / Python / other].
I don’t know, sounds dicey. In any case, that’s not related to this project.
Will this fix Emacs’s long-standing long-lines problem?
No. That would require changes to algorithms or architecture, which are language-independent. Nothing is free, and deep problems don’t just solve themselves because you sprinkled on some Rust; you have to actually figure out a solution. Rust isn’t magic.
Will the Rust code get upstreamed?
For several reasons, I doubt it.
- Rewrites always introduce instability and new bugs, and so far at least there is nothing to be gained in exchange.
- Rust is based on LLVM, which is apparently not Free. I don’t really understand the details, but I do tend to trust Richard Stallman. If someone comes up with a solid Rust frontend for GCC, we can drop this reason.
- Remacs doesn’t require copyright assignment to contribute, and Emacs does. Upstream won’t accept code with murky legal status.
A lot of tantrums have been thrown about reasons 2 and 3.
You’re using the word port wrong. It means extending existing code to a new platform, not rewriting code in a new language.
No, port is a kind of fortified wine.
How can I contribute?
The easiest thing to do would be to actually use Remacs and report any bugs you find. Crashes are bugs, obviously, but so are any deviations from expected Emacs behavior, even small ones.
If you want to contribute code, just find a C
DEFUN and then port it. The file
src/window.c has lots of easy ones (that’s where I started). From there you can work your way up to progressively harder functions. But hurry, before all the low-hanging fruit is gone! There used to be more, like
car-less-than-car, but I’ve already picked a lot of those strawberries.
Strawberries don’t grow on trees.
Oh. Well anyway, if you’re really ambitious, you can try setting up a profiler. Currently we don’t know how much is spent on, for example, type conversion, and profiling would give some insight into what’s really going on.
How many Remacs contributors are there?
Remacs forks Emacs, so the contributor list includes anyone who has ever worked on Emacs. But if the question means Remacs-only contributors, then we can check for anyone who has modified a Rust file:
That gives 103 as I write this. Accounting for duplicates and false positives, let’s call it around 80. I would guess that between half and three quarters of those are drive-bys.
Where has Remacs been discussed?
Where has this FAQ been discussed?