Solod: How Go Can Finally Become a Better C
Solod: Go can be a better C
I created Solod, a strict subset of Go that compiles directly to readable C11 code. You get Go's safety, tooling, and syntax without the overhead of garbage collection or a runtime. Everything is stack-allocated by default, offering systems-level control while letting you use familiar Go types and functions. It bridges the gap for developers who want Go's structure with C's performance.
So is for Go developers who want systems-level control without learning a new language. And for C programmers who like Go's safety, structure, and tooling.
- ventana
Translating a language into a different language is a popular thing to do these days, but still not a very easy one. I feel it's like peeling an infinite onion of misery. First, you write a parser of your source language, figure out the translation of the instructions, and emit the code in the target language, and you're very happy when your translated Hello world compiles.
Then, a user (like me) tries writing something like
package main
func main() {
register := 42
println(register)
}
well, oops.
/tmp/solod_build3904763637/main.c: In function 'main':
/tmp/solod_build3904763637/main.c:6:21: error: expected identifier or '(' before '=' token
6 | so_int register = 42;
| ^
/tmp/solod_build3904763637/main.c:7:29: error: expected expression before 'register'
7 | so_println("%" PRIdINT, register);
| ^~~~~~~~ (exit status 1)
OK, now you grab the list of reserved words of the target language, which is not always an easy thing to do, and rename type names and variables as needed.
The next bad thing is when you step on your own toes and see that the new names you invented, like `so_int` or `so_println`, will inevitably pollute the global namespace. We'll either cross our fingers and hope that no one will create a variable named `so_int`, or we'll need to add all our new kind-of-reserved words to our already big list of exceptions.
I'm sure there are multiple levels of complexity […]
- pjmlp
Go is a better C already, designed by C authors themselves, with other UNIX key figures.
Which while some of the design decisions might be debatable, they actually knew what C is all about, informed by their own experience with what worked in C, Alef and Limbo, across UNIX, Plan 9 and Inferno.
- aarvin_roshin
The author's original blog post, which goes into some more detail: https://antonz.org/solod
- jay_kyburz
I've been using Go and Raylib to make a game lately and I really don't have a problem with garbage collection. It's so fast that it's not having an impact on my frame rate.
I was a little worried at the start because nobody would normally consider Go for games, but I did a bunch of tests and found it's just no big deal.
(I'm focused on game play and not interested in pushing hardware to its limits.)
- kitd
The idea of using a subset of an existing popular language is very wise IMHO. We can (and apparently are) debating the merits of the language runtime, but what a subset gives you is immediate access to a large pile of existing tooling that you'd have to write yourself, eg linters, formatters, lsps, etc. Stuff that is purely source-oriented.
That hadn't really occurred to me before.
- bb88
How does it deal with pointers if everything is stack based? You can't really return a pointer to something on the stack because it could get overwritten between when you return it and when you access it.
- gnull
> So is for Go developers who want systems-level control without learning a new language. And for C programmers who like Go's safety, structure, and tooling.
Wut?
Also, how do you preserve garbage collector semantics without garbage collector?
- benjiro29
The problem with these type of new / transcompile languages is not the langue, its the lacking libraries and 3th party assets. Great if just want the most basic hello world programs, but the moment you need ... for example a http server. Then your often with:
a) none
b) http 1.1
c) ... forget about more
Maybe you need rar support ... O well, ... And then you always enter the world where you need to start linking external libs, and then your mixing not just the base language and the transcompile but also whatever interface for calling those external libs.
Ironically, with LLMs being around, your often better to just have it write whatever is missing. Until you find out then, that the language misses some feature.
O great, you needed crypto support. Ok let the LLM write it for you, its only 100x slower then whatever was written years ago and had tons of enhancements and edge cases fixed.
At that point, you can just tell a LLM to write in C from the start, and be done with it. lol.
Transcompile languages have always had tons of issues, and there is a reason why non became popular. Haxe comes to mind. How many years this exist and barely anybody knows it. Because your often just better writing in the original language and fixing the issues, or picking a better fitting language for your project.