1:00 might be possible that your editor does weird sh*t if it wasn't coded in the best language ever : c++ No ok seriously i know rust is better but stop hurting old guys' (like me) feelings : when i studied coding, cpp was the best language around.
no. at least to the first. While it is fine in embedded systems and DIY projects, its clearly meant for general purpose usage. Also, pure c? Vs what? Mixed language projects?
But what can you say about a dude that rattles off Carbon - passing it off as though its a viable choice for today's professional working programmers? Carbon is years away from reaching that kind of viable mainstream status. From the get go I visibly watched as the analog credibility meter flatlined as soon as the AI engine parsed and analized that sentence. It even activated the seldom-heard Star Trek red alert alarm. Had to enter that special code that is normally only used to stand down ready-to-launch ICBMs to get that alarm turned off.
I also prefer Rust over Zig but I think it's very interesting, so to address some of your concerns: - Zig will get a Package Manager and the Lead Developer Andrew Kelley was live streaming development on it just a few days ago - Zig is null safe, pointers can't be null by default and nullable types have to be null-checked before you can use them (almost the same as Rust Options) - You agreed on "no hidden control flow", but once you realize that this means that Zig doesn't have destructors, you might disagree :) - Don't be too mad about undefined, it just means "uninitialized" and will be caught when used incorrectly in debug builds (Rust also has this with mem::uninitialized) - Zig basically has Rust-like enums with union(enum), they work almost exactly the same and you will have to switch on them to access the data like in Rust Overall I think that Rust has many more use cases but we shouldn't say that it will "win", since Zig also has it's niche and it's a very interesting language.
Rust still wins in the sense that the entire construct of the borrow checker is also to prevent many problems related to racing conditions and memory leaks, in Zig you just can't have many of these guarantees. But surely, Zig is indeed an interesting language, I just hope it's fanbase didn't turn into another C++-like toxic community
@@diadetediotedio6918 The borrow checker simply does not work in low level environments and graphics programming. Undefined behavior is all over the place in the embedded space. By giving those guarantees, it makes it harder and very difficult to interact with the C ABI at all.
Handling memory correctly without handling it is what makes it great from the beginning for me. If someone copies it and improves in other things I am in.
I wouldn't say Rust was easy to learn for me, but it made sense: I came to Rust with mostly C/Java/Python knowledge and I kept struggling with mutability in Java/Python, and C just being hard to get right/having to reimplement basic data structures all the time. With that background, I wanted something that dealt better with mutability than Java/Python, and something which wasn't as involved as C/C++ to get dependecies working, for that, Rust is the perfect midpoint (even though it's closer to C/C++ than Java/Python).
With c specifically I just keep important pieces of my previous code around to reuse in different programs like data structures, and you gain knowledge and experience implementing them at least once in your life, although it's not that necessary I still like it.
@@ghosthunter0950 I do implement data structures for fun, but I'd rather use a battle tested data structure than whatever I come up with for actual code.
@@radinkhosraviani8634 learning go isn't a bad move, largely because it's a pretty small investment compared to something like rust or C++. It's easy to get productive quickly. It'd probably be a good place for you to start with statically typed languages.
@@Jplaysterraria this however doesn't suggest that its the language's job to make this possible. There are plenty of data structure libraries for c. Use one.
@@QberryShortcake Alexander Stepanov and Daniel Rose, "From Mathematics to Generic Programming" The name vector in STL was taken from the earlier programming languages Scheme and Common Lisp.
The dog itching sound was so funny 😁 Btw one of the most hyped projects written in Zig is Bun by Jared Sumner and when i tried it the first time I got a segmentation fault 🤷♂️
I have this program that built for a large telcom company that uses the Intel DPDK library to replace the kernel networking stack and takes over complete management of a specified ethernet interface. DPDK is written entirely in C. DPDK also isvrather primitive in that one works with it by reading and writing entire raw packet via RX/TX port. There is no high level Berkley networking stack sitting atop that (though there are projects that graft such on). In my case I justbneed to support UDP transport but I still wanted a socket abstraction for dealing with different traffic sessions, so I heavily modified the UDPDK library to provide that - it too is all C. So everyone is familiar with Linux epoll vs POSIX poll. I needed to add such an API to UDPDK. Well, epoll is superior to poll and can scale to tens of thousands - perhaps overbhundred thousand concurrent socket sessions. The poll API tops out at level of a thousand to few thousand sessions. epoll is probably at least ten times more efficient if not more. However, implementing epoll is complex - implementing poll is simple. Naturally I implemented POSIX poll. The performance is good to up to a thousand and perhaps acceptable to around 4 thousand. This is considered okay as get a huge boost in network traffic throughput from DPDK. And this will be deployed in K8 and sonwill be load balanced clustered - need more session capacity then launch another container instance. But if I redesign the poll call data structure to be data oriented - like Zig does its containers, and use SIMD to do the poll processing, I would automatically make the scaling of my poll API 8 times greater. Scaling to 20 to 30 thousand concurrent socket-based traffic sessions would be a wonderful win. There is even talk of support for SIMD in C++ 26 But gcc has intrinsics for doing this too - which will be what I use. But a language that could directly support this would be kind of cool.
The test declaration syntax is just beautiful, would love something like that in Rust instead of marking everything with attributes, also having test names as strings, just gorgeous
You can also use local declarations in place of a string, to signal you're specifically testing it. E.g. fn parseInt(bytes: []const u8) u32 {...} test parseInt { // -- test the function -- } which is really nice
libc is bloated? I just looked it up, yes under Linux Zig directly does sys calls without libc! But most other programming languages (like Rust) still link libc as a kind of system call abstraction layer. libc is a really small standard library. It doesn't even provide a hash table (unless that changed recently). Software bloat comes from shipping a full browser engine with your software (Electron), not from linking libc!
the nasty thing about clib is that the C APIs it defines are versioned even at a linker level. So it's incredibly easy to write a program that binds with libc, using a latest compiler and latest Linux distro, then find your program won't run on other distros that are just a matter of a fewvyears old - even though there is no semantic change that would break the working of your program, and at the C language level the API signatures remain exactly the same. It's way overly tedious to try and work around this libc versioning crap. One thing I appreciate about Go is that there is a like ability to build a Go program to where it doesn't bind to libc at all. If it was easy to opt out of the stringent version binding on libc APIs I wouldn't mind it, but it's a too much of a mess to cope with.
@@TheSulross That's true and was actually a reason why I linked an otherwise standalone (Rust!) binary with musl instead of glibc once. But that's a glibc issue, not a general libc issue. But granted, it's effectively the same. Though I wouldn't call it a bloat issue, but a versioning issue. But that's now splitting hairs.
I really enjoyed these takes. I'm an instructor who teaches programming, algorithms, data structures, etc. to high school and college students. I've given Rust serious consideration time and time again as a first language for these students. I also go back and forth on the issue. You have many separate camps, which makes it a difficult question. You have students ages 12-18, students ages 18+, and those that are self-taught at home of various ages. The question of what to learn first or even second heavily depends on which camp you're in and also what country you live in. For students, Rust could be a good first or second language. At least at this time, Zig would not be. I could see a language like Zig in the future with the same philosophies being a good candidate for teaching programming to students, but as it stands right now, it's maybe a third language, maybe.
I would say that Rust is a great language for newbies. I say this after I have struggled with C (and it's variants for decades). Rust forces you to think about Data, who owns it and who can borrow it. There is additional thought about Rust that you need, instead of code and debug, refactor and debug. Sure debugging is a fact of life, however I want to feel like I'm learning something and the Rust Analyser and Cargo Checker do a great job. If you ask a Python programmer what is the Heap, they may look at you and blink, with Rust you learn more about what's going on under the hood, just by declaring a variable for an integer addition. I like the fact that you deploy rust on Microcontrollers (that anyone can buy and play with) and they also create Web interfaces with it. I think it will be the swiss-army knife of programming. I've heard that Zig is the C replacement and Rust is the Cpp replacement, but I don't know.
Rust would be cool if the teacher was really focused on individual support and explained things really well, because it feels like a tough language where you really need to know quite a few "whys" to get things come right when you write it. It's not forgiving and it drives me mad when it feels like every implementation has different syntax rules to compile, any detail you change breaks it until you figure out that the rules have changed. But then again, with good teaching it might work nicely, especially if the student didn't have experience that directs them to wrong conclusions. That in my opinion is equally difficult about Rust like Primeagen said too.
Prime: "I'm tired, need a small rest." *Spends the next week publishing more videos than there are days.* Go to the Bahamas without your laptop or something or imma break in and shave your face in your sleep
it's essential to ditch the smart phone to have anything resembling a true vacation break people should just go to Walmart and get a $30 simple, calls/sms-only burner phone - then only allow significant others to have its phone number, and take only that phone on vacations.
You can avoid segfaults by not adding \0 by just initializing your buffer to \0s initially (using something like bzero or my fav memset(buf, '\0', sizeof(buff))) and then once you copy your chars to that array / buffer you don't have to explicitly put a \0 at then end since the memory is already filled with \0s and you are overwriting them with whatever you want given you don't overflow the buffer.
I have some input on the "first language to learn" thing. I think Prime gets the point perfectly, if Rust is your first language, you learn it once and learn it right - all while the language itself teaches you - the rust compiler not only teaches you the language but also teaches you programming as a whole.
There's a lot more chance you'll give up on programming though when you're new and only see a huge wall and the benefits are only going to be visible after you scale the wall. I've seen people give up on easier languages who I know would be able to program.
This has 100% been my experience while learning programming. Most of my knowledge has been learned while I have been learning rust and it actually tells you the issue which is so nice.
@@andrewdunbar828everyone is able to program with enough time and effort put in. Programming is nothing special and you dont need to be a genius for it. Its just effort and time, like anything really.
@@andrewdunbar828 I don't think the wall is anywhere near as huge as that for C++. I learned C++ as a kid and struggled with it for years; its surface area is insanely massive with difficulties everywhere, for any newcomer. I strongly believe I would have had a far easier time learning Rust had it been as mature as it is now back then. It's built around the same principle, lifetime-based resource management, but is the conceptually simpler language by far, with an easier ecosystem of tools and packages to use.
As a C# programmer, off the rip the sentiments expressed after hearing "no hidden control flow" is felt. That's actually the main reason why I suggest Rust to C# programmers.
Totally agree. I really love Zig. I feel more comfortable with it than Rust. But this preference does not mean Rust is shit for me. I like seeing Rust used but I don’t like using it in first person 😅
@@etodemerzel2627 I don't doubt that, its just that If i'm going to invest my time into a language it needs to have some staying power, C isn't going anywhere but rust will with time take over C++'s edge and has been growing alot and devs love it.
I like Zig and Rust, but I'm not actually productive these days so maybe that's moot. I have noticed a few other people who like both though and they tend to be the types that are not language fanboys and are not prone to attacks and hyperbole, etc.
I've done a lot of C and I try to use it as little as possible. The thing is that you only use C where you absolutely have to. 2 such usecases are languague interop (zig can maybe be used here if it also is compatible with the C ABI, I don't know), and embedded platforms that only have a gcc based compiler that only supports C properly. Which is the biggest usecase for me and thus zig will probably never do that, and I think it will take some time before those platforms don't exist anymore and everything supports llvm based compilers. So in those usecases zig is just not competing and C remains the only viable option, and in the other usecases it is competing with C++ and Rust and imho not really with C, and then I don't really see it gain a lot of traction, but who knows.
libc is optional, if you’re doing embedded programming in C then you should know exactly what you’re linking in, what your trap table looks like, your entry point, and everything that happens in your boot loader to set up your stack and whatnot. These things are not inherent to C, and they are pretty much all configurable. I don’t see how Zig would be any different, but I’m happy to be corrected.
and even doing Linux specific programming, libc is a huge pain in the arse because of it's versioning of its APIs. What one builds on a late model distro, binding to its versions, can then end up not being able to run on customer distros that are just a few years old (Canonical sells pro support for LTS releases that can go out to 12 years). It's a pain to try and opt out of that and buildvreleases thatbare capable of running on older releases while doing so using the latest in distros and compiler releases. Zig has taken on a righteous battle indeed in attempting to solve the infamous libc problem. Linux libc tyranny is straight from the pits of Hell.
ปีที่แล้ว +7
Unit testing is good where it's needed. Mainly, on medium to high level functionality.
Fantastic rant about try/catch (exception handling is actually goto structure - error occurs and execution jumps to "unknown" location). Also, really like the mantra "errors add value".
Using modern C++ I disable exceptions and use a template class based on std::variant for function return type - so a return is either the desired value or an error. Thus the coding style for error handling is much like Go. I also have a template that I call defer - it is constructed with a lambda. I use defer for RIAA cleanup of things like file descriptors, sockets, database connections - things that are not simple memory-only objects. So here too the coding resembles Go. And I uses std::span for passing anything that is array-like and std::string_view for span of string chars. Passing all array-like things via std::span means can use all the memory safe operations found on std::vector such as iterators and, say, range-based for loops. Can trivillaly use std::for_each, the algoritms, the new range-based feature of C++20, etc. (std::span doesn't get enough press to highlight what a game changer it is for writing safer and very versatile code that is still most efficient). If I then need to pass a string to an API that expects a null terminated C string then just use strndupa() to make a bounds safe copy of the string_view span that is null terminated and entirely existent on the stack, and pass that string to said API - but all the APIs that I write take std::string_view.. (I do hi-perf networking and it's an absolute no-no to touch the malloc heap when executing the data plane code paths. Using the heap is only permissible on control plane execution paths.) So do these things with modern C++ and life is very civilized - most hygienic, so to speak. The fact that C++ can directly consume C headers and directly interact with C is actually its super power - depite how much it gets flamed for being its legacy ball-and-chain. I'd say that Zig would be the definite better alternative for my domain use case than Rust would be. But modern C++ is just nailing things so well that there's just no compelling incentive for switching (let alone the cost and timeline of rewrite factors). The one annoyance is sprinkling noexcept on all the function declarations, but can certainly live with that. And if ever forget to add noexcept, well that's not a foot gun. Yeah, throwing exceptions was a dead end. We should all just repent and strive to be better people after acknowledging the error of our ways.
I would say C should be the first language for most people. Especially if you do a CS degree. It just teaches you so much about how computers work and you'll appreciate why rust's borrow checker is so amazing.
While I do agree that every programmer should learn C at some point, I don't think it's a great first language. As a beginner, thinking algorithmically is already hard enough. Adding all the complications a low-level language like C brings doesn't lead to a great learning experience imo.
@@waldtrautwald8499 That's the thing though. It depends on what you want to learn. For a CS student, C brings a lot of value because it teaches a lot about low-level aspects of the computer. What better moment to learn it than at that moment? It's useful when learning operating systems, networks, computer graphics, etc. But it's true that when you're studying these subjects, including data structures and Algorithms it can be an obstacle to manage it's dirty aspects while trying to learn the fundamentals of what you're studying. As for a self-taught developer/student it's better to start with something more "tangible" imo. Because you want to enter the market as fast as possible and trying to understand all the aspects of computing that C can help expose is time consuming.
During my final exams in college, a girl beside me literally cried with head on the desk because she got segfault in her linked list implementation and she couldn't find the source.
I think that "Rust is a hard language" is not the best way to describe the experience with it. I would think that the best way to describe it, to someone that haven't used it, is that "Rust is a language that is slower to implement". The language requires us to focus on way more details than other languages. We have to think about the way memory is managed. We have to think about the compiler. Ownership, pointers, traits and generics. That is rough to get started. I think that new developers should be given the option: "Do you want to learn a language that will allow you to spend a short time coding and a long time debugging, or a language that takes a long time coding and almost no time debugging?"
With respect to everyones opinion and this being to some degree subjective, I don’t agree that Rust is slower to implement after you know it well, but is indeed harder to learn to that extent as a programmer. The Rust language is generally not more verbose than other systems programming languages, but it takes longer to get to the point that you write code that just compiles first try. At least that’s my 2 cents after 4 years professionally coding in rust. Rust has more concepts you need to master than most programming languages, but really isnt that slow to implement 98% of the time (ofc comparing to C(with variants)/Java etc).
@@AlexanderHyll I kind of agree with your point. But I have trouble when it comes to learning new crates. Sometimes we have to go deep into the type system to find out what returns what. It gets a lot easier with practice, but messing around with the type system can be rough.
rust is complex, it is declarative by design. it won't wipe your ass, you have to ask for it its slow language to master just because there is much to learn the time you spend to get the first build of your program that does "something" even if not properly. is slower than other languages. a lot slower in fact. but time to deliver a program however is faster than comparable languages. a LOT faster. just because there is less debugging time. and usually ends with something that at least feels a lot more reliable. and that seems like that's why everyone ends loving rust. there is that period when you are halfway thru development when each new problem that emerges seems to get worse than the previous one. and you feel like just tossing the whole codebase in the garbage and starting again. while in rust the experience is the opposite, not only you have less problems in general as most things **just works** even against our best intuition while the complexity of the issues don't escalate.
rust is insanely fast to implement once youve learned it Almost all the features of the borrow checker that slow you down can be bypassed. Need to quickly whip up something and dont want to have to deal with keeping track of mutable references etc? .clone() everywhere, itl run like ass and its unclean as fuck, but if youre whipping something up quickly as a PoC you dont care about that anyway. Thats ownership dealt with. Traits you straight up dont even need to touch for 80% of what you can do in rust, you only really start touching traits as an implementation detail, which again isnt relevant for PoC's Generics are the same story as traits, when youre in rapid development "Do it wrong but do it fast" you can just code with explicit types, after youve already nailed the PoC you can always come back in and coalesce the code down using generics to remove duplication. As for pointers, I dont really touch pointers in rust I havnt found a scenario yet where I actually need to use pointers instead of references. Rust is just as fast as any other language to prototype a PoC its slower to implement the final prod version, but thats because youre expected to actually code it properly instead of taking shortcuts which you SHOULD already be aiming for for a prod release, quick hacky code is purely in the realm of PoC's and should never be shipped, shipping that shit is just asking for technical debt.
Damn your reactions are so funny. This is what modern programming community lacks, honesty and fun, everyone is super snug and "kind" on other platforms and it just ends up being boring, uninspired and boys just block each other lol.
I think when you are actually doing systems programming, Zig the language is better than Rust the language. A large part of that is the allocator story, and another large part of that is how difficult it is to write correct unsafe Rust. Zig is also really compelling for working with C and incrementally updating a C codebase. I think the Rust community does not spend nearly enough effort on making unsafe Rust safer in practice, to help people write correct safe abstractions. The Rust allocator story is pretty awful for many systems language use cases too. I think Zig succeeds on both of these fronts On the other hand, Zig has a whole lot of catching up to do with the tool chain and third party library ecosystem.
Next rust release is focused on improving unsafe rust. Release 2024 will make all the safe rust features be also available for unsafe rust constructs. It will be better enough to compete.
Allocators are very, VERY OS dependant. Even architecture dependent. Rust simply does not include it's allocator for embedded applications, and you must implement one for your device. Rust was not made around supporting C, unlike Zig. So yes, rust does prefer full rewrites, but I wouldn't say that it is a bad Idea.
Actually rust's macros are capable of introducing hidden flow control. For example "bail" and "ensure" macros from anyhow crate return implicitly. It's hidden control flow, they hide return keyword, which is imo bad.
I use unit tests to speed up development. The round trip to develop something is much faster in a unit test. 13:29 a well known golang library for testing is 'testify'. It has the assert functionality. It also has a require functionality, which will stop the whole test run because of preconditions. Assert continues to collect more test fails.
24:50 Honestly, as a 3rd year software engineering student who learnt Rust, I agree that what makes it difficult for many, is how different it is from other languages. But the concepts themselves aren't actually that difficult, they're just new. I would almost liken it to learning a new programming paradigm. So being someone who is still learning, and hasn't necessarily gotten stuck in doing things the ways I've always done them, I haven't found Rust that difficult to learn. That being said, I haven't made any super complex projects with Rust yet. But so far I tend to like it much more than C++. Managing memory and pointers in C++ seems error prone the moment a system no longer fits within your cognitive load.
I learned C when my friends took a minor introduction course and learned Java. To date they complain that they diddn't need to learn pointers, it made it more difficult for them to learn after the fact. So I say go all-in on complicated languages first.
Some programming languages are like a hammer, some are like a Swiss army knife, and some are like a triple decker craftsman toolbox. What I love about rust is that it is the triple decker craftsman toolbox of languages. Coming from my education/career which was entirely in C, C*+, and J̶̧͎̯̔͊a̴̖̺͂v̶̜̄̒ȁ̶̤, Rust felt different from all of them. It felt like learning to program again. Rust is amazing because when I want a specific tool I just find it in the toolbox and it is a fully functioning, well maintained, safe tool. The problem is filling through the drawers of the triple decker craftsman toolbox and knowing what tool to use. It’s less intuitive but can be very powerful. When you are holding a hammer everything is a nail if it doesn’t have to look pretty and when you have a Swiss army knife you can solve any problem if it is small enough, but with the full toolbox you can make the ideal solution for most problems once you get familiar with it.
I think it is quite not so easy for beginners compare to C/C++ where you can dip into lang smoothly step by step. Console print function is not so intuitive at first, and Heap allocating is also require understanding of std library. But for professionals aiming for full control it would be a good choice (after release of 1.0)
Your thought at 23:56? THIS! This is what bit me hard going into Rust. Learning it was like a bootcamp in the "break you down, destroy your understanding of the world, and recreate you brick-by-brick" sense. It took a while, but it had to unlearn a bunch of bad ideas I picked up from various dynamic languages. Fantastic observation.
Not all errors are recoverable, so I would argue that there is place for checked and unchecked errors. Old days when Hibernate throwed checked operations from every method (any sql query could fail do to loss of connection) .... was a living hell.
I agree with having to go through C, but I don't think it's "just so you can have the experience". I think it changes your mindset, you learn to pay attention yourself to details (the compiler and the C runtime won't). I would argue every new type of programming makes you a better programmer in all languages.
2:10 > "If this function throws, which function is going to catch it above you?" But if this function just fails returning some error code, which function is going to handle it, if any at all?
I had a similar thought about that part. I think Zig's model is still better, though, because you can't start throwing errors without obviously changing the signature of the function. If a function returns error, caller simply must deal with it, if only to pass it on. And compiler's going to know which errors could be returned from a given function so it can track it for you and make you deal with it at some moment. I think you can do similar things with try/catch handling but in Zig it's just cleaner, all is there in plain sight.
Computerphile dropped a new video on rust...it's one of the SIMPLEST explanation how memory allocation happens in RUST...in the video it's also compared to C++ as well
I have no idea if this is best, but 30+ years ago when I learned programming at first, I learned BASIC. I didn't learn about things like loops and function calls, those were things I had to make on my own. Then when I went into undergrad and learned about them, it felt like cheating... BUT I also knew how they were working "under the hood." So I think a good way to learn the basics is to learn how they work in implementation, even if you don't necessarily build a whole project that way. My kids are interested in learning programming and I'm struggling with the best way to teach them. I think the best way is to start with just very simply, here's what a computer is: a processor and memory. Instructions are stored in memory sequentially, and the processor just executes those instructions in order, and here's what those instructions look like (a la BASIC). From that basis, then we can build in the concepts of loops and function calls, then data structures, etc. I don't know though. I don't know the best way. Maybe Harvard CS50 is best?
To add to the "no hidden control flow", here's a story from the battlefield. Team of top notch engineers build a multi-peta-byte capable backend for dataflow and processing. Front-end team using some node+react end up on a call with the big wigs about why the application is erroring out. They point to the top notch engineers, I do a search from the stack to where the function is that isn't catching the throw. Turns out, they were calling us in node without ANY try catch or exception handling using promises or async. NONE! NONE AT ALL! So when their "fetch" threw an error (as one should when you receive a 500 from a server) it didn't know what to do and so it did.... nothing.... No error message, no UI update, no notification to the user, no log, nothing.
As an embedded C dev, I've been wanting a C with fewer "implementation defined", and some sensible quality-of-life ADA features - Zig looks very promising. Packed data types like Zig's may not be as pretty as the ADA type syntax, but it's still looking grand for mapping up register bit fields.
I love the idea of Zig and maybe it's just because I'm brand new at learning a newer language, coming from mainly C, Python, and MATLAB the past few years, but the Zig compiler always seems so angry at me :D. A very difficult to write language at first, but I can see if you can get good at Zig then you must be an incredibly talented programmer.
Google on Monday donated $1 million to the Rust Foundation specifically to improve interoperability between the language and C++. C++, a popular general purpose programming language, has arguably fallen out of fashion due to concerns over safety.Feb 5, 2024
update for those not in the know, zig moves fast! some of primes concerns are mediated already, and many more things are to come. it is very fun to watch this language grow and evolve
I've been using Odin as my systems programming language of choice. I liked it so much I ported my C++ (ptoo!) project into Odin and it was way easier to extend, work with, and came out to less lines of code when I ported it directly. I'm interested in Zig, and have done a few trivial things in it, but haven't made anything big with it yet. Zig does feel like it's got a thick layer of boomer-programming aesthetics... Not good or bad, Zig just *feels* like an old language.
Am I the only one when heard "below the C-level" joke had a one specific tune play in my head that goes along with the lyrics "arrrre you rrready kids? aye-aye captain!"
My old man started programming on a Burroughs mainframe in the 1970s. Yes they literally wrote their programs on paper! The handwritten program would be given to a typist who would type it out onto punch cards. It would then be given to a second typist who would put the punch card machine and verify mode and retype the program. Then they would get the punch cards back and look through them to find the remaining errors. Then they would send it to be compiled, and they would get the compile errors the next morning.... The process repeats.
The big problem with a lot of the more recent languages (or languages that have evolved a lot recently) is the excessive syntax. There are just too many syntactical additions in languages like rust or even python or recent versions of JavaScript for that matter.
I like Rust and Zig (and Swift). I wouldn't say Zig is better than Rust because it depends on your criteria, most of which is usually subjective. To me C is more low level than Zig. Maybe passing allocators around and I think not having temporaries would be things that are lower level in Zig than C. As someone who came from the 8-bit days and programming in assembly before C I always found C had bloat, but a lot less than almost every other language.
other things that makes zig more low level than c is alignment, alignment is a first class concern in zig, there are a bunch of built ins to mess with memory layout where in C there's almost none. but yeah overall zig has more high level features than c does, that's how it manages to become a "better c". if it had the same level of abstractions it wouldn't be that different from it
If you like Zig you'll love Nim! writes and reads like Python, compiles to C/C++/Objective c/Javascript, best FFI and interop, has a python-nim bridge, no memory management (unless you want) with the same performance as C, the list goes on. I love it
@@kishirisu1268 There isn't an additional layer they're compilation targets. You have a single, concise syntax to do it all without sacrificing anything. I find it absurd that you find this absurd
@@lod2414 Exactly. If you target a c/c++ backend it will produce optimized c/++ code and then gets ran through your normal c compiler. For javascript, it just produces the code in a single file. There is a WASM and LLVM backend too but I haven't used them
Try Odin. With all the bundled libraries, getting things moving around the screen is really easy and setting up Odin in the first place is easy. Great place for beginners to start.
Hmm, multiple languages are now kind of trying to be better than Rust. Here we have Zig, but there's also the V language, and there are probably even more coming up. The issue is that these programming language projects are all very young and unfinished. While Rust is actually very mature in comparison and has really started to break through. Quite a difference. Those other projects still risk being descontinued when things end up not being popular enough and people stop investing in them. A lot of time has been invested in making Rust a very well designed, robust language. Things might change in the future, but I think at this moment Rust is still the most interesting one to continue learning.
Regarding the last part, I think "maintain it with zig" is a really powerful way to put their foot in the door of C.
ปีที่แล้ว +8
Rust is not hard. It just takes some time learn it. Like twice the time of other ones for learning the basics. Only twice because Rust compensates the hard parts to learn with much simpler constructs than other languages. For me now it's much easier than Python and bash.
I test things to make sure they work the way I think they do, like I write code, and I write my tests to make sure it works specifically the way I wrote it, I attempt to strongly type all the values, and I write counter tests to make sure that it's not returning results when it shouldn't. I've been so tired of thinking that it works the way I intended and instead KNOW that it works the way I intended
13:23 “I don’t do red-green-refactor”. I take very similar stance to Prime on testing for the most part, but probably lean a little more on the fewer tests side. One thing I do, which might be different than what is being referenced here, is when a nasty bug comes up that I want to guard against regressing is to write a test that fails before fixing it (which then passes). There have been far too many times when I either think I’ve fixed a bug but actually didn’t, or had a regression but lost context on how it was fixed before (b/c the code has changed too much that git directly before/after the fix doesn’t show how to fix it NOW) that this is non-negotiable for me. Maybe this has a different name
He mentions carbon as the "language we already have" when carbon doesn't even have a simple compiler yet. That's how you know that guys knows nothing about what he's talking. ]
There was an episode of Myrhbusters years ago where they tested a myth about blind drivers. They found it was easier for a blind driver to follow the instructions of a literal backseat driver than it was for a blindfolded person who can see. The blind person has absolutely no preconceptions, they've never driven before. They just do exactly what they're told. People with previous driving experience couldn't help but want to apply all their own preconceptions and habits to the situation. I sometimes think this same idea would apply to Rust as a first language. Most people struggle because Rust is very different from the expectations they can't help bring with them (why FP bros have less trouble, their expectations align). New folks have none.
Just as an annoying WHELL ACKYUHALLY about the hidden control flow: You have CHECKED exceptions. These are exceptions that the compiler forces you to deal with. These are very much not hidden, and a lot of developers hate having to write their code in a safe and reasonable manner. (Guess which one Java uses by default.) Then there are UNCHECKED exceptions. These do not force you to deal with them and will happily bubble up your call stack until they're either caught by a framework, or they blow up your entire program. C# uses this. There has been a flamewar over checked vs unchecked exceptions in the enterprise space over this for two decades or so. I have my own opinions, but I'll keep them to myself.
NULL termination: Use clang-tidy and activate "bugprone-not-null-terminated-result" and "bugprone-string-literal-with-embedded-nul¶". Problem solved. I couldn't image programming C or C++ without clang-tidy and clang-format. And please active the clang- or the gcc-sanatizers as well.
The C++ gag of learn it in 21 days: you must practice and learn C++ for 90 years, go back in time, then kill your past self, then you've learned it. I lost it so hard I cried. That was so gosh darn funny sir.
I've always been more in favour of the alternate return paths as arguments approach than the errors as return values approach. Basically, if a procedure can fail in a recoverable way, take the handler for that failure case as a required argument. If it can fail in non-recoverable ways, log+exit, crash hard and fast while keeping record of why. And if you want to provide the option for the caller to opt in to recoverability, those should be two (or more) different procedures with different signatures and not an optional parameter.
Seems helpful for a function with multiple steps where it could fail instead of splitting each stage into a separate function. You could have a single function that accepts Option-al handlers, maybe with a sort of builder style struct if there are a lot of handlers. I don't see why this pattern precludes ever using Result, in fact it could be useful to combine them in some scenarios.
@@michaelthompson7217 Unrecoverable errors basically have three possible paths to go. Muddle on in a corrupted state and accumulate garbage that you foist on the user, muddle on in a corrupted state and foist that corrupted state onto connected systems, or shut down - either as neatly as you can at your own devise, or hard and fast by the kernel. [EDIT] Becoming totally unresponsive and keeping rendering over everything else was a common fourth option back in the DOS and Windows 9x era, as well as anything else that running user programs in ring 0 afforded you...
Vector comes about because the creator of the C++ Standard Template Library, Alexander Stepanov, called its arrays Vector. A mistake he says he regrets in one of his video presentations. Which I on TH-cam someplace. Everyone else has continued with "Vector" since then, it's tradition.
Zig shouldn't have a lot of trouble entering any place where C is already in. That's the advantage, you can import any C function and you can even kinda transpile C to Zig. So in theory even if you don't have a library in Zig for what you want, so long as there is a C one you should be good
learning computer programming for the first time is hard these days. I started in Pascal then learnt some C, then did some C++ back in the 90s. Then not being in software development, then just doing dirty for loops in interpreted languages where I didn't need to really care. Then coming back to Rust it makes you feel like you're doing CS 101 all over again. I think if people don't learn on Rust first, then people should learn in C then move to Rust.
Programmers in about 105 different programming languages were challenged to write a specific test code that found and counted prime numbers. RUST was about 3.5 times faster than just about any other language including assembler language. The only language that was faster than RUST was ZIG - which was twice as fast as RUST. If you want your program to run as quick as possible - it turns out this very new programming language is the one to beat.
0:18 That spit is personal. I always laugh out loud when hear that hawking sound followed by spitting for C++, C#. And I listen to these vids while doing something else :D Edited timestamp for better timing.
So only ever been a hobbyist, and only ever used Python. And about 6 months ago now I decided to learn Rust, and I personally found it very easy to pick up and start building stuff. Now was it good, or anything, no, and never was gonna be. But I've loved learning Rust, compared to when I was first starting out with Python.
Zig's build system is great, takes away the pain of C . But then you have to take care of the allocators, which is cool for hobby projects, not sure in production.
1:35 - Jesus Christ I'm so much with you on that. I hate throwing errors. I would much rather break the entire language's paradigm and return an error or a list with the return value and possible error and just straight up do it the procedural way.
functions not having what it throws in the signature is also one of the biggest problems in C++. Yeah you do have noexcept there but almost no one actually uses that correctly and it's basically only in code documentation and doesn't actually enforce anything
GO SUB TO LLL!!!
Original: th-cam.com/video/zFELcHTki9U/w-d-xo.html
Author: www.youtube.com/@LowLevelLearning
♥
Subbed cheers
Already was 🙂
1:00 might be possible that your editor does weird sh*t if it wasn't coded in the best language ever : c++
No ok seriously i know rust is better but stop hurting old guys' (like me) feelings : when i studied coding, cpp was the best language around.
No beeping while saying “C*+”? I thought this was a family friendly channel..
yeah, that was a C*+ move from the Primeagen
C*+? … oh no I made it worse
fuck you and wait for it..
no beep, huh
I for one am shocked.
Why would he say C pointer plus?
I'm still waiting for someone to make a language called Zag, so the cycle becomes complete.
Zig for Backend
Zag for Frontend
@@eshwarprasad524 dude i would switch to full-stack if we got this.
I WANNA REALLY REALLY REALLY WANNA ZIG A ZIG - AH!
😂
if that isnt the name of the upcoming package manager for zig, i aint using the language
Zig is clearly to replace simple pure C on embedded systems or DIY projects. It's clearly safer so less frustrating to beginner.
no. at least to the first. While it is fine in embedded systems and DIY projects, its clearly meant for general purpose usage. Also, pure c? Vs what? Mixed language projects?
@@homelessrobot I wanted to say that Zig is not 1:1 C++ replacement.
@@AK-vx4dy OK, i see.
@@SimonWoodburyForget Right. But Rust let you build guard rails for entire teams even in lowlevel language.
But what can you say about a dude that rattles off Carbon - passing it off as though its a viable choice for today's professional working programmers?
Carbon is years away from reaching that kind of viable mainstream status.
From the get go I visibly watched as the analog credibility meter flatlined as soon as the AI engine parsed and analized that sentence.
It even activated the seldom-heard Star Trek red alert alarm. Had to enter that special code that is normally only used to stand down ready-to-launch ICBMs to get that alarm turned off.
I also prefer Rust over Zig but I think it's very interesting, so to address some of your concerns:
- Zig will get a Package Manager and the Lead Developer Andrew Kelley was live streaming development on it just a few days ago
- Zig is null safe, pointers can't be null by default and nullable types have to be null-checked before you can use them (almost the same as Rust Options)
- You agreed on "no hidden control flow", but once you realize that this means that Zig doesn't have destructors, you might disagree :)
- Don't be too mad about undefined, it just means "uninitialized" and will be caught when used incorrectly in debug builds (Rust also has this with mem::uninitialized)
- Zig basically has Rust-like enums with union(enum), they work almost exactly the same and you will have to switch on them to access the data like in Rust
Overall I think that Rust has many more use cases but we shouldn't say that it will "win", since Zig also has it's niche and it's a very interesting language.
Rust still wins in the sense that the entire construct of the borrow checker is also to prevent many problems related to racing conditions and memory leaks, in Zig you just can't have many of these guarantees. But surely, Zig is indeed an interesting language, I just hope it's fanbase didn't turn into another C++-like toxic community
@@diadetediotedio6918 The borrow checker simply does not work in low level environments and graphics programming. Undefined behavior is all over the place in the embedded space. By giving those guarantees, it makes it harder and very difficult to interact with the C ABI at all.
@@ScibbieGames an argument for using both of them in different situations.
@@ScibbieGames
This is simply a lie, take a look on Asahi Lina commentaries on Rust utilities for driver development for an interesting example
Handling memory correctly without handling it is what makes it great from the beginning for me. If someone copies it and improves in other things I am in.
I wouldn't say Rust was easy to learn for me, but it made sense:
I came to Rust with mostly C/Java/Python knowledge and I kept struggling with mutability in Java/Python, and C just being hard to get right/having to reimplement basic data structures all the time.
With that background, I wanted something that dealt better with mutability than Java/Python, and something which wasn't as involved as C/C++ to get dependecies working, for that, Rust is the perfect midpoint (even though it's closer to C/C++ than Java/Python).
With c specifically I just keep important pieces of my previous code around to reuse in different programs like data structures, and you gain knowledge and experience implementing them at least once in your life, although it's not that necessary I still like it.
@@ghosthunter0950 I do implement data structures for fun, but I'd rather use a battle tested data structure than whatever I come up with for actual code.
Have you tried golang? I’m tearing myself apart on what to learn. I only know the basics of python and basics of javascript
@@radinkhosraviani8634 learning go isn't a bad move, largely because it's a pretty small investment compared to something like rust or C++. It's easy to get productive quickly. It'd probably be a good place for you to start with statically typed languages.
@@Jplaysterraria this however doesn't suggest that its the language's job to make this possible. There are plenty of data structure libraries for c. Use one.
Apparently C++ is why, but the guy who picked the name "vector" didn't realize what it meant in math.
And now everyone does it.
Scheme, Common Lisp -> C++, Java -> everyone else
@@testtest-qm7cj what
@@QberryShortcake Alexander Stepanov and Daniel Rose, "From Mathematics to Generic Programming"
The name vector in STL was taken from the earlier programming languages Scheme and Common Lisp.
In Zig I think they just run out of names. They have arrays, arrayList and wanted something for the SIMD stuff and had to go with Vector
@@PabloparsilVector for SIMD actually makes sense to me
The dog itching sound was so funny 😁
Btw one of the most hyped projects written in Zig is Bun by Jared Sumner and when i tried it the first time I got a segmentation fault 🤷♂️
lmao
Zig vectors are vectors like vec3 and vec4, used for easy SIMD. The growable array is a std.ArrayList 🎉
A vector in Zig is actually a type intended for SIMD operations, not a dynamic array.
I have this program that built for a large telcom company that uses the Intel DPDK library to replace the kernel networking stack and takes over complete management of a specified ethernet interface. DPDK is written entirely in C.
DPDK also isvrather primitive in that one works with it by reading and writing entire raw packet via RX/TX port. There is no high level Berkley networking stack sitting atop that (though there are projects that graft such on). In my case I justbneed to support UDP transport but I still wanted a socket abstraction for dealing with different traffic sessions, so I heavily modified the UDPDK library to provide that - it too is all C.
So everyone is familiar with Linux epoll vs POSIX poll. I needed to add such an API to UDPDK.
Well, epoll is superior to poll and can scale to tens of thousands - perhaps overbhundred thousand concurrent socket sessions. The poll API tops out at level of a thousand to few thousand sessions. epoll is probably at least ten times more efficient if not more.
However, implementing epoll is complex - implementing poll is simple. Naturally I implemented POSIX poll.
The performance is good to up to a thousand and perhaps acceptable to around 4 thousand. This is considered okay as get a huge boost in network traffic throughput from DPDK. And this will be deployed in K8 and sonwill be load balanced clustered - need more session capacity then launch another container instance.
But if I redesign the poll call data structure to be data oriented - like Zig does its containers, and use SIMD to do the poll processing, I would automatically make the scaling of my poll API 8 times greater. Scaling to 20 to 30 thousand concurrent socket-based traffic sessions would be a wonderful win.
There is even talk of support for SIMD in C++ 26
But gcc has intrinsics for doing this too - which will be what I use. But a language that could directly support this would be kind of cool.
The test declaration syntax is just beautiful, would love something like that in Rust instead of marking everything with attributes, also having test names as strings, just gorgeous
You can also use local declarations in place of a string, to signal you're specifically testing it. E.g.
fn parseInt(bytes: []const u8) u32 {...}
test parseInt {
// -- test the function --
}
which is really nice
Elixir also has this, but it's a macro.
libc is bloated? I just looked it up, yes under Linux Zig directly does sys calls without libc! But most other programming languages (like Rust) still link libc as a kind of system call abstraction layer. libc is a really small standard library. It doesn't even provide a hash table (unless that changed recently). Software bloat comes from shipping a full browser engine with your software (Electron), not from linking libc!
the nasty thing about clib is that the C APIs it defines are versioned even at a linker level. So it's incredibly easy to write a program that binds with libc, using a latest compiler and latest Linux distro, then find your program won't run on other distros that are just a matter of a fewvyears old - even though there is no semantic change that would break the working of your program, and at the C language level the API signatures remain exactly the same.
It's way overly tedious to try and work around this libc versioning crap.
One thing I appreciate about Go is that there is a like ability to build a Go program to where it doesn't bind to libc at all.
If it was easy to opt out of the stringent version binding on libc APIs I wouldn't mind it, but it's a too much of a mess to cope with.
@@TheSulross That's true and was actually a reason why I linked an otherwise standalone (Rust!) binary with musl instead of glibc once. But that's a glibc issue, not a general libc issue. But granted, it's effectively the same. Though I wouldn't call it a bloat issue, but a versioning issue. But that's now splitting hairs.
I really enjoyed these takes. I'm an instructor who teaches programming, algorithms, data structures, etc. to high school and college students. I've given Rust serious consideration time and time again as a first language for these students. I also go back and forth on the issue. You have many separate camps, which makes it a difficult question. You have students ages 12-18, students ages 18+, and those that are self-taught at home of various ages. The question of what to learn first or even second heavily depends on which camp you're in and also what country you live in. For students, Rust could be a good first or second language. At least at this time, Zig would not be. I could see a language like Zig in the future with the same philosophies being a good candidate for teaching programming to students, but as it stands right now, it's maybe a third language, maybe.
I would say that Rust is a great language for newbies. I say this after I have struggled with C (and it's variants for decades). Rust forces you to think about Data, who owns it and who can borrow it. There is additional thought about Rust that you need, instead of code and debug, refactor and debug. Sure debugging is a fact of life, however I want to feel like I'm learning something and the Rust Analyser and Cargo Checker do a great job. If you ask a Python programmer what is the Heap, they may look at you and blink, with Rust you learn more about what's going on under the hood, just by declaring a variable for an integer addition. I like the fact that you deploy rust on Microcontrollers (that anyone can buy and play with) and they also create Web interfaces with it. I think it will be the swiss-army knife of programming. I've heard that Zig is the C replacement and Rust is the Cpp replacement, but I don't know.
Rust would be cool if the teacher was really focused on individual support and explained things really well, because it feels like a tough language where you really need to know quite a few "whys" to get things come right when you write it. It's not forgiving and it drives me mad when it feels like every implementation has different syntax rules to compile, any detail you change breaks it until you figure out that the rules have changed. But then again, with good teaching it might work nicely, especially if the student didn't have experience that directs them to wrong conclusions. That in my opinion is equally difficult about Rust like Primeagen said too.
Lisp. That simple.
12:30 My main rule for unit tests is that I'll write them if, when writing a function, I go "wait will this be an off-by-one error?"
Prime: "I'm tired, need a small rest."
*Spends the next week publishing more videos than there are days.*
Go to the Bahamas without your laptop or something or imma break in and shave your face in your sleep
>implying he sleeps
He livestreams then an editor goes in and chops out individual videos from it
You got a Segfault when you dereferenced his unallocated sleep variable.
This is such an interesting mix of anger and loving sentiment.
it's essential to ditch the smart phone to have anything resembling a true vacation break
people should just go to Walmart and get a $30 simple, calls/sms-only burner phone - then only allow significant others to have its phone number, and take only that phone on vacations.
You can avoid segfaults by not adding \0 by just initializing your buffer to \0s initially (using something like bzero or my fav memset(buf, '\0', sizeof(buff))) and then once you copy your chars to that array / buffer you don't have to explicitly put a \0 at then end since the memory is already filled with \0s and you are overwriting them with whatever you want given you don't overflow the buffer.
I have some input on the "first language to learn" thing. I think Prime gets the point perfectly, if Rust is your first language, you learn it once and learn it right - all while the language itself teaches you - the rust compiler not only teaches you the language but also teaches you programming as a whole.
There's a lot more chance you'll give up on programming though when you're new and only see a huge wall and the benefits are only going to be visible after you scale the wall. I've seen people give up on easier languages who I know would be able to program.
I like Rust. But it doesn't teach you "programming as a whole". It teaches you imperative programming with a dash of functional.
This has 100% been my experience while learning programming. Most of my knowledge has been learned while I have been learning rust and it actually tells you the issue which is so nice.
@@andrewdunbar828everyone is able to program with enough time and effort put in. Programming is nothing special and you dont need to be a genius for it. Its just effort and time, like anything really.
@@andrewdunbar828 I don't think the wall is anywhere near as huge as that for C++. I learned C++ as a kid and struggled with it for years; its surface area is insanely massive with difficulties everywhere, for any newcomer. I strongly believe I would have had a far easier time learning Rust had it been as mature as it is now back then. It's built around the same principle, lifetime-based resource management, but is the conceptually simpler language by far, with an easier ecosystem of tools and packages to use.
I love unit testing, it saves me so much time.
As a C# programmer, off the rip the sentiments expressed after hearing "no hidden control flow" is felt. That's actually the main reason why I suggest Rust to C# programmers.
I love Zig, and I think it’s one of those things where you either gravitate toward it or Rust.
Totally agree. I really love Zig. I feel more comfortable with it than Rust. But this preference does not mean Rust is shit for me. I like seeing Rust used but I don’t like using it in first person 😅
I’d pick rust, zig feel like some offshoot c replacement
Zig is really nice to use. Very simple and straightforward, yet very powerful.
@@etodemerzel2627 I don't doubt that, its just that If i'm going to invest my time into a language it needs to have some staying power, C isn't going anywhere but rust will with time take over C++'s edge and has been growing alot and devs love it.
I like Zig and Rust, but I'm not actually productive these days so maybe that's moot. I have noticed a few other people who like both though and they tend to be the types that are not language fanboys and are not prone to attacks and hyperbole, etc.
I've done a lot of C and I try to use it as little as possible. The thing is that you only use C where you absolutely have to. 2 such usecases are languague interop (zig can maybe be used here if it also is compatible with the C ABI, I don't know), and embedded platforms that only have a gcc based compiler that only supports C properly. Which is the biggest usecase for me and thus zig will probably never do that, and I think it will take some time before those platforms don't exist anymore and everything supports llvm based compilers. So in those usecases zig is just not competing and C remains the only viable option, and in the other usecases it is competing with C++ and Rust and imho not really with C, and then I don't really see it gain a lot of traction, but who knows.
One of the primary use cases for Zig is exporting a library with the C ABI for other programming languages to call into.
libc is optional, if you’re doing embedded programming in C then you should know exactly what you’re linking in, what your trap table looks like, your entry point, and everything that happens in your boot loader to set up your stack and whatnot. These things are not inherent to C, and they are pretty much all configurable. I don’t see how Zig would be any different, but I’m happy to be corrected.
and even doing Linux specific programming, libc is a huge pain in the arse because of it's versioning of its APIs. What one builds on a late model distro, binding to its versions, can then end up not being able to run on customer distros that are just a few years old (Canonical sells pro support for LTS releases that can go out to 12 years).
It's a pain to try and opt out of that and buildvreleases thatbare capable of running on older releases while doing so using the latest in distros and compiler releases.
Zig has taken on a righteous battle indeed in attempting to solve the infamous libc problem.
Linux libc tyranny is straight from the pits of Hell.
Unit testing is good where it's needed. Mainly, on medium to high level functionality.
Zig is an ultra mini ultra simple ultra clear language and I don't think it can even be compared.
Odin is simpler and clearer than Zig
@@Br4dButt0wskito me you can only call a programming language "system's programming language" of it supports freestanding targets.
Fantastic rant about try/catch (exception handling is actually goto structure - error occurs and execution jumps to "unknown" location). Also, really like the mantra "errors add value".
Using modern C++ I disable exceptions and use a template class based on std::variant for function return type - so a return is either the desired value or an error. Thus the coding style for error handling is much like Go. I also have a template that I call defer - it is constructed with a lambda.
I use defer for RIAA cleanup of things like file descriptors, sockets, database connections - things that are not simple memory-only objects.
So here too the coding resembles Go.
And I uses std::span for passing anything that is array-like and std::string_view for span of string chars. Passing all array-like things via std::span means can use all the memory safe operations found on std::vector such as iterators and, say, range-based for loops. Can trivillaly use std::for_each, the algoritms, the new range-based feature of C++20, etc. (std::span doesn't get enough press to highlight what a game changer it is for writing safer and very versatile code that is still most efficient).
If I then need to pass a string to an API that expects a null terminated C string then just use strndupa() to make a bounds safe copy of the string_view span that is null terminated and entirely existent on the stack, and pass that string to said API - but all the APIs that I write take std::string_view.. (I do hi-perf networking and it's an absolute no-no to touch the malloc heap when executing the data plane code paths. Using the heap is only permissible on control plane execution paths.)
So do these things with modern C++ and life is very civilized - most hygienic, so to speak.
The fact that C++ can directly consume C headers and directly interact with C is actually its super power - depite how much it gets flamed for being its legacy ball-and-chain.
I'd say that Zig would be the definite better alternative for my domain use case than Rust would be. But modern C++ is just nailing things so well that there's just no compelling incentive for switching (let alone the cost and timeline of rewrite factors).
The one annoyance is sprinkling noexcept on all the function declarations, but can certainly live with that. And if ever forget to add noexcept, well that's not a foot gun.
Yeah, throwing exceptions was a dead end. We should all just repent and strive to be better people after acknowledging the error of our ways.
I would say C should be the first language for most people. Especially if you do a CS degree. It just teaches you so much about how computers work and you'll appreciate why rust's borrow checker is so amazing.
While I do agree that every programmer should learn C at some point, I don't think it's a great first language. As a beginner, thinking algorithmically is already hard enough. Adding all the complications a low-level language like C brings doesn't lead to a great learning experience imo.
@@waldtrautwald8499 That's the thing though. It depends on what you want to learn. For a CS student, C brings a lot of value because it teaches a lot about low-level aspects of the computer. What better moment to learn it than at that moment? It's useful when learning operating systems, networks, computer graphics, etc. But it's true that when you're studying these subjects, including data structures and Algorithms it can be an obstacle to manage it's dirty aspects while trying to learn the fundamentals of what you're studying.
As for a self-taught developer/student it's better to start with something more "tangible" imo. Because you want to enter the market as fast as possible and trying to understand all the aspects of computing that C can help expose is time consuming.
During my final exams in college, a girl beside me literally cried with head on the desk because she got segfault in her linked list implementation and she couldn't find the source.
@@0xDEAD_Inside lol that's a little extreme 😂. I imagine she was unded a lot of stress and this was the final straw.
@@shimadabr Yeah! She was a straight A student and segfaults are back breakers even for experienced programmers.
Prime should do a review of Eskil Steenberg's projects in C. Would be interesting.
I know he streams on twitch but do those streams get posted somewhere ?
I think that "Rust is a hard language" is not the best way to describe the experience with it. I would think that the best way to describe it, to someone that haven't used it, is that "Rust is a language that is slower to implement". The language requires us to focus on way more details than other languages. We have to think about the way memory is managed. We have to think about the compiler.
Ownership, pointers, traits and generics. That is rough to get started. I think that new developers should be given the option: "Do you want to learn a language that will allow you to spend a short time coding and a long time debugging, or a language that takes a long time coding and almost no time debugging?"
With respect to everyones opinion and this being to some degree subjective, I don’t agree that Rust is slower to implement after you know it well, but is indeed harder to learn to that extent as a programmer. The Rust language is generally not more verbose than other systems programming languages, but it takes longer to get to the point that you write code that just compiles first try. At least that’s my 2 cents after 4 years professionally coding in rust. Rust has more concepts you need to master than most programming languages, but really isnt that slow to implement 98% of the time (ofc comparing to C(with variants)/Java etc).
@@AlexanderHyll I kind of agree with your point. But I have trouble when it comes to learning new crates. Sometimes we have to go deep into the type system to find out what returns what. It gets a lot easier with practice, but messing around with the type system can be rough.
rust is complex, it is declarative by design. it won't wipe your ass, you have to ask for it
its slow language to master just because there is much to learn
the time you spend to get the first build of your program that does "something" even if not properly. is slower than other languages. a lot slower in fact.
but time to deliver a program however is faster than comparable languages. a LOT faster. just because there is less debugging time. and usually ends with something that at least feels a lot more reliable.
and that seems like that's why everyone ends loving rust. there is that period when you are halfway thru development when each new problem that emerges seems to get worse than the previous one. and you feel like just tossing the whole codebase in the garbage and starting again.
while in rust the experience is the opposite, not only you have less problems in general as most things **just works** even against our best intuition while the complexity of the issues don't escalate.
rust is insanely fast to implement once youve learned it
Almost all the features of the borrow checker that slow you down can be bypassed.
Need to quickly whip up something and dont want to have to deal with keeping track of mutable references etc? .clone() everywhere, itl run like ass and its unclean as fuck, but if youre whipping something up quickly as a PoC you dont care about that anyway.
Thats ownership dealt with.
Traits you straight up dont even need to touch for 80% of what you can do in rust, you only really start touching traits as an implementation detail, which again isnt relevant for PoC's
Generics are the same story as traits, when youre in rapid development "Do it wrong but do it fast" you can just code with explicit types, after youve already nailed the PoC you can always come back in and coalesce the code down using generics to remove duplication.
As for pointers, I dont really touch pointers in rust I havnt found a scenario yet where I actually need to use pointers instead of references.
Rust is just as fast as any other language to prototype a PoC
its slower to implement the final prod version, but thats because youre expected to actually code it properly instead of taking shortcuts which you SHOULD already be aiming for for a prod release, quick hacky code is purely in the realm of PoC's and should never be shipped, shipping that shit is just asking for technical debt.
@@MrTeathyme good point
Damn your reactions are so funny. This is what modern programming community lacks, honesty and fun, everyone is super snug and "kind" on other platforms and it just ends up being boring, uninspired and boys just block each other lol.
I think when you are actually doing systems programming, Zig the language is better than Rust the language. A large part of that is the allocator story, and another large part of that is how difficult it is to write correct unsafe Rust. Zig is also really compelling for working with C and incrementally updating a C codebase.
I think the Rust community does not spend nearly enough effort on making unsafe Rust safer in practice, to help people write correct safe abstractions. The Rust allocator story is pretty awful for many systems language use cases too. I think Zig succeeds on both of these fronts
On the other hand, Zig has a whole lot of catching up to do with the tool chain and third party library ecosystem.
Odin is more simple and lots of options for custom allocators.
Next rust release is focused on improving unsafe rust. Release 2024 will make all the safe rust features be also available for unsafe rust constructs. It will be better enough to compete.
Allocators are very, VERY OS dependant. Even architecture dependent. Rust simply does not include it's allocator for embedded applications, and you must implement one for your device.
Rust was not made around supporting C, unlike Zig. So yes, rust does prefer full rewrites, but I wouldn't say that it is a bad Idea.
Unsafe Rust is like a language inside a language. It was such a dumb decision. Unsafe Rust is anti-rust 100%
prime should do a stream with andrew kelley like he did with rich harris
Actually rust's macros are capable of introducing hidden flow control. For example "bail" and "ensure" macros from anyhow crate return implicitly. It's hidden control flow, they hide return keyword, which is imo bad.
I use unit tests to speed up development. The round trip to develop something is much faster in a unit test. 13:29 a well known golang library for testing is 'testify'. It has the assert functionality. It also has a require functionality, which will stop the whole test run because of preconditions. Assert continues to collect more test fails.
24:50 Honestly, as a 3rd year software engineering student who learnt Rust, I agree that what makes it difficult for many, is how different it is from other languages. But the concepts themselves aren't actually that difficult, they're just new. I would almost liken it to learning a new programming paradigm.
So being someone who is still learning, and hasn't necessarily gotten stuck in doing things the ways I've always done them, I haven't found Rust that difficult to learn. That being said, I haven't made any super complex projects with Rust yet.
But so far I tend to like it much more than C++. Managing memory and pointers in C++ seems error prone the moment a system no longer fits within your cognitive load.
I learned C when my friends took a minor introduction course and learned Java.
To date they complain that they diddn't need to learn pointers, it made it more difficult for them to learn after the fact. So I say go all-in on complicated languages first.
Some programming languages are like a hammer, some are like a Swiss army knife, and some are like a triple decker craftsman toolbox.
What I love about rust is that it is the triple decker craftsman toolbox of languages. Coming from my education/career which was entirely in C, C*+, and J̶̧͎̯̔͊a̴̖̺͂v̶̜̄̒ȁ̶̤, Rust felt different from all of them. It felt like learning to program again. Rust is amazing because when I want a specific tool I just find it in the toolbox and it is a fully functioning, well maintained, safe tool. The problem is filling through the drawers of the triple decker craftsman toolbox and knowing what tool to use. It’s less intuitive but can be very powerful. When you are holding a hammer everything is a nail if it doesn’t have to look pretty and when you have a Swiss army knife you can solve any problem if it is small enough, but with the full toolbox you can make the ideal solution for most problems once you get familiar with it.
Under da C! Under da C! Darling it's betta down by da metal, under da C!
I think it is quite not so easy for beginners compare to C/C++ where you can dip into lang smoothly step by step. Console print function is not so intuitive at first, and Heap allocating is also require understanding of std library. But for professionals aiming for full control it would be a good choice (after release of 1.0)
Your thought at 23:56? THIS! This is what bit me hard going into Rust. Learning it was like a bootcamp in the "break you down, destroy your understanding of the world, and recreate you brick-by-brick" sense. It took a while, but it had to unlearn a bunch of bad ideas I picked up from various dynamic languages. Fantastic observation.
I beleave any scripting language used to create anything more than 100 lines such as bash scripts is a bad idea.
@@fulconandroadcone9488, what's a "scripting language" :p. Try to answer without describing dynamic/hosted languages.
This video was very enjoyable. Thanks.
you are welcome :)
the exception thing sounds like something typescript could handle, like in java with the "throws Exception" and then force you to handle it
Not all errors are recoverable, so I would argue that there is place for checked and unchecked errors. Old days when Hibernate throwed checked operations from every method (any sql query could fail do to loss of connection) .... was a living hell.
I agree with having to go through C, but I don't think it's "just so you can have the experience". I think it changes your mindset, you learn to pay attention yourself to details (the compiler and the C runtime won't).
I would argue every new type of programming makes you a better programmer in all languages.
2:10 > "If this function throws, which function is going to catch it above you?"
But if this function just fails returning some error code, which function is going to handle it, if any at all?
I had a similar thought about that part.
I think Zig's model is still better, though, because you can't start throwing errors without obviously changing the signature of the function. If a function returns error, caller simply must deal with it, if only to pass it on. And compiler's going to know which errors could be returned from a given function so it can track it for you and make you deal with it at some moment. I think you can do similar things with try/catch handling but in Zig it's just cleaner, all is there in plain sight.
Computerphile dropped a new video on rust...it's one of the SIMPLEST explanation how memory allocation happens in RUST...in the video it's also compared to C++ as well
I have no idea if this is best, but 30+ years ago when I learned programming at first, I learned BASIC. I didn't learn about things like loops and function calls, those were things I had to make on my own. Then when I went into undergrad and learned about them, it felt like cheating... BUT I also knew how they were working "under the hood." So I think a good way to learn the basics is to learn how they work in implementation, even if you don't necessarily build a whole project that way.
My kids are interested in learning programming and I'm struggling with the best way to teach them. I think the best way is to start with just very simply, here's what a computer is: a processor and memory. Instructions are stored in memory sequentially, and the processor just executes those instructions in order, and here's what those instructions look like (a la BASIC). From that basis, then we can build in the concepts of loops and function calls, then data structures, etc.
I don't know though. I don't know the best way. Maybe Harvard CS50 is best?
To add to the "no hidden control flow", here's a story from the battlefield. Team of top notch engineers build a multi-peta-byte capable backend for dataflow and processing. Front-end team using some node+react end up on a call with the big wigs about why the application is erroring out. They point to the top notch engineers, I do a search from the stack to where the function is that isn't catching the throw. Turns out, they were calling us in node without ANY try catch or exception handling using promises or async. NONE! NONE AT ALL! So when their "fetch" threw an error (as one should when you receive a 500 from a server) it didn't know what to do and so it did.... nothing.... No error message, no UI update, no notification to the user, no log, nothing.
How did they take having the finger being pointed back towards them? 😂
Try Catch2 for c++ testing. Super lightweight, one header. Not crazy amounts of overhead syntax.
As an embedded C dev, I've been wanting a C with fewer "implementation defined", and some sensible quality-of-life ADA features - Zig looks very promising. Packed data types like Zig's may not be as pretty as the ADA type syntax, but it's still looking grand for mapping up register bit fields.
I love the idea of Zig and maybe it's just because I'm brand new at learning a newer language, coming from mainly C, Python, and MATLAB the past few years, but the Zig compiler always seems so angry at me :D. A very difficult to write language at first, but I can see if you can get good at Zig then you must be an incredibly talented programmer.
Yes, that's exactly how zig does errors; you can declare error sets, which are effectively sum types.
Jeeeeesus, for a programming channel this is iiiiintense... Love the energy. Keep on!
7:50 You know you spent too much time on _Vim_ in a windowless room when…
…you see bloat in _C_ . 😄
Google on Monday donated $1 million to the Rust Foundation specifically to improve interoperability between the language and C++. C++, a popular general purpose programming language, has arguably fallen out of fashion due to concerns over safety.Feb 5, 2024
update for those not in the know, zig moves fast!
some of primes concerns are mediated already, and many more things are to come.
it is very fun to watch this language grow and evolve
try catch are magical when you get some levels of recursion/calls/loops and you need to break to many levels up in the stack, nothing can beat this
Zig has labeled loops, so you can break out of any loop you want.
magic is the right word, but voodoo might be even more accurate.
I've been using Odin as my systems programming language of choice. I liked it so much I ported my C++ (ptoo!) project into Odin and it was way easier to extend, work with, and came out to less lines of code when I ported it directly. I'm interested in Zig, and have done a few trivial things in it, but haven't made anything big with it yet. Zig does feel like it's got a thick layer of boomer-programming aesthetics... Not good or bad, Zig just *feels* like an old language.
interesting. lots of people talking odin
@@ThePrimeTimeagen Get gingerBill, the BDFL of Odin on your show. You'll have a great time!
@@krisdabrowski5420 GingerBill, Andrew Kelly, and Joe Blow are always worth listening to when they're talking about languages and compilers.
@@ThePrimeTimeagen Odin is great. I’ve been using it and it’s really made graphics programming easy and understandable for me! You should cover it!
Am I the only one when heard "below the C-level" joke had a one specific tune play in my head that goes along with the lyrics "arrrre you rrready kids? aye-aye captain!"
My old man started programming on a Burroughs mainframe in the 1970s. Yes they literally wrote their programs on paper! The handwritten program would be given to a typist who would type it out onto punch cards. It would then be given to a second typist who would put the punch card machine and verify mode and retype the program. Then they would get the punch cards back and look through them to find the remaining errors. Then they would send it to be compiled, and they would get the compile errors the next morning.... The process repeats.
The big problem with a lot of the more recent languages (or languages that have evolved a lot recently) is the excessive syntax. There are just too many syntactical additions in languages like rust or even python or recent versions of JavaScript for that matter.
are they really 'too much' though? What is your metric for the justification of new syntax, and whats it's 'cost'?
Barely half a minute. Barely half a minute in. Barely. And Prime is already JUMping from his chair. That's some good TV here :D
In my first job i had to reverse engineer a C database extension. And the funny part is that i was hired as a Python Dev 🤣
I like Rust and Zig (and Swift). I wouldn't say Zig is better than Rust because it depends on your criteria, most of which is usually subjective.
To me C is more low level than Zig. Maybe passing allocators around and I think not having temporaries would be things that are lower level in Zig than C.
As someone who came from the 8-bit days and programming in assembly before C I always found C had bloat, but a lot less than almost every other language.
other things that makes zig more low level than c is alignment, alignment is a first class concern in zig, there are a bunch of built ins to mess with memory layout where in C there's almost none. but yeah overall zig has more high level features than c does, that's how it manages to become a "better c". if it had the same level of abstractions it wouldn't be that different from it
If you like Zig you'll love Nim! writes and reads like Python, compiles to C/C++/Objective c/Javascript, best FFI and interop, has a python-nim bridge, no memory management (unless you want) with the same performance as C, the list goes on. I love it
@@kishirisu1268 There isn't an additional layer they're compilation targets. You have a single, concise syntax to do it all without sacrificing anything. I find it absurd that you find this absurd
@@leonlysak4927 So it just sounds like code generation. YOu write Nim and it compiles to one of those other languages? or bytecode or machine code?
@@lod2414 Exactly. If you target a c/c++ backend it will produce optimized c/++ code and then gets ran through your normal c compiler. For javascript, it just produces the code in a single file. There is a WASM and LLVM backend too but I haven't used them
Try Odin. With all the bundled libraries, getting things moving around the screen is really easy and setting up Odin in the first place is easy. Great place for beginners to start.
Hmm, multiple languages are now kind of trying to be better than Rust. Here we have Zig, but there's also the V language, and there are probably even more coming up.
The issue is that these programming language projects are all very young and unfinished. While Rust is actually very mature in comparison and has really started to break through. Quite a difference.
Those other projects still risk being descontinued when things end up not being popular enough and people stop investing in them.
A lot of time has been invested in making Rust a very well designed, robust language.
Things might change in the future, but I think at this moment Rust is still the most interesting one to continue learning.
Regarding the last part, I think "maintain it with zig" is a really powerful way to put their foot in the door of C.
Rust is not hard. It just takes some time learn it. Like twice the time of other ones for learning the basics. Only twice because Rust compensates the hard parts to learn with much simpler constructs than other languages. For me now it's much easier than Python and bash.
I test things to make sure they work the way I think they do, like I write code, and I write my tests to make sure it works specifically the way I wrote it, I attempt to strongly type all the values, and I write counter tests to make sure that it's not returning results when it shouldn't. I've been so tired of thinking that it works the way I intended and instead KNOW that it works the way I intended
13:23 “I don’t do red-green-refactor”. I take very similar stance to Prime on testing for the most part, but probably lean a little more on the fewer tests side. One thing I do, which might be different than what is being referenced here, is when a nasty bug comes up that I want to guard against regressing is to write a test that fails before fixing it (which then passes). There have been far too many times when I either think I’ve fixed a bug but actually didn’t, or had a regression but lost context on how it was fixed before (b/c the code has changed too much that git directly before/after the fix doesn’t show how to fix it NOW) that this is non-negotiable for me. Maybe this has a different name
He mentions carbon as the "language we already have" when carbon doesn't even have a simple compiler yet. That's how you know that guys knows nothing about what he's talking.
]
"not a great catcher" - coach probably made him play right field position like me
There was an episode of Myrhbusters years ago where they tested a myth about blind drivers. They found it was easier for a blind driver to follow the instructions of a literal backseat driver than it was for a blindfolded person who can see. The blind person has absolutely no preconceptions, they've never driven before. They just do exactly what they're told. People with previous driving experience couldn't help but want to apply all their own preconceptions and habits to the situation.
I sometimes think this same idea would apply to Rust as a first language. Most people struggle because Rust is very different from the expectations they can't help bring with them (why FP bros have less trouble, their expectations align). New folks have none.
Just as an annoying WHELL ACKYUHALLY about the hidden control flow:
You have CHECKED exceptions. These are exceptions that the compiler forces you to deal with. These are very much not hidden, and a lot of developers hate having to write their code in a safe and reasonable manner. (Guess which one Java uses by default.)
Then there are UNCHECKED exceptions. These do not force you to deal with them and will happily bubble up your call stack until they're either caught by a framework, or they blow up your entire program. C# uses this.
There has been a flamewar over checked vs unchecked exceptions in the enterprise space over this for two decades or so. I have my own opinions, but I'll keep them to myself.
Why not share? This comment section is full of great discussion
I unit test all of my self-made library code extensively, which reduces my bugs to the stuff you might put in a main()
NULL termination: Use clang-tidy and activate "bugprone-not-null-terminated-result" and "bugprone-string-literal-with-embedded-nul¶".
Problem solved. I couldn't image programming C or C++ without clang-tidy and clang-format. And please active the clang- or the gcc-sanatizers as well.
The C++ gag of learn it in 21 days: you must practice and learn C++ for 90 years, go back in time, then kill your past self, then you've learned it. I lost it so hard I cried. That was so gosh darn funny sir.
Awesome vid! Prime is hilariously genius. However, consider your business logic broken if it's not tested.
Try-catch hidden control flow was just reimplementation of INTERCAL's COME FROM statement.
I've always been more in favour of the alternate return paths as arguments approach than the errors as return values approach. Basically, if a procedure can fail in a recoverable way, take the handler for that failure case as a required argument. If it can fail in non-recoverable ways, log+exit, crash hard and fast while keeping record of why. And if you want to provide the option for the caller to opt in to recoverability, those should be two (or more) different procedures with different signatures and not an optional parameter.
Seems helpful for a function with multiple steps where it could fail instead of splitting each stage into a separate function.
You could have a single function that accepts Option-al handlers, maybe with a sort of builder style struct if there are a lot of handlers.
I don't see why this pattern precludes ever using Result, in fact it could be useful to combine them in some scenarios.
it sounds like you prefer to crash and exit on any unrecoverable error?
@@michaelthompson7217 If it's deemed unrecoverable, what else are you supposed to do?
@@michaelthompson7217 Unrecoverable errors basically have three possible paths to go. Muddle on in a corrupted state and accumulate garbage that you foist on the user, muddle on in a corrupted state and foist that corrupted state onto connected systems, or shut down - either as neatly as you can at your own devise, or hard and fast by the kernel.
[EDIT] Becoming totally unresponsive and keeping rendering over everything else was a common fourth option back in the DOS and Windows 9x era, as well as anything else that running user programs in ring 0 afforded you...
Hell yea! Collab with LLL would be fan-friggin-tastic!
yeah LLL is great
Vector comes about because the creator of the C++ Standard Template Library, Alexander Stepanov, called its arrays Vector. A mistake he says he regrets in one of his video presentations. Which I on TH-cam someplace. Everyone else has continued with "Vector" since then, it's tradition.
Zig shouldn't have a lot of trouble entering any place where C is already in. That's the advantage, you can import any C function and you can even kinda transpile C to Zig. So in theory even if you don't have a library in Zig for what you want, so long as there is a C one you should be good
17:36 The way Low Level Learning guy is looking at ThePrimeagen jucy ace is killing me
learning computer programming for the first time is hard these days. I started in Pascal then learnt some C, then did some C++ back in the 90s. Then not being in software development, then just doing dirty for loops in interpreted languages where I didn't need to really care. Then coming back to Rust it makes you feel like you're doing CS 101 all over again. I think if people don't learn on Rust first, then people should learn in C then move to Rust.
This guy is a web development guy . I know him . He just making video from his basement. Nonclue for this guy .
hidden control flow is cool for anti debugging techniques and anti analysis. Cool stuff
Programmers in about 105 different programming languages were challenged to write a specific test code that found and counted prime numbers. RUST was about 3.5 times faster than just about any other language including assembler language. The only language that was faster than RUST was ZIG - which was twice as fast as RUST. If you want your program to run as quick as possible - it turns out this very new programming language is the one to beat.
how can Rust and Zig be faster then assembler ? Is it bcs. of the optimization from the compiler ? I hope somebody can explain me that.
@@npc_codeit's hard to handwrite fast assembly. The compiler is really smart
Came for the reaction, stayed for the yelling 👍
There is two thing I respect Java for and that is SomeGeneric and forcing the developer to handle exceptions or declare that it throws an exception.
0:18 That spit is personal. I always laugh out loud when hear that hawking sound followed by spitting for C++, C#. And I listen to these vids while doing something else :D
Edited timestamp for better timing.
Testing after writing the code is kind of a thing I hear many people doing. Not that the TDD is bad or hard, but still kind of a preference thing.
So only ever been a hobbyist, and only ever used Python. And about 6 months ago now I decided to learn Rust, and I personally found it very easy to pick up and start building stuff. Now was it good, or anything, no, and never was gonna be. But I've loved learning Rust, compared to when I was first starting out with Python.
"But I thought we didn't do jokes below the C level".
*Everyone liked that*
Zig's build system is great, takes away the pain of C . But then you have to take care of the allocators, which is cool for hobby projects, not sure in production.
Vectors are the coolest part of zig imo. Super easy simd work
1:35 - Jesus Christ I'm so much with you on that. I hate throwing errors. I would much rather break the entire language's paradigm and return an error or a list with the return value and possible error and just straight up do it the procedural way.
functions not having what it throws in the signature is also one of the biggest problems in C++. Yeah you do have noexcept there but almost no one actually uses that correctly and it's basically only in code documentation and doesn't actually enforce anything
The only time I use TDD is when designing an APi. I find it easier to visualize how an API should work by actually writing the client code first.
Net. The compiler help is what I ve been looking all my life. I found my language.