5 ms·
This 100% I’m darn sick of reading articles that don’t consider tradeoffs. Engineering can be defined as “a search for the optimal set of tradeoffs”. But, it s
by xorvoid 4y ago
This 100%
I’m darn sick of reading articles that don’t consider tradeoffs. Engineering can be defined as “a search for the optimal set of tradeoffs”. But, it seems like every article I ever read about new tech only discussed pros, not cons. I don’t get it. The cons are just as important, if not more so. Unfortunately, for some reason, people associate cons with flaws/weaknesses/failures rather than just a “point on the tradeoff curve”. Often: no perfect solution exists and those claiming otherwise are being dishonest. I would love to see this culture change at least for engineering literature where we should know better.
All that said: I DO think that Zig has selected a reasonable point in the tradeoff curve. I just really want to understand that point better. How am I supposed to use it most effectively if I don’t understand it?
- bsder 4y agoHere is the question I think that you need to answer to choose between Rust and Zig: If your dependencies wrap more than 2 external libraries that have poor architecture, you're about to have a miserable time in Rust. Rust creates a lot of friction if an external library has a poor architecture. And, by default, most libraries have a very poor architecture. This leads to things like: "Giving up on wlroots-rs"--http://way-cooler.org/blog/2019/04/29/rewriting-way-cooler-in-c.html http://way-cooler.org/blog/2019/04/29/rewriting-way-cooler-i... Talk about the issues of RLua--https://www.reddit.com/r/rust/comments/biq864/giving_up_on_wlrootsrs/ https://www.reddit.com/r/rust/comments/biq864/giving_up_on_w... "The thing that was SO tiring about writing this for me wasn't Rust, it was reasoning about the C library that I was binding. I'm just... tired of using C APIs! I'm tired of not having the compiler reason for me, I'm tired of having to second guess at what invariants the API expects and guess at what of a myriad of interesting non-local behavior a function call will do. I know that the Lua C API is a really, especially bad example, but I just don't know what the general solution is here." Consequently, this is where you get "Rewrite All The Things In Rust!" What's the point of fighting with Rust over all these nice safety guarantees and then throwing them out at the API boundary? If you can keep everything in Rust, this simply isn't an issue. This is where Zig shines. It catches some of the main classes of bugs but still lets you talk to libraries with crap architecture. Zig gets the fact that infrastructure and ecosystem matter--unlike everybody else operating in the C space (the cross compiling is phenomenal, for example, because they put a lot of work into it). Zig is doing some interesting things, but it's mostly some very solid choices with a lot of elbow grease applied. And that's worth a LOT. As an aside, I will also say that Zig feels better for embedded programming than Rust. Rust feels like it has stalled in embedded areas (things like sized integers, bitfield packing, placement construction of data structures, statics and globals that don't have locking overhead, lack of do-while, etc. although I would like to point out in Rust's favor that Rust finally got label-break-value which is a godsend when porting embedded code with goto error handling) while Zig has explicitly targeted those from the beginning. That makes Zig feel better for embedded from an ergonomic perspective, to my (obviously quite subjective) taste.
- capr 4y agoThe Lua C API is now bad because you can't easily make Rust bindings to it?
- girvo 4y agoI also agree that Zig has more promise for embedded than Rust, in my opinion. I use Nim daily for embedded firmware development for similar reasons that I like Zig, but Nim has some baggage that can get in the way at times around it’s compiler (though fixing those issues is surprisingly accessible I’ve found). That said, until someone works out how to properly integrate Zig or Nim or etc. into CMake, then there’s always going to be friction. Too much of the IDF world relies on it and it’s quirks. In Nim land I get around this by --compileOnly to C sources, which works but is a little cumbersome. Rust is rebuilding the embedded world from scratch, which is a non starter for my work. I do have hope Zig will have a better story than both for this, but we will see!
- tialaramex 4y ago> I would like to point out in Rust's favor that Rust finally got label-break-value Oh, interesting, I was wondering if this (breaking with both a label and a value) existed (in a different context), and I concluded it didn't exist and so probably nobody had wanted it, but turns out it's in the next version and I didn't hear about it. I don't understand a desire for do-while, I can't imagine what I might write where that looks reasonable and the loop equivalent in Rust is not very good. If all you wanted was nicer C then yeah, Zig is that and Rust isn't -- I just don't think "nicer C" is a reasonable goal any more.
- bsder 4y ago> I don't understand a desire for do-while It has to do with porting code, generally. If I'm writing original Rust, I rarely miss it. It's not a huge deal, but you bump into it juuuust often enough to (probably unfairly) curse Rust out when you hit it yet again. Here's code from CMSIS DAP debug probe firmware from ARM: https://github.com/ARMmbed/DAPLink/blob/main/source/daplink/cmsis-dap/DAP.c#L788 https://github.com/ARMmbed/DAPLink/blob/main/source/daplink/... Note the nested do { do { } while (); if (err) break;} while(); if (err) break; Should that code be rewritten? Most certainly it should, and it should be given a proper Error type. However, when you are first porting it, you need to match semantics or you get a bunch of off-by-one, missed error, or missed end of stream bugs. And, as you point out, the Rust loop{} equivalents suck. We've all written suboptimal code, and we all live in a suboptimal world. :)