I've not posted her in a bit partially because it feels like the work I'm doing is a bit "present-company". I put my editor on pause because I hate all languages I could write it in. I want a good dynamic language where I can develop the editor in itself without ever restarting it. I want something multi-threaded. I want something with a lightweight runtime. But ultimately, I really just want to boil the ocean and this feels like a fun way.
So I've been making my own language. It is a dynamically typed functional language that compiles straight to machine code (no vm at all). Today, I finally got my persistent vectors properly working (After finally figuring out that my bug was in the gc (still not fixed) not my implementation.) I decided as an experiment to implement clojures HAMT based persistent vectors into the language itself (not at the compiler/runtime level). In fact, even my mutable arrays are implemented in the language with a primitive allocation function and some fetching "fields" primitives.
Sadly my implementation is about 6x slower than clojures on my artificial benchmark. But honestly that's pretty darn good! I have done 0 optimizations, Clojure's data structures are all implemented in java. That means I'm about 6x slower than java on this benchmark. Not bad. Trying to figure out next if I want to do some performance work, or continue building out features.
The whole thing is premised on the idea that there are no* popular, modern dynamically typed languages. Javascript, python, and ruby are all decades old and are showing their age. Clojure and Elixir are the only contenders. Clojure will never be popular because it is a lisp. Elixir's super power and its limitation is the beam.
Python, ruby, and javascript all lack a good story on multi-threading. Ruby and python are slower than they ought to be. All of them are OO inspired. I think functional langauges + Rust have shown a different way of programming. All of them have weird quirks and problems around packages/modules/scoping, things we've since learned to do better. Finally, they have bad tooling for inspecting performance, memory, usage etc.
All of this is the situation I'm designing into. I want to build something that
1) Can be popular (so no lisp)
2) Can be fast (so focusing on performance from the beginning, no slow interpreter)
3) Has good module/namespace support
4) Is multi-threaded
5) Is lightweight (does not depend on a big existing platform)
6) Has great performance and memory tooling support
As for the actual code design. I've started from the ground up with a aarch64 machine code generator. I have an IR that is an infinite register machine. An AST on top of that. I've implemented 3 different GC systems (Mark and Sweep, Compacting, and a simple generational collector).
That's quite a bit, so happy to answer any questions
is it immutable all the way, immutable first or mutable first with immutable support?
the multithread support is going to be raw "pthreads"? or some core abstraction like actors, channels etc?
The goal is that people will write immutable code. But I’m going to be fairly pragmatic in that regard. It will be very similar to Clojure. There will be ways to write mutable stuff. But everything is pushing you to write immutable stuff.
Multithreading as in system threads. The language should be flexible enough that anything more than that should be able to be written in user land. Still flirting with the idea of delimited continuations in the base language. Which would give you all the power you need for anything like that.
The most esoteric inspiration I can think of is pyret. Just like pyret I plan on having nice support for algebraic data types (but not trying to do their gradual type stuff) and first class ways of doing tests.
Really this is clojure + rust + batteries included. Those are the main inspirations.
FYI - in places where you can guarantee stack-based immutability, you might consider using Jart's ABC garbage collector. She does it in 40 bytes. YMMV.
I just want to say, I think:
a) This feels like future not present.
b) #devlog-together is agnostic to future vs present. It's a space for anything you want to share.