Very nice project! I love the fact that you have almost no dependencies for the compiler. I'm interested in learning how to build a compiler for web assembly and your code seems very clean, simple and easy to follow. Thanks!
I like that you have a vscode extension already - I'm making a similar language project, and you really don't notice how much you miss even basic syntax highlighting until it's gone
Cool project . I am also designing a Wa language for Wasm (https://github.com/wa-lang/wa), we are currently improving support for the WebGPU library and LSP extension.
It's funny to watch how often new programming languages resemble visually (and conceptually) the language they are written in. You can put it the other way: just look at a syntax sample and try to guess the implementation language.
I can see some problem here. Probably, it means the author is under heavy influence of the implementation language, that limits their thinking and creativity scope to the concepts of that language.
A single individual is likely to miss a lot of edge cases that a larger organisation (like the Rust foundation) has thought of while creating the language.
In that sense, I believe following the conventions created by a large and well-known entity is likely to produce better results.
I was going to say: I bet this is written in Rust, they use https://docs.rs/syn/latest/syn/ to not write their own parser/lexer, and this is how you get Rust-looking languages... I'm surprised.
It's funny yeah but it makes sense and is not really a problem.
You would write a compiler in the language that is the closest to your perfect. Trying to fix the original language by making a "clone" of it and adding/removing features to your liking.
That is what I want to change here by making a very simple language that if someone would like they could just fork it and add/remove the needed features instead of building one from scratch.
If this idea won't work then at least a very simple compiler would be a good learning resource, so a win win anyways.
Right, this is not the problem par se. To me this is a rather philosophical question. Related to the motivation behind the project.
If someone has some particular domain problem to which they need to introduce the new programming language, then, probably, it should look somehow different to all existing languages, otherwise they would be used.
Alternatively, the motivation could be: OK I need ExistingLanguageX(-alike) but in the domain/environment where it's not present yet, for example, WASM.
The motivation question is always of interest to me since it allows to judje for the long-term perspectives of the project.
However don't take this as a discouragement rant, learning case is a good motivation/raison d'être too.
I personally wouldn't call anything Rust based "simple" (I'm not trying to hate on Rust, it's my daily driver.), so I have to ask: Wouldn't be the simplest possible wasm language, a small macro system for WAT, that bootstraps a slightly more highlevel lisp dialect?
Wasm already seems like an increadibly high-level language, given that it's a low-level compilation target.
I don't see how WASM is that high level. It doesn't have types except numbers (ignoring reference types and the GC proposal), which makes it lower level than LLVM IR. The control flow constructs are also much closer to SSA form than anything viable for humans.
If you ever try to write WAT by hand you realize that it's very much a compilation target, not something you'd ever want to manually write.
Unlike LLVM, control flow is actually structured, no arbitrary jumps, functions, tables, real harvard separation of code and data.
The restriction to only number types, is more a byproduct of trying to keep the 1.0 spec as mvp as possible, and reference types are gonna be a big shift in that regard.
I mean compare these two. One is a (very low level) language, the other is (high level) assembly.
That was how it started actually, I wanted to make a superset of WAT. But then I switched to a more familiar C-like constructs and that gave me a big boost in productivity.
I think the superset of WAT idea is very viable and someone more comfortable with s-expressions should explore that for sure.
> a small macro system for WAT, that bootstraps a slightly more highlevel lisp dialect
Lisp traditionally has immutable data structures and a garbage collector, in which case I would consider it more complicated than LO.
I would be very interested if it’s possible to create an extremely simple garbage collector or an ergonomic Lisp that isn’t garbage collected, but a solution doesn’t spring to mind.
A classic mark-and-sweep GC for a heap of uniform structs (like cons-pairs) can be implemented in a few lines of code. Garbage collection is not inescapably complicated, it just gets more challenging as you impose more constraints: multithreading, generations, compaction, minimizing bookkeeping overhead, etc.
> Lisp traditionally has immutable data structures
Can you provide a source for this? Common Lisp and its predecessors certainly do not have immutable data structures out of the box. The usual data structures are cons cells, lists (composed of cons cells anyway), vectors, and hash tables.
> I would be very interested if it’s possible to create an extremely simple garbage collector or an ergonomic Lisp that isn’t garbage collected, but a solution doesn’t spring to mind.
PreScheme immediately comes to mind for me as does ulisp. The latter in particular is designed for microcontrollers with limited memory.
While I'm a huge fan of immutable persistent datastructures, I don't think that they are a neccesity.
And linked lists with reference counting are really easy to do, and don't have any leaks if you don't allow cons cell abuse. (which would mess with immutablity anyways)
You could also do linear types like carp [0], or you could just do manual memory management.
I feel like most people will call something with macros and s-expressions, a reasonable, if brutalist, lisp.
Pairs in Lisp are mutable, traditionally, and there are other mutable data types like vectors. For targeting wasm only there's no need to figure out a GC solution as that is something the host provides in wasm 2.0.
it's not that related, I like to create compilers/transpilers/weird languages, see the "Language Projects" section here: https://marianoguerra.github.io/
But there's a relation, two years ago I prototyped a thing that tried to make a headless version of instadeq that could run in the browser and the server, the idea was a dataflow language where the data was represented as apache arrow tables where filters and transformation expressions where compiled to wasm. The prototype kind of worked and I had a lot of fun, I thought about sharing the fun by writing a small book about creating 10 toy languages that compiled to Wasm, I shared the idea with Patrick, he said he was thinking about something similar and the idea evolved into the current book.
In-browser data analysis is a great place to use Wasm. Javascript is great, but larger datasets really benefit from SIMD + tighter memory control/controlled memory layouts.
Neat project! I liked the dev log writeups (despite the multiple rickrolls), hope you keep doing these. It was interesting seeing your reasoning. I'm starting a for-fun language project that should compile to wasm and native, and was debating between wasm -> wasm2c or llvm -> emscripten. Your posts about ffi/bindings issues were helpful, I'm probably going to try wasm (or just wat) first and then binaryen for wasm -> wasm optimization.
Looks interesting! Always glad to see more WASM native languages coming. You may take a look at MoonBit(https://github.com/moonbitlang/moonbit-docs/tree/main). The language is Rust-like with gc support, and we also have a full toolchain like cloud IDE, compiler, build system, and package manager.
AssemblyScript is very strange to me. The whole point of wasm is you can avoid javascript/typescript language and do stuff in a browser in go, rust, or now LO!
I wouldn't say that's the whole point of Wasm. Speed & efficiency are also key goals, which are what AssemblyScript play into, giving access to that speed potential in a format that's easy for web devs
And the similarities between AS and TS (or especially JS) are very superficial. They share some grammar, and utilize many of the same type system features, but AS is fundamentally a different language with fundamentally different semantics (which are much closer to WASM, and then much closer to those other compile-to-WASM choices).
A big advantage of WasmGC is it would allow your binaries to be smaller, since you wouldn't need to bundle an allocator for heap::alloc and free. Kotlin and Java binaries can in some cases be be much smaller than C++ and Rust for that reason.
I've been working on integrating it with WASM-4 runtime this past week. And with minimal changes to the compiler I created this demo game: https://rawcdn.githack.com/glebbash/LO/da8305293f5438967619e...
Game source here: https://github.com/glebbash/LO/blob/main/examples/test/demos...