8 ms·
Solod: Go can be a better C
- bb88 2mo agoHow 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.
- deleted 2mo ago[deleted]
- zabzonk 2mo agoWell, it does say: "Everything is stack-allocated by default; heap is opt-in through the standard library." So it supports both stack and heap, and I guess static allocation too.
- wrs 2mo agoExactly as well as C does, it seems. func newPerson() *Person { p := Person{Name: "Alice", Age: 30} return &p } becomes static main_Person* newPerson(void) { main_Person p = (main_Person){.Name = so_str("Alice"), .Age = 30}; return &p; } Quoting the FAQ: "So itself has few safeguards other than the default Go type checking. It will panic on out-of-bounds array access, but it won't stop you from returning a dangling pointer or forgetting to free allocated memory. Most memory-related problems can be caught with AddressSanitizer in modern compilers, so I recommend enabling it during development by adding -fsanitize=address to your CFLAGS." So saying you get the "safety of Go" is a bit of a stretch.
- nvme0n1p1 2mo agoYeah that's not great. It's easy to be faster than go if you haven't thought about memory management yet. I bet go with GOGC=off is faster than plain go too.
- inigyou 2mo agoThis is impossible. General words like "faster" are subjective, and useless in a technical context unless you ground the discussion by giving them specific definitions. Otherwise everyone ends up talking past each other.
- nvme0n1p1 2mo agoWhoa, I have my very first crazy internet stalker. What fun! Do an internet search for "go garbage collector benchmark" if you're curious what the grownups are talking about.
- nixon_why69 2mo agoThat's undefined behavior in C I thought? You're addressing the memory of a stack frame that already collapsed when it returned. I think it's ok for compilers to either segfault or work like you'd think they would for that example in C. You can pass pointers to earlier frames in the stack, they're still active, but you can't return a pointer to an expired stack frame.
- aw1621107 2mo agoI think you're basically agreeing with the person you're replying to; they're pointing out that Solod doesn't really provide the "safety of Go" since the translation trivially exposes the user to UB that would not be present in Go.
- nixon_why69 2mo agoYou're right, I misread their point, sorry for the pedantry OP.
- leecommamichael 2mo agoI really like this idea. I was reading a post earlier about how Go generics are implemented, and how they're sort of leveraging root GC-types in the "runtime" to avoid the same bloat as monomorphization causes in, say, C++. I wonder how Solod will do that? I guess plain monomorphization? I guess that's fine since C compilers are so speedy.
- heyitsdaad 2mo agoInsert Look What They Need To Mimic A Fraction Of Our Power meme here.
- aarvin_roshin 2mo agoThe author's original blog post, which goes into some more detail: https://antonz.org/solod https://antonz.org/solod
- jay_kyburz 2mo agoI'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.)
- SarikayaKomzin 2mo agoI’ve been considering using Odin and Raylib for this because of its similarities to Go, but using Go itself is appealing. Do you have any good resources for what you’ve learned, or is it an unexplored frontier?
- jay_kyburz 2mo agoI don't know If I can be very helpful, I'm using gen2brain's binding [1]. I started about a year ago asking the AI very beginner questions about Go and 3d math. I think it did steer me down some wrong path sometimes and of course I did some dumb things myself too. I'm not using Agents, just asking questions about features, then writing the code myself by hand. I really like the power of the tools and the constraints of the language in Go. It's been fun so far. [1] https://github.com/gen2brain/raylib-go https://github.com/gen2brain/raylib-go It's interesting you would mention Odin because I spend a fair amount of time playing with it as well. It was easy to get started and fun. Fast, easy to iterate. The reason I moved away was not the language itself, but I felt it was too much Ginger Bills baby. Oh, and managing memory is no fun. I want to make game play, not think about allocations :)
- sarchertech 2mo agoI’ve used Odin and Raylib for some prototypes, and it’s terrific!
- faangguyindia 2mo agoi've been using Go on backend now all the time. Wish something like this existed instead i am stuck with flutter and react native on Mobile. When will a time come when i can use some functional languages like Haskell or a plain boring language like Go for making apps with OTA ability for mobiles. As vibe coding takes over, app store approval will become slowerer and OTA is really great when you need to make quick changes! You can OTA each day and do base app release to store once each week. i think this maybe the space where very little work is being done.
- asp_hornet 2mo agoNot sure of your exact constraints but is something like this useful? https://hyperview.org/ https://hyperview.org/
- deleted 2mo ago[deleted]
- djha-skin 2mo agoIt cannot be a better C. You cannot implement exceptions in it using set jump for example, but the biggest problem is memory management. You can't implement your own arena allocator in golang.
- tptacek 2mo agoI've drastically sped up commercial shipping C code by implementing arena allocators and Go is my daily driver and it's not clear to me why you're making this claim.
- prerok 2mo agoNot the OP but I guess what they are saying is that since this language is a subset of go and if you use it as such then an arena allocator cannot be used in the transliterated code. Maybe it's possible to force the transliteration to use a different allocator and then you could use the one you wrote in C?
- usrnm 2mo agoTo be fair, you don't need to implement exceptions in golang because they already exist in the language, they're just called panics
- prerok 2mo agoIndeed, but I guess OP is saying that the panics are not supported in this language.
- thot_experiment 2mo agoIt cannot. C is a wonderful language that makes me smile every time I pick it up. A truly universal tool that lets you go wherever your heart desires. Go is a prison designed to enforce a bleak uniformity on all of it's users. For only by painting everything a uniform gray can we ensure we are all equal.
- ghthor 2mo agoThis is a very exciting project; love writing go with the tooling, but I miss writing C from my getting started days
- pjmlp 2mo agoGo 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.
- deleted 2mo ago[deleted]
- nine_k 2mo agoGo is not a better C, in the sense that you cannot write an OS with it. Runtime, GC, etc. But Go is a better language for many programs that were often written in C: network servers, CLI utilities, TUI utilities, etc.
- pjmlp 2mo agoPlenty of OSes, since Xerox PARC days have been written in GC systems languages. Interlisp-D, Smalltalk, Cedar, Topaz, Oberon, Active Oberon, Singularity, Midori, Ironclad Go's runtime is written in Go. The whole compiler toolchain, GC, compiler, linker, Assembler, is written in Go. There are Go compilers for bare metal, no OS needed, like TinyGo, the runtime, written in Go is the OS. I love the "you cannot write an OS in a GC language" discourse. It isn't only a mainstream thing because everyone only cares about UNIX clones.
- cturner 2mo agoThe fact that people care a lot about Unix clones is significant, though. nine_k could have been more effective in arguing the point, but it seems like a strong point to argue. Do you think you Go is flexible enough to write a Unix clone with performance equivalent to a C-unix? If so, why has it not been done?
- meling 2mo agoThere is Biscuit from OSDI 2018 https://pdos.csail.mit.edu/projects/biscuit.html https://pdos.csail.mit.edu/projects/biscuit.html
- gnull 2mo ago> 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?
- odo1242 2mo agoThe answer is apparently "you don't": - Everything in the language is statically allocated or stack-allocated. You have to call a malloc / free function to get heap allocated things - The language is not memory safe (you can't return slices, pointers, or interface types from a function if the thing was created inside the function, unless you used heap allocation) - Interfaces (the only variable size struct Go has) are implemented by creating a struct of function pointers. Arrays and maps (the non-struct variable size types) are implemented as stack-only and maps are limited to 1024 keys. You can opt into heap-based arrays / maps in the standard library to bypass this.
- brabel 2mo agoIt sounds incredibly dangerous in the hands of a usual go programmer who has no idea what the difference between the stack and the heap is.
- nixon_why69 2mo agoBeen a while since I used go but I remember it being kind of uniquely hard to tell? Like a struct is on the stack, but a *struct is maybe on the heap, depending on escape analysis?
- DanielHB 2mo agoisn't it the exact same as C in this regard? The pointer being on the stack or not depends how it was originally allocated.
- 2mo ago
- Panzerschrek 2mo agoYet another attempt to reinvent a better C. Curious, but unpractical. If one need a better C, C++ should be used instead.
- nine_k 2mo agoC++ is like PHP: it used to be a terrible language, and you can still reach for everything terrible if you wish. But during last maybe 10 years, C++ made a lot of effort to become a language with fewer footguns and more safe, high-level tools. Still I won't start a new project in C++. If I wanted high-level features and zero-cost abstractions, I'd take Rust. If I wanted working really close to hardware, do bit-twiddling and knowing where every byte is allocated, I'd take Zig. If I wanted to write a small piece of code intended to run absolutely everywhere, including old and esoteric architectures, I would still have to go with C (plain, old).
- Panzerschrek 2mo ago> If I wanted working really close to hardware, do bit-twiddling and knowing where every byte is allocated, I'd take Zig Why not C++? It allows as many low-level operations as one wishes, but don't forces you to manage memory manually where it isn't necessary. > If I wanted to write a small piece of code intended to run absolutely everywhere GCC and Clang have support of C++ since many years. Is there any modern platform for which no GCC or Clang backend exist?
- nine_k 2mo agoWhy not C++: build system(s), stdlib, modularity (though C++20 has modules, who uses them?), presence of UD. Better languages don't carry the unfortunate baggage of 1970s which C++ needs to be compatible with.
- lelanthran 2mo ago> Yet another attempt to reinvent a better C. Curious, but unpractical. If one need a better C, C++ should be used instead. Those two languages are on the opposite ends of any complexity scale. Someone looking for a better C has a ton of options before getting to "lets use C++ and ask our devs to practice discipline".
- kitd 2mo agoThe 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.
- sureglymop 2mo agoThat seems like a smart insight... but, if you're going to use an existing linter it will lint the full existing language and not your subset. So, if you accidentally code something that is not in the subset but is in the full language, the linter would then happily accept that. Imo there will be similar issues for lsps and formatters also. You're going to probably end up in a situation where you have to fork all of those anyway.
- raluk 2mo agoAt first glance looks like stipped C++ with minor differences. For example go have row polimorphism compared to OOP in C++. What else is there that C++ does not have?
- RossBencina 2mo agoThe "a better C" meme needs to die. It's ill defined. Everyone wants something different. For me, GC disqualifies any language as a better C. Bjarne Stroustrup promoted C++ as a better C. But C++ killed off some of C's killer low-level features like type-punning via unions. Indeed it's only in recent years that low-level memory manipulation, such as std::start_lifetime_as and the implicit lifetime rules were standardised. The whole strict aliasing fiasco made C and C++ permenantly worse. Some people say Zig is a better C, but it is certainly not a minimal language, if that's how you define better. For me a better C would have an abstract model that matched machine-level memory access (i.e. no type-based alias analysis) would be as minimal as C in terms of feature set, would clean up C warts like operator precedence, and would be as deterministic as possible (e.g. deterministic memory layout, including bit fields, would be possible without hacks)...
- kfreds 2mo agoWhat do you think of Ada's representation clauses and Zig's packed structs? Do they give you the syntax and semantics for arrangement (ordering, padding, widths), endianness, and control of bit order that you want? Also, thank you for an educational comment. Edit: I forgot to ask about your thoughts on Ada's and Zig's type punning.
- z0ltan 2mo ago[dead]
- arnsholt 2mo agoJohn Regehr tried to start an initiative to make what he called Friendly C, removing some of the most blatant C footguns, and even that turned out to be extremely hard to get consensus on: https://blog.regehr.org/archives/1287 https://blog.regehr.org/archives/1287
- cjs_ac 2mo agoEveryone agrees C has problems, but there’s no consensus on what those problems are. People build ‘better Cs’ to solve the problems they see in the language, and offer them to the community for the benefit of those who share their tastes. It’s perfectly fine for you to disagree with them, but it’s also perfectly fine for them to publish their solutions to their problems. ‘A better C’ is a good description for these projects. ‘The better C’ would not be.
- ventana 2mo agoTranslating 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 beyond this. Not trying to say that seeing a bunch of new translators from language A to language B is bad: not at all! It really seems that this is one of the popular usages of the agents, and a rewarding one. But doing it without hidden bugs is kinda hard.
- kfreds 2mo agoThat seems like a brittle approach to transpilation. A transpiler should translate all of the language's semantics, including resolving identifiers as symbols, and then choose legal names for them in the target language. Also, there is so much more to a language than its surface syntax. I've never designed a transpiler (I'm not a programmer), but surely the correct approach is to transform the source code into its type-checked AST, and then translate to the target language from there?
- ventana 2mo ago> A transpiler should translate all of the language's semantics, including resolving identifiers as symbols, and then choose legal names for them in the target language. Yes, it should; but it also makes things much more difficult. This specific transpiler indeed builds an AST, but does not care about identifiers, just emitting them as is [1] (I hope I found the correct place in the code). [1]: https://github.com/solod-dev/solod/blob/8485bc867ae0f0269d754de063aa43cc3b0b4c1a/internal/clang/expr.go#L394-L413 https://github.com/solod-dev/solod/blob/8485bc867ae0f0269d75...
- rao-v 2mo agoArn't goroutines the killer feature of go? Don't see how you'd get them with this approach.
- pillmillipedes 2mo agoI doubt that it can. so in addition to C's quirks (which I know about), I have to care about go's quirks and solod's quirks as well? and for what? there's no solod-to-regular-go interop aiui, so just some tooling and the standard library?
- smalljelly2018 2mo ago[dead]
- jdw64 2mo agoNO Developers who use a particular language reshape their mental model to fit that language. Go is centered around its runtime. If you switch to C11, do you really need to be thinking about a goroutine scheduler, never mind garbage collection? Even just looking at example code, would a Go developer ever think defer pool.free is necessary? The mental model is completely different.
- pulkas 2mo agono it cant.
- pulkas 2mo agobun tried hard to be written in zig. eventually, they fell back to rust. there's a lesson here: subset languages are fine for experiments and small projects, but they're rarely the right choice for production software. ...and C still can't be replaced. it's still the language of choice for mission-critical systems and low-level problem solving.
- sanbor 2mo agoGood point! Regarding C being the language of choice for mission-critical systems, probably you want to avoid memory bugs that might result ruining the mission. I understand many projects have large C codebases or interact with other projects in C, but migrating to Rust when possible (like replacing lead pipes as you find them for plastic pipes) sounds like a smart choice to build mission-critical low level systems.
- jorams 2mo ago[dead]
- mrkeen 2mo agoWhat's the lesson to be learned from Roc migrating from Rust to Zig?
- ghosty141 2mo agoIf with "production software" you mean large pieces of software I'd generally agree. I personally like Zig but I'd never write a huge 200k loc project with it, I see it more fit for low level stuff like small embedded devices where you must interface with C code.
- lionkor 2mo agoGo is not like C in any way. It doesn't feel like C, it feels like C# with mediocre syntax changes and extremely explicit error handling -- like someone took the bad parts of C and added them to a high level language. I don't get it at all. Green threads are cool, but again, it's easy to write unsafe concurrent code in Go, so why would I choose it over e.g. Rust (where its hard to write unsafe concurrent code) or C++ (which gives me more control)?
- throwaway81523 2mo agoThis looks silly. It's about a Go subset with no GC and various other restrictions that make it map onto C. But then you have most of the problems of C. It's unclear what the advantages are supposed to be. Rust or Ada seem way preferable, depending on the application area.
- kyo5uke 2mo ago[flagged]
- Rexxar 2mo agoVery interesting. I have a personal experimental project to convert go to c++ but it's less advanced than this (https://github.com/Rokhan/gocpp https://github.com/Rokhan/gocpp). My initial intention was to manage garbage collector with some smart pointer or something like Boehm GC but I've still not reached the point where it's the main problem to solve.
- benjiro29 2mo agoThe 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.
- win311fwg 2mo ago> Transcompile languages have always had tons of issues, and there is a reason why non became popular. While implementations have all died out now in favour of direct compilation, C++ the language was designed to be a transpiled language, and was for many years with C as the target. You can likely find many who agree that it has tons of issues, but unpopular it is not.
- mpyne 2mo agoTypescript is an even better example. And there are some domain-specific languages that aren't meant to become popular general-purpose languages, but succeed in their niche through the help of transpilation to a general-purpose language.
- win311fwg 2mo agoTypescript isn't nearly as popular as C++ and, aside from a couple of legacy features that don't seem to be commonly used, it can be erased without needing transpilation. What makes it a better example?
- Decabytes 2mo agoI did this with a python languah
- throwway120385 2mo agoDoes it generate the same extremely fat binaries? I've seen Go binaries get into hundreds of megabytes for things you could do with C/C++ with a few megabytes. Most of it seemed to be string tables and other things that could be reduced but not eliminated with compression.
- win311fwg 2mo agoA large part of that depends if we get something equivalent to gc's scheduler or not. Concurrency is still under development. Most likely it will take a simpler approach, like tinygo, which won't require tons and tons of code.
- ericyd 2mo agoI know this is probably a bad question but it says that this language would be good for C developers who like Go's safety. Isn't Go's safety achieved by its garbage collection, which is eliminated in this language? What elements of Go are safer than C which would be preserved in this subset language?
- Onavo 2mo agoDoes it support pointer arithmetic?
- syngrog66 2mo agoThe worst of both worlds.
- awson 2mo agoIs the author even aware of C tooling?
- derekbsnider 2mo agoSo this makes me think that a "better" idea is let C be the actual underlying foundation for all of these languages because most languages are written in C (and C++) in the first place, so instead of forcing this strict divide, why not allow for every language to be transpilable into C so that the end result is that you could code in any language you like, because in the end, it can all be compiled with a standard c compiler? This could just be the new rule going forward... want to make a new programming language? Sounds good... so long as it can be transpiled into C code. Doing some weird shady stuff that generates machine code directly? No problem -- put it into a library that can be linked in.