Back to the talks Previous by track: Bookclub tapas Next by track: Juicemacs: exploring speculative JIT compilation for ELisp in Java Track: Development

One year progress update Schemacs (formerly Gypsum)

Ramin Honary (he/him) - Pronunciation: "Rah-mean" (hard-H) "Ho-na-ree", Mastodon (preferred): ; blog: https://tilde.town/~ramin_hal9001; Codeberg: https://codeberg.org/ramin_hal9001/schemacs - SourceHut: https://sr.ht/~ramin_hal9001

Format: 24-min talk ; Q&A: BigBlueButton conference room Etherpad: https://pad.emacsconf.org/2025-schemacs
Etherpad: https://pad.emacsconf.org/2025-schemacs
Status: Q&A to be extracted from the room recordings

Talk

02:07.200 The scope of the project 04:24.760 Difference with Robin Templeton's project (Guile-Emacs) 05:49.720 Progress made since last year 07:28.040 Portable React-like GUI 09:06.040 Demo 11:48.700 Additional changes 14:12.020 Other Scheme implementations 17:06.200 GUI framework 21:51.520 Wrapping up

Duration: 23:14 minutes

Q&A

00:00.000 Q: I think that Kiczalez et al.'s metaobject protocol has a scheme implementation, does this mean schemacs will be metaobject-changeable in practice? 01:33.400 Q: How will the GUI display code be r7rs compliant afaik there is no dlopen in r7rs? 02:43.040 Q: Do you think some of schemacs could be extracted into SRFIs since you have made it portable between scheme implementations? 03:34.320 Q: Is there a recommended scheme implementation or does it try to be as portable as possible? 04:04.840 Q: How would Schemacs deal with Emacs' (re)display architecture? Would it be having its own display architecture? If so, how can it be compatible with things like overlays, images, etc.? From what I know, Emacs is extremely idiosyncratic here. 05:28.560 Q: You were saying that you'd like to get "most" of the one thousand three hundred and something Emacs packages done. Is there a technical blocker to doing them all? Or just a problem of getting enough people in to help and start writing scheme? 07:31.960 Q: What are you thoughts on Chicken Scheme? Would it be a good fit? 08:56.600 Q: Can this emacs lisp implementation be used by Guile's emacs lisp "mode"? 10:42.800 Q: I wonder if we could do some sort of programmatic analysis on popular Emacs packages to see what list of functions they tend to depend upon, follow function calls down to the lowest level 11:36.640 Q: Do you think there is an opportunity to use Racket? 13:24.040 Q: Shouldn't it be enough to just implement the builtin functions? Most of the commands are written in Emacs Lisp, right? 16:59.720 Q: Tell us more about this show-stopping bug! How to squash it? Can people help? 19:21.760 Q: Are there performance concerns with implementing certain C primitives in pure scheme? 21:07.052 Q: If this project is successful, are you worried about a possible split in the community between Schemacs and GNU Emacs users? 23:07.600 Q: The dream of never even needing to change to the web browser - would schemacs bring us closer to that? 24:30.000 Q: Anything specific other than minimalism that made you choose Scheme over Common Lisp? 26:40.680 Closing thoughts

Listen to just the audio:
Duration: 27:51 minutes

Description

During EmacsConf 2024 last year I presented my work on a clone of GNU Emacs written in Scheme which also clones the Emacs Lisp programming language. In this talk, I will briefly present an overview of the project similar to the talk I gave last year, and then discuss the progress that I have made on this project in the past year.

To quote the description from the presentation I gave last year:

Unlike other editors which only clone the Emacs keybindings (Edwin, Jed, jEdit, Jove, Lem, MG, Yi, Zile), I hope my Emacs clone will also fully clone the Emacs Lisp programming language well enough that many of the packages in ELPA, Non-GNU ELPA, and perhaps even MELPA, can be used in [Schemacs, formerly "Gypsum"] without any modification. I would also like to talk a little bit about how I am implementing it (the software architecture), and invite others to contribute.

I think my project is of interest to many Emacs users because, firstly, I have personally spoken with a relatively large number of people who have expressed interest in making Emacs programmable in Scheme. Secondly, there is a good amount of prior art for Scheme implementations of Emacs. There are even builds of Emacs that link to Guile which provides a "scheme-eval" built-in function that translates between Elisp data types and Scheme data types. The Guile compiler itself ships with an Emacs Lisp compiler as well, although it does not provide enough of Emacs's built-in functions to be of much use.

The progress I have made so far:

  • Ported all Guile-specific parts of the Emacs Lisp interpreter to fully standards-compliant R7RS Scheme code. The interpreter now runs on a few different Scheme implementations, not just Guile. The GUI remains Guile-only for now.

  • Implemented a new R7RS-compliant lexer and parser which constructs an Abstract Syntax Tree (AST) data structure, making it easier to find the source of errors and produce informative back traces.

  • Implemented enough of the Emacs Lisp interpreter to be able to load the "subr.el" source file, this defines what you might call the "core" of the Emacs Lisp language, including macros such as "defun" and "lambda."

My primary goal continues to be to make it as easy as possible for other people to contribute to this project. Pretty soon it should be possible to run the Emacs Regression Test suite (ERT) in the cloned Emacs Lisp interpreter. Once this is done, we can run the same test code used during the building and testing GNU Emacs to test Schemacs. Hopefilly then, anyone will be able to select a failing test, write code to make the test pass, and submit a patch.

About the speaker:

I am Ramin Honary. I have been professional software engineer for 17 years and I have always had a passion for functional programming languages, especially Haskell and the Lisp family of languages.

