alt.hn

4/7/2026 at 12:48:01 AM

Solod – A subset of Go that translates to C

https://github.com/solod-dev/solod

by TheWiggles

4/7/2026 at 3:35:44 AM

I was curious how defer is implemented. `defer` in Go is famously function-scoped, not lexically-scoped. This means that the number of actively-deferred statements is unbounded, which implies heap allocation.

The answer is that Solod breaks with Go semantics here: it just makes defer block-scoped (and unavailable in for/if blocks, which I don't quite get).

https://github.com/solod-dev/solod/blob/main/doc/spec.md#def...

by ridiculous_fish

4/7/2026 at 3:45:49 AM

What's the point if it's incompatible? The README suggests using go's testing toolchain and type checker, but that's unreliable if the compiled code has different behavior than the tested code. That's like testing and typechecking your code in a C++ compiler but then for production you run it through a C compiler.

Would have been a lot more useful if it tried to match the Go behavior and threw a compiler error if it couldn't, e.g. when you defer in a loop.

Is this just for people who prefer Go syntax over C syntax?

by hmry

4/7/2026 at 6:26:19 PM

I don't work regularly on it but I have a proof of concept go to c++ compiler that try to get the exact same behaviour : https://github.com/Rokhan/gocpp

At the moment, it sort of work for simple one-file project with no dependencies if you don't mind there is no garbage collector. (it try to compile recursively library imports but linking logic is not implemented)

by Rexxar

4/7/2026 at 7:14:09 AM

tbh I'd rather have this behaviour, defer should've been lexically scoped from the beginning.

by crowdyriver

4/7/2026 at 11:22:25 AM

As long as you exclude defers in a loop, this can be done statically: count the maximum number of defers in a function, and add an array of that size + counter at the function entrance. That would make it a strict subset.

by tgv

4/7/2026 at 5:48:35 AM

> This means that the number of actively-deferred statements is unbounded, which implies heap allocation.

In C you can allocate dynamically on the stack using alloca or a VLA.

by 1718627440

4/7/2026 at 2:06:52 AM

I don't really "get" the sweet-spot being targeted here. You don't get channels, goroutines, or gc, so aside from syntax and spatial memory safety you're not really inheriting much from Go. There is also no pathway to integrate with existing Go libraries.

Spatial memory safety is nice but it's the temporal safety that worries me most, in nontrivial C codebases.

by Retr0id

4/7/2026 at 2:12:33 AM

Looks to me like having the ability to write Go syntax and interop directly with C is the plus.

by tidwall

4/7/2026 at 2:20:29 AM

I do like Go's syntax but I can't help thinking the best language for C interop is C.

by Retr0id

4/7/2026 at 2:46:02 AM

> I do like Go's syntax but I can't help thinking the best language for C interop is C.

SWIG[0] is a viable option for incorporating C code as well.

0 - https://swig.org/Doc4.4/Go.html#Go

by AdieuToLogic

4/7/2026 at 3:29:14 AM

I love how SWIG is still around! I first used it about 30 years ago to integrate with Perl, then later with Java.

by stevekemp

4/8/2026 at 1:33:46 AM

>having the ability to write Go syntax and interop directly with C is the plus.

It's always a plus to interop with the lingua franca of programming languages.

I think D language approach is more organic and intuitive that you can interop directly, and now that it's natively supported by the D compiler make it even better [1],[2].

[1] Interfacing to C:

https://dlang.org/spec/interfaceToC.html

[2] Adding ANSI C11 C compiler to D so it can import and compile C files directly (105 comments)

https://news.ycombinator.com/item?id=27102584

by teleforce

4/7/2026 at 4:16:42 AM

Go's syntax is basically C tho lol

what's the benefit? for loops?

by whateveracct

4/7/2026 at 5:33:39 PM

This is actually perfect for me.

Go is my most productive language, but it is the worst for some of the usecases I want to use it for due to goroutines and GC pauses and things like that.

I learned C and programming when I was a middle school math nerd and so my understanding of functions was colored by the algebraic definition of a single value function. This led to me writing my code in a more functional paradigm than an object oriented paradigm. I struggled to learn Java. I struggled in programming class when we made the switch from VB6 to vb.net because I didn’t really understand object oriented programming.

I find go’s procedural nature to be the best language for my understanding of programming with functions. The way the object oriented code is possible, but not required allows me to build types and objects that I can compose and use as I understand them, not the way that object oriented, inheritance, and polymorphism requires me to subclass.

I recently have had the idea for a project and I found the perfect ECS library that would allow me to compose my entities and components the way I do in Go, but it does not interface cleanly with Cgo either in runtime overhead or development overhead.

The official bindings for it are rust, c, c#, zig, lua, and clojure.

This would allow me to use it by writing Go code that calls it natively like C.

I’m not concerned about not getting to use Go libraries. I believe in Roll Your Own and always had to roll my own when I was learning C. Go’s stdlib is tight and lends itself to RYO really well.

by xerox13ster

4/7/2026 at 5:40:07 AM

I guess there is no point except Anton is having fun do it.

by cocodill

4/7/2026 at 5:08:41 AM

The claim that no goroutines makes this pointless isn't quite right. Migrated 50 services off Docker Compose using Nomad and half of them had zero concurrency needs. A safe Go-syntax C target is actually useful for that layer.

by 0xmrpeter

4/8/2026 at 3:40:38 PM

You sure they weren't just using http or something and thus the concurrency was effectively hidden by the library? Almost any services that takes requests of any kind uses goroutines extensively.

by smw

4/7/2026 at 2:08:36 AM

"To keep things simple, there are no channels, goroutines, closures, or generics."

I wonder if it could be integrated with https://github.com/tidwall/neco, which has Go-like coroutines, channels, and synchronization methods.

by tidwall

4/7/2026 at 10:55:51 AM

If this sounds good to you, you would like the Odin programming language.

by leecommamichael

4/7/2026 at 3:39:03 PM

This is more interesting project: https://git.urbach.dev/cli/q

by cptmurphy

4/7/2026 at 10:17:17 PM

That is an interesting project, which i have been following for a while. Unfortunately, progress has slowed a lot recently. I hope development picks up…and that the author chooses a different name for the language.

by ternaryoperator

4/7/2026 at 3:14:17 AM

Anton also wrote the fantastic codapi [1] for embedding executable code snippets with wasm

[1]: https://codapi.org/

by remywang

4/7/2026 at 7:36:56 AM

Somewhat similar language, https://vlang.io

It’s a mix of go and rust syntax that translates to C

by xentripetal

4/7/2026 at 7:18:30 AM

I'm reminded of the tools in programs like Ghidra or IDA which can take assembly code and convert it into a C-like language. If you could create one of those tools that also takes in the source file so that it names things somewhat reasonably, could you create an anything to C translator? As long as the original file compiles to assembly, that is

by voidUpdate

4/7/2026 at 8:47:44 AM

I once used Ghidra to decompile a hand-written ARM assembly floating point library and compile the result to a different architecture, and it was significantly faster than GCC’s built in methods…

But in general this kind of thing is very unreliable for any non-trivial code without a lot of manual work, so a better approach could be to compile to WebAssembly which can be translated into C

by circuit10

4/7/2026 at 8:52:13 AM

It may be easier if you also have the original source file (I've not don't much decompilation myself, only seen other people doing it), as more of a custom solution rather than using an existing system

by voidUpdate

4/7/2026 at 2:06:09 PM

As a Go developer I would use this unless...I would have to build the std libraries myself. Now I also wonder how this compares with tinyGo. Why would you pick one over the other...

by thefounder

4/7/2026 at 5:14:30 AM

> So supports structs, methods, interfaces, slices, multiple returns, and defer.

> To keep things simple, there are no channels, goroutines, closures, or generics.

Sure, slices and multiple return values are nice, but it's not what makes Go good. When people think about Go they usually think about channels and goroutines. YMMV

While I do kind of get what the appeal and target audience is supposed to be, I absolutely don't get why you'd choose a subset and still have it behave differently than the Go counterpart. For me that destroys the whole purpose of the project.

by numlock86

4/7/2026 at 9:35:30 PM

> multiple returns

So no go error handling?

    x, err := func()
Not a choice I would have made.

by kristianp

4/7/2026 at 6:20:29 AM

Love it. And from my experience the need for Go Routines is not that urgent.

Sure when I started Go there were Go routines plastered everywhere. And now I think harder: “do I really need a go routine here?”

by weitzj

4/7/2026 at 8:50:08 AM

Interesting approach. What was the main motivation for targeting C specifically instead of something like LLVM or WASM as an intermediate?

by joshuahart

4/7/2026 at 9:49:44 AM

Biggest reason is usually the toolchain. Debuggers, sanitizers, profilers all just work when your target is C. Go through LLVM and you get similar optimization but now you own the backend. With C, gcc and clang handle that part.

by nulltrace

4/7/2026 at 6:41:22 AM

Might this help in memory leaks in go ... what will happen to the code that translated to pointers ....wrong conversation...CODE CRASH??

by jimgill

4/7/2026 at 6:59:13 AM

I seem too stupid. Why not use C11 in the first place? Can anyone explain?

by Surac

4/7/2026 at 6:01:55 AM

Love the design considerations here!

by matthewmueller

4/7/2026 at 5:42:28 AM

We need this for TypeScript.

by vaughan

4/7/2026 at 6:38:43 AM

Translating code to C usually results in some nearly unreadable code. I submit the C++ to C translator, cfront, as evidence. I've looked into using C as a target backend now and then, but always "noped" out of it.

I was pleasantly surprised to discover, however, that C code can be readily translated to D.

by WalterBright

4/7/2026 at 8:11:40 AM

I don’t think that’s a valid comparison. It compares two entirely different cases.

In general, if the guts of Foo are similar to those of Bar, translating Foo to Bar is fairly easy.

If Foo has additional guts, as in the C++-to-ℂ translator, translating those parts can lead to hard to read code.

In the C-to-D translator case, it’s not Foo that has additional guts, though, but Bar.

Then, a reasonable 1:1 transaction is easy. Doing it in idiomatic style can still be hard, though. For example D has garbage collection, classes and inheritance. I doubt the readily translation of C to D will replace C equivalents (e.g. a garbage collector written in C that’s part of the code) by those where possible.

by Someone

4/7/2026 at 6:27:33 PM

It's true that D has many features that are not part of C, and a translator from C to D will not recognize constructions in C meant to exhibit inheritance. It's also true that a C to D translator will not be able to translate metaprogramming done with the C preprocessor.

It is a valid comparison, though, as there is no point to designing a language that has a 1:1 mapping to/from C.

by WalterBright

4/7/2026 at 2:38:35 AM

Does it work with the preprocessor?

by Onavo

4/7/2026 at 3:10:39 AM

This is a bit too barebones. At least bring goroutines dude

by MegagramEnjoyer

4/7/2026 at 4:17:06 AM

way too hard

by whateveracct

4/7/2026 at 7:55:24 AM

stackful coroutines are not hard to implement

by lukaslalinsky

4/7/2026 at 11:16:17 PM

bro

by MegagramEnjoyer

4/7/2026 at 5:44:20 AM

[flagged]

by Sarthakofficial

4/7/2026 at 8:11:02 AM

[dead]

by melodyogonna