9 ms·
Having fun with this. Never bought into rust (have studied, have a (mostly AI-generated app in rust). Wrote some Zig but Odin is even less overhead for me. I
by pseudony 3mo ago
Having fun with this.
Never bought into rust (have studied, have a (mostly AI-generated app in rust).
Wrote some Zig but Odin is even less overhead for me. I first loved Zigs built-in build system but having tried to wrap/use C libraries from both, I must say I prefer Odin.
Wrapping some sqlite 3 API’s for my first little Odin program - just because I need so little of the API that it seems easier this way - and speaking to C from Odin is a pleasure.
That is, imho, where Rust fails the most - the second part is the C++’ish approach to memory management (RAII) - that’s not how systems programming or games (I’m told) tend to work.
To each their own. I had some fun with Rust too, but for me, Odin seems the most appealing :)
- CyberDildonics 3mo agoThat is, imho, where Rust fails the most - the second part is the C++’ish approach to memory management (RAII) - that’s not how systems programming or games (I’m told) tend to work. What does this mean? Who told you that?
- dustbunny 3mo agoCasey Muratori and Jon Blow have pushed this concept frequently. They largely don't deeply elaborate, which is sad because I am a professional game developer who is interested in precisely presented knowledge so I can apply it to my work. My interpretation is that games want to allocate large pools of resources, like GPU buffers, cpu memory, etc, and reuse that memory over and over. Ie: Reinitialize it. In my experience, RAII is my preferred pattern for certain things (std::lock_guard), and you can almost certainly express the majority of these "uber game dev patterns" using RAII/smart pointers/etc, but the c++ implementation of these "uber game dev patterns" tends to be more complicated (and imo esthetically ugly) compared to really well written C. These new languages (zig, odin, jai) appear to be attempts to improve C to allow an alternative to C++ that doesn't have the ugly baggage that C++ has.
- pdpi 3mo agoCasey Muratori and Jon Blow are both hyper-dogmatic "my way or the highway" types, and, crucially, neither of them has built any of the super high fidelity types of game that would require that level of optimisation. They're basically influencer types.
- sarchertech 3mo agoCasey worked on tooling for AAA games that most certainly needed “that level” of optimization. Jon Blow worked on numerous AAA games that required “that level” of optimization. And he’s one of the very few developers in the last 15 years who have managed to sell more than a million copies of a game running on a scratch built 3D engine. You can disagree with their opinions, but they certainly have the experience to back those opinions up.
- gf000 3mo agoWell, Minecraft sold far more and it's a scratch built 3d engine isn't it? Popularity is certainly not a technical achievement.
- sarchertech 3mo agoMinecraft doesn't use an off the shelf engine, but I wouldn't really call Minecraft scratch built. It's built on top of LWJGL. Popularity isn't a technical achievement in itself. But what is a technical achievement is that he built a visually impressive 3d engine that worked well enough for over a million people to buy it at a time when almost no one else was doing this. Minecraft was released nearly 10 years earlier--before Unity and Unreal had completely taken over. I'm also not saying that the witness engine is somehow better than anything else out there, but it's a significant enough technical accomplishment that along with Jon Blow's other work, he has the experience to back up his opinions. I've also never seen the critique that Jon Blow is just an influencer with no relevant experience from anyone with equivalent relevant experience. I've seen other experienced game devs who disagree with him, but I've never seen them say that he doesn't have the experience to have them.
- scott01 3mo agoFrom what I understood, their critique of RAII is twofold: coupling of allocation and initialisation, and enforcement of deallocation. The ease of use of smart pointers makes it tempting to allocate/free of temporary structures even within one single function. Given enough number of such occurrences, it kills performance by a thousand cuts. Also I remember they mentioned it’s not necessary to free memory if you’re about to close your program, because the OS will take the memory back. Obviously you need to gracefully deinitialise some things, like audio or other devices, but that’s beyond the discussion. As on some references, Ryan Fleury did an episode on Wookash podcast on RAD debugger showing ECS like approach. IMO, their RAII critique is a but nuanced, but because of their personality the discourse often gets polarising. Edit: the sibling comment just proved my last point.
- tancop 3mo agomost of that criticism only works on C++. rust does enforce RAII but uses stack allocation for locals by default instead of touching the heap so it skips the slow part. on the other hand there are no constructors (just normal functions) so you cant initialize values in place, only stack allocate and return. i think rust needs to add in place init and change the rules from "always init at declaration site" to "must be initialized at first use" like kotlin. the big missing piece is custom allocators that let you use something like a bump arena with the same convenience as system malloc. they already exist on nightly but nobody knows when they will land on stable. honestly thats the biggest problem with rust, they come up with a lot of useful changes but then take ages to stabilize because the core team is overworked. they also have a kind of perfectionist culture as a reaction to all the half baked features shipping in C++. there should be a stage between nightly and full release where feature is in stable toolchains behind a cfg flag and you get a warning if upstream crates use it. show commitment to shipping it in time but still make it clear that it can change (in minor incompatible ways) before release.
- scott01 3mo agoThanks for this, I’m actually learning Rust (albeit slowly) atm, and still can’t wrap my head around how arena allocs would fit the borrow checker
- andrepd 3mo ago> Casey Muratori and Jon Blow have pushed this concept frequently Ah... The school of what I like to call "maximum opinions and minimal evidence". Aggressive arrogant dismissal of anything except their exact view (and for Muratori, you're also "woke" for good measure), coupled with a complete lack of _hard evidence_ to back up their views. In that regard, they're not unlike "investment advice" instagram influencers.
- christophilus 3mo agoI can see why you would think that about Jon Blow, though I disagree. But Casey? He has a number of thorough videos with plenty of evidence, and has never struck me as arrogant.
- indy 3mo ago"coupled with a complete lack of _hard evidence_ to back up their views" Didn't Casey Muratori write a proof of concept windows terminal to highlight Microsoft's substandard implementation? And Jonathan Blow has spent the past decade+ developing his own programming language and funding the development of a game. Seems like they are backing their views.
- jstimpfle 3mo agoApparently you're the school of dismissive person who can't even be bothered to look up their technical achievements.
- CyberDildonics 3mo agoConfusing achievements in one area for evidence in another is literally an appeal to authority fallacy.
- jstimpfle 3mo agoYou must mean confusing achievements in the area of creating large maintainable and performant systems on the one hand, with achievements in the area of creating large maintainable and performant systems on the other hand? And let me incude Ryan Fleury here who graduated from Casey-school with honors, he is maybe the most impressive programmer I know. His work on the raddebugger is outstanding.
- CyberDildonics 3mo agoI think those guys both hate C++ so much that they want to dismiss everything about it instead of using all the features that work for them like most people. My interpretation is that games want to allocate large pools of resources, like GPU buffers, cpu memory, etc, and reuse that memory over and over. Ie: Reinitialize it. They might say this, but there isn't a good technical rationalization here since anyone can create a global data structure just as easily in C++.
- andrepd 3mo agoExactly! The most interesting arguments for Rust that I've ever read have come not from people who hate C++, but precisely from people who are really into C++, because those are the people who actually recognise its shortcomings are are better positioned to give INSIGHTFUL criticism into it. People who are motivated by a superiority complex or by the wish to impress a herd of twitter followers hardly if ever produce a thought I want to read.
- dismalaf 3mo agoHate C++? They both use(d) it...
- CyberDildonics 3mo agoI didn't say they don't know it.
- dismalaf 3mo agoAs opposed to using C, Rust, or something else (Jon eventually made Jai but Casey still uses C++). Obviously they don't outright hate it.
- CyberDildonics 3mo agoThey talk about hating it all the time and using some minimal subset because they have to, but the point here is not what these two internet personalities hate, it's that there isn't a technical rationale against being able to use destructors. They are hugely convenient but also completely easy to avoid if someone wants to.
- tialaramex 3mo agoCasey spends a lot of effort on what he considers an anti-pattern where you're making a huge number of separate objects. I think a lot of this comes from Java, a language where all the user defined types actually are obliged to be heap allocations. If I make a Goose type, and I say I want a Goose, Java will allocate space on the heap for the Goose and put my Goose there, that's really how Java works. If I make a growable array of them ArrayList<Goose>, and add each of 500 geese, that's 500 allocations for geese plus maybe 8 allocations for the ArrayList, so 508 total. Ouch. If making a Goose was itself cheap this overhead hurts badly. But a lot of languages aren't like that, and so this doesn't translate. Obviously in Rust with Vec<Goose> that's only 8 allocations, each local Goose lives in the stack - or, if you knew up front there were 500 geese, you Vec::with_capacity(500) and it's a single allocation - but similar is true in many languages, Java is an outlier.
- ahtihn 3mo agoMaybe I'm missing something but when would the 500 geese instances ever be stack allocated in Rust? That comparison seems unfair, the lifetime of that kind of object isn't going to be compatible with stack allocation. Allocations are really really cheap in Java by the way, so I don't get how 500 allocations would even be an issue.
- tialaramex 3mo agoWhen you make a local variable with a Goose in Java, that's a heap allocation Goose jim = make_a_goose_somehow(); // Java, so jim is on the Heap, no way around it When you make that variable in Rust... let jim : Goose = make_a_goose_somehow(); // Rust, jim is on the stack Now, if we make a bunch of geese, maybe in a loop, and we put them into our growable array type... ArrayList<Goose> geese = new ArrayList<Goose>(); // ... some loop eventually Goose a_goose = somehow_get_this_goose(); // That's an allocation geese.add(a_goose); But in Rust... let geese: Vec<Goose> = Vec::new(); // ... some loop eventually let a_goose : Goose = somehow_get_this_goose(); // But this is not geese.push(a_goose);
- 3mo ago
- torginus 3mo agoThey might've pushed it, but they certainly didn't invent the idea. Although I'm not 100% familiar with their arguments. POD - objects with no behavior are pretty popular way of representing data, you can serialize and deserialize them, etc. They have a pretty big caveat in non-GC languages - if you have an object with something like a dynamic array in it, suddenly your stateless POD becomes stateful, and needs RAII otherwise you get a memory leak. No idea how they solve that without GC.
- moron4hire 3mo agoYeah, that's weird. I first learned about RAII from professional game developers at gamedev.net.
- pseudony 3mo agoGames ? Many have talked about it, but many also make their games work inside of Unity and so on, so, depends on the project. My angle is systems programming, and there, it absolutely matter. If you are performance sensitive, then you try to avoid crossing the user-space -> kernel boundary more than you have to. Eg, ask for lots of memory, manage with arenas. Interestingly Odin and Zig both lean into this heavily. Rust went a different route but has tried later to bolt on pluggable allocators.
- kibwen 3mo ago> My angle is systems programming, and there, it absolutely matter. If you are performance sensitive, then you try to avoid crossing the user-space -> kernel boundary more than you have to. Eg, ask for lots of memory, manage with arenas. This gives the misleading impression that ordinary memory allocators are materially different from arena allocators. They aren't. Both types of allocators first ask for a big block of memory from the kernel, then dole that memory out in userspace. There's no need to cross the userspace/kernel boundary more often than you need to, especially when you consider that you can replace the standard platform allocator with whatever you want. To wit, C doesn't emphasize arena allocation anywhere near as much as Zig et al do, and yet nobody alleges that C is somehow less suitable for systems programming than these languages. Have you considered why that is? Because, for the most part, arena allocation doesn't make a significant difference, and in the places where it actually does make a difference, you can trivially build an arena allocator on top of the standard allocator.
- wasmperson 3mo agoAgreed. IME the main reason to choose arena allocators is for correctness, not speed. They make similar time/space tradeoffs to garbage collectors in that they grant higher allocation throughput in exchange for more memory usage. The perf argument against RAII is very abstract and is less "RAII causes bad performance" and more "the kind of design that leads you to reach for RAII is the kind of design that's bad for performance." There exist similar hand-wavy arguments against many other C++/Rust features. More generally, "you shouldn't even want that" is basically a meme at this point in programming language design. Every new-ish language has some version of it.
- frizlab 3mo agoDid you try Swift? Its interoperability with C (and even C++) is great IMHO.
- hollowturtle 3mo agoIt's GC
- leecommamichael 3mo agoPedantically I’ll say it’s reference counted, and someone else will say that’s still a form of GC and I’ll just save us the mini-thread. Reference counting has deterministic timing, you can run a deconstructor without registering objects for deletion and running any known finalizers (what you need to do in all GC langs I’m aware of.)
- frizlab 3mo agoYes, but only classes are GC (refcounted as parent comment says, indeed). structs and other elements are not. You can even use the same ownership model as rust (borrowing et al.) with non copyable types.
- Someone 3mo ago> Reference counting has deterministic timing Define “deterministic timing”. - One object going out of scope may mean calling free once, but it also can trigger calling free billions of objects, even for the exact same object - Even freeing one object can have largely varying running time, e.g. to coalesce free blocks or, because it happens to be the last block in a virtual memory region, to unmap a block of virtual memory, blocking the program potentially for an arbitrary time - With garbage collection (as with reference counting), lots of the overhead of objects going out of scope can be moved onto a specialized thread. > you can run a deconstructor without registering objects Not requiring finalizes does make reference counting easier, yes. The downside is have to store the reference counts somewhere, and keep them up to date (enough)
- 3mo ago
- hkalbasi 3mo agoIf the major obstacle for adopting Rust is C interop, you may find my project CO2[1] appealing. It helps you to define C crates, `#include` C headers, while exporting a Rust API with Rust types in your crate boundary. [1]: https://github.com/hkalbasi/co2 https://github.com/hkalbasi/co2