19 ms·
Zig feels more practical than Rust for real-world CLI tools
- tonetegeatinst 1y agoAs far as my understanding of zig goes....it can compile into C....so if you really want secure C code you can compile zig into C?
- dayvster 1y agoNot quite, it can translate C into zig using the `translate-c` command that it comes with. But it compiles directly into machine code
- Ar-Curunir 1y agoWhile Zig prevents certain kinds of memory safety issues that C does not, it still suffers from memory-safety issues not found in safe Rust.
- Cloudef 1y agoZig can compile into C, but it's not portable C
- MangoToupe 1y ago[flagged]
- dayvster 1y ago[flagged]
- simonask 1y agoI’m not an idiot! However, 3 months ago me was clearly an idiot judging from the utter crap he wrote. Me in 3 months is also an idiot, he won’t get the greatness of these genius hacks I’m making.
- Ygg2 1y agoI'm not an idiot either. But past and future me get to be idiots from time to time. Alcohol and lack of sleep are a helluva mind cripplers.
- KingOfCoders 1y ago"All it took was some basic understanding of memory management and a bit of discipline." The words of every C programmer who created a CVE.
- markphip 1y agoCame here to add the same comment. Had it on my clipboard already to post. You said it better
- dev_l1x_be 1y agoThe amount of seggfaults I have seen with Ghostty did not raise my spirits.
- txdv 1y agoI haven't seen a single one.
- mlvljr 1y ago[dead]
- neerajk 1y agosegfaults raise my belief in spirits
- greesil 1y agoPossibly a good Halloween costume idea to go as a segfault. It would scare some people.
- dpatterbee 1y agoI've had at least one instance of Ghostty running on both my work and personal machine continuously since I first got access to the beta last November, and I haven't seen a single segfault in that entire time. When have you seen them?
- Imustaskforhelp 1y agoWhat are your thoughts on nim, odin and v-lang, D-lang? I feel like I am most interested about nim given how easy it was to pick up and how interoperable it is with C and it has a garbage collector and can change it which seems to be great for someone like me who doesn't want to worry about manual memory management right now but maybe if it becomes a bottleneck later, I can atleast fix it without worrying too much..
- dayvster 1y agoI have not given any of those 3 a fair enough shot just yet to make a balanced and objective decision. Out of all of them from what little I know and my very superficial knowledge Odin seems the most appealing to me, it's primary use case from what I know is game development I feel like that could easily pivot into native desktop application development was tempted to make a couple of those in odin in the past but never found the time. Nim I like the concept and the idea of but the python-like syntax just irks me. haha I can't seem to get into languages where indentation replaces brackets. But the GC part of it is pretty neat, have you checked Go yet?
- O-stevns 1y agoOdin has no primary use case, it just happens that a lot of the members in the community have made or are interested in game making
- Imustaskforhelp 1y agoMy understanding of odin was that its good for data oriented. I haven't really looked into odin except joining their discord and asking them some questions. it seems that aside from some normal syntax, it is sort of different from golang under the hood as compared to V-lang which is massively inspired by golang After reading the HN post of sqlite which recommended using sqlite as a odt or some alternative which I agreed. I thought of creating an app in flutter similar to localsend except flutter only supports C esq and it would've been weird to take golang pass it through C and then through flutter or smth and I gave up... I thought that odin could compile to C and I can use that but it turns out that Odin doesn't really compile to C as compared to nim and v-lang which do compile to C. I think that nim and v-lang are the best ways to write some app like that though with flutter and I am now somewhat curious as to what you guys think would be the best way of writing highly portable apps with something personally dev-ex being similar to golang.. I have actually thought about using something like godot for this project too and seeing if godot supports something like golang or typescript or anything really. Idk I was just messing around and having a bit of fun lol i think.
- ranger_danger 1y agoIMO, as a C++ developer, Swift makes the most sense to me if I were looking for a safer alternative. I think people prefer what's familiar to them, and Swift definitely looks closer to existing C++ to me, and I believe has multiple people from the C++ WG working on it now as well, supposedly after getting fed up with the lack of language progress on C++. The most recent versions gained a lot in the way of cross-platform availability, but the lack of a native UI framework and its association with Apple seem to put off a lot of people from even trying it. I wish it was a lot more popular outside of the Apple ecosystem.
- tonetegeatinst 1y agoCan you share some swift resources so I can look into the features of swift compared to zig and C?
- Yiin 1y agothat sounds like a query for llm
- tizio13 1y agoDefinitely check out swift.org/ . A few pages that are good jumping points are: https://docs.swift.org/swift-book/documentation/the-swift-programming-language/guidedtour/ https://docs.swift.org/swift-book/documentation/the-swift-pr... https://swift.org/documentation/cxx-interop/ https://swift.org/documentation/cxx-interop/ https://swift.org/blog/swift-everywhere-windows-interop/ https://swift.org/blog/swift-everywhere-windows-interop/
- majorchord 1y agohttps://www.douggregor.net/posts/swift-for-cxx-practitioners-value-types/ https://www.douggregor.net/posts/swift-for-cxx-practitioners...
- deleted 1y ago[deleted]
- Nevermark 1y ago> So when it comes to memory management there are two [THREE] terms you really need to know, [THE REGISTER BANK,] the stack and the heap. Edits mine. I like to keep the spacetime topologies complete. Constant = time atom of value. Register = time sequence of values. Stack = time hierarchy of values. Heap = time graph of values.
- simonask 1y agoThe benefit of Zig seems to be that it allows you to keep thinking like a C programmer. That may be great, but to a certain extent it’s also just a question of habit. Seasoned Rust coders don’t spend time fighting the borrow checker - their code is already written in a way that just works. Once you’ve been using Rust for a while, you don’t have to “restructure” your code to please the borrow checker, because you’ve already thought about “oh, these two variables need to be mutated concurrently, so I’ll store them separately”. The “object soup” is a particular approach that won’t work well in Rust, but it’s not a fundamentally easier approach than the alternatives, outside of familiarity.
- Galanwe 1y ago> Seasoned Rust coders don’t spend time fighting the borrow checker My experience is that what makes your statement true, is that _seasoned_ Rust developers just sprinkle `Arc` all over the place, thus effectively switching to automatic garbage collection. Because 1) statically checked memory management is too restrictive for most kinds of non trivial data structures, and 2) the hoops of lifetimes you have to go to to please the static checker whenever you start doing anything non trivial are just above human comprehension level.
- amw-zero 1y agoHow often are you writing non-trivial data structures?
- swiftcoder 1y agoI don't think there are any Arcs in my codebase (apart from a couple of regrettable ones needed to interface with Javascript callbacks in WASM - this is more a WASM problem than a rust problem).
- ChadNauseam 1y agohaha, I was about to leave the exact same comment. how are you finding wasm? I’ve been feeling like rust+react is my new favorite tech stack
- giancarlostoro 1y agoI want to like Zig, but D still exists and feels like everything I want from a C-like alternative to C++ I just wish the rest of the industry had adopted it long ago. Zig has a strange syntax, and Rust is basically eating chunks of the industry, especially in programmer tooling across various languages as is Go (it powers most cloud providers and is the 2nd top choice for AI right after Python).
- sethops1 1y agoI remember before Rust when Go vs. D was the topic of the day. I even bought a D book and was working through it when Go was announced, and it won me over. The difference maker for me was the standard library; working with Go was just easier, full stop. That and using names like 'int64' instead of 'double', because that's what my brain likes apparently.
- giancarlostoro 1y ago100% agree. I really love D the language, if I could go back in time I would find Walter and challenge him that he couldn't write {insert half of the Go std lib packages} into the STD lib for D because its too hard and impossible, in the hopes he takes the bait. I would love to see something like a 'Framework' for D that is maintained by the maintainers, but isn't necessarily the standard library, because people get really touchy when you mess with the STD lib, maybe a way to test the waters before actually adding new packages to it, having an HTTP server OOTB with D would be amazing.
- pjmlp 1y agoD would be great, unfortunately they never got the killer application for mass adoption.
- bfrog 1y agoBecause it doesn't actually enforce anything and lets you blow your foot off just like C?
- rawkode 1y agoWhy does a personal blog need so many advertising options?
- ModernMech 1y agoYeah this whole blog is sus. Author claims to have been around for 17 years, doesn't have a single project of note and makes naive claims. Github history has thousands of commits per year every single day to private repos, yet very little public code or record to offer credibility. Not clear where they work or what they work on. Makes inflammatory claims about hot-topic languages. Throws up ads on the blog. Personally posts blog to HN on a relatively new account, rather than it organically finding its way here. Sorry I'm not buying it. He seems to know what he's doing, from the author's Twitter: Post something slightly mentioning rust in r/cpp, Rust evangelists show up, post something slightly mentioning rust in r/zig, Rust evangelists show up. How is this not a cult?
- hnlmorg 1y agoWhat you’ve described there is a 90% match for most people in tech.
- Tade0 1y ago> Author claims to have been around for 17 years, doesn't have a single project of note and makes naive claims. Plenty of such people out there. This guy appears to just personally dislike Rust for reasons undisclosed and tries to rationalize it via posts like this one. It's like with this former coworker of my former coworker who was really argumentative, seemingly for the sake of it. I did some digging and found that his ex left him and is now happily married. Turns out that when he was criticizing the use of if-else in Angular templates what he was really thinking about was "if someone else".
- tcfhgj 1y agobuilding houses or power lines without regulations feels more practical as well
- moochmoochmooch 1y ago[flagged]
- dayvster 1y agoI can guarantee you that none of it was written by ChatGPT or any other LLM. As for the Ads, even though it's my site, I'd urge you to turn on adblocker, pi-hole or anything like that, I won't mind. I have ads on there yes, but since I primarily write tech articles for a target audience of tech people you can imagine that most readers have some sort of adblocker either browser, network or otherwise. So my grand total monthly income from ads basically covers hosting costs and so on.
- karmakaze 1y agoI was going to say that it's greatly understating the value of the borrow checker. It guarantees no invalid memory accesses. But then it added: > This means that basically the borrow checker can only catch issues at comptime but it will not fix the underlying issue that is developers misunderstanding memory lifetimes or overcomplicated ownership. The compiler can only enforce the rules you’re trying to follow; it can’t teach you good patterns, and it won’t save you from bad design choices. In the short times that I wrote Rust, it never occurred to me that my lifetime annotations were incorrect. They felt like a bit of a chore but I thought said what I meant. I'm sure there's a lot of getting used to using it--like static types--and becomes second nature at some point. Regardless, code that doesn't use unsafe can't have two threads concurrently writing the same memory. The full title is "Why Zig Feels More Practical Than Rust for Real-World CLI Tools". I don't see why CLI tools are special in any respect. The article does make some good points, but it doesn't invalidate the strength of Rust in preventing CVEs IMO. Rust or Zig may feel certain ways to use for certain people, time and data will tell. Personally, there isn't much I do that needs the full speed of C/C++, Zig, Rust so there's plenty of GC languages. And when I do contribute to other projects, I don't get to choose the language and would be happy to use Rust, Zig, or C/C++.
- kllrnohj 1y ago> I don't see why CLI tools are special in any respect. Because they don't grow large or need a multi-person team. CLI tools tend to be one & done. In other words, it's saying "Zig, like C, doesn't scale well. Use something else for larger, longer lived codebases." This really comes across in the article's push that Zig treats you like an adult while Rust is a babysitter. This is not unlike the sentiment for Java back in the day. But the reality is that most codebases don't need to be clever and they do need a babysitter.
- cestith 1y agoDo you know any other languages that tend to be safer than C and suitable for CLI tools but without the borrow checker? Over many years I’ve seen a lot in C++, Go, Perl, Python, Ruby, Pascal, various shells, assembly, Java, and some in Haxe, Ada, Lisp, Scheme, Julia, forms of Basic, and recently JavaScript or Typescript. Most of those are more memory safe than C. None of them have the borrow checker. This leaves me wondering why - other than proselytizing Zig - this article would make such a direct and narrow comparison between only Zig and Rust.
- antoineMoPa 1y agoI also loved Zig when manually typing code, but I increasingly use AI to write my code even in personal projects. In that context, I'd rather use Rust more, since the AI takes care of complex syntax anyway. Also, the rust ecosystem is bigger, so I'd rather stick to this community. > Developers are not Idiots I'm often distracted and AIs are idiots, so a stricter language can keep both me and AIs from doing extra dumb stuff.
- kevinrineer 1y ago> I'm often distracted I really appreciate this in my role, where I have an office right next to the entrance to the building. I get walk-ins all of the time. When my door is closed, I get knocks on the door all of the time. Both AI and strict languages are great tools in my environment, where focus for me is as abundant as water in a desert.
- benashford 1y agoAren't these two points contradictory? Forgive me if I'm misunderstanding. > Rust’s borrow checker is a a pretty powerful tool that helps ensure memory safety during compile time. It enforces a set of rules that govern how references to data can be used, preventing common programming memory safety errors such as null pointer dereferencing, dangling pointers and so on. However you may have notice the word compile time in the previous sentence. Now if you got any experience at systems programming you will know that compile time and runtime are two very different things. Basically compile time is when your code is being translated into machine code that the computer can understand, while runtime is when the program is actually running and executing its instructions. The borrow checker operates during compile time, which means that it can only catch memory safety issues that can be determined statically, before the program is actually run. > > This means that basically the borrow checker can only catch issues at comptime but it will not fix the underlying issue that is developers misunderstanding memory lifetimes or overcomplicated ownership. The compiler can only enforce the rules you’re trying to follow; it can’t teach you good patterns, and it won’t save you from bad design choices. This appears to be claiming that Rust's borrow checker is only useful for preventing a subset of memory safety errors, those which can be statically analysed. Implying the existence of a non-trivial quantity of memory safety errors that slip through the net. > The borrow checker blocks you the moment you try to add a new note while also holding references to the existing ones. Mutability and borrowing collide, lifetimes show up, and suddenly you’re restructuring your code around the compiler instead of the actual problem. Whereas this is only A Thing because Rust enforces rules so that memory safety errors can be statically analysed and therefore the first problem isn't really a problem. (Of course you can still have memory safety problems if you try hard enough, especially if you start using `unsafe`, but it does go out of its way to "save you from bad design choices" within that context.) If you don't want that feature, then it's not a benefit. But if you do, it is. The downside is that there will be a proportion of all possible solutions that are almost certainly safe, but will be rejected by the compiler because it can't be 100% sure that it is safe.
- scoopdewoop 1y agoThis is a really bad take, on par with the "we don't need types" post from last week. The thing I wish we would remember, as developers, is that not all programs need to be so "safe". They really, truly don't. We all grew up loving lots of unsafe software. Star Fox 64, MS Paint, FruityLoops... the sad truth is that developers are so job-pilled and have pager-trauma, so they don't even remember why they got in the game. I remember reading somewhere that Andrew Kelley wrote zig because he didn't have a good language to write a DAW in, and I think its so well suited to stuff like that! Make cool creative software you like in zig, and people that get hella about memory bugs can stay mad. Meanwhile, everyone knows that memory bugs made super mario world better, not worse.
- dayvster 1y agoUh I'm confused, so you think my take is bad because memory safety should not matter ?
- scoopdewoop 1y agoI think its a bad take because "Developers are not Idiots" and "be disciplined" are not good arguments. Its just choosing to ignore the problem rust solves. I am fine with ignoring the problems that rust solves, but not because I'm smart and disciplined. It just fits my use-case of making fast _non-critical_ software. I don't think we should rewrite security and networking stacks in it.
- dayvster 1y agoThen we're sort of in agreement. I don't think you need the ritual and complexity that rust brings for small and simple scripts and CLI utilities...
- KuSpa 1y agoAnd rust doesn't market itself as small and simple scripting language? Choose the tool that fits your usecase. You would never bring wasm unity to render a static html file. But if you make a browsergame, you might want to.
- swiftcoder 1y agoThis article seems pretty confused about what the borrow checker does or does not do - I've never heard compile time enforcement listed as a negative of the borrow checker before. It might do the author good to try writing some (non-trivial) memory management in both Zig and Rust some time.
- iphone_elegance 1y agowhen I think of rust I think of beauties like this, self.last.as_ref().unwrap().borrow().next.as_ref().unwrap().clone() I know it can be improved but that's what I think of
- Klonoar 1y agoWithout any context it’s impossible to tell if code needs to be that obtuse or if uou somehow built your way into a setup that you could’ve avoided. ;P
- einpoklum 1y agoGP is suggesting that one typically finds oneself in such a situation with idiomatic code. Even if it can be avoided with some effort, it will all too easily not be avoided.
- stonemetal12 1y agoThe fact that your app crashes when you run out of stack is a compiler bug, not a feature. Memory is memory. The fact that languages in the 40s split in it to stack and heap, doesn't make it a foundational mathematical law. Yes, safety isn't correctness but if you can't even get safety then how are you supposed to get correctness? For small apps Zig probably is more practical than Rust. Just like hiring an architect and structural engineers for a fence in your back yard is less practical than winging it.
- ccapitalK 1y agoBehold, I've brought you a compiler bug. https://play.rust-lang.org/?version=stable&mode=debug&edition=2024&gist=5340e015f227f7fd40745f5ea68dd0fb https://play.rust-lang.org/?version=stable&mode=debug&editio...
- xwowsersx 1y agoNo shade here, just a genuine question: why run ads on a blog like this? A personal technical blog probably doesn't get a ton of traffic. So what's the point? I'm honestly curious.
- illuminator83 1y agoActually, developers are idiots. Everyone is. Some just don't know it or won't admit it. I once joined a company with a large C/C++ codebase. There I worked with some genuinely expert developers - people who were undeniably smart and deeply experienced. I'm not exaggerating and mean it. But when I enabled the compiler warnings (which annoyed them) they had disabled and ran a static analyzer over the codebase for the first time, hundreds of classic C bugs popped up: memory leaks, potential heap corruptions, out-of-bounds array accesses, you name it. And yet, these same people pushed back when I introduced things like libfmt to replace printf, or suggested unique_ptr and vector instead of new and malloc. I kept hearing: "People just need to be disciplined allocations. std::unique_ptr has bad performance" "My implementation is more optimized than some std algorithm." "This printf is more readable than that libfmt stuff." etc. The fact is, developers, especially the smart ones probably, need to be prevented from making avoidable mistakes. You're building software that processes medical data. Or steers a car. Your promise to "pay attention" and "be careful" cannot be the safeguard against catastrophe.
- Cloudef 1y agoTo be honest, the generated machine code / assembly is often more readable than the actual c++ code in c++ stdlibs. So I can sympathize with the "This printf is more readable than that libfmt stuff." comment :)
- illuminator83 1y agoOh, they were not talking about the implementation of these things. Just the the user side: printf("Error: File `%s` in batch %d failed.", file.c_str(), batch) vs fmt::print("Error: File `{}` in batch {} failed.", file, batch) One of which is objectively safer and more portable than the other. They didn't care. "I like what I've been doing for the last 20 years already better because it looks better.". "No Its not because I'm just used to it." "If you are careful it is just as safe. But you gotta know what you are doing." And best of all - classic elitism: "If you are not smart enough to do it right with printf, maybe you shouldn't be a C++ programmer. Go write C# or something instead." The same person was not smart enough to do it right in many places as I've proven with a static analyzer.
- kennykartman 1y agoIf I had a penny for every time I heard that devs are not idiots, I'd be billionaire. It's true, but devs are not infallible and that's the point of Rust. Not idiots, not infallible either. IMO admitting that one can make mistakes even if they don't think they have is a sign of an experienced and trustworthy developer. It's not that Rust compiler engineers think that devs are idiots, in fact you CAN have footguns in Rust, but one should never use a footgun easily, because that's how you get security vulnerabilities.
- einpoklum 1y agoAh, sweet flame war fuel. Maybe we'll even get a tabs vs. spaces article next.
- rubiquity 1y agoThis blog is atrocious from an ad standpoint and the recent flood of posts feels promotional and intentionally controversial. The articles are also devoid of any interesting perspectives. Are people actually reading this?
- pjmlp 1y agoI love the irony to see the C crowd rediscovering Modula-2 and Object Pascal safety, through Zig. Apparently it isn't programming with a straightjacket any longer, like on Usenet discussions.
- anon-3988 1y agoi am sorry but how does point 1 and point 2 for safety work together? You don't want the program to corrupt your program but also does not want to immediately crash the moment some invariant is not being held? > Compile-time only: The borrow checker cannot fix logic bugs, prevent silent corruption, or make your CLI behave predictably. It only ensures memory rules are followed. Also not really true from my experience. There have been plenty of times where the borrow checker is a MASSIVE help in multithreaded context.
- bitwize 1y agoTwo words: Skill issue. The catgirls have no problems producing lots of great software in Rust. It seems more such software comes out every day, nya :3
- andrewshadura 1y agoDoes it?
- articulatepang 1y ago> Last weekend I’ve made a simple CLI tool for myself to help me manage my notes it parses ~/.notes into a list of notes, then builds a tag index mapping strings to references into that list. Straightforward, right? Not in Rust. The borrow checker blocks you the moment you try to add a new note while also holding references to the existing ones. Mutability and borrowing collide, lifetimes show up, and suddenly you’re restructuring your code around the compiler instead of the actual problem. I'd love to see the actual code here! When I imagine the Rust code for this, I don't really foresee complicated borrow-checker or reference issues. I imagine something like struct Note { filename: String, // maybe: contents: String } // newtype for indices into `notes` struct NoteIdx(usize); struct Notes { notes: Vec<Note>, tag_refs: HashMap<String, Vec<NoteIdx>> } You store indices instead of pointers. This is very unlikely to be slower: both a usize index and a pointer are most likely 64 bits on your hardware; there's arguably one extra memory deref but because `notes` will probably be in cache I'd argue it's very unlikely you'll see a real-life performance difference. It's not magic: you can still mess up the indices as you add and remove notes. But it's safer: if you mess up the indices, you'll get an out-of-bounds error instead of writing to an unintended location in your process's memory. Anyway, even if you don't care about safety, it's clear and easy to think about and reason about, and arguably easier to do printf debugging with: "this tag is mentioned in notes 3, 10 and 190, oh, let's print out what those ones are". That's better than reading raw pointers. Maybe I'm missing something? This sort of task comes up all day every while writing Rust code. It's just a pretty normal pattern in the language. You don't store raw references for ordinary logic like this. You do need it when writing allocators, async runtimes, etc. Famously, async needs self-referential structs to store stack local state between calls to `.await`, and that's why the whole business with `Pin` exists.
- erk__ 1y agoPointers to a vec could also be invalidated at any point when adding a new element and causing a reallocation (I think Miri will shout at you if you use a invalidated pointer here)
- carodgers 1y agoThis really misses a major point. If you write something in Zig, you can have some confidence in the stability of the program, if you trust yourself as a developer. If someone else writes something else in Zig, you have to live with the possibility that they have not been as responsible as you would have preferred.
- aidenn0 1y agoIndeed. The other day I was messing around with making various associative data structures in Zig. I stole someone else's benchmark to use, and at one point I ran into seriously buggy behavior on strings (but not integers) that wasn't caught at the point where it happened early even with -Odebug. Turns out the benchmark was freeing the strings before it finished performing all of the operations on the data structure. That's the sort of thing that Rust makes nearly impossible, but Zig didn't catch at all.
- mattwilsonn888 1y agoThis is true for every language. Logic bugs exist. I'll take good OS process isolation over 'written-in-Rust' though I wouldn't mind both. That being said, you've missed the point if you can't understand that safety comes at a real cost, not an abstract or 'by any means necessary' cost, but a cost as real as the safety issues.
- travisgriggs 1y ago> memory safety is one puzzle piece of overall software safety So this. We currently spent about a month carefully instrumenting and coming to understand a subtle bug in our distributed radio network. This all runs on bare metal C (samd21 chips). Because timing, and hundreds of little processors, and radios were all involved, it was a pita to surface what the issue was. It was algorithmic. Not a memory problem. Writing this in rust or zig (instead of straight C) would not have fixed this problem. I’d like to consider doing next generations of this product in zig or rust. I’m not opposed. I like the extra tools to make the product better. But they’re a small part of the picture in writing good software. The borrow checker may improve your code, it doesn’t guarantee successful software.
- GardenLetter27 1y agoNope, rust-analyzer is incredible whereas the Zig LSP felt worse than Go. I agree the borrow checker can be a pain though, I wish there were something like Rust with a great GC. Go has loads of other bad design decisions (err != nil, etc.) and Cargo is fantastic.
- seabrookmx 1y agoSyntactically speaking, Gleam fits the bill. It's very new/immature though and isn't in the same performance bracket since it runs on the BEAM.
- mackeye 1y agohow is its startup time? ive wanted to learn it or ocaml for a while and might take the plunge
- seabrookmx 1y agoI only wrote some toy programs in it, and it didn't jump out to me as an issue. I don't have any real data for you though, sorry!
- nmilo 1y agoI don't know why anyone would write CLI tools in rust or zig. I/O is going to be your bottleneck way more often than GC, in fact I don't really get the GC hate outside of game dev, databases and other memory intensive applications. Why not use Go, Python, etc? People try to make a false dichotomy between memory safety vs. non-memory safety when really it's GC vs. no GC --- memory safety without it is going to be hard either way. More time should be spent on justifying to yourself why you shouldn't be using a GC, and less on which kind of GC-less language you use. (If you go no GC "because it's fun" then there's no need for the post in the first place --- just use what's fun!)
- K0nserv 1y agoNot Python because getting Python to run on different machines is an absolute pain. Not Go because of its anaemic type system.
- seabrookmx 1y agoGo is a great option for CLI tools (even though I'm not a fan of the language itself). Python CLI apps can be a big pain to distribute if you have a bunch of dependencies. I think this is also why Rust and Zig are also attractive.. like with Go it's easy to create a statically compiled binary you can just cp into /usr/local/bin.
- astrange 1y ago> in fact I don't really get the GC hate outside of game dev Most mobile games are implemented in a system with GC (Unity with il2cpp), and it's not even a /good/ GC, it's Boehm.
- pjmlp 1y agoAnd if not, they are probably written in a mix of Koltin/Java/NDK, or Objective-C/Swift with ARC (chapter 5, https://gchandbook.org/contents.html https://gchandbook.org/contents.html).
- shmolyneaux 1y agoInstant startup times are really nice. You definitely notice the difference. It also means that you can be a bit lazier when creating wrappers around those tools (running 1000's of times isn't a problem when the startup is 1ms, but would be a problem with 40ms of startup time). Distribution can also be a lot easier if you don't need to care about the user having a specific version of Python or specific packages available.
- K0nserv 1y agoI mostly don't agree with this take. A couple of my quibbles: "Cognitive overhead: You’re constantly thinking about lifetimes, ownership, and borrow scopes, even for simple tasks. A small CLI like my notes tool suddenly feels like juggling hot potatoes." None of this goes away if you are using C or Zig, you just get less help from the compiler. "Developers are not idiots" Even intelligent people will make mistakes because they are tired or distracted. Not being an idiot is recognising your own fallibility and trying to guard against it. What I will say, that the post fails to touch on, is: The Rust compiler's ability to reason about the subset of programs that are safe is currently not good enough, it too often rejects perfectly good programs. A good example of this it the inability to express that the following is actually fine: struct Foo { bar: String, baz: String, } impl Foo { fn barify(&mut self) -> &mut String { self.bar.push_str("!"); &mut self.bar } fn bazify(&self) -> &str { &self.baz } } fn main() { let mut foo = Foo { bar: "hello".to_owned(), baz: "wordl".to_owned(), }; let s = foo.barify(); let a = foo.bazify(); s.push_str("!!"); } which leads to awkward constructs like fn barify(bar: &mut String) -> &mut String { bar.push_str("!"); bar } // in main let s = barify(&mut foo.bar);
- deleted 1y ago[deleted]
- Svoka 1y agoLooking at your code I have more confidence that quoted statement is false.
- K0nserv 1y agoWhich statement and why? The code is obviously stupid and convoluted because I threw it together in a minute to illustrate a point.
- dayvster 1y agothis is an excellent example do you mind if I examine it a bit closer and perhaps use it in my article?
- Svoka 1y ago[flagged]
- Someone 1y ago“Rust lifetimes can be chore, so use a C-like language that requires you to manage them in your head” Weird that they don’t consider other options, in particular languages with reference counting or garbage collection. Those will not solve all ownership issues, but for immutable objects, they typically do. For short-running CLI tools, garbage collecting languages may even be faster than ones with manual memory management because they may be able to postpone all memory freeing until the program exits.
- quotemstr 1y agoI'm still having a hard time understanding who is supposed to use Zig. If I don't need absolute best performance, I can use GC-ed systems like Node, Python, Go, OCaml, or even Java (which starts fast now thanks to Graal AOT) and enjoy both the safety and expressive power of using a high-level language. When I use a GCed language, I don't have to worry about allocation, lifetimes, and so on, and the user gets a plenty good experience. If I need the performance only manual memory management can provide (and this situation arises a lot less often than people think it does), I can justify spending the extra time expressing my thoughts in Rust, which will get me both performance and safety. Why would I go to the trouble of using Zig instead of Rust? Zig, like Rust, incurs a complexity and ecosystem cost. It doesn't give me safety in exchange. I put in about as much effort as I would into a Rust program but don't get anything extra back. (Same goes if you substitute "C++" for "Rust".) > All it took was some basic understanding of memory management and a bit of discipline. Is the idea behind Zig just that it's perfectly safe if you know what you're doing --- therefore using Zig is some kind of costly signal of competence? That's like someone saying free-solo-ing a cliff face is perfectly safe if you know what you're doing. Someone falls to his death? Skill issue, right? We have decades of experience showing that nobody, no matter how much "understanding" and "discipline" he has, can consistently write memory-safe code with manual memory management in a language that doesn't enforce memory safety rules. So what's the value proposition for Zig? Are you supposed to use it instead of something like Go or Python or AOT-Kotlin and spend more of your time dealing with memory than you would in one of these languages? Why? Or are you supposed to use it instead of Rust and get, what, slightly faster compile times, maybe? And no memory safety?
- dmytrish 1y agoSo far, most of Zig enthusiasts look to me like people who get sugar rush from writing fast native code and are ignorant (i.e. newcomers to system programming) or arrogant (e.g. long time C programmers stubbornly stuck in their ways) enough to think that memory safety is just a question of not writing stupid bugs. Or luddites that think that programs must always be simple enough to get memory safety right.
- pjmlp 1y ago
- Animats 1y agoHe has a point. Backlinks in Rust are too hard. You can do them safely with Rc, Weak, and RefCell, and .borrow(), but it's not trivial. If your program runs for a short time and then exits, arena editing is an option. That seems to be what the author means by "CLI tools". It's the lifetime, not the input format. "Rust is amazing, if you’re building something massive, multithreaded, or long-lived, where compile-time guarantees actually save your life. The borrow checker, lifetimes, and ownership rules are a boon in large systems." Yes. That's really what Rust is for. I've written a large metaverse client in Rust, and one of the regression tests I run is to put an avatar in a tour vehicle and let it ride around for 24 hours. About 20 threads. No memory leaks. No crashes. That would take a whole QA team and lots of external tools such as Valgrind in C++, and it would be way too slow in any of the interpreted languages.
- hadlock 1y agoI wrote a physics-accurate flight sim in rust that takes in to account the curvature of the earth and local gravitational fluctuations, it has two tests, one is to fly SFO-Sacramento-Seattle about a 5 hour "flight" at 60 frames per second, the longer one is to fly SFO to Tokyo about 22 hours; it has never once crashed or had a memory leak, it has always worked flawlessly. In 7 years of writing rust I've only ever had a handful of crashes, mostly when writing my own 2d software renderers. The only time I touch C or C++ these days is fixing legacy stuff.
- 12_throw_away 1y ago> I wrote a physics-accurate flight sim in rust Off-topic - that sounds amazing, is this commercial or hobby software? Any way I could learn more about it?
- atonse 1y agoYeah seriously, I was also intrigued by it!
- deleted 1y ago[deleted]
- efnx 1y ago> You’re constantly thinking about lifetimes, ownership, and borrow scopes, even for simple tasks. As a professional Rust developer, I don’t find I do this. I occasionally think of those things. But I do remember a short adjustment period when I was learning Rust that I would get frustrated by the borrow checker. Of course, that’s it doing its job!
- dpc_01234 1y agoThe title is about CLI tools, then it seems like bunch of cope about borrow-checker-phobia. I would actually be interested in a honest comparison of a Rust CLI program using clap, duct and some other standard CLI handling libraries with their Zig equivalents. Show the code side by side, how much boilerplate each requires. Then compare how quickly they compile in debug and release mode, how fast they start, how big the binaries are after stripping, stuff like that.
- daft_pink 1y agoI think the underlying question is why move to Zig from a C variant? There is a lot of research showing that a high percentage of security bugs are from memory safety issues across many different studies. I believe this is why people are pushing moving to Rust. However, if you don’t get the memory safety in Zig. Why bother moving from your existing coding language? Why not just not learn a new language and code where you are?
- mattwilsonn888 1y agoI don't use Zig, but I can answer your questions: Because Zig is a better language across the board. And that includes safety. You can have a language that doesn't do heavy static-analysis like Rust which still makes safety a lot easier than C/C++. Memory safety is not even a flaw of C/C++, it's a tradeoff. That being said, even if memory-safety was a 'feature' (rather than a tradeoff, and yes, Rust did a better job minimizing the trade than GC or FP languages), it's not the only feature.
- bsder 1y ago> I think the underlying question is why move to Zig from a C variant? Null pointers disallowed by default. Slices. Superb cross-compilation. Easy C interop. Comptime instead of C preprocessor. There are lots more. The problem Rust is up against is that the number of people who want Rust simply because of "strict typing" far, far, far outnumbers those who care about safety or speed. And that leads to the issue that most people really should be using a GC language like OCaml rather than Rust. Unfortunately, the OCaml ecosystem ... :(
- vanyle 1y agoFor CLI tools, the program usually only executes for a few seconds and then returns. In this context, you don't even need arena allocators or any memory management at all. You can write the tool in C with malloc and let the OS free the memory at the end without worry. You could argue with the reasoning that C feels more practical than Zig for real-world CLI tools. The argument provided by the author feels a bit besides the point.
- NielsAndersen67 1y agoI have been writing Rust code for 3.5 years. I never fight the borrow checker. The ownership rules are a blessing, when ever the compiler yells at me, then I know I am doing something that would have caused a seg fault i. C. It took a little while to get used to Rusts syntax, but once I got it, it was the best programming language I have ever used. It is just so beautiful how it enables multi threading and ensures that all errors are handled.
- godshatter 1y agoI'm a C programmer who has tried to move to other languages, but I keep coming back to C for a few different reasons. It's a small language and I can keep it in my head along with much of the standard library and that's very useful. I've learned where to step to avoid most of the UB pitfalls and I've learned to simplify memory management as much as possible to avoid lifetime and ownership pitfalls. I do realize that this doesn't get rid of bugs completely, though. Also, I started programming on a TRS-80 color computer with cassette tape storage and it still feels crazy to just do stuff and it allocates somewher and you have little control over what happens and some other process runs in the background that tries to clean up after you. I bounce off of languages (for hobby projects) with such a large list of features and with executable sizes that are so huge. I can't help it.
- massung 1y ago> Seasoned Rust coders don’t spend time fighting the borrow checker... Experienced Rust coders aren't going to find themselves in various borrow checker (and lifetime) pitfalls that newbies do, sure. That said, the borrow checker and lifetime do cause problems for even experienced Rust programmers. Not because they don't understand memory management, lifetimes, etc. But because they don't - yet - fully understand the problem being solved. All programs are an evolutionary process of developing a solution to a problem (or many problems). You think one thing, code it up, realize you missed something or didn't fully grok the issue, pivot, etc. Rust does a great job in the compiler of letting the user know if they've borked something. But often times a refactor/fix in C/D/Zig due to learned (or new) requirements is just a tweak, while in Rust it becomes a major overhaul because now something needs to be `mut` or have a lifetime added to it. I - personally - consider that "fighting" the borrow checker, regardless of how helpful (or correct) it also is.
- HackerThemAll 1y ago> whereas Zig has good developer ergonomics and allows me to produce memory safe software with a bit of discipline C also allows to produce memory safe software with a bit of discipline. This "bit of discipline" is the issue here which developers are lacking.
- pjmlp 1y agoIt must be harder than Shaolin discipline, given the failure after 50 years.
- davemp 1y agoThere are levels here, Zig addresses: - out of bounds access (70% of CVEs) - nullptr dereferences - type safety issues That’s massively better than C. Preventing use after free errors requires much less discipline than never missing a boundary or bungling a signed/unsigned conversion. Zig also has a knock your socks off incredible cross platform build system, empowers some really nice optimizations/ergonomics with comptime, has orders of magnitude faster build times that C++/rust. Zig is still < v1.0 so standard library could use some work and there are other warts, but I think it will be a great choice for performance oriented programs in the future.
- lerno 1y agoI find some of Rust dev reactions to this article pretty embarrassing. As if memory safety was some holy grail only provided by Rust. Here is a bunch of more memory safe languages that are more popular than Rust: Python, Java, JS ... should I continue? But wait, there's more. Can Rust verify that arbitrary in-data is valid, like having contracts statically checked at compile time? It can't, and so then by the same logic as some people calling non-Rust languages "gibberish" for not having a borrow checker, should we call Rust "gibberish" because it can't check those invariants at compile time like C3 can do? No? Then get off that high horse. And by the way, my great fear is that we'll get more adoption by Rust while at the same time Rust is unable to improve the compile times. C++, Swift and Rust, the three horsemen of infamously long compile times. The borrow checker isn't the main problem, just like C++'s problems isn't complex template messages – it's that both takes so long to compile. Time you could spend reading and testing the code. Long compile times inhibits refactoring and cause bugs to stay unfixed.
- simonask 1y agoThe point about "gibberish" is getting at a fundamental misunderstanding that people have about Undefined Behavior. Rust's concept of "safety" really means "absence of Undefined Behavior". Lots of people don't seem to understand that C, C++, and Zig programs containing UB are gibberish - they are not C, C++, or Zig programs, but something else entirely. The key insight here is that in any language, UB invalidates the entire program. It no longer does what you think it does, your tests are all moot, and so on. But a lot of people seem to think that there is an acceptable amount of UB in any code base. There isn't. UB is a concept that exists for every language, even languages like Python, Java, C#, JavaScript, but those languages make it very hard to encounter accidentally. Before Rust, there was no way to guarantee the absence of UB without a significant runtime cost, so that's a very meaningful invention.
- buggymcbugfix 1y agoOP: Rust feels impractical. ATS: Hold my beer.
- YmiYugy 1y agoZig is pretty neat. Compiles quickly, integrates nicely with C and its sdtlib was designed with explicit allocators in mind. It's a perfectly fine choice for building small CLIs, but many of the criticisms of rust just don't land right of me. Let's go through some slightly exaggerated interpretations of them. 1. Relying on the compiler for memory management makes you a bad programmer: Every skill has its applications, but having a compiler that ensures memory safely (for the most part) changes what is required of a good programmer and being able to safely manage memory by hand is less important. 2. The borrow checker is all or nothing: If you use unsafe or turn your memory bugs into logic bugs by using indexes you do miss out on safety guarantees of the borrow checker, but a) Rust has other compelling features, e.g. pattern matching, parametricity, b) Zig/C safety doesn't hold up better when doing things that require unsafe in Rust, c) the unsafe use and index wrangling can be encapsulated. The rest of your code can use the borrow checker just fine. 3. But safety is more than memory safety: Of course there is. I think this is a bit of a straw man argument, because I don't think that's a common claim the rust community let alone the foundation makes. 4. Rust strongly encourages you to structure your code around the compiler: I think this claim is valid, but I want to dispute that this is such a bad thing. You are probably a log smarter than the compiler. So you need to dumb it down, so the compiler will understand. Code that requires less brain power to understand is usually good. I've had some experiences where the borrow checker guided me to find a nicer structure for my code. The learning curve however is real. It takes a lot of time to build the intuition around the borrow checker and not run head first into it all the time. IMHO for small CLI tools it's fine to clone your way out of a dead end, even if it seems ugly.