Hi everyone!
I’m working on creating a new programming language focused on education and need advice on selecting the right backend approach.
My language requirements include:
- Quick build times
- Automatic memory management
- Clear error messages that beginners can understand
- Ability to halt execution and examine program state
- Seamless user experience where compilation happens behind the scenes (similar to how Python handles bytecode compilation invisibly)
Execution speed isn’t critical as long as the language starts up quickly.
I’ve ruled out native compilation since it doesn’t fit my needs. While JVM or BEAM platforms seem promising, JVM has slower startup times and might limit my control over execution flow and error formatting.
I’m leaning toward building a custom interpreter or VM. Should I create this on top of an existing virtual machine to leverage its JIT compilation and garbage collection? Or would implementing everything from scratch be better?
If I go the custom route, would using a natively-compiled language with GC support like Scala Native cause any issues? I’m already planning to use Scala for the compiler frontend.
interesting project! have you considered what kinda debugging features students will actualy use? like stepping through code line by line or maybe visualizing variable changes? that might help decide between interpreter vs custom vm approach. also curious - what age group are you targeting? younger kids might need different error handling than college students.
honestly i’d skip the custom vm route entirely and just go with a tree-walking interpreter. way simpler to implement and debug features work naturally since you controll every step. for educational use the performance hit wont matter much and you’ll spend less time fighting gc issues in scala native. python started this way too before getting fancy optimizations.
Building a custom interpreter in Scala makes perfect sense for your educational language project. I went through a similar decision process when developing a domain-specific language for teaching algorithms. For your requirements, I would recommend implementing a bytecode interpreter rather than a tree-walking interpreter. This approach gives you complete control over execution flow for debugging features while maintaining reasonable performance. You can implement pause-and-inspect functionality much more easily when you control the execution stack directly. Regarding Scala Native, I have experience using it for compiler projects and found startup times excellent, but garbage collection can be unpredictable under heavy allocation patterns. Since you mentioned execution speed is not critical, regular Scala JVM might actually serve you better despite slower startup, particularly because you get mature GC and can leverage existing JVM tooling. Consider implementing your interpreter with a simple stack-based virtual machine design. This approach provides the execution control you need for educational debugging features while keeping the implementation manageable. You can always add JIT compilation later if performance becomes important.