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...
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?
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)
In C you can allocate dynamically on the stack using alloca or a VLA.
Spatial memory safety is nice but it's the temporal safety that worries me most, in nontrivial C codebases.
SWIG[0] is a viable option for incorporating C code as well.
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)
what's the benefit? for loops?
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.
I wonder if it could be integrated with https://github.com/tidwall/neco, which has Go-like coroutines, channels, and synchronization methods.
[1]: https://codapi.org/
It’s a mix of go and rust syntax that translates to C
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
> 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.
So no go error handling?
x, err := func()
Not a choice I would have made.Sure when I started Go there were Go routines plastered everywhere. And now I think harder: “do I really need a go routine here?”
I was pleasantly surprised to discover, however, that C code can be readily translated to D.
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.
It is a valid comparison, though, as there is no point to designing a language that has a 1:1 mapping to/from C.