Discussion / notes

  • Q: I think that Kiczalez et al.'s metaobject protocol has a scheme implementation, does this mean schemacs will be metaobject-changeable in practice? 
    • A: I was not aware of that implementation, but I will look into it. The MOP has not been necessary for building the GUI, actually (apart from the fact that Guile-GI uses GOOPS to organize the Gtk3 bindings). Pretty soon I will demonstrate the React-like programming framework I have developed for the Schemacs GUI.
    • A: I don't need a meta-object protocol for Schemacs, at least so far it hasn't been necessary, but may be something to look into if it can be made cross-platform (for various R7RS Schemes).
  • Q: How will the GUI display code be r7rs compliant afaik there is no dlopen in r7rs?
    • A: To handle these platform-dependent concerns, I make heavy use of the cond-expand macro. Basically any Scheme implementation upon which I would like to run the Schemacs GUI will have to have it's own unique back-end code that is loaded-in to the main Scheme program. cond-expand has mechanisms for checking which Scheme implementation it is using, so it is pretty easy to write code that can load-in different back-ends for whatever platform you are using.
  • Q: Will it be possible to write multithreaded code for Schemacs?
    • A: The GUI is inherently single-threaded, but SRFI-18 provides multi-threading. So yes, there is multi-threading, and I do have ways of evaluating Scheme code inside of the GUI thread so that you can update the GUI. This is necessary for running external processes and putting the results into buffers. But anyone should be able to use the threading mechanism through the ordinary SRFI-18 APIs. https://srfi.schemers.org/srfi-18/srfi-18.html
  • Q: Do you think some of schemacs could be extracted into SRFIs since you have made it portable between scheme implementations?
    • A: Absolutely. I have considered making a SRFI for my (schemacs lens) library. I would like to break up the Schemacs into libraries and publish them on the Akku package manager, or in the Guix repository. I am hopeful that some of the libraries I have written will be useful for other Scheme programmers. https://akkuscm.org/
  • Q: Is there a recommended scheme implementation or does it try to be as portable as possible?
    • A:(He said earlier that Guile was the only version that worked so far.  He wants it to work for all R7RS though.) That's right, Guile is the reference implementation, the GUI only works on Guile, but Emacs Lisp works on Guile, Chibi, and Gauche. I would like to support as many Scheme's as possible. If you want to get started with Scheme and you want to try Schemacs, I recommend Guile.
  • Q: How would Schemacs deal with Emacs' (re)display architecture? Would it be having its own display architecture? If so, how can it be compatible with things like overlays, images, etc.? From what I know, Emacs is extremely idiosyncratic here.
    • A: That is all "to be determined." At some point we will have to emulate the Emacs Lisp display architecture in Schemacs, but for the time being Schemacs has it's own completely different display architecture.
  • Q: You were saying that you'd like to get "most" of the one thousand three hundred and something Emacs packages done. Is there a technical blocker to doing them all? Or just a problem of getting enough people in to help and start writing scheme?
    • A: just a matter of implementing enough of Emacs' built-in functions; this relates to the bug we saw in the presentation (stack dump); other people will have trouble contributing until this is resolved because it does not handle closures correctly.  once that is worked out it will be a matter of implementing Emacs' C-based functions in scheme.  Don't have a way to be sure but we probably do not need all of them implemented.
  • Q: What are you thoughts on Chicken Scheme? Would it be a good fit?
    • A: I think it will be; tried this in preping for the presentation but ran into some issues; tried using the pattern matcher from Alex Shinn; each implementation has a slightly different take on macro-expansion for pattern matching; I would definitely love help in this area. I will probably have to avoid pattern matching to make it fully portable, or else implement my own pattern matcher which I can be sure will work on all R7RS Scheme implementations.
  • Q: Can this emacs lisp implementation be used by Guile's emacs lisp "mode"?
    • A: This was touched on last year; Emacs Lisp in guile is a different implemtation which is unfortunately quite incomplete, it can't even run some of the GNU Emacs initialization code.  When I first started I was using Guile Emacs Lisp's parser, however it did not give source locations, and was not portable to other Schemes, so I had to basically write everything for Schemacs from the ground-up. If Andy Wingo is interested, we can probably replace the existing Guile Emacs Lisp implementation with Schemacs.
  • Q: I wonder if we could do some sort of programmatic analysis on popular Emacs packages to see what list of functions they tend to depend upon, follow function calls down to the lowest level
    • A:  Yes, please do this for me! :D :D
  • Q: Shouldn't it be enough to just implement the builtin functions? Most of the commands are written in Emacs Lisp, right?
    • A: Yes, correct. That is the approach I am taking. My goal is to get the Emacs Regression Test suite (ERT) system working in Schemacs Emacs Lisp, then we can just use the reports generated by the GNU Emacs regression tests to see what Emacs Lisp functions we have left to implement in Schemacs.
  • Q:  Do you think there is an opportunity to use Racket?
    • A: Yes, looking at getting Schemacs working Chez then could somehow move onto Racket; haven't tried R7RS for racket. Racket works on Chez, and I would like to make Schemacs work on Chez, but I won't be able to make use of Racket libraries. Alexis King has written a R7RS language package for Racket, and I haven't tried it yet, but it may be a good way to get Schemacs to work in Racket.
  • Q: Tell us more about this show-stopping bug! How to squash it? Can people help?
    • A: Unfortunately, this is something I will have to do on my own unless you happen to be a Scheme genius who can read and understand all of my code so far in a short amount of time. It has to do with how closures work. Closures were introduced with Emacs 27 (?) and lexical scoped variables for ELisp.  When we create and return a lambda that uses a variable declared outside of the Lambda in a "let" binding, that variable resides on the stack, so the Lambda must have a "note" that captures part of the current stack and then later restores it when the Lambda is executed. This is where the issue is: it is not capturing the variables from the stack properly.  The plan is to do static analysis of the Lambda and then store a reference to those vairbles in the Lambda data structure.
  • Q: Are there performance concerns with implementing certain C primitives in pure scheme?
    • A: No :) I think it was Donald Knuth who said "Premature optimization is the root of all evil." The graphical back-end is usually written in C anyway (Gtk3), so the graphics is being done in C. Besides that, Scheme compilers like Guile, Chez, Gambit, and Chicken all have very good performance characteristics. So for the time being, I don't think performance is a major concern.
  • Q:  If this project is successful, are you worried about a possible split in the community between Schemacs and GNU Emacs users?
    • A: There seems to be a large call for a scheme based editor, so the demand for this "split" is already there. There have been attempts at rewriting Emacs in Scheme since the early 90s. And there hasn't been a good, free-software, Scheme-based programming environment like Emacs since Edwin on MIT Scheme.  So Schemacs may cause some fragmentation but "a rising tide raises all ships".  If I have time I would also like to contribute some of what I learn from Schemacs back to GNU Emacs, for example I would like to work on an interactive canvas library based on the "Cairo" SVG rendering library. Cairo is already built-in to Emacs, so I would like to maybe port my Schemacs interactive canvas (still a work in progress) to GNU Emacs when I have some time.
  • Q:  The dream of never even needing to change to the web browser - would schemacs bring us closer to that?
    • A: I hope so!  this is also a dream of mine!  I wanted to make sure I have a good workable UI framework like React so we can write proper GUIs for applications such as a Mastadon client, it could be very nice to have a better GUI for this, or for Magit, or Gnus. I would love to be able to do as much as possible in Schemacs, e.g. social networking, public Git repos. That is a goal of mine for this project.
  • Q: Anything specific other than minimalism that made you choose Scheme over Common Lisp?
    • A: Philosophical question :)  I love Haskell, and I once had a conversation with William Byrd (author of "MiniKanren," who studied under Dan Friedman at the University of Indiana) who told me about why he didn't like Haskell and suggested looking into Scheme. I like Haskell because it is a very pure implementation of the "System-F" Lambda Calculus, and I like Scheme because it's closer to the mathematical framework of the Untyped Lambda Calculus, but Scheme is friendly (without the strict type system), similar to Python. It provides a tiny framework from which all of computer science can be explored.  Excited to see what this tiny language can do. I like the idea of starting from a tiny "kernel" language and using it to build-out all other alglorithms and software. I think it is a shame that there isn't much Scheme code out there, and I would like to try to expand the Scheme software ecosystem.
  • https://codeberg.org/ramin_hal9001/schemacs
  • https://github.com/spk121/guile-gi  <-- that is the GUI back-end, by the way.
  • https://gi.readthedocs.io/en/latest/   <-- that is GObject Introspection, this is how the GUI bindings work.
  • lol it feels like rahim has been standing at the same place since last year :P
  • Basically, yes, I haven't moved at all! Of course I have moved away from that spot in the interim once or twice.
  • Awesome talk, I will surely try to contribute even though I don't know stuff yet :)

    • All are welcome, if you don't know anything, I'll be happy to try and teach you!
  • amazing progress

  • nice talk.
  • I'm so excited for this project! Amazing update 😊
  • I wonder if we could do some sort of programmatic analysis on popular Emacs packages to see what list of functions they tend to depend upon, follow function calls down to the lowest level
  • would love to see that
  • That is probably a good idea (getting rid of the baggage)

