
Gccemacs: Experiment with native compiled Emacs Lisp - pjmlp
http://akrl.sdf.org/gccemacs.html
======
jlarocco
I've always wished Emacs would have been written in Common Lisp. It would
already support this, and it's all around just a better language (IMO).

There's Climacs, but it's so far behind...

~~~
dmortin
Couldn't emacs lisp be simply ported to work on the JVM? Then emacs would get
a battle tested virtual machine, and the emacs devs could focus on the editor,
instead of dealing with VM speed.

~~~
sansnomme
Keep your fingers crossed for Remacs. Cranelift can probably give it a
magnitude increase of speed if things go well.

They are about halfway through, give them a hand!

[https://github.com/remacs/remacs/wiki/Progress](https://github.com/remacs/remacs/wiki/Progress)

If every C/C++ programmer/member of the Rust Evangelism Strikeforce here on HN
help port a function, we would have a Rust Emacs in under a month.

C'mon everyone, the remaining code is pretty simple and straightforward:

[https://github.com/remacs/remacs/tree/master/src](https://github.com/remacs/remacs/tree/master/src)

Just mechanical translation to Rust. ONE FINAL SPRINT, and we will be done.
The hard work of setting up the tooling and macros are already finished. Many
here are happy to moan and complain about Electron infecting everything.
Channel your anger into this project! Just help port one function, this isn't
even leet coding level of difficulty. If you believe yourself to be a great
software engineer, then lend a hand. Don't want Electron editors like VS Code
and Atom to be the only game in town 5 years from now? Help translate a couple
lines now. It's literally a single docker pull to setup the dev env.

Low hanging fruits:

[https://github.com/remacs/remacs/blob/master/src/indent.c](https://github.com/remacs/remacs/blob/master/src/indent.c)

Tl;Dr: like Leftpad but more ugly.

~~~
sedachv
None of these proposals are going to address the main problem: most Emacs
modes depend on a lot of regular expressions for syntax highlighting and many
other things. Regular expressions are slow; it is a computational complexity
problem. That is, for example, the main problem behind long lines being slow
(and why they are not so slow in fundamental-mode). Now that Emacs has multi-
threading, pervasive regular expressions are the last big thing that is
responsible for noticeable performance issues.

~~~
sansnomme
What sort of Regex are they using? The garden variety can be compiled to DFAs
(O(n)) which a modern computer should have no issues handling. Further
optimizations

~~~
sedachv
Here is a good example:

[http://git.savannah.gnu.org/cgit/emacs.git/tree/lisp/emacs-l...](http://git.savannah.gnu.org/cgit/emacs.git/tree/lisp/emacs-
lisp/lisp-mode.el#n430)

DFAs for regular expressions use exponential memory for regular expression
size (also exponential time to compile them to DFAs). Try that for the regular
expressions in the link above. There is no way to make regular expressions
fast.

------
luknax
Emacs-devel thread:

[https://lists.gnu.org/archive/html/emacs-
devel/2019-11/msg01...](https://lists.gnu.org/archive/html/emacs-
devel/2019-11/msg01137.html)

~~~
neonate
From that thread ([https://lists.gnu.org/archive/html/emacs-
devel/2019-11/msg01...](https://lists.gnu.org/archive/html/emacs-
devel/2019-11/msg01164.html)):

 _I was already into gcc and libgccjit. I thought was cool to apply these to
some lisp implementation. I decided to have Emacs as a target cause I imagined
would have been useful and because I 'm obviously an Emacs user and fan.

I wanted to do something with the potential to be completed and up streamed
one day. Therefore I discarded the idea of writing the full lisp front-end
from scratch. On the other side I considered the idea seen in previous
projects of reusing the byte-compiler infrastructure quite clever.

The original plan was the to do something like Tromey's jitter but gcc based
and with a mechanism to reload the compiled code. So I did it.

I had a single pass compiler all written in C that was decoding the byte code
and driving libgccjit.

I was quite unhappy with that solution for two reasons:

1- The C file was getting huge without doing anything really smart.

2- After some test and observation became clear that to generate efficient
code this approach was quite limited and a more sophisticated approach with a
propagation engine and the classical compiler theory data structures was
needed. The idea of just driving gcc and having everything magically optimized
was simply naive.

So I came up with the idea of defining LIMPLE and using it as interface
between the C and the lisp side of the compiler.

In this way I had the right IR for implementing the 'clever' algorithmic into
lisp and the C side has just to 'replay' the result on libgccjit. Moreover it
saved me from the pain of exposing libgccjit to lisp.

I then realized I could, instead of decoding op-codes, just spill the LAP from
the byte-compiler. This makes the system simpler and more robust cause I get
also information on the stack depth I can double check or use during
limplification.

Lastly I managed to reuse the information defined in the byte-compiler on the
stack offset of every op to generate automatically or semi the code of my
compiler for the translation from LAP to LIMPLE for good part of the op codes.

The rest just iterating over tests debugging and implementing._

------
admax88q
Dynamic languages like lisp are much better suited for jitting. The author
acknowledges that most functions do not contain type information of what they
return, limiting the amount of optimizations.

Jitting is better suited for handling this type of situation since you can JIT
the version of the function for common types with a suitable guard that the
input types are what you expected. Thanks to modern branch prediction those
guard conditions are essentially free in the common casez and in the slow case
you were slow anyways since you haven't jitted that version yet.

~~~
samatman
This is doubly true of emacs lisp, which is both dynamic in the type sense and
dynamic in scope.[0]

Thus one has to guard both against type change, and change in what function a
symbol resolves to.

[0] elisp does have lexical scope, but it's bolted-on, reduces performance (at
least, used to) and isn't used in the core codebase, which predates it.

~~~
vkazanov
Not true, lexical vars are much faster in emacs.

