Motivation:
I want to have a lisp which, runs in the browser, interops easily with existing javaScript libraries, and is reasonably fast. clojureScript sort of is this, but its macros are kind of a kludge (clojureScript macros are written in clojure and have to be in a seperate file from the rest of the code, also hygienic only), interop isn't seamless, and I don't want to start a jvm every time I want to compile some code. A straight arc to javaScript compiler would have to be really smart to produce fast code, and interop wouldn't be seamless either. So I decided to try writing my own language.
Implementation:
Since macros can call functions which were defined in the same file, the functions needed to be evaluated right after being compiled. So I couldn't just do a simple "jasper code in, javaScript code out" compiler in haskell. So there is a self hosted[1] compiler/repl.
Current status:
It is already sort of usable, but I wouldn't recommend anyone else to use it for anything beyond throw away tinkering, because I still might decide to make big changes to the semantics.
Not sure if that are the things you wanted explained.
[1] Self hosted compilers are a pain in the behind, one has to mentally switch between the language version the compiler is written in and the language version the compiler is compiling and when you break you compiler you can't use it to compile the fixed version.
"A straight arc to javaScript compiler would have to be really smart to produce fast code, and interop wouldn't be seamless either. So I decided to try writing my own language."
"Current status: It is already sort of usable, but I wouldn't recommend anyone else to use it for anything beyond throw away tinkering, because I still might decide to make big changes to the semantics."
You could be telling the story of my recent language projects too. :-p
---
"Self hosted compilers are a pain in the behind, one has to mentally switch between the language version the compiler is written in and the language version the compiler is compiling and when you break you compiler you can't use it to compile the fixed version."
That's a really good warning to hear, because I was headed toward having a self-hosted compiler myself.
Nevertheless, I think I'm still headed in that direction. Once you or I have a self-hosted compiler, if it can compile to a platform, it can also run on that platform. That's a way to escape from the original platform you built it on: Write a compiler backend, and then just move to that platform for developing in the future. This could be a pretty nice superpower when we have the silos of C#-based Unity, Java-based Android, etc.
"Once you or I have a self-hosted compiler, if it can compile to a platform, it can also run on that platform."
In theory yes, but it wouldn't be a good idea for jasper because it is a relatively thin layer on top of javaScript. So a backend for a different platform would have to emulate a lot of JS quirks, which would be complicated and produce slow code.
So if you want to make a cross platform language, it should be a thicker layer on the first platform from the beginning.
"Nevertheless, I think I'm still headed in that direction."
Always make backups of your compiler binaries or don't overwrite old compiler binaries so in case of a bug you don't end up with only one, broken, compiler binary.
Thanks for the answer, especially the thoughts on self-hosted compilers. I'd always found myself vaguely unsatisfied with them as an outsider trying to understand them, so it's very useful to hear similar sentiments from someone who actually has experience building them.
BTW, I followed the instructions to run it and was pleasantly surprised by how painless it was.
I actually worried that it wasn't painless enough, and that I should have waited for the web repl to be done before submitting.
These long strings contain the compiled macros. They are only there for debugging. They belong in comments instead of strings, but I didn't think of it at that time.