Transcript

Hi, EmacsConf 2025. My name is Ramin Honary, and I'd like to talk to you today about my project called Schemacs which I presented last year. Back then it was called "Gypsum" and the name has since changed. So my name is Ramin Honary. I'm an Emacs enthusiast, have been since 2017 or so. I'm a full stack software developer. I love Haskell, Scheme, anything functional programming related, and of course Emacs. I started learning Scheme about three years ago, and this is my third time presenting at EmacsConf. So the Schemacs project that I'm talking to, I'm talking about to you today, was originally called "Gypsum". The reason I did not call it "Schemacs" was that the name "Schemacs" was taken on GitHub. But in the past year, I was able to get the permission of the author of GitHub's Schemacs project to name my project the same thing, even though it's a very similar project. So I changed the name. Let me see if I can quickly show the screen. So yeah, I have archived the old project. It's still there, but there's an explanation in the readme file and a screen grab of the conversation I had with the original author of GitHub Schemacs. My Schemacs is not on GitHub at all. It's only on Codeberg. So please don't get confused. But yes, I received permission to change the name and so I did. And I would like to give a quick shout-out to user "Tusharhero" for helping me with that. This person really helped make that name change happen. So back to the slides.
[00:02:07.200] The scope of the project
And so now I'd like to clarify the scope of the project. I don't think I quite made it clear well enough last year, but... Although I'm definitely cloning the Emacs Lisp programming language, the actual scope of the Schemacs project is to make an Emacs-like app platform for Scheme. I don't consider Emacs to be a text editor. I consider Emacs to be a Lisp app platform. So it's similar to something like the World Wide Web, or Microsoft's .NET app platform, or Java. These are all examples of app platforms. I would like Schemacs to make it easy for not only people to use it for things like editing text or, you know, for using your computer through a command line or manipulating your Git repository. I'd also like you to be able to create simple GUIs or TUIs using Scheme. So that's also one of the goals of this project. It will of course have an Emacs-like text editor, and I will clone Emacs Lisp. So hopefully GNU Emacs users will feel comfortable moving over to Schemacs because they'll be able to use your init. You'll be able to use your init.el file. So configuring and scripting Schemacs should be done in Scheme. I'd like to encourage scripting in Scheme and creating new workflows and macros in Scheme. It will support Emacs Lisp depending on how much of the Emacs Lisp interpreter I can clone. That will be supported but not encouraged. But you should still be able to run your init.el. And I would like it to be good enough, this Emacs Lisp interpreter should be good enough to run packages from ELPA. Although it will probably be some time before it will be able to run something as large as Org Mode or Magit.
[00:04:24.760] Difference with Robin Templeton's project (Guile-Emacs)
It is slightly different from the Guile-Emacs project. This is the work of Robin Templeton who presented last year. Guile-Emacs links the Guile runtime into the Emacs executable. It's not a Scheme application. Emacs, the core of Emacs is written in C. Guile, the core of Guile is written in C. What Robin Templeton has done is, at the C level, linked "libguile.so" into Emacs and then provided a programming layer where you can call the Scheme interpreter from Emacs Lisp so that you can run Scheme programs from within Emacs without having to launch a separate process and communicate over a channel such as a socket. You won't need "SLIME" or anything. The Guile interpreter is just right there inside of Emacs. But my project is not like this at all. Schemacs is written completely from the ground up in R7RS-compliant Scheme. And because it's R7RS-compliant, it's not bound to any one particular Scheme implementation, although Guile is the reference implementation. One goal of this project is to be able to run Schemacs on any R7RS-compliant Scheme implementation.
[00:05:49.720] Progress made since last year
The work that I've done this past year mostly is internal. There's not much that you can see on the surface. But the most... One of the most important things that I did was I rewrote the parser in R7RS Scheme, so it no longer depends on the Guile regular expressions library. The parser now also provides source locations, so if an error occurs in Emacs Lisp, there will be a stack trace and it will show you where in the source code the error occured. This was not possible last year. And because it no longer depends on Guile, I can make it work on multiple Scheme implementations. So far, I've been able to get it to run on the Chibi Scheme interpreter and the Gauche Scheme interpreter, as well as Guile, which is the reference implementation. For a short time, it did work also on Chez Scheme, the Chez Scheme compiler, using Gwen Weinholt's "Akku," which is a program that translates R7RS Scheme to R6RS Scheme. And with that translation, because Chez Scheme is pretty strictly an R6RS compiler, the translation allows you to run R7RS programs. But due to some change, I'm not sure where, it may have been changed in the Schemacs source code, or it may have been a change to Akku, but it no longer builds on Chez. It did at one point. I'd like to try to fix that.
[00:07:28.040] Portable React-like GUI
The second most important thing that I've worked on is a portable React-like GUI. And so React, for anyone who has done web programming, is a very popular framework for programming web applications. And I've provided something very similar to that in Scheme now. So it works. I have constructed a DOM data structure in Scheme. It's just an ordinary Scheme data structure. It works like the web's "Document Object Model" or the "DOM" data structure. And then this Scheme DOM data structure can be rendered using any GUI framework that is convenient for the Scheme implementation that you're targeting. And you should be able to implement also rendering to a CLI as well. The current reference implementation is using a framework called Guile-GI. This is the "GObject Introspection" framework. It's a very simple GObject Introspection framework for Guile, and it binds to GTK3 on Linux. There's a similar framework called G-Golf which I'd like to begin using as well, also for Guile. G-Golf seems to be a bit more well-maintained, a bit... It has better features. G-Golf may be a better rendering backend for the reference implementation, but I would like to provide both. I will give a demo of this now. Unfortunately not a whole lot to see compared to last year. First thing I'd like to show is that I now have a Makefile. You can look inside this Makefile and if you're able to read a Makefile, you can see that I have several targets now available. You can build Schemacs for Guile, you can build Schemacs for Gambit, or Stklos, or Chicken, or Chez, although none of these (except for Guile) currently works. These targets will actually build the source code, but then you would have to load it into the REPL separately. There are targets for launching a Gauche REPL and a Chibi REPL. You can also run the Emacs Lisp tests in Gauche and Chibi. You can also start a Guile REPL through this Makefile. So I will do that right now in the shell. (...make the text larger...there we go...) OK, so we have this directory of the source code. Let's just begin by running "guile.sh". This will launch a REPL and you can load "main-guile". This will launch the GUI. This is the basic proof of concept GUI that uses Guile-GI. So it may be hard to see. I cannot change the size of the text yet. I've implemented the M-: feature where you can eval in a minibuffer some Scheme code. (string-append "hello" ...) It outputs the result in the buffer. This is basically the "*Messages*" buffer. And that's all the more that I have. This is the same state it was in last year. It hasn't changed a whole lot since back then.
[00:11:48.700] Additional changes
But I have made additional changes. So first of all, you can run (let me just go back into the Guile)... you can run the Emacs Lisp interpreter tests, so "elisp-tests". As you can see, it gives you a stack trace. So this is an error that I've been able to reproduce. I know exactly what the cause of this error is. It is not finding a variable because the closure is not correctly capturing its environment. So there should be a variable in the closure, but that variable has not been captured and so it is causing an error. It is currently loading "byte-run.el". Let me show you what code that is here. So I've copied into the source repository for Schemacs some of the Elisp code from GNU Emacs. So I have this "subr.el". This declares most of the core of Emacs Lisp that's not written in C. There's also "byte-run.el". Schemacs Emacs Lisp can now evaluate this. This is where functions like "defun" are defined, and "defmacro". So as you can see, defun itself is a defmacro defined right here. It's written in Emacs Lisp itself, defined in terms of defalias. So I can evaluate "byte-run", I can evaluate "macroexp", and the failure occurs somewhere in "subr.el". Although if you look at the stack trace, it doesn't provide all the necessary information. So it appears to be happening in byte-run.el. Really, it's an error that's occurring inside of a macro, and the macro call site is somewhere in subr.el. Anyway, take note of this stack trace. This was run from within Guile.
[00:14:12.020] Other Scheme implementations
Now what I've done this past year is make it work on other Scheme implementations. Use "make" to launch a Gauche REPL. Now I'm inside of Gauche. This is the command that you would use to launch a Gauche REPL. And I can load the same program (load "elisp-tests.scm"). You get the exact same result as Guile. So we have two different Scheme implementations producing the same result. Let's try "make" a Chibi REPL. This is Chibi Scheme. And you can (load "elisp-tests.scm"). Chibi is a bit slower, but you get the exact same result. So we have three different Scheme implementations all running Emacs Lisp, and all producing the same result. I think that's... I'm fairly proud of that accomplishment. I was able to get the code written to the point where it actually runs on multiple implementations. You can also try making it for other Scheme compilers like "schemacs-mitscheme" for example, but this will fail. You can try building it for "schemacs-chez", Let's try Chez... there we go. And it will use Akku, and it will fetch the necessary dependencies. But it fails, and I haven't been able to debug that quite yet. Stklos fails for a similar reason. Gambit... Chicken still doesn't build all the way yet. The Makefile at least has places for it. If anyone can help me out and get Schemacs to compile on these other Scheme implementations, I'd appreciate it. I can probably figure it out myself, but that will take more time. And let me just show you quickly the test program. Basically this is the Emacs Lisp test program that I was just running, and it produces an error. All it does is it loads these files here in this order, and it fails right around here. So it's able to load these two. And yeah, that's what I've accomplished on the Emacs Lisp side of things.
[00:17:06.200] GUI framework
The next thing I want to show you is the GUI framework that I've written, which I'm fairly proud of so far. So this is the GUI framework (oops, I better launch it again, OK...) and let me show you the tests. So here in the tests, you can start to see some examples of how you use it. So here is a "counter" test, and this is kind of like the "hello world" of reactive programming frameworks, where you have a state variable, sometimes called an "observable." I'm calling it "number", and it uses "=" to check if the state has updated. If an update occurs and the new value is different from the old value according to the "=" function, then trigger a state update in the GUI as well. Initialize to 0, bound to "number". I have a "button" function which creates a simple button. It takes a label and an action. Right here you see the "div" command. This is what creates a "div". Using the properties, I describe that this div is a push-button and the "on-button-push" is an action. The action is to update the variable "number" using whatever function or lambda was provided to it. And then the content that you see on screen, that you will see on screen when it runs, is here. You create a "div-pack cut-vertical". You declare two buttons and then you declare this "use-vars" which will take the content of this variable here, this observable, and place it into the GUI next to the buttons here. So what you will see on screen is a "plus" button which increments, here is the "increment" function, a "minus" button which decrements, and then the content of the variable that is being incremented and decremented. The advantage of these reactive frameworks is that with very few lines of code you can create fairly complex interfaces. The less code you have to write, the fewer chances you have to make mistakes. So let's just run this program. This was the "counter-test." And that is the debug window. Here's the "counter." I'm sorry it's not much larger than this. But here's the "plus" button, the "minus" button, and here's the "number", 0. And I can increment or decrement as much as I like. So yeah, that's kind of the hello world of reactive programming. (I'll reboot the REPL...) The next thing I want to show you is this layout test. And I'll just run the test first. So here we have basically a tiling window manager kind of thing, where you can resize the tiles and then by clicking on these buttons here, you can change the layout. So you can do two on the right, two up above, or three up above. So, yeah. Those tiling windows, as you can see, once I work this branch into the main branch of Schemacs, I can use that to implement the split window functionality for Schemacs, the editor. So here's what this split... Here's the layout test that you just saw. Let me make it a bit smaller so that it all fits on one screen. So basically we have the "button" command again, and then these are the button actions which basically just changes the layout, and then I have the layout. So this layout is a "div." The first div just places three buttons in a row. The next layout is a div within a div. So we have one div which places the button called "two right" buttons, and the div above it, which places the "three in a row" button or the "two above" buttons. And here's the next... So there's three different layouts, and clicking on one of their associated buttons will just change the layout. As you can see, very little code to create a somewhat complex user interface. That's the advantage of using reactive or declarative UI programming paradigms. So yeah, this has not been merged into Schemacs at the time of this recording, but will be soon hopefully.
[00:21:51.520] Wrapping up
So yeah, I think I've already gone on for 20 minutes. So I guess I'll just end my presentation here. I have lots more to talk about. I guess I will say one last thing before I go: that I would very much like for others to try and contribute to this project. I will do my best to try and help teach anybody or work with anybody, especially even if you don't have much experience with Scheme. I'd like to help everybody try to contribute. Basically I want to get this proof of concept working. I want to get a stable user interface up and running, and then we can start working on improving the Emacs Lisp interpreter all together. There are close to 1,400 built-in functions which need to be implemented. We don't need to get all of them in order to be able to run probably most of ELPA, but as much as possible. We would like to clone Emacs Lisp and I need help. So get a hold of me. My project is on Codeberg. Well, (oh, I can't show this here), but I will end it there. Thank you for listening.

