As a Rust person, this was a fun fascinating step through the zig code, where it feels simultaneously foreign and familiar... like the two are sharing some of the same spirit, except Zig is maybe the spicier little sibling.
I think the Zig version will become way more easier in the future, because there will probably be more matured frameworks that will do a bigger part of the job for you and the standard library, as well as the build tools might also bring more features build in. IMHO it's not a really fair comparison between a page based on a framework like Axum and with all the already matured build tools of Rust and this very rudimentary server in Zig and it's still relatively early status concerning showing the general capability of the languages. And no, I'm no Zig-Fanboy, I've got no experience using it and only learned a few basics in Rust. But it's just logical that Rust is easier to use for that purpose, since Rust is more mature, has more build in functionality and more mature frameworks, since it's older and way more people work on it. The first stable release of Rust existed already 10 years ago, while the work on Zig hasn't even effectively started back then.
I get what you're saying but he didn't really use any extra functionality in Axum that wasn't present in the Zig framework. All of the differences he talks about actually are actually language differences. Locking is that way in Rust because of Rust, not Axum, and Zig's string formatting is better from allocation perspective because of Zig, not the framework.
I am still learning Rust. These smart pointers look complicated. This is the point of learning where I am. Thank you for sharing. Your videos are very valuable to me.
The trick to really understand Rust and its features is to first understand why they exist in the first place. Many smart pointers exist to highlight and solve ownership or memory safety problems. In my experience, learning rust is a great opportunity to really think about why your code is structured the way it's structured. It really highlights some fundamental lower level details that don't often get much attention and are easy to get wrong, hence why so many security vulnerabilities and bugs are found in software written in unsafe languages. Even if you don't end up developing rust applications, the journey of thoroughly learning rust is an incredible self-improvement experience. I find that now, after a few years regularly writing rust, I feel much more confident developing code in other non-safe or higher level languages and I tend to think more about memory management, ownership, and all those minute but crucial details that rust forces you to consider. Good luck with your journey and remember, if the rust compiler yells at you, it's usually worth listening to because there may be subtle low level details you haven't thought about.
The ultimate video should be Rust vs Zig vs Go vs Node vs Python. It will be a lot of work thou ^^ I'm working with Odin in a simple game now, it's been a pleasure to work with, I may try to see if I can setup an http server
that would be a fun comparison indeed! might be hard to make it shorter than 1 hour though 😎 I keep hearing great things about Odin, really hoping I get time to explore it more...
I find it easier to read zig code then rust macro. Most dev think rust is easy, magic is hidden away in macro and syntax, rarely need to change anything. If someone needs to tweak and change something like say Tokio and other libs, and optimize for specific use cases, it's much harder to comprehend and reason about with rust. For cases unsafe is required, zig is much better in ergonomics.
1. what's so difficult about reading the format! macro compared to zig? it's literally the same. 2. Most devs don't think Rust is easy. Ever heard of life times? 3. Syntax of nearly every programming languages hides away magic, see also Zig's try, error, optional, format strings, etc. But Rust also makes things visible in Syntax, namely lifetimes, the lifetime of objects, data availability in mutexes 4. "For cases unsafe is required, zig is much better in ergonomics." Rust is safety first after all
I dont use any language constructs, they hide the magic of the raw OP codes. I write binaries by hand . This way I have FULL control over the program, which is especially important for writing my Todo WebApp for my 10 users
@ClimateChangeDoesntBargain Jep, people don’t have to agree with you, if you prefer rust and best choice for your use cases, by all means all the power to you. There are no universal truth regarding any programming language. If you like it doesn’t mean everyone need to like it as much as you do. Life and tech are about trade off and balance, less about ideology and preferences.
@@NabekenProG87 Yes, you should probably write compiler and javascript engine for your 10 users. And you will learn a ton by doing so, better skill and more paid. Can't se the down side. Or you can go the easy way with React, Svelt, Htmx etc. and other thousand JS libs, without understand what's running under the hood. I heard now and days LLM is half decent and spit out react code out of the random.
Interesting video for me that makes me realize that zig is not for me, especially for the kind of applications that I usually work on. Zig and Rust are really the modern versions of C and C++ respectively at least regarding the manual vs automatic memory allocation/deallocation. I prefer to follow the Rust strict rules even through it forces redesign sometimes than managing memory myself.
Those languages are very different in terms of what they focus on. The main focus of Rust is safety while Zig main focus is performance and control (same as C and C++). Zig promises simple, always readable code that will allow the user to make the most out of the resources of their computer. Safety to Zig should never stop the programmer from making what they want to make. Rust promises safety and high level code/ergonomics, that will allow users to write compiled code without fear of memory errors. Performance to Rust should never be prioritized over safety guarantees. My point is that there is more difference between Zig and Rust than between C and C++, because C and C++ are "performance first" languages while Rust really takes the "safety first" which makes a lot of differences in design.
Hey! I didn't know you left Emacs. Are there any particular reason? I'm still using it for Org mode and other stuff I do in there, like email, but was considering a switch.
@@codetothemoon Also considering switch to zed. Really like it. I have made it work very close to my LazyVim setup. Especially like multibuffer editing.
I switched from vscode to zed a few months ago and I don't regret it. Developing rust code in Zed is a great experience and the editor is blazingly fast even when working with big codebases, as opposed to vscode which can be frustratingly slow. As far as I know, Zed doesn't currently support debugging and for that I spin up vscode on the fly. Fortunately, as a Rust developer I don't need to use a debugger very often. Sometimes you encounter minor issues with new versions of Zed, but the community is very active and a fix is usually available in a short time. I tried Zed on a dinosaur Intel Atom 2gb ram with no GPU and it ran flawlessly (a terminal session and brave browser were running at the same time).
The use of a lazy lock seems fairly non idiomatic and makes this a bit more complicated than it should be if you were using state extractors instead. Probably the simplest useful type to use here would be an Arc wrapping a Dashmap. It would be good to actually show the path handling for this too rather than just one item.
Great point. I actually had it implemented using an Arc and Axum shared state originally, but the Zig implementation didn't have the superfluous reference counting, so I wanted to remove it in the Rust version for a more apples to apples comparison. The requirement that Axum shared state be reference counted always bothered me, because in most cases said shared state is effectively 'static, making reference counting pointless.
Really nicely done and very fair video, there are some realities when dealing with either Rust or Zig that's important to recognize and you rarely hear them described like this in one video
Been using zig for a few projects now and I still can't fully wrap my mind around it sometimes. That said, I've been trying to learn Rust for a while too and it makes even less sense to me :D Maybe I should just stick to my beautiful syntax-sugar-packed languages like Kotlin (which can compile to native code as well, btw, making it very comparable to Go)
I feel like borrow checker for this kind of application is easier to handle than all those different types of allocators. But also I havent used Zig, so i dont know how easy or hard it is to accidentally make memory leaks in Zig.
Both zig and rust here use the same underlying setup - a small pool of os threads, each handling multiple concurrent connections using async io You can see from Anton’s test that they both perform much the same (ie - they both exceed the best Go/Java/whatever backends)
I actually set out to use zzz for this experiment, but had to pivot when I couldn't quite get things working. After speaking with the author I think it turned out that the issues were on my end, but at that point I was already too far along with http.zig
Having about the same amount of experience in both (quite little, both in context of simple game development), I see that zig sacrifices brevity for explicitness while rust seemingly wants to be C++ 2. I might have to give zig another try, seeing it comes with C support out the box.
@ i am a data scientist, developing ML solutions and data pipelines, sometimes also REST APIs and web backends - with Python. I also know R quite well and I can develop R functions in C++ with Rcpp. For a while, I keep thinking on - what language shall I implement fast Python algorithms if I need to? (And sometimes I need to.) The obvious choices are pure C or Cython (this is the base case); or Rust with PyO3; or C++ with nanobind or pybind11. Or just Zig! I learnt only a couple days ago, that there is a python package ziglang, which installs Zig, the compiler etc. and it is also super easy to develop Python packages in Zig. => So my primary use case is developing Python packages. The secondary use case for me is a REST API, which I develop today with FastAPI or DRF; but Rust could also be a good idea here thanks to polars and axum or actix.
I implemented RDS using Rust CGI. The technology is really old, similar to HTMX. Certainly, it would be cool also using ZIG CGI. I will consider to make a presentation too. Damn, why I found your video too late, so I had to use own HTML encoding and a template engine. Should I switch to yours implementations or continue using mine? I guess you can't suggest.
Thanks for a great video. Rust may require a different approach to development which may feel uncomfortable at first, but it looks a lot more elegant than Zig. I just don't understand why the user needs to defer memory deallocation. It seems antiquated. What happens if I send that variable to another thread and then deallocate due to defer? I assume a segfault? The fact that the faulty code compiled is scary.
Try it again .. this time take an arbitrary struct of any type, and render a working input form for the fields of that struct, and on POST populate an object of that same arbitrary type. You could do it easily in Go using runtime reflection. It would be trivial in Zig using comptime. You could do in Rust if you rolled your own macro. If you did that, you would get a much better feel for the differences between the languages.
I agree. I'm still learning Rust at the basic level. Is there anything in Rust that is similar to JsontNode in the Java Jackson library (it's a class that can be mapped to any json string)?
I've been writing Zig for about 3 years, it's obviously the opposite for me. Typically Zig isn't written on long lines like that though, it looks a lot better when you break long function calls across several lines. Zig fmt does it for you as long as you use a comma on the last argument
@@codetothemoon it's not really a matter of being open minded or not in my opinion. it's more of a fact. using a low level language for high level tasks is going to be inherently more challenging. the lower level the language the more difficult and annoying it is going to be. that's pretty much why all web languages are garbage collected.
Having just rewritten a large finance/ERP web based app from Go to Zig over the last 18 months, I don’t necessarily agree with that conclusion (that there is no point doing web apps in low level tools) Aside from the fact that it runs a bit faster and uses practically no memory- an unexpected outcome is that the whole app has less than half the lines of code compared to the go app. Zig gave us the ability to build abstractions that are mostly declarative instead of the reams of imperative code that Go needs. Our typescript devs have no problem following the zig implementation, but struggle to grok the original go code
@ i never said there wasn't a point in using low level languages for web apps. i was talking about zig specifically. if you're going to go down that route then it would make sense to choose a low level language that's less difficult for those kinds of things. andrew designed zig to be a c replacement and have seamless c interop. that's as low level as it gets. swift and rust are much better for those specific tasks from a practical standpoint because they're not as low level. they have different memory management models that are more similar to garbage collection.
I think on some points zig looks more like c++ than rust. For example for the RwLock, in zig like in c++ you have to lock it manually. While it gives more freedom, I think it's way too easy to forget it, and later it could break something. I know it's skill issues, but if there wasn't any skill issue the term "debugging" wouldn't exist
Having to manually deal with memory allocations and defer just seem antiquated when compared to Rust's memory managment. I'm not really sure what Zig is going for here, it just seems like a step backwards
For most use cases I agree. I'm still trying to process and fully understand anecdotes from people like Primeagen and Mitchell Hashimoto who seem to prefer Zig because they didn't enjoy using Rust. I feel like there is something there that I haven't fully understood yet. Maybe it is in part because I haven't worked on any truly "large" Rust projects yet.
First of all, Zig is just "better C" - that's why you are doing manual allocations/dellocations. Second of all, Rust is like a really hot girl with ugly face - why aren't lifetimes automatic? Why do I have to sometimes move a thing into a local variable if I want to use it in a loop? and probably couple more things if you do some async code
not having the borrow checker and stuff like this leads to a larger number of possible solutions for a problem - want to lock something in once place and handle the jnlocking in another? sure, fo ahead without foghting the compiler, it may be a stupid idea, but sometimes that can make sense in a project
@@Qrzychu92 Lifetimes are not automatic because the program analysis required to ensure safe memory use without some help with annotations is an unsolved problem in computer science. Perhaps you could earn a Phd solving that problem.
Maybe I'm missing something but I fail to see Zig's advantages compared to say the C++ I was using in 1995... At least there I could use a destructor to release a lock when the variable goes out of scope... 😅
Yeah for those that view said automatic releasing of locks as must-haves, Zig seems to be the wrong choice. But not everyone views this as essential...
Zig supports compile-time execution, can build Zig, C and C++ for any platform without installing additional toolchains, has arbitrary-width integers, bit-packed structs, differentiation between single, multi and sentinel-terminated pointers, naked and custom calling conventions, fast compile times, a very powerful build system and more Is that what using C++ in the 90s was like? Zig is a very explicit language, that's why it doesn't have destructors
@@codetothemoon true, but that’s also true for almost every other language out there. If you have operations that must be tightly coupled (such as updating a person record whilst holding a lock over it), then most languages would encourage you to build a safe abstraction around the person object that does just that. Idiomatic safe Rust code doesn’t always translate well to other languages if you do it line for line. You have done a good job illustrating that with a simple example :). You can provide the same safety in Java / go / js / python / zig for example, but the onus is on the author to bake it into the code structure rather than have the type system enforcing it automatically. Different paths to achieve the same end, Horses for courses. You can do lock safety wrong in Rust as well, but the language will fight back hard and make it painful. It won’t totally prevent you from writing unsafe code, but it will give enough pain to cue you in that you are going about it the wrong way. When you start doing it the right way and let the type system do the hard work, your code becomes elegant and fun to write. Similarly with Zig and allocators - because allocations are right in your face all the time, you get immediate pain feedback if you are going about things inefficiently. You can either push through and write a tonne of messy boilerplate, or rethink how you are managing memory resources. The more efficient your method, the cleaner and more elegant the code. Nice ! Programming languages are as much about being feedback devices as they are coding tools. Get good at Rust, and you will be better at writing safe code in any language. Get good at zig, and you will write way more efficient code in other languages. Get good at Erlang, and you will design fault tolerance in any other system you build, etc.
@@mgord9518 thanks, those are interesting features for some use cases. Still I can't get the people that compare Zig to Rust for things like safety and correctness, that are my main 2 reasons I started using Rust.
- chooses two of the fastest languages for the backend - also chooses the stupidest library to develop the frontend, which makes a web request for every user interaction instead of using browser’s capabilities
Just to let you know, if you don't use a template engine for your server sided html, you might lose an offer. I did one technical interview for htmx with node and didn't feel like I should use any. During the demo I showed the code and mentioned I saw the most popular template libs but did not want to use it for this small demo and the eng on the other side said yeah we are using that. I'm 90% sure that decision of laziness cost me that opportunity.
sorry but this comes off as an inexperienced guy trying to explain to his viewers why their favorite programming language is still the best. You wouldn't write a high level web server in Zig in the same sense that you wouldn't write it in C. Sure, Rust might seem easier on the surface if you already know the complexities of the language, but you're missing the point of Zig. Try actually doing something systems or low level related. Write a doubly linked list in Zig and Rust. Write a GUI framework in both. Write a simple garbage collector. Write something cross platform that interfaces with the native OS APIs. Then you'll see the appeal of Zig. This is just a lazy attempt at jerking rustaceans. You clearly have no idea how Zig works.
This comment comes out as a bit rude, but I do agree that this is not Zig's field. As a Rust developer who works on compilers and virtual machines, I find Rust a great language to work on low level code. However, I'm sometimes forced to use unsafe blocks because I'm managing memory myself. I still like the low level Rust experience despite the verbosity, but I do also understand the appeal of simpler languages that shine in this specific field like Zig.
Zig is cool when the alternative is C/C++. But, its somehow so unreadable and verbode at the same time. Rust most of the time is easy to read and with macros the verbose stuff can just be moved somewhere else. Yeah you can abuse it but still, Rust feels way more productive and actually fun. Not sure about Zigs compiler, but after having used Rust for over a year I couldn't write Python anymore. No compiler which directly fails, no guarantees, hated it :D
Rust feels very polished as long as you stay in the bounds of the API the library author crafted for you. It holds your hands along every step of the way. Thats what I love about it. I think thats a good thing for most use cases, but of course the memes a out livetimes are not without reasons
It's funny for me it's the exact opposite, I really find Zig to be easy to read, I don't know there is really nothing hidden from you, it's just there I never get surprised. I like Rust too, but sometimes I try do to something, look at functions and traits, and it's full on macros, and I'm like, Ok not for me lol. But I get it it's very much like how I absolutely hate C++, and love C, and some people hate C and love C++.
@@TheMachina42Rust definitely appeals to the "kitchen sink" crowd while Zig appeals to people who like simple languages. I went from Go and C to Zig and found it very easy to pick up. Rust still looks like hieroglyphics to me and I find C++ unbearable
@@mgord9518 Yes to me it's the same, I've observed it many times, there is really two kind of developers, the Result based developer and the Craftsman based developer, Result based developer tends to like more abstractions, and work better with complexity, and Craftsman tends to prefer low abstraction, low complexity language. I understand the appeal of Rust, just like I understand why people still use that godforsaken atrocity that C++ is. But it's just not for me either.
One day I dropped a box of nails on the ground, barefoot, at night, in a room with the lights off. Guess which one of these two languages reflects the experience of going across the whole room to get to the lightswitch.
I'm pretty much with you for the most part. Though still keeping an open mind, curious to learn more from Zig fans, especially those who are also fluent with Rust
@@codetothemoon yep, I understand that completely, rather my comment goes to: even if there are some cool things in zig, and the compile time is much faster, still, for security reasons, I would not change. Rather I think that Rust should just work on its compile times and its static\const variables add what is missing, but that depends on the Rust foundation I guess... Security for me will always go first, either way.
the borrow checker can be a pain, but I would prefer that it call me an "idiot"... than pay the price later when my code fails and I get sued... I'lll stick with the borrow checker calling me a loser... jajaja
It would be interesting to try to mimic the arena allocation in the request handler in Rust. I think it could be more efficient as you probably can automatically reuse allocated memory for all requests, thus you save a few syscalls per request.
great idea! I think there are some Rust crates that implement Arena allocation, but I haven't tried them. I'd love to hear from the Axum/Actix folks about whether arena allocation is used under the hood, and whether it would make sense to expose those arenas to developers in handler functions like httpz does
@@codetothemoonBoth Actix and Axum depend on the global allocator, which, in case of Rust, would be whatever is provided by your system; for example malloc on *NIX platforms (macOS, Linux, etc.) and HeapAlloc on Windows. While you can change the global allocator (i.e. to jemalloc, mimalloc for Axum or SnMalloc for Actix), in the future versions of Rust you may be able to change the allocator for things like Vec and String, as well as implementing your own via a trait through the unstable `allocator_api` feature, or you can use the "allocator-api2" crate as a polyfill. So hopefully these APIs could take advantage of that in the future.
@@CalifornianViking complexity for the shake of complexity and challenge is quite moronic while not being business friendly Zig if far more productive and easier to maintain, 20 years down the line all programs written in Rust will be a nightmare to maintain. Simplicity and boring is what we should thrive for, just like Golang which is a boring language but it just works.
@@dranon0o - why do you say that Rust will be hard to maintain? In my view, it is a very structured and explicit language that tells the software engineer exactly what is wrong. I am not concerned about the maintainability of Rust. I am concerned about the maintainability of JavaScript, Python, C, C++, etc where there are so many traps that the developers don't even know exist. My biggest struggle with Rust was that my mind thought about memory management like C does it, and object orientation like Java and C#. Once I realized that C (and most other languages) handle memory wrong and that most other object-oriented languages are taking the wrong approach, then I saw that Rust was really simple and beautiful. Rust is not complex.
zig is beautiful language, they will bring async soon with some llvm detachment, and rust has no chance Zig: C/C++ interoperability Even more control over memory, no hidden control flow Comtime > Rust macros No stupid lifetimes No confrontations with borrow checker More transparent foundation Faster compilation(incremental compilation is coming)
I think that Zig does not compete with Rust. People write Rust because they do not want to think about allocations much if at all while still having a high degree of speed and safety, also the ability to encode alot of information about your program in its type system. Peope write Zig because the want to have the ability to control every minute detail of the computer, which sometimes is necessary but brings also a very high degree of mental burden with it. You have to think about alot of things more than in rust, less than in C but still alot.
You raise some great points - from what I've seen of comptime, so far I think I'm going to like it better than Rust procedural macros. This video topic didn't lend itself to that comparison, but I definitely should have mentioned Zig's faster compilation. It's really nice.
@@codetothemoon Rust macros and Zig comptime serve different purposes. Why everybody compares them? Primary goal for macros is code generation by taking an input and based on it producing output, and comptime is evaluating some expressions in compile time. And "stupid lifetimes", "No confrontations with borrow checker", no those are not great points. If anyone has no idea why lifetimes exist in Rust and borrow checker is an issue, than they should not write any code in none of the non GC languages, and none of the parallel and concurrent code in any language either.
The first 500 people to use my link skl.sh/codetothemoon01251 will get a 1 month free trial of Skillshare!
Need to provide credit card to get an account.
As a Rust person, this was a fun fascinating step through the zig code, where it feels simultaneously foreign and familiar... like the two are sharing some of the same spirit, except Zig is maybe the spicier little sibling.
really happy you liked it! I like your perspective.
I think the Zig version will become way more easier in the future, because there will probably be more matured frameworks that will do a bigger part of the job for you and the standard library, as well as the build tools might also bring more features build in. IMHO it's not a really fair comparison between a page based on a framework like Axum and with all the already matured build tools of Rust and this very rudimentary server in Zig and it's still relatively early status concerning showing the general capability of the languages. And no, I'm no Zig-Fanboy, I've got no experience using it and only learned a few basics in Rust. But it's just logical that Rust is easier to use for that purpose, since Rust is more mature, has more build in functionality and more mature frameworks, since it's older and way more people work on it. The first stable release of Rust existed already 10 years ago, while the work on Zig hasn't even effectively started back then.
I get what you're saying but he didn't really use any extra functionality in Axum that wasn't present in the Zig framework. All of the differences he talks about actually are actually language differences. Locking is that way in Rust because of Rust, not Axum, and Zig's string formatting is better from allocation perspective because of Zig, not the framework.
I am still learning Rust. These smart pointers look complicated. This is the point of learning where I am. Thank you for sharing. Your videos are very valuable to me.
The trick to really understand Rust and its features is to first understand why they exist in the first place. Many smart pointers exist to highlight and solve ownership or memory safety problems. In my experience, learning rust is a great opportunity to really think about why your code is structured the way it's structured. It really highlights some fundamental lower level details that don't often get much attention and are easy to get wrong, hence why so many security vulnerabilities and bugs are found in software written in unsafe languages. Even if you don't end up developing rust applications, the journey of thoroughly learning rust is an incredible self-improvement experience. I find that now, after a few years regularly writing rust, I feel much more confident developing code in other non-safe or higher level languages and I tend to think more about memory management, ownership, and all those minute but crucial details that rust forces you to consider. Good luck with your journey and remember, if the rust compiler yells at you, it's usually worth listening to because there may be subtle low level details you haven't thought about.
Writing a web frontend in Zig is the most glorious overkill ever.
It's the backend being written in Zig 😎
But the statement is still true 🤓
@@summerWTFE you're telling me you dont want safety and verbosity in your projects? thinkge
Today's web frontends are suffering from obesity, they very much need a magic potion like Zig.
The ultimate video should be Rust vs Zig vs Go vs Node vs Python. It will be a lot of work thou ^^
I'm working with Odin in a simple game now, it's been a pleasure to work with, I may try to see if I can setup an http server
that would be a fun comparison indeed! might be hard to make it shorter than 1 hour though 😎 I keep hearing great things about Odin, really hoping I get time to explore it more...
@@codetothemoon I would love to see you give Odin a try! I'll add +1 to the great things you're hearing about Odin
Add java in there and I'll do the Java part.
vs C# minimal apis
I find it easier to read zig code then rust macro. Most dev think rust is easy, magic is hidden away in macro and syntax, rarely need to change anything. If someone needs to tweak and change something like say Tokio and other libs, and optimize for specific use cases, it's much harder to comprehend and reason about with rust. For cases unsafe is required, zig is much better in ergonomics.
1. what's so difficult about reading the format! macro compared to zig? it's literally the same.
2. Most devs don't think Rust is easy. Ever heard of life times?
3. Syntax of nearly every programming languages hides away magic, see also Zig's try, error, optional, format strings, etc. But Rust also makes things visible in Syntax, namely lifetimes, the lifetime of objects, data availability in mutexes
4. "For cases unsafe is required, zig is much better in ergonomics." Rust is safety first after all
I dont use any language constructs, they hide the magic of the raw OP codes. I write binaries by hand . This way I have FULL control over the program, which is especially important for writing my Todo WebApp for my 10 users
@ClimateChangeDoesntBargain Jep, people don’t have to agree with you, if you prefer rust and best choice for your use cases, by all means all the power to you. There are no universal truth regarding any programming language. If you like it doesn’t mean everyone need to like it as much as you do. Life and tech are about trade off and balance, less about ideology and preferences.
@@NabekenProG87 Yes, you should probably write compiler and javascript engine for your 10 users. And you will learn a ton by doing so, better skill and more paid. Can't se the down side. Or you can go the easy way with React, Svelt, Htmx etc. and other thousand JS libs, without understand what's running under the hood. I heard now and days LLM is half decent and spit out react code out of the random.
@ For you it might be about you preferring Zig, however for me it's not about preferring Rust, but about your claims.
Interesting video for me that makes me realize that zig is not for me, especially for the kind of applications that I usually work on.
Zig and Rust are really the modern versions of C and C++ respectively at least regarding the manual vs automatic memory allocation/deallocation.
I prefer to follow the Rust strict rules even through it forces redesign sometimes than managing memory myself.
I'm with you. There's probably a use case for Zig, but so far for me it's definitely not web applications.
Zig is the C the sequel, but Rust is Rust.
Those languages are very different in terms of what they focus on. The main focus of Rust is safety while Zig main focus is performance and control (same as C and C++).
Zig promises simple, always readable code that will allow the user to make the most out of the resources of their computer. Safety to Zig should never stop the programmer from making what they want to make.
Rust promises safety and high level code/ergonomics, that will allow users to write compiled code without fear of memory errors. Performance to Rust should never be prioritized over safety guarantees.
My point is that there is more difference between Zig and Rust than between C and C++, because C and C++ are "performance first" languages while Rust really takes the "safety first" which makes a lot of differences in design.
Noticed you're on Zed now lol. Nice! How is it for you?
yeah I really like it so far! Not sure yet if it's my new daily driver, but it's a serious contender for the role!
Hey! I didn't know you left Emacs. Are there any particular reason? I'm still using it for Org mode and other stuff I do in there, like email, but was considering a switch.
@@joaol.galdino8738 🧬
@@codetothemoon Also considering switch to zed. Really like it. I have made it work very close to my LazyVim setup. Especially like multibuffer editing.
I switched from vscode to zed a few months ago and I don't regret it. Developing rust code in Zed is a great experience and the editor is blazingly fast even when working with big codebases, as opposed to vscode which can be frustratingly slow. As far as I know, Zed doesn't currently support debugging and for that I spin up vscode on the fly. Fortunately, as a Rust developer I don't need to use a debugger very often.
Sometimes you encounter minor issues with new versions of Zed, but the community is very active and a fix is usually available in a short time.
I tried Zed on a dinosaur Intel Atom 2gb ram with no GPU and it ran flawlessly (a terminal session and brave browser were running at the same time).
The use of a lazy lock seems fairly non idiomatic and makes this a bit more complicated than it should be if you were using state extractors instead. Probably the simplest useful type to use here would be an Arc wrapping a Dashmap. It would be good to actually show the path handling for this too rather than just one item.
Great point. I actually had it implemented using an Arc and Axum shared state originally, but the Zig implementation didn't have the superfluous reference counting, so I wanted to remove it in the Rust version for a more apples to apples comparison. The requirement that Axum shared state be reference counted always bothered me, because in most cases said shared state is effectively 'static, making reference counting pointless.
The GPA, mine’s lower than yours comment had me rolling 🤣
Really nicely done and very fair video, there are some realities when dealing with either Rust or Zig that's important to recognize and you rarely hear them described like this in one video
Been using zig for a few projects now and I still can't fully wrap my mind around it sometimes. That said, I've been trying to learn Rust for a while too and it makes even less sense to me :D
Maybe I should just stick to my beautiful syntax-sugar-packed languages like Kotlin (which can compile to native code as well, btw, making it very comparable to Go)
Reason to not choose Go over Kotlin?
@@shrin210you can make more money programming with kotlin
@shrin210 kotlin has some really nice syntax and a nicer type-system than go
@Iuigi_t
WAY nicer
Kotlin is a great language imo 😎
I feel like borrow checker for this kind of application is easier to handle than all those different types of allocators. But also I havent used Zig, so i dont know how easy or hard it is to accidentally make memory leaks in Zig.
with what I currently know, I'd agree. hoping to hear from Zig experts on this though!
@codetothemoon same, me too. We should just say Rust is better than Zig and they will be automatically summoned here
@@mr.togrul--9383ikr- so glad you agree
The Zig version relied on OS threads for requests whereas the Rust version was using async concurrency, right?
Both zig and rust here use the same underlying setup - a small pool of os threads, each handling multiple concurrent connections using async io
You can see from Anton’s test that they both perform much the same (ie - they both exceed the best Go/Java/whatever backends)
zzz framework is the fastest for zig, built on top io_uring, it's as low level as it can get.
I actually set out to use zzz for this experiment, but had to pivot when I couldn't quite get things working. After speaking with the author I think it turned out that the issues were on my end, but at that point I was already too far along with http.zig
Ah yes zzz the lib that is cheating at benchmarks 😂
@@RustIsWinning is it? how so?
Having about the same amount of experience in both (quite little, both in context of simple game development), I see that zig sacrifices brevity for explicitness while rust seemingly wants to be C++ 2. I might have to give zig another try, seeing it comes with C support out the box.
This video let me make a final decision between Rust and Zig: both. Thank you.
nice, so it depends on the project? what projects do you plan to use Zig for?
@ i am a data scientist, developing ML solutions and data pipelines, sometimes also REST APIs and web backends - with Python. I also know R quite well and I can develop R functions in C++ with Rcpp. For a while, I keep thinking on - what language shall I implement fast Python algorithms if I need to? (And sometimes I need to.) The obvious choices are pure C or Cython (this is the base case); or Rust with PyO3; or C++ with nanobind or pybind11. Or just Zig! I learnt only a couple days ago, that there is a python package ziglang, which installs Zig, the compiler etc. and it is also super easy to develop Python packages in Zig. => So my primary use case is developing Python packages.
The secondary use case for me is a REST API, which I develop today with FastAPI or DRF; but Rust could also be a good idea here thanks to polars and axum or actix.
I implemented RDS using Rust CGI. The technology is really old, similar to HTMX. Certainly, it would be cool also using ZIG CGI. I will consider to make a presentation too. Damn, why I found your video too late, so I had to use own HTML encoding and a template engine. Should I switch to yours implementations or continue using mine? I guess you can't suggest.
Thanks for a great video.
Rust may require a different approach to development which may feel uncomfortable at first, but it looks a lot more elegant than Zig.
I just don't understand why the user needs to defer memory deallocation. It seems antiquated. What happens if I send that variable to another thread and then deallocate due to defer? I assume a segfault?
The fact that the faulty code compiled is scary.
Try it again .. this time take an arbitrary struct of any type, and render a working input form for the fields of that struct, and on POST populate an object of that same arbitrary type.
You could do it easily in Go using runtime reflection.
It would be trivial in Zig using comptime.
You could do in Rust if you rolled your own macro.
If you did that, you would get a much better feel for the differences between the languages.
I agree. I'm still learning Rust at the basic level. Is there anything in Rust that is similar to JsontNode in the Java Jackson library (it's a class that can be mapped to any json string)?
great idea! comptime seems to be one of the main selling points of Zig, and this would have been a great way to work it into the video
@@codetothemoon The main selling point of Zig is that it segfaults 😂
The Rust code looks more readable than Zig's at first glance. However, this might just be because I program in Rust a lot.
I'd agree, but I also have the same prior bias as you. So I'm hoping some Zig experts will chime in here
I've been writing Zig for about 3 years, it's obviously the opposite for me. Typically Zig isn't written on long lines like that though, it looks a lot better when you break long function calls across several lines. Zig fmt does it for you as long as you use a comma on the last argument
it does not make sense to use zig for web apps. it's too low level. the borrow checker is more of a middle ground.
I'm still keeping an open mind. But for the most part I'd agree with you, with what I know now.
@@codetothemoon it's not really a matter of being open minded or not in my opinion. it's more of a fact. using a low level language for high level tasks is going to be inherently more challenging. the lower level the language the more difficult and annoying it is going to be. that's pretty much why all web languages are garbage collected.
Having just rewritten a large finance/ERP web based app from Go to Zig over the last 18 months, I don’t necessarily agree with that conclusion (that there is no point doing web apps in low level tools)
Aside from the fact that it runs a bit faster and uses practically no memory- an unexpected outcome is that the whole app has less than half the lines of code compared to the go app. Zig gave us the ability to build abstractions that are mostly declarative instead of the reams of imperative code that Go needs.
Our typescript devs have no problem following the zig implementation, but struggle to grok the original go code
@ i never said there wasn't a point in using low level languages for web apps. i was talking about zig specifically. if you're going to go down that route then it would make sense to choose a low level language that's less difficult for those kinds of things. andrew designed zig to be a c replacement and have seamless c interop. that's as low level as it gets. swift and rust are much better for those specific tasks from a practical standpoint because they're not as low level. they have different memory management models that are more similar to garbage collection.
What editor is this?
Zed. Been using it for about a week. Haven't made any decisions yet but it seems really nice so far.
I think on some points zig looks more like c++ than rust. For example for the RwLock, in zig like in c++ you have to lock it manually. While it gives more freedom, I think it's way too easy to forget it, and later it could break something. I know it's skill issues, but if there wasn't any skill issue the term "debugging" wouldn't exist
Having to manually deal with memory allocations and defer just seem antiquated when compared to Rust's memory managment. I'm not really sure what Zig is going for here, it just seems like a step backwards
For most use cases I agree. I'm still trying to process and fully understand anecdotes from people like Primeagen and Mitchell Hashimoto who seem to prefer Zig because they didn't enjoy using Rust. I feel like there is something there that I haven't fully understood yet. Maybe it is in part because I haven't worked on any truly "large" Rust projects yet.
It's a systems programming language, of course it's not productive if you use it to make a website. A game on the other hand...
First of all, Zig is just "better C" - that's why you are doing manual allocations/dellocations. Second of all, Rust is like a really hot girl with ugly face - why aren't lifetimes automatic? Why do I have to sometimes move a thing into a local variable if I want to use it in a loop? and probably couple more things if you do some async code
not having the borrow checker and stuff like this leads to a larger number of possible solutions for a problem - want to lock something in once place and handle the jnlocking in another? sure, fo ahead without foghting the compiler, it may be a stupid idea, but sometimes that can make sense in a project
@@Qrzychu92 Lifetimes are not automatic because the program analysis required to ensure safe memory use without some help with annotations is an unsolved problem in computer science. Perhaps you could earn a Phd solving that problem.
Maybe I'm missing something but I fail to see Zig's advantages compared to say the C++ I was using in 1995... At least there I could use a destructor to release a lock when the variable goes out of scope... 😅
Yeah for those that view said automatic releasing of locks as must-haves, Zig seems to be the wrong choice. But not everyone views this as essential...
Zig supports compile-time execution, can build Zig, C and C++ for any platform without installing additional toolchains, has arbitrary-width integers, bit-packed structs, differentiation between single, multi and sentinel-terminated pointers, naked and custom calling conventions, fast compile times, a very powerful build system and more
Is that what using C++ in the 90s was like? Zig is a very explicit language, that's why it doesn't have destructors
@@codetothemoon true, but that’s also true for almost every other language out there.
If you have operations that must be tightly coupled (such as updating a person record whilst holding a lock over it), then most languages would encourage you to build a safe abstraction around the person object that does just that.
Idiomatic safe Rust code doesn’t always translate well to other languages if you do it line for line. You have done a good job illustrating that with a simple example :). You can provide the same safety in Java / go / js / python / zig for example, but the onus is on the author to bake it into the code structure rather than have the type system enforcing it automatically. Different paths to achieve the same end, Horses for courses.
You can do lock safety wrong in Rust as well, but the language will fight back hard and make it painful. It won’t totally prevent you from writing unsafe code, but it will give enough pain to cue you in that you are going about it the wrong way. When you start doing it the right way and let the type system do the hard work, your code becomes elegant and fun to write.
Similarly with Zig and allocators - because allocations are right in your face all the time, you get immediate pain feedback if you are going about things inefficiently. You can either push through and write a tonne of messy boilerplate, or rethink how you are managing memory resources. The more efficient your method, the cleaner and more elegant the code. Nice !
Programming languages are as much about being feedback devices as they are coding tools. Get good at Rust, and you will be better at writing safe code in any language. Get good at zig, and you will write way more efficient code in other languages. Get good at Erlang, and you will design fault tolerance in any other system you build, etc.
@@mgord9518 thanks, those are interesting features for some use cases.
Still I can't get the people that compare Zig to Rust for things like safety and correctness, that are my main 2 reasons I started using Rust.
11:26 Interesting how the "try" in zig works exactly the same as _ye olde_ try!() macro in rust 2018
oh interesting, didn't know about this as it was prior to my first foray into Rust!
- chooses two of the fastest languages for the backend
- also chooses the stupidest library to develop the frontend, which makes a web request for every user interaction instead of using browser’s capabilities
Just to let you know, if you don't use a template engine for your server sided html, you might lose an offer. I did one technical interview for htmx with node and didn't feel like I should use any. During the demo I showed the code and mentioned I saw the most popular template libs but did not want to use it for this small demo and the eng on the other side said yeah we are using that. I'm 90% sure that decision of laziness cost me that opportunity.
That dot before everything is really annoying unfortunately
3:05 you don't have to write clientside javascript with Leptos or Dioxus either
you're totally right - I should have just said "you don't have to write any client side code" or something to that effect
Programming language should balance memory safety, preventing concurrency issues, performance and productivity. Zig is worse then rust in 4 out of 4.
for this project, I'm inclined to agree. not yet sure if this carries over to other use cases as well...
sorry but this comes off as an inexperienced guy trying to explain to his viewers why their favorite programming language is still the best.
You wouldn't write a high level web server in Zig in the same sense that you wouldn't write it in C. Sure, Rust might seem easier on the surface if you already know the complexities of the language, but you're missing the point of Zig. Try actually doing something systems or low level related. Write a doubly linked list in Zig and Rust. Write a GUI framework in both. Write a simple garbage collector. Write something cross platform that interfaces with the native OS APIs. Then you'll see the appeal of Zig.
This is just a lazy attempt at jerking rustaceans. You clearly have no idea how Zig works.
This comment comes out as a bit rude, but I do agree that this is not Zig's field. As a Rust developer who works on compilers and virtual machines, I find Rust a great language to work on low level code. However, I'm sometimes forced to use unsafe blocks because I'm managing memory myself. I still like the low level Rust experience despite the verbosity, but I do also understand the appeal of simpler languages that shine in this specific field like Zig.
I was notified of a response to my comment but I cannot see any response here
Zig is cool when the alternative is C/C++.
But, its somehow so unreadable and verbode at the same time. Rust most of the time is easy to read and with macros the verbose stuff can just be moved somewhere else. Yeah you can abuse it but still, Rust feels way more productive and actually fun.
Not sure about Zigs compiler, but after having used Rust for over a year I couldn't write Python anymore. No compiler which directly fails, no guarantees, hated it :D
Rust feels very polished as long as you stay in the bounds of the API the library author crafted for you. It holds your hands along every step of the way. Thats what I love about it. I think thats a good thing for most use cases, but of course the memes a out livetimes are not without reasons
It's funny for me it's the exact opposite, I really find Zig to be easy to read, I don't know there is really nothing hidden from you, it's just there I never get surprised. I like Rust too, but sometimes I try do to something, look at functions and traits, and it's full on macros, and I'm like, Ok not for me lol. But I get it it's very much like how I absolutely hate C++, and love C, and some people hate C and love C++.
@@TheMachina42Rust definitely appeals to the "kitchen sink" crowd while Zig appeals to people who like simple languages. I went from Go and C to Zig and found it very easy to pick up. Rust still looks like hieroglyphics to me and I find C++ unbearable
@@mgord9518 Yes to me it's the same, I've observed it many times, there is really two kind of developers, the Result based developer and the Craftsman based developer, Result based developer tends to like more abstractions, and work better with complexity, and Craftsman tends to prefer low abstraction, low complexity language. I understand the appeal of Rust, just like I understand why people still use that godforsaken atrocity that C++ is. But it's just not for me either.
Thanks, I'll stick with Rust.
For most things, I'm right there with you.
Both look way too complicated for just serving some web pages.
One day I dropped a box of nails on the ground, barefoot, at night, in a room with the lights off. Guess which one of these two languages reflects the experience of going across the whole room to get to the lightswitch.
me maining c++ because i like it the most:
if C++ would have better tooling, I would definitly go with C++ instead of Zig.
No string types. seriously !!!
I might be with you on this one, depending on what the requirements are
Yea... sticking with Rust like others have said. I really can't imagine writing code without the rust analyzer any more. Thanks.
I'm pretty much with you for the most part. Though still keeping an open mind, curious to learn more from Zig fans, especially those who are also fluent with Rust
@@codetothemoon yep, I understand that completely, rather my comment goes to: even if there are some cool things in zig, and the compile time is much faster, still, for security reasons, I would not change. Rather I think that Rust should just work on its compile times and its static\const variables add what is missing, but that depends on the Rust foundation I guess... Security for me will always go first, either way.
the borrow checker can be a pain, but I would prefer that it call me an "idiot"... than pay the price later when my code fails and I get sued... I'lll stick with the borrow checker calling me a loser... jajaja
Excellent in-depth analysis, in zig the while loop for extracting form data was scary 🙂
thanks glad you liked it!
No job vs no job
Why you gotta call me out like that.
Skill issue
Go, slaps both of them for a htmx frontend
interesting why do you think so?
go is not system level language, creators ignored 20 years of language science, for making more money for google
@@codetothemoon it's easy to write, and do what you want
@@donateus6743 as I said go is just better for a htmx frontend, not for some embed systems programing
@@donateus6743 maybe I missed something. Who is paying to use Go?
It would be interesting to try to mimic the arena allocation in the request handler in Rust.
I think it could be more efficient as you probably can automatically reuse allocated memory for all requests, thus you save a few syscalls per request.
great idea! I think there are some Rust crates that implement Arena allocation, but I haven't tried them. I'd love to hear from the Axum/Actix folks about whether arena allocation is used under the hood, and whether it would make sense to expose those arenas to developers in handler functions like httpz does
@@codetothemoonBoth Actix and Axum depend on the global allocator, which, in case of Rust, would be whatever is provided by your system; for example malloc on *NIX platforms (macOS, Linux, etc.) and HeapAlloc on Windows.
While you can change the global allocator (i.e. to jemalloc, mimalloc for Axum or SnMalloc for Actix), in the future versions of Rust you may be able to change the allocator for things like Vec and String, as well as implementing your own via a trait through the unstable `allocator_api` feature, or you can use the "allocator-api2" crate as a polyfill. So hopefully these APIs could take advantage of that in the future.
Rust has the ugliest syntax I have ever seen
It looks unfamiliar at first, then it becomes really beautiful.
@@CalifornianViking complexity for the shake of complexity and challenge is quite moronic while not being business friendly
Zig if far more productive and easier to maintain, 20 years down the line all programs written in Rust will be a nightmare to maintain. Simplicity and boring is what we should thrive for, just like Golang which is a boring language but it just works.
@@dranon0o - why do you say that Rust will be hard to maintain? In my view, it is a very structured and explicit language that tells the software engineer exactly what is wrong. I am not concerned about the maintainability of Rust. I am concerned about the maintainability of JavaScript, Python, C, C++, etc where there are so many traps that the developers don't even know exist.
My biggest struggle with Rust was that my mind thought about memory management like C does it, and object orientation like Java and C#. Once I realized that C (and most other languages) handle memory wrong and that most other object-oriented languages are taking the wrong approach, then I saw that Rust was really simple and beautiful. Rust is not complex.
YourMama said that to yo. Stop pretending LOL
zig is beautiful language, they will bring async soon with some llvm detachment, and rust has no chance
Zig:
C/C++ interoperability
Even more control over memory, no hidden control flow
Comtime > Rust macros
No stupid lifetimes
No confrontations with borrow checker
More transparent foundation
Faster compilation(incremental compilation is coming)
I think that Zig does not compete with Rust. People write Rust because they do not want to think about allocations much if at all while still having a high degree of speed and safety, also the ability to encode alot of information about your program in its type system. Peope write Zig because the want to have the ability to control every minute detail of the computer, which sometimes is necessary but brings also a very high degree of mental burden with it. You have to think about alot of things more than in rust, less than in C but still alot.
Zig and Rust are very much not competitors.
You raise some great points - from what I've seen of comptime, so far I think I'm going to like it better than Rust procedural macros. This video topic didn't lend itself to that comparison, but I definitely should have mentioned Zig's faster compilation. It's really nice.
@@codetothemoon Rust macros and Zig comptime serve different purposes. Why everybody compares them? Primary goal for macros is code generation by taking an input and based on it producing output, and comptime is evaluating some expressions in compile time. And "stupid lifetimes", "No confrontations with borrow checker", no those are not great points.
If anyone has no idea why lifetimes exist in Rust and borrow checker is an issue, than they should not write any code in none of the non GC languages, and none of the parallel and concurrent code in any language either.
@@codetothemoon the compilation speed would be interesting piece of info...how much faster is the Zig compile speed compared to Rust?