When Zig Outshines Rust | Prime Reacts

  Рет қаралды 130,526

ThePrimeTime

ThePrimeTime

Күн бұрын

Recorded live on twitch, GET IN
/ theprimeagen
Blog article: alic.dev/blog/dense-enums
Author: Adrian Alic | alic.dev
MY MAIN YT CHANNEL: Has well edited engineering videos
/ theprimeagen
Discord
/ discord
Have something for me to read or react to?: / theprimeagenreact
Hey I am sponsored by Turso, an edge database. I think they are pretty neet. Give them a try for free and if you want you can get a decent amount off (the free tier is the best (better than planetscale or any other))
turso.tech/deeznuts

Пікірлер: 325
@genericuser1546
@genericuser1546 7 ай бұрын
if anyone is confused about 15:17 the padding is required for struct alignment, since the 1 byte tag is being stored with a type that has larger alignment requirements (u16/u32)
@yannick5099
@yannick5099 7 ай бұрын
Zig is super cool. It's a modern version of C with lessons learned. Language, tooling and community are great. I have high hopes for the language.
@pmoohkt
@pmoohkt 7 ай бұрын
So sad I'm allergic to the letter 'Z' nowadays for... reasons. I abandoned ZIO (a functional layer on top of Scala), and didn't buy a ThinkPad Z13 for exactly the same reasons. Call me crazy on that one !
@AlFredo-sx2yy
@AlFredo-sx2yy 7 ай бұрын
@@pmoohkt I know where your Z phobia is going and i just can't help but wonder what does that have to do with programming. Is it just me or are you Rust folk overly political?
@yevgenydevine
@yevgenydevine 7 ай бұрын
@@pmoohkt you could've said you are retarded in fewer words.
@pmoohkt
@pmoohkt 7 ай бұрын
@@AlFredo-sx2yy Sorry, I'm not a Rust folk at all, I work in Scala. Yes I 100% agree that it has nothing to do with programming and it's a personal feeling... just seeing the letter Z inside a logo makes me want to look elsewhere... like when I see the German symbol of war last century, I tend to forget that it was (and still is !) a representation of sun and well being for more than 2500 years. Nothing political, gut feeling... I may very well be the only one 🙄 Question: how would it be if you put a sticker of the Zig language (that big Z in brackets) on your laptop and go to sit in a coffee shop? Maybe OK in US, not sure how it will work in Eastern Europe however, and you will have lots of new friends in Russia for sure !
@vikhr
@vikhr 7 ай бұрын
@@pmoohkt I think you need to stop being addicted to politics and mainstream media, it looks like it is causing irreversible brain damage.
@steffahn
@steffahn 7 ай бұрын
5:19 - the padding is actually just because the u64 is 64-bit aligned. The tag is just a single byte, Rust doesn’t make these bigger than necessary. But for the u64 to be 64-bit aligned, now the enum Foo must also be aligned this much, which is where the padding comes from.
@zactron1997
@zactron1997 7 ай бұрын
I love Rust, but I agree I'd love Zig's comptime system as an alternative to macros. Rust macros are vastly better than C, but there's definitely utility in comptime.
@FlanPoirot
@FlanPoirot 7 ай бұрын
The con of zig's comptime is that writing an LSP for it is just harder. Types and fields can change based on the platform you are, type definitions can be created through a comptime thing, so your LSP has to be able to run arbitrary Zig code on the fly to be able to give you accurate autocompletion.
@VivekYadav-ds8oz
@VivekYadav-ds8oz 7 ай бұрын
​@@FlanPoirotI don't see how that'd be different than running arbitrary Rust code for proc-macros.
@zzzyyyxxx
@zzzyyyxxx 7 ай бұрын
Too bad the person working on compile time macros in Rust was chased away...
@FlanPoirot
@FlanPoirot 7 ай бұрын
@@VivekYadav-ds8oz in rust every compile time thingy is easily marked as such, they're either const or a macro, zig allows arbitrary code at compile time
@chainingsolid
@chainingsolid 7 ай бұрын
@@zzzyyyxxx If your looking to generate code at compile time D has string mixins. You write some mostly regular D code that generates a string at compile time and it gets treated like source code the compiler read off disk.
@kuhluhOG
@kuhluhOG 7 ай бұрын
8:20 This reminds me. AT some point Gamer's Nexus was also benchmarking compile speed of CPUs because of common request. But they noticed something: It effectively just "benchmarks" how much Cache a CPU has (more = faster) with minimal differences when two CPUs have the same amount of Cache (except ofc if we talk multiple generation difference, but that's to be expected). So at some point they stopped because they also just could have given their viewers the datasheets. (They tested this by compiling Chromium from scratch.)
@weeb3277
@weeb3277 7 ай бұрын
total zigger victory
@lorenzodrea4640
@lorenzodrea4640 7 ай бұрын
Idk why people sometimes present zig as an opposite to rust when they are amazing complementary languages. You want memory safety -> rust You want memory controll -> zig They both have a lot of features in common (can't wait for zig 1.0 so i can start learning it)
@bashiry4218
@bashiry4218 7 ай бұрын
You want memory safety -> go You want memory controll -> zig
@lorenzodrea4640
@lorenzodrea4640 7 ай бұрын
@@bashiry4218 waiting for the garbage collector to de-allocate you comment /jk
@nathanfranck5822
@nathanfranck5822 7 ай бұрын
I'm learning now - It's fun! ZLS has an option to buildOnSave which helps me fail faster. It'll be nice when Github Copilot isn't 2 years out of date for all the stuff that's changed
@mattymerr701
@mattymerr701 7 ай бұрын
​@@lorenzodrea4640 now it'll never happen because you made a reference to it
@swapode
@swapode 5 ай бұрын
TBF it's really rather rare edge cases where Zig offers better memory control. Like Rust's approach to ADTs is exactly what you want in over 99.9% of cases, because you'll generally wanna save CPU cycles over a hand full of bytes. And it's not that Rust doesn't allow to do the same thing, it just doesn't help you there. I'm doing some embedded stuff in Rust right now, and I'd rather write a bit more Rust code than introducing another language (besides the need for the Zig solution simply hasn't come up yet). I suspect I'd see it the same way if I was writing a compiler. I'd take a couple of hours to write the packed array data structure for that specific purpose and be done with it. Sure, it's not generic, and it'd be cool if it was, but a couple of hours saved once for a big project is actually utterly meaningless - especially when there are way more hours that Rust will save me in the overall project. But maybe that's unfair, I spent a quite a bit of time to get truly comfortable in Rust - and it seems unrealistic to expect the same from other developers. Not because it's a bad idea, but because most just accept that Rust is hard and give up before they're even halfway comfortable in safe Rust.
@JoseColonTV
@JoseColonTV 7 ай бұрын
Learn Zig or Ocaml? Go for Zig man, it's the future of systems programming. I predict (crystal ball moment here) that when Zig is mature enough (post 1.0) Linus will prefer it over Rust for the Linux Kernel. Rust is great and provides many safety guarantees, but if you're a C kernel hacker, it's definitely more natural and painless to switch to Zig.
@jmickeyd53
@jmickeyd53 7 ай бұрын
Learning Zig is clearly the more practical choice, but I think the real benefit of learning a new language is to learn a new paradigm. It forces you to think about solving the problem in new and different ways. And for that, I think OCaml has more value, even if you never write another line of OCaml after you're done.
@sprenten1
@sprenten1 7 ай бұрын
In this instance It's even more painless to write the same thing in C than either Rust or Zig.
@shrin210
@shrin210 4 ай бұрын
​​@@ITSecNEO Keep your opinion to yourself. Zig is safer than C. Unsafe code in C != unsafe code in Zig. Because zig is so similar C that it will be easier to integrate if existing codebase is in C. Unlike rust which is totally different to code. Many reasons to use Zig. If they implement it or not time will tell.
@shrin210
@shrin210 4 ай бұрын
@@ITSecNEO Atleast make a convincing point before posting jargon like facts(opinions). You could have included points related to systems programming about why not zig? Your facts was just basic blog about memory unsafe vs memory safe 🫤
@sean_r
@sean_r 3 ай бұрын
​@ITSecNEO dude i dont think zig will be integrated either but jesus theres no need to get so aggressive about it. on top of that, you hardly have said anything that would indicate your knowledge on the subject, and particularly with yor comments on zog's safety, i find it hard to believe you know what you're talking about when it comes to zig. aside from all of that, your comments come off as just kinda bitchy and arrogant
@JDalmasca
@JDalmasca 7 ай бұрын
I think the TS equivalent to Rust enums is like passing type arguments into generics and then using a type union like the one you showed. Maybe something like this?: type Foo = undefined | Bar | Baz Doesn't seem like quite the right syntax, but probably close.
@replikvltyoutube3727
@replikvltyoutube3727 7 ай бұрын
The thing missing from article is that, even though there are different size arrays, each element will also need to have a type information. That's how you do match over elements
@apestogetherstrong341
@apestogetherstrong341 7 ай бұрын
"comptime ... is like you write zig that writes zig" Can't wait for him to learn about lisp in like 10 years
@SaHaRaSquad
@SaHaRaSquad 5 ай бұрын
It sounds like you assume the only reason people don't use lisp is because they don't know about it.
@adamm450
@adamm450 5 ай бұрын
@@SaHaRaSquad arguably one of the reasons why people dont use lisp is because they know about it
@apestogetherstrong341
@apestogetherstrong341 5 ай бұрын
@@SaHaRaSquad it is
@apestogetherstrong341
@apestogetherstrong341 5 ай бұрын
@@SaHaRaSquad or actually, the reason they don't use it is "no i don't like the parens". that's it
@apestogetherstrong341
@apestogetherstrong341 5 ай бұрын
@@adamm450 do you know about it?
@yaksher
@yaksher 7 ай бұрын
@2:00 I believe Rust uses the smallest integer size that can store the number of enum variants for the tag (so, u8 almost always), not a word.
@MetroidChild
@MetroidChild 7 ай бұрын
This is explained later in the video, but in order to not tank performance, types need to stay aligned to their size. This means if you have an 8 byte union (i64, i32 etc) you still need another 8 bytes for the type tag if it's stored right next to the union in memory (to keep the upcoming 8 byte union aligned), this means 9 bytes of storage becomes 16 bytes.
@yaksher
@yaksher 7 ай бұрын
@@MetroidChild I mean, it depends, but yeah I guess it does mean that the tag is usually a word in practice. But if all of the types in the enum have 1, 2, or 4 byte alignment instead of 8 byte alignment, then it's relevant. That said, yeah, if you have a u64 in your enum somewhere, it'll probably end up requiring the tag be padded to a word yeah.
@wliaputs
@wliaputs 7 ай бұрын
@@MetroidChild Why does that tanks performance?
@MetroidChild
@MetroidChild 7 ай бұрын
@@wliaputs "safe" programming languages have to add more pointer checking if a data type is unaligned, if you use "unsafe" languages without dynamic pointer checking performance won't take a hit, at least not on modern processors (10 years ago it was a different story).
@disieh
@disieh 7 ай бұрын
I don't remember where I read it, possible some CppCon video. My understanding why Rust chose so explicit and painful integer conversions is learnings from C and C++. People running analyzers on C and CPP which found overflow issues often found it next to impossible to deduce after-the-fact what under or overflow behaviour was correct choice. It was so tricky that sometimes even original authors did not know. Rust tried to preempt this by being much more strict about conversions and over/underflows.
@ruanpingshan
@ruanpingshan 7 ай бұрын
A lot of the time, whenever I include any math/scientific C++ library, the compiler output is absolutely flooded by numerical conversion warnings, making it very difficult even to find error messages.
@blenderpanzi
@blenderpanzi 7 ай бұрын
That makes sense for converting e.g. u64 to u32, but why do you need to be explicit when converting u32 to u64? What possible problem can there be? Which is what he asked in the video.
@disieh
@disieh 7 ай бұрын
@@blenderpanzi my guess, they made it explicit so whoever is writing the code is forced to think about, hopefully reducing unintentional mistakes. Only time will tell whether this system was a good choice or not. In some ways same theme as borrow checker, attempt to turn hard-to-debug issues into compile-time issues.
@blenderpanzi
@blenderpanzi 7 ай бұрын
@@disieh Yeah, but what mistake can there be when converting from u32 to u64? If you need to do the cast even when there is no reason, then doesn't casting become like clicking away error messages? You're just doing it without thinking?
@disieh
@disieh 7 ай бұрын
@@blenderpanzi Only reason I can think of is if you do widening conversion somewhere, you realistically end up doing narrowing conversion somewhere later. Explicit conversions force you to type stuff that can be searched later --- or analyzed by a tool for that matter. Is there a less invasive way to achieve same thing? I don't know, probably. Also I think they probably thought its easier to first make something that works and is strict, only later loosen it up when its more clear what can be loosened without sacrificing correctness.
@jacknguyen5220
@jacknguyen5220 7 ай бұрын
As someone who has implemented indexing on segmented arrays using trees, I can confirm dealing with indexes can become a nightmare. For example, 1 optimization that could be considered here is optimizing the index bookkeeping for long contiguous segments with the same size or type, which when I last did it I basically had trees on top of my trees.
@FrankHarwald
@FrankHarwald 7 ай бұрын
21:49 custom bit width integers is something I've always wanted to do but never could - outside of VHDL, Verilog & custom Clang intrinsics.
@boy_deploy
@boy_deploy 7 ай бұрын
Yeaaaaah! been waiting for another Zig video ❤
@evtimpapushev7137
@evtimpapushev7137 7 ай бұрын
On the question at 15:29 - tags match the size of the fields because of memory alignment. Each data type aligns at addresses divisible by the size of the data type.
@JorgetePanete
@JorgetePanete 7 ай бұрын
You can't deny that Rust has SotA throughput in drama.
@blinkybool
@blinkybool 7 ай бұрын
16:00 that’s the field_map array in the code snippet you skipped. The field to clusters bookkeeping is handled internally in the data structure, and it provides an interface for appending, getting a removing.
@simonfarre4907
@simonfarre4907 7 ай бұрын
Which makes me wonder? Why not write this in C++ where this would be fairly trivial. More trivial than Rust, certainly, but even so, more trivial than Zig?
@spidertyler
@spidertyler 7 ай бұрын
hah, I saw this a while ago and was just waiting for you to make a video about it. Much easier than reading the article myself lol.
@broken_abi6973
@broken_abi6973 7 ай бұрын
This would be an example where C++ outshines Rust. It is ok. I will see my way out.
@sprenten1
@sprenten1 7 ай бұрын
Absolutely not you can't leave, we need to create a C and C++ party here, because this is kind of how good C programs have handled memory, used void pointers, structs, and arrays of structs as kind of a generics or variants. Also there is a way to pack the data in C that the Zig example doesn't use which would further reduce memory and increase speed even with a pack and unpack tradeoff and I know it can be done in C++ too.
@sean_r
@sean_r 3 ай бұрын
well c++'s lack of static reflection would make this completely impossible
@victorpinasarnault9135
@victorpinasarnault9135 7 ай бұрын
I ❤ Zig
@thedelanyo
@thedelanyo 7 ай бұрын
For the next decades I guess it's gonna be Rust vs Zig
@steveoc64
@steveoc64 7 ай бұрын
"When Zig outshines Rust" - man, any article that covered that question would be a very very looooooooooooooooong list of use cases
@itz_premium
@itz_premium 7 ай бұрын
I have a new favorite quote now... "If you wanna just raw dog some strings in there.."
@wesleydahar7797
@wesleydahar7797 6 ай бұрын
The memory saved by creating an array of vectors of arrays (AoVA) also incurs dynamic memory allocation, non-trivial member access/iteration, poor cache locality, and memory/performance overhead for maintaining the complex AoVA structure. Unless you're working with tens of thousands of elements in single (not multiple) collections, you're not going to see any benefit of memory usage over performance cost and the data access limitations from even a syntax standpoint. I'd imagine that wide references into that collection will immediately negate the saved memory, especially for tightly coupled data structures like ASTs. There will be dynamic memory allocation for a mutable AoVA (even if it is never resized) because the worst case requirement of storing only the type with the largest size and alignment will necessitate that the total worst case space is allocated at some point if many of the elements are set to those types during runtime. I think it's better all around to simply pre-allocate the worst case space and accept that alignment will incure at worst an 8 byte overhead for the tag and structure alignment and handle exceptional, large types as pointers/references instead of by value.
@maksymiliank5135
@maksymiliank5135 7 ай бұрын
I've read this article a while ago and I thought to myself that it would be cool if Prime read it because it shows why SOA is great for caches
@itellyouforfree7238
@itellyouforfree7238 7 ай бұрын
5:20 no, the padding is there to satisfy alignment requirements of the subsequent field
@dealloc
@dealloc 7 ай бұрын
The equivalent in TypeScript is to define a type which has a unique tag (e.g. an object with a "type" field, that has a unique value amongst the other variants with the same field, but different values). A union of those types would be a tagged union. You can add additional data onto each variant, even with the same values as other variants, as long as the tag is unique. Undefined, null and whatever does not need to be part of this at all. They would also be serializable the same way enums are in Rust with serde_json. You'd still need to specify to serde _how_ to serialize and desrialize, it's no different than doing it in JS.
@balen7555
@balen7555 7 ай бұрын
#[derive(Serialize, Deserialize)] Damn, I had to specify to serde *how* to indeed.
@FlanPoirot
@FlanPoirot 7 ай бұрын
let's not pretend that you're doing anything relevant with typescript, all those type definitions are an illusion, whether they're there or not does not really matter for memory alignment or layout, those definitions are just there for your own conform they're not really changing anything.
@andrueanderson8637
@andrueanderson8637 7 ай бұрын
@@FlanPoirot Of course TypeScript types don't change memory layout, what would be the point of using a high level language if I needed to worry about memory layout? Might as well just write the C code at that point (and, e.g., compile to WASM)
@dealloc
@dealloc 7 ай бұрын
@@balen7555 You miss the point. Those are just proc macros that result in additional code in your build-that code is generated as compile time. The point is not what the API looks like, but that the steps to serialize and deserialize those objects to conform into and from those types is equivalent no matter the language.
@dealloc
@dealloc 7 ай бұрын
@@FlanPoirot This was specifically pointing to Prime's example of using "undefined | string" union, which are not tagged unions (in the traditional sense). The point was to illustrate how you can create tagged unions equivalently in TS. The post itself was talking about enums, not tagged unions specifically. All tagged unions in any language is "an illusion" because they are concepts in type theory, and are not compiled into machine code. I specifically didn't mention enums, because they are specific to the implementation of a compiler.
@b4rti89
@b4rti89 7 ай бұрын
Daddy Prime, more Zig please! :)
@SimGunther
@SimGunther 7 ай бұрын
Dlang SumTypes are a marvel in every way for how powerful, but frustrating they are to use, especially for sum types that include classes with at least two levels of hierarchy. Once you figure out how they work to shape the design of the solution to your problem, it's a glorious thing to witness how effortless maintenance for these parts of the program are.
@FlanPoirot
@FlanPoirot 7 ай бұрын
people still care for D in 2023? D blew their one opportunity to get popular by shipping with a garbage collector enabled by default. and from what I've heard the better C mode of D is kinda pointless if you want to use external libraries anyways cause they all rely on the GC.
@SimGunther
@SimGunther 7 ай бұрын
@@FlanPoirot Proving that Dlang is maintained by engineers not smart enough to make a sensible language for high quality business, but clever enough to make some neat conveniences for engineers who still care to use Dlang in _insert current year_
@HypoceeYT
@HypoceeYT 7 ай бұрын
@@FlanPoirotA GC that's guaranteed to only ever run when you allocate memory and there is none free to allocate, which the compiler will check for you in your hotspots with one keyword; that's mitigated or eliminated by the same things you do for performance in any manual memory language; and which has been used in financial trading code, the most latency-sensitive programming imaginable. Carry on.
@timseguine2
@timseguine2 6 ай бұрын
​@@HypoceeYT Dlang's garbage collector performance is quadratic in the heap size. That makes it by far the slowest GC compared to any other GC language out of the box.
@HypoceeYT
@HypoceeYT 6 ай бұрын
@@timseguine2Cool story. I very much doubt that next to Python, given....Python...but even if so, so what? We're assured that GC performance doesn't matter because all GCs are poison; we're following off a comment that Dlang destroyed itself by putting a GC in by default, ewww blech mah performance, it's on my hands, get it off. A GC that's guaranteed by the compiler not to run has no performance impact. You rough out your program as in (GC-tainted crippled languages that nobody uses since they blew their one chance at popularity by putting in a GC) Python or C# or anything on the JVM including Kotlin, then tag your performance hotspots nogc and put in object pools and such to tweak them, as if you were in C or C++ but sane and with a bunch of other conveniences and lovely idioms. How is doing all that flow in the same language, with a single keyword that enforces the rules at the compiler level (much like a subset of Rust's philosophy) and tells you where to look if you hit a memory problem, worse? And then there's the crazy team that needed to go big and fast and not have big GC pauses, needed GC -enabled algorithms, and accomplished their performance goal by running the GC _more often_, placing a mathematical upper bound on the amount of memory it could possibly need to clear.
@blenderpanzi
@blenderpanzi 7 ай бұрын
OT (because one of the chat messages): If you double click you can select a whole word. Keep the mouse button pressed to select word by word instead of character by character. This way you don't need mad FPS skills to quickly select text. Also triple click selects whole paragraphs.
@mage3690
@mage3690 7 ай бұрын
I thought triple click was for lines, unless HTML just considers everything between tags to be "lines" for some reason.
@blenderpanzi
@blenderpanzi 7 ай бұрын
@@mage3690 Well, it spans wrapped lines, but doesn't span over . Whatever one might call that unit.
@mage3690
@mage3690 7 ай бұрын
@@blenderpanzi honestly, not shocked by that. It's a wrapped line. It is a really weird unit to explain to anyone who doesn't know what wrapped lines are, though; and it gets even more confusing when you start considering certain text editors like Quark and WordPerfect (there's a Wiki article on this, shocker). Most environments do agree that triple click is for one line, wrapped or not. WordPerfect says it's for an unwrapped line, and Quark says it's for a sentence--and adds quad and quintuple clicks for paragraph and document, respectively.
@wliaputs
@wliaputs 7 ай бұрын
Wow I didn't know I can drag after double clicking
@gagagero
@gagagero 7 ай бұрын
What's the plugin that auto-generated the match statement at the beginning? Copilot?
@ryanseipp6944
@ryanseipp6944 7 ай бұрын
I wonder what the performance impact of all this effort would be. On one hand, you have much less memory utilized for padding, and can theoretically fit more into a cache line. On the other hand, to iterate through, or utilize in some way seems to require quite a bit of indirection by looking up indicies and swapping between arrays in the SoA. The latter maybe kills the benefits of more tightly packing the memory layout due to cache lines getting swapped out constantly? I don't know the answer, but interesting to think about.
@aoeuable
@aoeuable 7 ай бұрын
The answer to your thoughts is: Stop thinking and benchmark. But to contribute to the speculation: SOA like this will be slower for random access, but faster to iterate through, in both cases only if memory is the bottleneck in the first place otherwise they're going to be the same (indexing maths is negligible compared to what a CPU can do in a memory load).
@MetroidChild
@MetroidChild 7 ай бұрын
Really depends what you need, splitting out the tags into their own array is basically free though if you just need element sized unions, it only like 3-5 extra ops per access, prefetching on modern processors handle any remaining latency.
@garanceadrosehn9691
@garanceadrosehn9691 7 ай бұрын
Very well-written and obviously well-researched article. Definitely interesting and worthwhile. Thanks for picking this to review. I suspect you've already figured this out, but 'AoVA' was defined earlier in the article: _"I don't think there's a name for this collection, so I call it array of variant arrays (or AoVA). "_
@Kabodanki
@Kabodanki 7 ай бұрын
I ❤ zig.
@JoeTaber
@JoeTaber 7 ай бұрын
We never got an answer on how to actually index into this (memory efficient) rats nest. Also, this is basically an ECS right? Has anyone tried ASTs with Bevy's ECS?
@TheSkepticSkwerl
@TheSkepticSkwerl 7 ай бұрын
I like how your montanian accent stands out when you say the word tag because you're pronouncing it just like they pronounce the word bag
@k98killer
@k98killer 7 ай бұрын
Primeagen skipped the one sentence that explained keeping pointers created at insertion in the vector implementation.
@dezlymac
@dezlymac 7 ай бұрын
😭 Man I understood like 2% of this... I need to learn a low level language like Rust or Zig. JS ain't it
@_start
@_start 7 ай бұрын
Learn C
@dezlymac
@dezlymac 7 ай бұрын
@@_start I'm looking for something more modern
@0netom
@0netom 7 ай бұрын
it's starting to look like it's already okay to learn Zig as the 1st low-level language... though learning C shouldn't take longer than a month or so, including the core of libc. it's hard to make such recommendations though, because i had decades to learn these things, since i was growing up in parallel as the computer industry :) i was born in 1977 and wrote my 1st for-loops on a ZX81 with 1kilobyte RAM, when i was 6 years old.
@dezlymac
@dezlymac 7 ай бұрын
@@0netom 😲 6 years old! Whoa that sounds freaking badass. As you mentioned you had decades to learn. I'm already studying Typescript, and Solidity, so realistically I would only be able to add one low level language to my arsenal. And to master it to a proficient. It's a bet which one would pay better dividends in the future. 5 Years experience with Zig, or 5 years experience with Rust...
@mgord9518
@mgord9518 7 ай бұрын
Zig is a pretty incredible language, but it's still fairly unstable at this point which might be confusing at first. I had a bit of a rough start learning Zig coming from Go as it's a bit harder to find articles explaining it. Most of the learning is gonna have to come from official documentation (which is quite good) and reading the stdlib source code. Although I haven't looked back since. Zig's advantages greatly outweigh the issues of it being a relatively less common language. Zig's C interop is literally so good that it's easier to use C libraries in Zig than it is to use them in C.
@debasishraychawdhuri
@debasishraychawdhuri 3 ай бұрын
Have a union of Boxes in Rust. So, instead of the variant Bar(String), have Bar(Box::). Anyway you had to put some kind of indirection somewhere, just use the allocation made by Box.
@aoeuable
@aoeuable 7 ай бұрын
I don't think Ocaml has particularly much to offer when you know Rust and Haskell, practically speaking. I would say loot it for ideas: Have a look at functors and modules and variants and how you can put modules in arrays and stuff which is all very neat and nice. Otherwise it's simply a functional language, you already know GC, HM types, and strict evaluation, just (maybe) not all in one place. As to Zig... why not unsafe Rust? That's a question I have in general. If you really want to bend your mind go for Maude, something dependently typed (pick one of Coq, Idris, Agda), or maybe Prolog.
@njnjhjh8918
@njnjhjh8918 7 ай бұрын
Especially functors, for quite a while I got annoyed by C++. "How dare you call a functional object a functor! These OCaml functors are real functors."
@complexity5545
@complexity5545 7 ай бұрын
Yep. Haskell > Ocaml. But evidently the newer generations are changing ocaml for the better. Zig is good because it primarily uses the LLVM language/compiler. That's a good foundation and reason to use it. You can (probably) output to LLVM then use Haskell/megaparsec to convert it to any other language/parser (that LLVM and haskell knows about). Especially if they keep adding features and the safety that C lacks. I might look into Zig. Why not unsafe rust? Because the community might annex your project and start making it "safe", slow, and not acceptable by the rust community.....actix. Prolog was a good laugh...LOL.
@adrian_franczak
@adrian_franczak 7 ай бұрын
What about performance if you don’t have padding?
@PaulWalker-lk3gi
@PaulWalker-lk3gi 8 күн бұрын
"I have no idea what hi is talking about, but that sounds terrible." Thank you.
@MDarkus3
@MDarkus3 7 ай бұрын
Not related but I would love to see you talk about WebAssembly
@ikhlasulkamal5245
@ikhlasulkamal5245 7 ай бұрын
Bro used the First Chat wisely
@chainingsolid
@chainingsolid 7 ай бұрын
I may have to sit down and try out Zig's comptime. I wonder if it can finally beat D's compile time abilities (see std.traits, mixins, and ctRegex to start) the last one writes the code to implement a given regex at compile time.
@SaHaRaSquad
@SaHaRaSquad 5 ай бұрын
comptime is amazingly intuitive to use imho. You just put "comptime" in front of a function call and that function will be executed by the compiler and the code is generated from its return value. Precompiling a regex would work exactly the same.
@davidbriggs8109
@davidbriggs8109 7 ай бұрын
I want to use ocaml, but when I do open Base, it throws errors
@YomiTosh
@YomiTosh 7 ай бұрын
All the time, you have to leave the space. - F. Alonso
@nikkehtine
@nikkehtine 7 ай бұрын
Quick question: should I try Zig? I started with JavaScript, now I write mostly in Go, sometimes I try C but I can't really wrap my head around it a lot of the time...
@vyyr
@vyyr 4 ай бұрын
You should probably stick to one language and "master" it first before moving to another one, language hopping is not good for you. As for learning zig over c, I wouldn't. Zig is great but its still too immature. And, not trying to be a dick but if concepts in C are not clicking for you, try some different tutorial, different lecture, different book, something because the complexity of C is actually understanding the basic concepts of CS and not the language quirks.
@vantagepointmoon
@vantagepointmoon 7 ай бұрын
No clue as to what is being talked about here, but it's very fascinating. I'll probably stay comfortably stupid about topics like that, but I appreciate people burning their brains thinking about these things
@avishjha4030
@avishjha4030 7 ай бұрын
What happened to the Like and Subscribe agen or Zig outshine Rust agen?
@curlyfryactual
@curlyfryactual 7 ай бұрын
13:10 yeah, of course that approach is hard ... that's almost identical to glibc small bins heap allocation implementation.
@equivocator7727
@equivocator7727 7 ай бұрын
Zig's comptime is so beautiful because it does generics imperatively where most other languages do them declaratively. In fact, I'd go so far as to say declarative programming constructs are almost always a sideways way to think about a problem space.
@phazechange3345
@phazechange3345 6 ай бұрын
Everyone always talks about generics, but comptime is actually not even mostly used for that. Comptime can reify *any* code, not just generics. This makes it extremely easy to, for example, present a unified API to your users, but individually package optimizations that their use case needs. Efficient inversion of control is trivial. Comptime is used for all sorts of things that has nothing to do with generics. Comptime is one of those things that might just turn all of programming on its head.
@VBB9999
@VBB9999 4 ай бұрын
what plugin are you using to get such suggestions as on 2:11? it looks close to cs suggestions in visual studio.
@4sat564
@4sat564 7 ай бұрын
ghostty terminal emulator presentation on zig showtime shows lots of interesting zig patterns
@0oShwavyo0
@0oShwavyo0 7 ай бұрын
Thumbnail backwards? Just a heads up I think someone put the rust/zig logos in the wrong place when slapping that together
@milckshakebeans8356
@milckshakebeans8356 11 күн бұрын
Is it possible to use the virtual memory algorithm for this. Maybe I didn't understand but it sounds like a vry similar problem to ram memory fragmentation.
@matheusjahnke8643
@matheusjahnke8643 7 ай бұрын
Actually... the memory layout of tagged enums is undefined.... It means it is generally like it was said... but there are exceptions. Like Option.... because we know valid null pointers don't exist. Or Option... because we know NonZeroU8 can't have a 0 value.
@ablobofgarbage
@ablobofgarbage 7 ай бұрын
shoutouts to Orzgorth
@blenderpanzi
@blenderpanzi 7 ай бұрын
"Why is the tag matching sizes?" Because of alignment. 16 bit values have 16 bit alignment, 32 bit values have 32 bit alignment, and 64 bit values have 64 bit alignment. Yes, modern processors allow unaligned memory access, but usually with a performance penalty, so compilers align values (unless you specify `#pragma pack` in C or `#[repr(packed)]` in Rust). So I gather the tag is actually only a 8 bit value if it doesn't need more bits (speculation), but if there are wider fields in the enum there is padding put in between. That's why you should sort the fields of your structs from biggest to smallest in order to minimize alignment padding. (Maybe also local variables? Those might be reordered by the compiler.)
@peter9477
@peter9477 7 ай бұрын
If you don't specify a primitive or C repr for your struct, the compiler chooses how you lay it out (at least that's my understanding), so it shouldn't be necessary to order fields that way in the general case in Rust.
@NomoregoodnamesD8
@NomoregoodnamesD8 7 ай бұрын
Alignment is important because generally speaking the processor only loads addresses aligned on those boundaries. So, on 32-bit, to read a 32-bit integer straddled across a boundary, two reads have to take place with some bit manipulation to combine the number into a single register. The space tradeoff of an aligned read is usually always worth it, so it's better to instead find ways to pack data where no padding is introduced. Even reading an 8-bit integer that isn't fully aligned may require a bitshift and a sign extend or bitwise-and. The exception? Sending/receiving data over the network. In order to save bandwidth, it may be worth considering the tightest packing and doing those bit manipulations. Especially since the latency of sending/receiving a network packet is so much greater than doing an unaligned read. It may even be worth considering to compress data before it goes onto the wire. For local variables, the order may not matter as the compiler most likely will optimize all/most of them into registers, and the CPU at run time may additionally optimize stack operations into register reads/writes.
@blenderpanzi
@blenderpanzi 7 ай бұрын
@@NomoregoodnamesD8 "Even reading an 8-bit integer that isn't fully aligned may require a bitshift and a sign extend or bitwise-and." How can an 8 bit integer be not aligned? At least on all platforms I know you can only address bytes (i.e. 8 bit steps) and 8 bit integers are byte aligned. So they're always aligned.
@AlexanderHyll
@AlexanderHyll 7 ай бұрын
As a reference to Primes "small optimization". The default memory layout already optimizes this? That's why it's not guaranteed to be laid out in the same order as the enum unless using for example repr(C).
@MetroidChild
@MetroidChild 7 ай бұрын
Struct layout optimization just means shuffling the elements within the struct to save space while still keeping members byte aligned to their size, for example making the padded 32 byte data structure {i8, i64, i8, i32, i16} into a16 byte data structure {i64, i32, i16, i8, i8}. This has nothing to do with splitting off enum unions into their own parallel data structures.
@VivekYadav-ds8oz
@VivekYadav-ds8oz 7 ай бұрын
Pretty sure that didn't even have an effect. The size of an enum is not even dependent on how the variants are arranged, it's only dependent on the largest variant, no matter its position.
@saultube44
@saultube44 7 ай бұрын
@16:00 For a long time Scientists couldn't figure out how plants could grow up hundreds of meters and still get water up there, without pumps or special physical properties/mechanisms; the answer was many years later when we discovered Fractals, that are how increasingly complexity is solved: you just have to find the right Fractal Equation for it and recursively apply it, or a number of them in an algorithm; that's how Nature solves it, that's how we should: the mathematically smart way
@cloudsquall88
@cloudsquall88 5 ай бұрын
if you have such large descrepancies between enum variants in rust, couldn't you just use a heap allocated type so that all of them would be the same size (ie the size of a reference plus whatever)?
@AttilaSzenczi
@AttilaSzenczi 5 ай бұрын
Exactly, I think this is an overcomplicated solution which does more harm than good. An interesting, but useless idea. If you need to bookkeep the ordering (which I would expect from a Vec), then the memory required for bookkeeping might far exceed the memory you win by this magic. Also any algorithm on top of that, like sorting is a nightmare. It might be useful in some very specific cases, but definitely not something I would like to randomly see in a codebase. I'd rather say, that if you have an actually big type amongst the enum variants, put that into the heap. Don't put everything to the heap because you don't want to destroy the cache friendliness of your code. Thats mostly unrelated to enums tho, big types are not belong to the stack.
@yakman8681
@yakman8681 7 ай бұрын
Fine I’ll try zig…finally got me🙄😭😭
@steamerSama
@steamerSama 4 ай бұрын
So, the point of the article is that zig maintains a special data structure to hold both the tags and the type in two different arrays thereby eliminating the need for padding, but in a roundabout way.
@pinpox
@pinpox 7 ай бұрын
Please more zig!
@maamardli
@maamardli 7 ай бұрын
Is it blazingly fast though?
@SaHaRaSquad
@SaHaRaSquad 5 ай бұрын
Comptime is the kind of feature that makes you wonder why this isn't how we've always been doing it. I am certain it will inspire many future languages.
@ragectl
@ragectl 4 ай бұрын
This article feels like an exercise in optimising for performance and potentially getting optimisations in the wrong places, while making it harder to track values. In which case just keeping the original structure and wearing some memory cost might be better. The performance could vary greatly based on system hardware factors.
@SvetlinTotev
@SvetlinTotev 6 ай бұрын
So what they are really trying to do is packing the memory and assuming this will improve performance. Which isn't a good assumption. Having multiple variable size arrays to store the different sized elements often *guarantees* memory segmentation. Even with very small arrays. In virtually every use case, there are better solutions. If you are going to go through the array sequentially, you could just tightly pack the data when storing it and then unpack it when reading it. And if you need random access, then the proposed solution only helps at all in the relatively small range of array sizes where the tighter packing would significantly decrease the cash misses. For very big arrays either solution would almost always miss, and for very small arrays the simple solution would never miss and the proposed solution will never miss only if all the separate arrays happen to be in cash. P.S. The reason for the padding after the tag is because all primitive types should be aligned to their size, otherwise i/o in the CPU registers would be a bit slower. Which would be a significant problem if most of the data is misaligned.
@corley-ai
@corley-ai 4 ай бұрын
Props on that thumbnail.
@codeman99-dev
@codeman99-dev 7 ай бұрын
2:11 - You don't "lift" with a match binding. A lift is something like JavaScript's Array.of function.
@iamworstgamer
@iamworstgamer 7 ай бұрын
dude how your nevim intellisense is so much much better than mine, I am also using lsp
@AK-vx4dy
@AK-vx4dy Ай бұрын
I have no idea what i'm talking about but i think there is some chunk of comparing apples to oranges in this article. Rust enums are not thought to be constructed in vast arrays, and are thought to be used with very frequent change of containded value type at runtime and so tag is inevitable in this case. About Zig i know nothing but seems that in zig is not possible to check containted type at runtime wich is a result of tag lacking in memory. To the rest, so easiness to construct special efficent data structures of this kind by using some kind of meta programing, at this momen is clearly win for Zig. I wish the best for both lanugages and i think both have rarely conflincting niches and specialisations. Rust typesystem and possibilites to guide futher contributors to code right path is insane (in good sense). Zig almost native interoperability with C, ability to compile C, abilty to replace build system and program it in Zig and ability to easy complie Windows exe on linux are insane(in good sense).
@TheBuzzSaw
@TheBuzzSaw 7 ай бұрын
Let's GOCaml
@saultube44
@saultube44 7 ай бұрын
@5:30 IIRC, 16 Bytes is a Cache Line, so is fed into the Execution Engine of the CPU through the Cache, way faster than reading 1 element at the time, in theory; I'm skeptical about it; tests needed. *This is how Software gets bloated and wasteful*
@computationaltrinitarianis1451
@computationaltrinitarianis1451 7 ай бұрын
If you curious about Zig's comptime and Ocaml, I would recommend a cursory glance at Lean 4. It is mostly focused on theorem proving, but is quite interesting as a general purpose language (though not as a systems langauge).
@noredine
@noredine 7 ай бұрын
This part 5:31 read like that "Retro Encabulator" video
@vikingthedude
@vikingthedude 7 ай бұрын
Why do we need the padding? I don't think the article brought that up. I'm not familiar with systems level programming so could someone help out?
@barterjke
@barterjke 7 ай бұрын
Because union (or enum is rust) is basically just any type in dynamic languages. You should keep the padding, because even tho you are currently storing, for example, 1 byte, you want to store 16 sometime in the future.
@barterjke
@barterjke 7 ай бұрын
if you are reffering to 15:20, it's because you can't store 1 byte along 8 byte, they should be alligned. The same reason bool is stored as byte, even tho it only need one bit. It's just how memory works. You can store it seperatly, the same way you can store bitmask instead of different bool variables, but it's more complicated, and in this case is considered unsafe by the author.
@YourNerdyJoe
@YourNerdyJoe 7 ай бұрын
If you're referring to the extra padding from the tag, it's to keep alignment. Aligned memory accesses are faster (has to do with how the hardware works without getting to detailed). For example the memory location of u64 should be a multiple of 8. In a tagged union where the tag is 1 byte, it needs padding b/c 9 bytes means the u64 won't be aligned to 8bytes but it will be if the total size is 16 bytes.
@parkerhuntington1360
@parkerhuntington1360 7 ай бұрын
To add a little more on the previous answer, some architectures don't support unaligned memory accesses. For example on a 64-bit riscv system, depending on the implementation, an unaligned load of a u64 might cause an exception. Even when this is supported it tends to be a little slower. This is because rather than passing around 1 byte at a time the cpu is passing around 8. Once you get to the cache, the system may be passing around blocks of 32 or 64 byte cache lines at a time. If you support unaligned access, then it may stretch two cache lines which needs extra logic to implement, which translates into more chip area and a higher price / more power dissipation / slower speeds. Even worse, an unaligned access could straddle page boundaries. So you then need to do two page table lookups to determine if the memory location can be accessed. In this case, even though the tag only needs to be a u8, since the payload that follows is a u64, it is padded out so that the u64 is aligned.
@redcrafterlppa303
@redcrafterlppa303 7 ай бұрын
11:20 but now instead of 56 bits padding per element we now have an additional 64bit pointer + fragmenting the varient tag from the data. In what world is that more efficient?
@user-py9cy1sy9u
@user-py9cy1sy9u 7 ай бұрын
Both tag and element arrays are the same size so you can access them both with one array index. No need for pointers. tags[3] and elements[3]
@redcrafterlppa303
@redcrafterlppa303 7 ай бұрын
@@user-py9cy1sy9u that's fair, but I'm not sure the wasted cache locality of tag and value would be worth the space savings. At this point you could better pack the enum and strip the padding. |tg| padding 56|u64| 128 bit/element To |tg|u64|72 bit/element Sure the cpu needs to copy the unaligned u64 value to work with it. But it likely will be more efficient than the extra allocation stress and fragmenting. I would love to see a benchmark testing booth approaches against each other.
@user-py9cy1sy9u
@user-py9cy1sy9u 7 ай бұрын
@@redcrafterlppa303 Cache locality matters if you only do random access to this thing. If you do foreach on these elements then cache fragmentation problem is non existent. It all depends on your use case. The author of this blog post is talking about optimizing compiler and in that case you go over each element in order and you are limited by the memory speed so any savings on that front is helpful
@redcrafterlppa303
@redcrafterlppa303 7 ай бұрын
@@user-py9cy1sy9u that's pretty true. The often forgotten fact applies that you can have inefficient code that is fine if it isn't the bottleneck of the program. If you Programm is super fast but crashes with out of memory it's not useful 😂👍 Jokes aside. This is pretty interesting on both sides for me personally because I'm currently writing a compiler and am therefore working on the compiler to work (efficiently) and language design to facilitate my language. Especially unions are interesting because my language makes even heavier use of them than even rust and if they need a variety of optimizations for different use cases I need to think about that in language design. In case you are interested the partial compiler is on github "RedIODev/Chorus". There aren't many examples, documentation or overview yet though.
@wesleydahar7797
@wesleydahar7797 6 ай бұрын
Compilers almost never iterate over collections of tagged unions. Random access is used by ASTs that want references to elements that contain RTTI and are allocated in pools of the appropriate 'Expr' or 'Token' type. Storing references into that complex fragmented structure has overhead which basically negates the value of the AoVA collection. The real issue with cache locality has to be the fragmented nature of the collection, but caches today are large so it's not the end of the world.
@iaconst4.0
@iaconst4.0 Сағат бұрын
good video , many persons say that zig is the fastest language program, is that true?
@redcrafterlppa303
@redcrafterlppa303 7 ай бұрын
23:00 I love prog macros. I wish we would get more integration with the compiler to get more information about the code and how it would be compiled to generate adjusting prog macros. Things like layouts of argument types etc. Just like he said. I feel like it should be more cyclic. The compiler should parse all the way pass it to the macro proc and then parse the result from the beginning. This way you get the full information the compiler pulls out of the syntax (like type lens, offsets etc) while you simply write rust code in that macro that the compiler is then parsing from new again with the macro fulfilled.
@TheWrapperup
@TheWrapperup 7 ай бұрын
Having compiler info would be very nice for sure, you could do so much more cool stuff at compile-time. This is why Jai has insane metaprogramming capabilities, they just give you imperative access to compiler information as a language feature. A lot of macros though don't require it though, so maybe some multiple stages for macros makes sense. Maybe for Rust, I think the API for it would have to revolve around passing span information around.
@pacotrim
@pacotrim 7 ай бұрын
So... Prime spent the first few minutes explaining Monads?
@nobleradical2158
@nobleradical2158 6 ай бұрын
The idea of a monad is more abstract than a tagged union, but yes, they are monads.
@labrabbits
@labrabbits 7 ай бұрын
dude didn't first time comment didn't go wasted. f for respect
@knifefest
@knifefest 7 ай бұрын
I think upcasting ints can't be implicit because big-endian systems require an actual move in memory.
@TremereTT
@TremereTT 4 ай бұрын
comp time in delphi/free pascal is super fast ...its a single pass compiler
@CielMC
@CielMC 7 ай бұрын
Me who enjoys writing proc macros: wait I'm the weird one?
@ThePrimeTimeagen
@ThePrimeTimeagen 7 ай бұрын
You're not a weird one, you're just one of 16 people that know how to do it
@BosonCollider
@BosonCollider 7 ай бұрын
This is also something that Julia has (and is significantly better at than Zig since it also has lisplike code generation which is *allowed* to use type information, and on top of that it has a low barrier of entry to write compiler extensions). The fundamental reason why Rust can't easily have it is because it has return type polymorphism, which means you can't treat the types as arguments and run arbitrary functions on it. Zig has some level of compile time evaluation on types, while Julia can run arbitrary code at any time and use it to generate code. I've written an achetype-based ECS system (struct of arrays, packs archetypes efficiently but falls back to hierarchical bitmaps if there are too many variants, and allows new type defs at runtime with the Julia JIT) in ~50 lines of Julia. It used exactly this kind of tricks (compile time type reflection) combined with one generated function (i.e. generated AST depends on type input).
@olekollo7875
@olekollo7875 5 ай бұрын
Julia is only good for date science
@tsalVlog
@tsalVlog 7 ай бұрын
I have a feeling the Linux kernel (or a derivative) will some day be built in Zig for memory composition, with modules built in Rust for memory-safety. It would be pretty dang stable out of the box.
@TheSulross
@TheSulross 7 ай бұрын
transitioning the Linux kernel to a Zig introduction would be more viable than trying to transition to Rust. Currently Rust usage is isolated away into being allowed for device drivers
@tsalVlog
@tsalVlog 7 ай бұрын
@@TheSulross that’s what I meant by modules..
@CakeIsALie99
@CakeIsALie99 7 ай бұрын
Why does a static string have an into() method
@wedoscao
@wedoscao 7 ай бұрын
Because rust impl Into on it
@peter9477
@peter9477 7 ай бұрын
Do you mean why as in "for what purpose"?
@ahdog8
@ahdog8 7 ай бұрын
When Prime does .into() in the video, he is copying the `&static str` (stored like a C string literal) into a `String`, which is stored on the heap. The into method is useful because you might want to mutate the static string, so you copy it into a not-static string.
@FrankHarwald
@FrankHarwald 7 ай бұрын
@ThePrimeTime Elixir is mostly a modernized Ruby, but at least it's trying to be a compiled language (not interpreted) & trying to allow for an efficient & simple usage of multi-threading (never seen that done well in Ruby). However, I don't like Ruby & its core language philosophy itfp so I wouldn't recommend it. I used to be a Python guy until I found Nim - which is basically a also Python, but it also compiles to native code & also allows for easy & efficient multi-treading (which I haven't seen in Python either without bending the spoon backwards). Plus: Nim is more mature then Elixir, outstanding cross-platform & cross-language support & already has existing real-world applications.
@thekwoka4707
@thekwoka4707 7 ай бұрын
Not everything is 16 bytes in js. A boolean is 1 byte
@hashomi0596
@hashomi0596 7 ай бұрын
Reel Oh ESSS kernels would not use enums. Except Windows ofc.
@Ben_EH-Heyeh
@Ben_EH-Heyeh 5 ай бұрын
Zig is cool. Elixir is an abstraction of Lisp. 😂
@yevgenydevine
@yevgenydevine 7 ай бұрын
“When Zig outshines Rust” Always and in everything.
@YunikMaharjan
@YunikMaharjan 7 ай бұрын
I remember learning about tagged unions few years ago and was like WOW that's inefficient. That costs a lot of space, specially if you have a vector of these enums. And settling on well there's nothing we as a programmer can do about it.
@weeb3277
@weeb3277 7 ай бұрын
outzigged.
@stevenhe3462
@stevenhe3462 7 ай бұрын
Elixir takes no time to learn.
@AK-vx4dy
@AK-vx4dy Ай бұрын
I thought Zig one main of founding points was *no implict*.... "you were the choosen one..." Or maybe this was in other new language ? 😅
Stop Using Rust Use C++ | Prime Reacts
13:55
ThePrimeTime
Рет қаралды 256 М.
Rust makes you feel like a GENIUS
10:48
No Boilerplate
Рет қаралды 396 М.
顔面水槽がブサイク過ぎるwwwww
00:58
はじめしゃちょー(hajime)
Рет қаралды 90 МЛН
Balloon Pop Racing Is INTENSE!!!
01:00
A4
Рет қаралды 15 МЛН
Surprise Gifts #couplegoals
00:21
Jay & Sharon
Рет қаралды 30 МЛН
Nim 2.0 Release! | Prime News
20:03
ThePrimeTime
Рет қаралды 58 М.
Zig for Impatient Devs
9:48
Isaac Harris-Holt
Рет қаралды 58 М.
Why Zig in a world w/ Go & Rust? w/ AJ @coolaj86
1:07:20
Utah Zig
Рет қаралды 2,5 М.
Every programming language explained in 15 minutes | Prime Reacts
43:42
i changed my mind about zig
9:34
Low Level Learning
Рет қаралды 140 М.
Rust is not a faster horse
11:37
No Boilerplate
Рет қаралды 315 М.
Torvalds Speaks: Rust's Impact on the Linux Kernel
3:50
Mastery Learning
Рет қаралды 536 М.
Interview with Senior Rust Developer in 2023
9:46
Programmers are also human
Рет қаралды 618 М.
Компьютерная мышь за 50 рублей
0:28
dizzi
Рет қаралды 2,2 МЛН
Рекламная уловка Apple 😏
0:59
Яблык
Рет қаралды 803 М.
How Neuralink Works 🧠
0:28
Zack D. Films
Рет қаралды 27 МЛН
Fiber kablo
0:15
Elektrik-Elektronik
Рет қаралды 3,8 МЛН