Captioner: sachac

Q&A transcript (unedited)

[00:00:00.000] Q: I think that Kiczalez et al.'s metaobject protocol has a scheme implementation, does this mean schemacs will be metaobject-changeable in practice?
[oops, forgot to start] [Corwin]: ... object protocol has a scheme implementation. Does this mean schemacs will be meta object changeable in practice? In the reference implementation for Guile, Guile has its own object-oriented system called Goops. I'm sorry, I'm hearing a delay. Anyway, I'm going to turn off my stream quick. There we go. So, um. Yes, uh, I, I don't I wasn't aware of the, um. the meta-object protocol that you have mentioned here, but I will look into it. I know that there isn't really a standard meta-object protocol for Scheme. That was an issue for me because I'm trying to make this cross-platform, and so I've done all of my work so far without a meta-object protocol because that's the easiest way to make it work on multiple Scheme implementations. But if there is a nice portable one that works on many implementations, I would use that, yes. It's just that so far it hasn't been necessary. I've been doing mostly functional reactive programming and React.js-like framework. I've created that for the GUI front end. And that's all the more I've needed so far. So, yeah. Oh, yeah, please, next question. Sure.
[00:01:33.400] Q: How will the GUI display code be r7rs compliant afaik there is no dlopen in r7rs?
As far as I know, there's no DL open in R7RS. Yeah, R7RS small is extremely small and does not have any features at all. But it does provide a conv expand macro. And this allows you to load in different code depending on which scheme implementation you're using. So basically, I'll have to write a different back end for each scheme implementation. And I think that's really the only way is possible at all, because there's no standardization. So essentially, the libraries that I've written for schemacs will become kind of a platform-independent way of writing GUIs for Scheme. It's just a matter of, will your Scheme implementation support the Schemacs GUI protocol? So I've kind of written my own protocol, and it's entirely R7RS small compliant. It's all done with record, what are they called, record types.
[00:02:43.040] Q: Do you think some of schemacs could be extracted into SRFIs since you have made it portable between scheme implementations?
could be extracted into SFRIs since you've made it portable between scheme implementations? Probably first thing I'll do is start splitting up and publishing independent libraries on the Akku package manager. This is a kind of a package manager ecosystem for Scheme, and in particular R7RS Scheme. And it's also mirrored on the other package manager, Snowfort, just by the way. But yeah, and then I might be also, I've considered creating a SRFI for the lens library, which is based on the Haskell lens library. I don't think that exists yet in Scheme, so I thought that might make a good SRFI.
[00:03:34.320] Q: Is there a recommended scheme implementation or does it try to be as portable as possible?
It's the only one that works with GUI, but as I demonstrated in my presentation, the Emacs Lisp interpreter works on multiple schemes so far, and I've had trouble with some of the scheme compilers. But yeah, I would recommend Guile.
[00:04:04.840] Q: How would Schemacs deal with Emacs' (re)display architecture? Would it be having its own display architecture? If so, how can it be compatible with things like overlays, images, etc.? From what I know, Emacs is extremely idiosyncratic here.
Emacs's re-display architecture will be having its own display architecture? And if so, how will you handle things like overlays and images? So basically, the scheme way of doing things So, I've created this React-like programming framework. It's like ReactJS or Vue.js. That is just the API of how you write GUI code in Scheme. And each Scheme implementation will have its own GUI backend, which implements that Protocol. And so when it comes time to link the Emacs Lisp built-in functions that do these things like overlays and so on, we're going to have to come up with some way of modeling that using the scheme framework that I've designed. And I may have to make alterations specifically to support Emacs Lisp. I don't know yet. I haven't got that far.
[00:05:28.560] Q: You were saying that you'd like to get "most" of the one thousand three hundred and something Emacs packages done. Is there a technical blocker to doing them all? Or just a problem of getting enough people in to help and start writing scheme?
to get the most out of the 1300 and something Emacs packages that exist. Are there technical blockers to doing them all or just a problem of getting enough people to jump into it? of the Emacs built-in functions. Right now, there's kind of a big bug. I mentioned this also in the presentation. The stacktrace that you saw during my presentation, that is the biggest bug right now that's preventing me from running most other code. And I don't think other people will be able to contribute to the code base until I get that bug fixed, because it doesn't capture closures correctly. it doesn't behave like Emacs Lisp does, and that's the big problem. So once I get that worked out, then it's just a matter of implementing enough of the EmacsLisp built-in functions, these are the functions that are mostly implemented in C, implementing those in Scheme. And that, yeah, that's the thing that I'm going to need a lot of help with because there's quite a few of those APIs. But I imagine, I have no idea, no way of knowing, but I imagine we don't need 100% of them in order to run most of ELPA. We probably can get some of the important large ELPA packages like Magit and Org mode with just enough of the Emacs Lisp built-in functions to handle that. But we won't really know until we've tried. So yeah, I'll try to get this bug fixed right away. That way we can all start working on it together, hopefully. We'll burn that bridge when we're on it or something.
[00:07:31.960] Q: What are you thoughts on Chicken Scheme? Would it be a good fit?
Will that be a good fit? Do you think? trying to run chicken scheme in my, um, presentation and, uh, I ran up against some kind of issue, which I really don't know how to debug. Um, it's probably something to do with the, uh, pattern matcher. Um, I'm using the pattern matcher, uh, written by Alex Shinn, which seems to be the most portable. Pattern matcher, uh, for our seven RS scheme. But not all scheme compilers implement, what is it called? The macro, I can't remember what it's called. There's the macro expansion system for R7RS small. All of these scheme implementations seem to have a slightly different take on how they work. And so that macro expander has been, for pattern matching, has been the biggest difficulty in making this code portable. And so I'm thinking of ways of maybe trying to ditch pattern matching, but that's such a useful feature and it's hard. So I don't know, we'll see if I can, if somebody can help me get it to work on chicken team, I'd really appreciate it.
[00:08:56.600] Q: Can this emacs lisp implementation be used by Guile's emacs lisp "mode"?
I did mention this last year in my presentation. Emacs list in Guile is totally different from what I've done. That implementation was written about 10 or 15 years ago. I can't remember exactly when. It is quite incomplete. I don't think it even runs most of the macro expanding code. Some of the code that is written for GNU Emacs in Emacs Lisp, where GNU Emacs is initializing itself, it can't even get the first file in that code. It hasn't been touched in 10 or 15 years. Initially, when I first started this project, I was using the parser for Guile's Emacs Lisp implementation, but it didn't give me things like source locations, so I had to rewrite that. And also, it wasn't portable. So yeah, because I want it to be portable, it's necessarily going to be not reliant on anything that's inside of the Guile library, including the Emacs Lisp interpreter that's there. Maybe I could replace the Emacs Lisp interpreter in Guile if Andy Wingo would be interested. All right. And I see we've got a few people that did jump into the BBB. I'm just going to quickly, oops. quickly try to make my text a little bigger so I can read a question that came here.
[00:10:42.800] Q: I wonder if we could do some sort of programmatic analysis on popular Emacs packages to see what list of functions they tend to depend upon, follow function calls down to the lowest level
on popular Emacs packages to see what list of functions they tend to depend on while a function calls down to the lower level. Somebody please do that for me. Yeah, this is really awesome. I use Guile, and I love Guile, and I also love functional programming, so this is really nice that you took the declarative approach. One thing that I'm interested in is, are you also considering Racket in the scheme group? Because I know a lot of people do not consider Racket as a sort of scheme thing, because it grew out of it.
[00:11:36.640] Q: Do you think there is an opportunity to use Racket?
Because I think Racket has a lot of good ideas that can be used. but it's very, very heavily dependent on Racket's macro expander, which is, well, yeah, the macro expander is extremely complex for Racket, and I don't think it's possible to port it to any other scheme, as far as I know. But Racket is based on Chez Scheme. And I am making an effort to port my code to Chez's Scheme. I mentioned this earlier, but there's the Gwen Weinholdt Akku system, which allows you to translate R7RS to R6RS. And since Chez is an R6RS compiler, I did at one point get the Emacs Lisp interpreter to compile for Chez, although I think there's been a change either to Akku or somewhere in my own code base. It doesn't build anymore, and I'm not sure why. But I would also very much like to run this on Chez. And I guess in that sense, we'll be able to work on Racket as well. There's also one other option. Alexis King has written an R7RS language package for Racket. I have not yet tried. running my package on R7RS for Racket. But that would be something interesting. Yes, I would like to try that. I do have some experience with Chez. So, uh, if I can find some time, I'll, I'll, I'll certainly like to, Yes. Yeah. Go ahead. Yeah.
[00:13:24.040] Q: Shouldn't it be enough to just implement the builtin functions? Most of the commands are written in Emacs Lisp, right?
what exactly is sort of, like, the, the approach is that you'll first want to do the interpreter and then have enough Elisp functions, getting the GNU Emacs Lisp functions interpreted or interpretable, and then go for GUI, or do you want to sort of like go hand in hand is like we have the interpreter working on and we have also the GUI and we sort of use one for the other? So I'm actually doing the GUI separately. The reason why is because the GUI for Schemacs is really just a clone of the look and feel of Emacs. It's not like an actual clone of the low-level C code that puts everything on screen. And I'm actually not really that interested in the low-level details of how Emacs draws things on screen either. I think it has a lot of historical baggage, and I'm actually trying to move away from that. So that was part of the reason why I started with this React.js or Vue.js-like Reactive GUI framework. So that GUI part is completely separate. And I want to worry about the details of how we make the GUI look and feel similar in Schemacs, similar to GNU Emacs. In Schemacs, using the Emacs programming language, I think that's something that we should worried about after we have enough of the Emacs Lisp implemented. There are sort of, I'm a bit worried. So, I don't know if, so one of my presentations is going to be tomorrow. I'm working on something called Emacs Viewer. It's a document viewer in Emacs. And essentially one of the issues that I'm up against is that Emacs's display system is sort of very... let's say, not flexible. When trying to analyze where this inflexibility comes from, I don't think it's just the display architecture. I think parts of Elisp itself are connected to the display architecture. The notion of a cell in a buffer, itself is connected tightly to how the re-display architecture works. So I think you'll have to sort of figure out what exactly you can salvage from Elisp without taking the display architecture baggage. that's going to be fairly challenging. It's all Turing-complete, so I imagine we're probably going to end up creating something like an emulator for the Emacs Lisp display architecture in Scheme that will somehow translate down to the React-like protocol that I've written. But yeah, I don't... I haven't... That's nice. Yeah, I'm glad. A lot of people have told me that they really are excited to see this project, and this really helps me keep focused on this project, because a lot of people are very interested. to a couple of questions from the past. We're starting to build up a good backlog. Thank you for that, Divya. Next question from the pad I have.
[00:16:59.720] Q: Tell us more about this show-stopping bug! How to squash it? Can people help?
How to squash it? How can people help? unless you're really a scheme genius and you can really read my code and immediately understand how it all works, I don't think you'd be able to help. It shouldn't be too difficult for me to fix. So it has to do with how closures work. And a closure is basically an object that can be created with stuff that's on the stack. And this is a feature, I think, that was introduced with Emacs 27. I can't remember exactly, but it's actually a relatively recent feature. It was ever since they introduced lexically scoped variable bindings in Emacs Lisp. And so yeah, the problem is that when you create like a let structure and you could declare a variable in the let. And then you create inside of that a second let structure, and you have a lambda inside of that. And the lambda references or uses a variable that was declared in the outer let binding. That outer let binding is somewhere on the stack. And the lambda you can actually return it as a value. So when you do return that lambda, it has to have a note somewhere inside that says, by the way, I'm using that variable. So you need to capture it and restore it to the stack whenever this lambda is applied, whenever you execute it. And that is where the error is. It's not capturing the stack variable properly. And I think what I'm going to do, I haven't looked into it in detail yet because I've gone back to GUI stuff recently, but what I'm going to do, I think, is just do a static analysis of the code inside of the Lambda and see which symbols are being used, and then just capture all of those and place those into the record type that stores the lambda. That's how I'm going to fix that, I think. I hope anyway that's going to work. You never know with bugs. They're always a little bit tricky. Okay, next question.
[00:19:21.760] Q: Are there performance concerns with implementing certain C primitives in pure scheme?
with implementing certain C primitives in pure Scheme? premature optimization is the root of all evil. I think it was the guy who invented the A* algorithm. His name escapes me at the minute. But yeah, I'm not concerned about performance yet, although most of the scheme compilers that I have seen, especially Chez and Gambit have extremely good performance characteristics. And so I think there won't be too much difficulty with performance, even implementing some of the C stuff. And besides, a lot of the GUI stuff is already written in C anyway. I mean, it would be cool if we had a scheme GUI library that painted to a canvas, maybe for a Wayland implementation or something. But I don't know. It's not a concern for me, performance. that the stream has cut away at this point, but we're still recording live. All of this will be put up on the website and so on like that. So, I appreciate all the enthusiastic questions and you're kind of tanking through them all. This is very encouraging and it really makes me want to keep on working on it. So it's great. I'm so glad to hear that because that's exactly the message I think you should be receiving. This is a fantastic project. Thank you so much. I'll just say so myself.
[00:21:07.052] Q: If this project is successful, are you worried about a possible split in the community between Schemacs and GNU Emacs users?
are you worried about a possible split in the community between Schemacs and GNU Emacs? And I really don't know what's going to happen. There seems to be already a huge demand for a scheme-based, a modern scheme-based editor. You know, the Edwin scheme for MIT scheme hasn't been touched since like 1987 or something, maybe 1993 or, but anyway. There seems to be huge demand. And so I guess a lot of people who are currently using GNU Emacs will probably just switch over because they've been wanting something like this for a very long time. And then, I mean, is that going to cause fragmentation? Is it really a big deal, though? I mean, it's all GPL-licensed code. I mean, I think a rising tide raises all the ships at the same time. So, yeah, also, the last thing I want to say about that is I would like to contribute some of what I do in Schemacs back into GNU Emacs, if I can. So, for example, I'm going to be working on like a canvas library where you can have interactive canvases and you know you can actually like draw pictures and put things with the mouse and drag things around. And I was thinking you know if if I can figure out how that works maybe I can write something like that for Emacs or GNU Emacs using the Cairo library, you know, SVG rendering library that they have. So, you know, if I have time, I would like to continue contributing to GNU Emacs as well. I'm sorry, what was the name of the library you mentioned? Oh, Cairo, like Cairo. Oh, Cairo, yeah. Absolutely. I spelled that poorly.
[00:23:07.600] Q: The dream of never even needing to change to the web browser - would schemacs bring us closer to that?
Would schemacs bring us closer to that? That's also a dream of mine. The part of the reason why I wanted to work, you know, make sure I had a really good workable GUI framework is so that I could, you know, we could write apps like, you know, they have a Mastodon client written in Emacs Lisp. that would be so nice to have this, you know, a really nice Mastodon client that was right inside of, you know, our scheme environment where we were doing our text editing and other stuff. I've always wanted something like that, or it would be cool to have just a slightly nicer GUI for Magit. So, yeah, I mean, like, yeah, being able to avoid the web entirely and just be able to like, you know, do social networking and do your GitHub stuff, everything from within Emacs or Schemacs in this case, that's a dream of mine as well. And so I hope that that's where we end up in a couple of years. The sooner the better. Anything, just double checking.
[00:24:30.000] Q: Anything specific other than minimalism that made you choose Scheme over Common Lisp?
Anything specific other than minimalism that made you choose Scheme over Common Lisp? Oh, yeah, it's kind of a philosophical question. So a couple of things. First of all, it was a conversation I had with William Byrd, and he's a guy who makes the miniKanren framework for Scheme. It was his PhD thesis. He worked with, I'm sorry, I just can't remember his name. He worked at the University of Indiana. Another famous Scheme or Lisp person was there. Friedman, Dan Friedman was his advisor. Yeah, big name in Lisp. Anyway, so I was talking with William Byrd, and I'm a huge Haskell fan, and he told me why he didn't like Haskell at all, and kind of convinced me to try Scheme out. And what I really like about Scheme is, yeah, like you said, the minimalism, but it's more that it is very close to the mathematical framework of lambda calculus. Haskell is probably the most pure lambda calculus that I've ever used, but Scheme is like the simply typed lambda calculus, and That just appeals to me. I think, you know, if you have this tiny, tiny core language from which all of the computing can be defined, I think it's kind of a shame that so far we just haven't explored that space yet. I mean, there's compared to JavaScript or Python, there's very little scheme code out there and it could be doing so much. And I would just like to try and expand the scheme ecosystem and see just what this tiny little language can do. And I think we haven't even seen a fraction of what it can do. That's why I've chosen scheme. I think we're just about close to our time here, but if you wanted to jump back in, I'm sorry, I had to cut you off a little before. I think I agree with most of what he said. So, yeah, thank you so much.
[00:26:40.680] Closing thoughts
keep watching my Mastodon and keep watching my Codeberg. I'm going to try and squash this bug as quickly as I can. I hope early next year, hopefully not much later than February, I'll actually be able to start taking in contributions for some of the Emacs Lisp built-ins in the code base. So, please keep watching. The pace of my development has increased pretty rapidly recently, and I think we're pretty close to getting something that we can all use together. for your exceptional work, and for jumping in, doing the live Q&A, rolling with us here as we have yet another "we'll see how it goes" conference. It's been just amazing so far, and this talk is no small part of that. Thank you. And thanks for all the questions, everyone.

Questions or comments? Please e-mail emacsconf-org-private@gnu.org

Back to the talks Previous by track: Bookclub tapas Next by track: Juicemacs: exploring speculative JIT compilation for ELisp in Java Track: Development