Lisp is the simplest language to bootstrap for sure.

i think stack languages are even simpler to bootstrap than lisps, and modern stack languages are not that much less comfortable.

a friend of mine is actually exploring that here: https://github.com/nagydani/seedling/

and by simple i mean that he's doing it using a ZX spectrum emulator as an artificial size/speed constraint.

we are exchanging ideas as we make progress, and when seedling will be ready i'll also bootstrap Maru off of that low-level stack machine.

you can think of (the bottom language of) seedling as the new C in the sense that it can function as the first layer, or the lowest common denominator on top of the hw to build upon, and can trivially reproduce itself onto a new hw.

out of the bootstrapper that isn't the core Lisp language. Of course, it's probably worth
having handcrafted LLVM code for the primitives that greatly affect performance.

i've admittedly haven't spent much time optimizing stuff, but i also haven't found myself needing to write LLVM/asm code to optimize anything. i'm much more progressing towards handling everything from lisp, from the handling of tagged immediate values to the nifty details of the GC. and that code hardly ever needs more than pointer dereference and arithmetic operations, and are already mapped pretty directly to LLVM/asm instructions. i have macros after all that can expand to the low-level primitives.

a big question of mine currently is hygienic macros and modules, and their interaction. more specifically: whether modules should have separate symbol tables, or only separate bindings together with a global symbol table. i'm leaning towards the latter because it makes many things simpler and independent (e.g. the reader doesn't need to know about modules)... and i think the implementation of hygienic macros should be a user library anyway that doesn't rely on isolated symbol packages, but rather on parsing the code templates and implementing the isolation on the AST level (as opposed to the lower level of symbol equality).

my implementation of modules is informed by this paper:

Submodules in Racket - You Want it When, Again? by Matthew Flatt
https://www.cs.utah.edu/plt/publications/gpce13-f-color.pdf