I’m writing a simple functional language with automatic memory management. Go’s simplicity seems it could be a good target for transpilation: garbage collection, decent concurrency paradigm, generally simple/flexible, errors as values. I already know Go quite well, but I have no idea about IR formats (LLVM, etc)
To be clear, using Go as a compiler backend would be a hidden implementation detail and there would be no user-level interop features. I’d like to bundle the Go compiler in my own compiler to save end-user headaches, but not sure how feasible this is. Once my language is stable enough for self-hosting, I’d roll my own backend (likely using Cranelift)
Pros
- Can focus on my language, and defer learning about compiler backends
- In particular, I wouldn’t have to figure out automatic memory management
- Could easily wrap Go’s decent standard library, saving me from a lot of implementation grunt work
- Would likely borrow a lot of the concurrency paradigm for my own language
- Go’s compiler is pretty speedy
Cons
- Seems like an unconventional approach
- Perception issues (thinking of Elm and it’s kernel code controversy)
- Reduce runtime performance tuneability (not to concerned about this TBH)
- Runtime panics would leak the Go backend
- Potential headaches from bundling the Go compiler (both technical and legal)
- Not idea how tricky it would be to re-implement the concurreny stuff in my own backend
So, am I crazy for considering Go as compiler backend while I get my language off the ground?
It’s a very normal and pragmatic thing to do. If the main novel functionality of your language can be hosted in Go, do it.
If your language requires stuff Go isn’t designed for like eval or a REPL, it might not help that much.