Prime Reacts: From C to C++ to Rust to Haskell

  Рет қаралды 347,649

ThePrimeTime

ThePrimeTime

Күн бұрын

Пікірлер: 1 200
@richardfairthorne7021
@richardfairthorne7021 Жыл бұрын
The original C was readable by an infant. I need an encyclopedia of the history of programming methodologies to understand his C++ refactor.
@richardfairthorne7021
@richardfairthorne7021 Жыл бұрын
Also, you can use explicit returns, and still end your block with an implicit return.
@marcossidoruk8033
@marcossidoruk8033 Жыл бұрын
I don't understand how on earth can anyone think any of the (modern) C++ versions is better, all the advancements in modern text editors and LSPs to make typing faster and for some goddamn reason some people are obsessed with typing less even if that means writing the most cryptic expressions known to man. The C version is not only orders of magnitude more readable but also more versatile, you can tweak it here or there if the requirements change, however the C++ ... Also the C version has no function calls and thus translated almost 1 to 1 to an equivalent assembly and thus the compiler may be able to optimize it much better, notice the C code had the least instructions in O2 and then in O3 the most probably due to loop unrolling. If I had to take a guess I would say the C code is noticeably faster than the rest. Both in O2 and O3.
@julealgon
@julealgon Жыл бұрын
At the end of the day, the C++ version is less error-prone though. That should be incentive enough to learn it.
@marcossidoruk8033
@marcossidoruk8033 Жыл бұрын
@@julealgon How on earth is that less error prone?????? It seriously boggles my mind. The rust version I can understand but the C++??? The original C code is as simple as it gets and it is much more explicit in every aspect and on top of that it is orders of magnitude easier to tweak, how in all hell is that more error prone than a single Statement that uses layers upon layers of abstraction that you have to remember specifically how every piece works including the return types and corresponding operator overloads for those types. Absolute insanity, what has happened to software development? And then what if you realised you had to handle a handful special cases? The C version you just add a couple ifs inside the loop or whatever and you are basically done, you can make little adjustments here or there no problem, the C++ version on the other hand is painfully specific and you would probably have to rewrite it just to make a minor modification. Would you rather maintain a 250 lines file that uses a different std::nonsense function every single line complete with overloaded operators everywhere or a 1000 or heck, even 2000 line C file that does exactly the same in the most explicit, simple way possible? I would take the C codebase any time.
@newyorthtimes4496
@newyorthtimes4496 Жыл бұрын
@@marcossidoruk8033 one thousand percent agree. Reading that refractored code gave me brain aneurism of the highest order.
@BenVisness
@BenVisness Жыл бұрын
7:47 “it avoids the possibility of off-by-one errors”, he says while adding 1 to the end of his range to make it inclusive
@dahahaka
@dahahaka 7 ай бұрын
The previous code has multiple places where off by one errors can stack and even cancel each other out due to < and
@tzint56
@tzint56 7 ай бұрын
Us Haskell giganerds avoid the possibility of off-by-one errors by not having iteration at all, and instead optimizing the language for recursion. Yes, that means no while loops, no for loops, no flow control made for a toddler. Off by one errors are straight up not possible since there's no mutability. index++ can't be an iterative step--It mutates a variable, and that is not allowed. Instead, we use function guards and define a condition for when recursion should stop. If going across a list, this is when the head of the list is empty. And yes, I can use C, Java, etc etc etc as well. I actually don't work in Haskell. But it has taught me to be a better programmer overall. On the surface this leads to memory usage concerns, but in practice the compiler will compose your functions together such that your entire program is more analogous to an end-to-end stream of data.
@DiVoidationStudio
@DiVoidationStudio 6 ай бұрын
​@@tzint56nah/
@oioio-yb9dw
@oioio-yb9dw 4 ай бұрын
​@dahahaka I just have a question; if you say to the language to do something and there is a chance it will not do it well, then why keep using said language over and over? It doesn’t make sense to me.
@NubeBuster
@NubeBuster 2 ай бұрын
At that moment I thought this guy must be joking right
@radioJim
@radioJim 7 ай бұрын
This is the guy Torvalds was talking about when he said "if the choice of C were to do nothing but keep the C++ programmers out, that in itself would be a huge reason to use C."
@feschber
@feschber Жыл бұрын
You don't have to debug Haskell because either a) you didn't use it in the first place b) you git everything right because you wrote it in Haskell and you are a genius
@ThePrimeTimeagen
@ThePrimeTimeagen Жыл бұрын
these are facts
@taurasandaras4699
@taurasandaras4699 Жыл бұрын
1 reply but top comment?
@noxabellus
@noxabellus Жыл бұрын
Nah actually Haskell is pretty easy to write but debugging it is impossible
@VojtěchJavora
@VojtěchJavora Жыл бұрын
​@@noxabellusyou use REPL for debugging.
@laughingvampire7555
@laughingvampire7555 Жыл бұрын
you only get that with JSDL unless you break JDSL and you make Tom angry
@k98killer
@k98killer Жыл бұрын
That c++ refactor was the most ridiculous and hilarious thing I've seen in a while. I burst into laughter at the exact same time Primagen did.
@lostsauce0
@lostsauce0 Жыл бұрын
"burst" 😂 There's an old article by Burst lib showing how to refactor a function that calculates the distance between two points to be generic. It's absolute insanity
@abhaysingh-lg2cr
@abhaysingh-lg2cr Жыл бұрын
literally you! 😳
@random6033
@random6033 Жыл бұрын
Also the entire thing is kind of pointless cuz.... MATH This is the objectively correct version: int calculate(int bottom, int top) { bottom += bottom & 1; top -= top & 1; if (bottom > top) return 0; return (bottom + top) * ((top - bottom) / 2 + 1) / 2; }
@xkali8119
@xkali8119 Жыл бұрын
@@random6033 sorry, but this version is rather cryptic, even if it's correct. I would rather keep the for loop.
@dimit3356
@dimit3356 11 ай бұрын
@@random6033 I compiled your code and his code and after removing the comments and empty lines yours was 105 lines long and his was only 102 long. so hardly no difference. I decided to use my twisted edrich mind and write it in my way i got for the following code only 99 lines of assembly: int calculate(int bottom, int top){ int sum = 0; m1: if(bottom
@jon9103
@jon9103 Жыл бұрын
7:50 "avoids off by one errors" Shows a loop that requires a + 1 to avoid being off by one. 😂
@uzbekistanplaystaion4BIOScrek
@uzbekistanplaystaion4BIOScrek Жыл бұрын
what i've learned: C is evergreen, can look really nice and is super readable, but will spontaneously transmute into a nuclear bomb if you look away for an instant. rust is the new kid on the block with fancy hair, but is still just C's cousin on mood stabilisers. haskell is an eldritch horror that will annihilate your mind but in return allows you to astrally project your code into a pocket dimension were it runs optimally. c++ is a hulking, grotesque abomination enslaved by sadists to run the entire world at our peril and would benefit from being taken round the back of the shed and shot squarely in the base of the skull.
@Naa-ee7nq
@Naa-ee7nq 10 ай бұрын
the problem with C++ is people like the guy who "refactored" the original C code if you use C++ sensibly, it's pretty great, but that usually requires a strict team-wide discipline namespaces are very useful, you can hack namespaces in C with struct and headers but it's not the same const ref& is extremely useful and allows for a lot of flexibility every other feature or library is to be used strategically and not "because it's cool" - the more features of a language you use the bigger the barrier you make for readability and maintainability - templates, std and boost features are to be used very strategically, with the exception of idiomatic things that will be commonplace anyway (like, say, vector stuff, ranges, safe strings etc etc) a massive problem with C++ is that when you have to use someone else's code it's often completely alien to your internal practices, but this happens with C as well just not as much generally you don't want to work with other people's code in C++ if it's not a readily usable library that you don't need to touch and that you can trust with your life that it works as is (namely std, or boost)
@tokiomutex4148
@tokiomutex4148 Жыл бұрын
It's amazing how C++ allows you to turn straightforward programs into something very close to APL programs.
@v01d_r34l1ty
@v01d_r34l1ty Жыл бұрын
C++ is a double edged sword, and the further you run down the blade, the sharper it gets. You can either leave legacy code and cut yourself with hours of painful debugging, or you can use modern features and cut yourself with hours of documentation review.
@xBZZZZyt
@xBZZZZyt Жыл бұрын
why youtube doesn't show reply?
@tokiomutex4148
@tokiomutex4148 Жыл бұрын
@@xBZZZZyt it's broken
@AVX512
@AVX512 Жыл бұрын
it's amazing how bad programmers write bad C++
@jjtt
@jjtt Жыл бұрын
The name iota literally comes from APL, so yeah
@TheEyalYemini
@TheEyalYemini 11 ай бұрын
This how you make code unreadable
@blarghblargh
@blarghblargh Жыл бұрын
"readability is a function of experience" this is the truest thing I've heard this week. how have I been programming for 30+ years and never, ever heard any dev say this? I say it all the time, and everyone just smiles and nods when I do, and acts like I need to get back to my fucking nursing home.
@marcossidoruk8033
@marcossidoruk8033 Жыл бұрын
Readability is a function of experience divided by how much your language sucks sqared. The C version is readable by an infant with neurological disorders, the Rust version is kinda nice, you just need to explain 2 things and it makes sense. The C++ version just doesn't make any sense, yes if you have experience you can read it but you shouldn't to when you could have just written it in C or in Rust and any random joe would have been able to read it.
@blarghblargh
@blarghblargh Жыл бұрын
@@marcossidoruk8033 "yes if you have experience you can read it" - this is all programming. that was the point I was agreeing with. don't shave yaks. get used to things that make you uncomfortable. eventually it'll all become easy.
@marcossidoruk8033
@marcossidoruk8033 Жыл бұрын
@@blarghblargh You didn't get the point at all. My whole point is that the C version is so much more explicit you barely need any experience or anything at all to understand it, its beautifully dumb code, compared with the C++ version is much more clear to a greater number of people and doesn't gatekeep people for being unnecessarily complicated and language specific, it is objectively better code. Hence why I said "it is a function of experience divided by how much your language sucks squared", the whole point is that experience is not the only relevant factor here. Saying as a response to this "thats all of programming" is a remarkably stupid answer. Its like saying "suffering is all of life", yes but does that mean that the ammount of suffering doesn't matter? Same thing here, with arbitrary experience you can understand anything, with arbitrary experience you can even understand languages like brainfuck or malbolge, yet nobody does that because why would you. For some reason people don't apply this logic to (modern) C++ and end up writing utterly pointless unmaintainable code like this just because it makes them feel smarter.
@blarghblargh
@blarghblargh Жыл бұрын
@@marcossidoruk8033 "a remarkably stupid answer". keep up this junior mindset and you'll never grow out of it. I never said C++ doesn't suck. I said it's all easy once you have experience. git gud, kid. and keep your negativity to yourself.
@notapplicable7292
@notapplicable7292 Жыл бұрын
> Writes a 10k line method > "readability is a function of experience" > okay grandpa
@Euphorya
@Euphorya Жыл бұрын
Haskell does require you to pretty much throw away everything you know about imperative programming. It's a completely different paradigm, but once you do learn how it works the code here is very readable. I recommend learning a bit of Haskell just because it requires you to think so differently about solutions.
@marcs9451
@marcs9451 Жыл бұрын
Also causes your solutions to be painfully slow. Computers are fundamentally imperative, if your functional language doesn't guarantee tail cal optimazation (only one I know of is Scheme) it quickly becomes a stack destroying monster that also ruins cache coherence. Pure functional languages manage to always do the worst case scenario for the CPU.
@havocindustries3078
@havocindustries3078 Жыл бұрын
​@@marcs9451I feel like you don't get the idea behind Haskell and company. The language is a tool that is supposed to help you write readable and maintainable code. Code is a medium to communicate with other developers. That a computer can understand the code you've written is merely a side product. Therefore it is better to write succinct code than fast code. The compiler's job is to produce fast code in more cases than a developer could do and still be correct. GHC is doing impressive work in that regard. Scala is available and production ready doing similar and it allows you to enforce TCO with @tailcall. There's a bunch of languages that try to push generally available optimizations. Rust is yet another example. For example, the optimisation behind option are available to all data structures of similar form. Looking at the current state of application development, it's green threads aka async / await all over the place. Your declared worst case scenario is the current state of every application in any language anyway. So why does it matter? A ton of programs transfer a few bytes between a client and a database. It's not like they actually need to have tremendous performance.
@thomassynths
@thomassynths Жыл бұрын
@@marcs9451 To be fair (and yes I know this is not pedantic since languages aren't the same as their implementations), but Haskell typically outperforms Python which is arguably more imperative than functional.
@mskiptr
@mskiptr Жыл бұрын
@@thomassynths It's usually said to be in the same ballpark as Java or C#. Not really that surprising given it's compiled and they are JITed, all of them have a runtime system and all do GC. It _can_ perform terribly ofc. If you use data structures not fit for the job, implement a slow algorithm or your code doesn't play well with the GC or laziness.
@hardknockscoc
@hardknockscoc Жыл бұрын
​@@marcs9451 I can't see my reply anymore. Maybe it got removed or maybe youtube is just having a fit. I'll just reiterate: functional languages are more open to optimization than imperative ones. And if you benchmark them, they perform incredibly fast compared to imperative. Just look at how Ocaml performs against Java. On top of this, the abstraction in which programmers think, doesn't need to concern itself with the underlying machine. That's literally the whole point of high level software. There's a reason compilers exist. Also Scheme is obviously not the only language with TCO lol. That's most functional languages. There are tons of compiler optimizations that a) improve cache locality and b) reduce stack usage. Rust is proof that you can have tons of functional stuff in a language while still keeping it fast. And Rust doesn't even have a runtime/GC. Just look at the logos crate: github.com/maciejhirsz/logos. This crate generates faster lexers than you could ever hope to write by hand and all you have to do is specify regexes for your tokens. You don't need to concern yourself with the algorithm used for lexing.
@maninalift
@maninalift Жыл бұрын
"iota avoids off by one errors.... Oh, by the way, don't forget to add one to top if you want an inclusive range" I like the code report channel but he's definitely more into arcane programming aesthetics than pragmatism. No idea why he decides to compare number of assembly instructions produced, its just as easy to benchmark the run time.
@yjlom
@yjlom Жыл бұрын
well code report just tries to write everything like it's APL
@TheMyHalo
@TheMyHalo Жыл бұрын
"iota avoids off by one errors.... Oh, by the way, don't forget to add one to top if you want an inclusive range" thats because every range is exclusive, every single one. Its not a hard thing to remember to youre always working on [a;b[
@isodoubIet
@isodoubIet Жыл бұрын
"iota avoids off by one errors.... Oh, by the way, don't forget to add one to top if you want an inclusive range"" How is that not an improvement over the original where you had to notice that the range was inclusive by looking at a single character?
@voskresenie-
@voskresenie- 3 ай бұрын
run time can be affected by tons of things other than the program itself. that's why when you run it 100 times, you'll get 100 different results. machine instructions is a more reliable comparison.
@maninalift
@maninalift 3 ай бұрын
@@voskresenie- reliable in the sense that it's more likely to return the same result each time (even then, it will vary) but not a reliable indicator of run time performance.
@grim.reaper
@grim.reaper Жыл бұрын
Prime: “c++ Longest way to say the shortest thing” Java: hold my beer!
@ThePrimeTimeagen
@ThePrimeTimeagen Жыл бұрын
This is true
@joshix833
@joshix833 Жыл бұрын
With java it would be something like the follwowing: int calculate(int bottom, int top) { if (bottom i % 2 == 0).sum(); }
@2mbst1
@2mbst1 Жыл бұрын
More like: Hold my FermentedAlcoholicBeverageBrewedFromMaltAndFlavoredWithHops.
@grim.reaper
@grim.reaper Жыл бұрын
@@2mbst1 🤣🤣🤣
@johnhilts5980
@johnhilts5980 Жыл бұрын
​@NETSPLIT you forgot to add "Factory"
@aarorissanen930
@aarorissanen930 Жыл бұрын
9:25 As a C++ dev; What the actual fuck is happening?
@sillymesilly
@sillymesilly 6 ай бұрын
This is why C devs should of stayed and never migrated to C++
@linuxguy1199
@linuxguy1199 29 күн бұрын
​​@@sillymesillyWhat? As a C developer we would never come up with such a descriptive name like std::views::iota, we'd call it orgextb
@Gabriel-wq4ln
@Gabriel-wq4ln Жыл бұрын
I can't believe there was a clean C++ program with LITERALLY a "for" and an "if" and the dude turned it into a program with functions which you gotta search what the parameters mean, passed functions as arguments to the said functions, declared a namespace (which you also gotta see what exactly it is) and brought a lot of new syntax that only works on the last versions of C++. It also takes 10x more to understand the "upgraded" version. Btw, love your videos, Prime (curly braces on new line lol) { }
@jasonwhite5578
@jasonwhite5578 Жыл бұрын
preach it - overengineering at it's best
@thomasziereis330
@thomasziereis330 Жыл бұрын
What do you mean the code was absolute garbage and the final c++ result was readable like a comment it literally written: sum all numbers from top to bottom that are filtered to be even. You can understand this code in like 5 seconds where you would still be figuring out the control flow of the original example. Ofc its not as beautiful als rust but its basically readable the same way
@Gabriel-wq4ln
@Gabriel-wq4ln Жыл бұрын
@@thomasziereis330 I mean, if you prefer it, alright. I still think the original one is cleaner. What about having to check what tf the iota function does?
@isodoubIet
@isodoubIet Жыл бұрын
@@Gabriel-wq4ln Iota has been an algorithm in the standard library for ages, every c++ programmer should already know it
@mrcrackerist
@mrcrackerist Жыл бұрын
@@thomasziereis330 it took me less then a second to understand the C code
@remboldt03
@remboldt03 11 ай бұрын
The C code was much more readable then the C++ one
@brady1123
@brady1123 Жыл бұрын
That C++ calculate function is an abomination. Here is a non-nested version that doesn't hurt my brain (and doesn't have an early return even though it really should): int calculate(int bottom, int top) { int acc = 0; for (int val = bottom; val
@Evan490BC
@Evan490BC Жыл бұрын
If you are going to use a God damned C loop, at least use a range-based one...
@bloody_albatross
@bloody_albatross Жыл бұрын
What happens if top is the maximum integer? Like: calculate(INT_MAX, INT_MAX)
@catcatcatcatcatcatcatcatcatca
@catcatcatcatcatcatcatcatcatca Жыл бұрын
@@bloody_albatrossINT_MAX,INT_MAX should return 0. It just.. Doesn’t return. Im not sure if INT_MAX,INT_MAX should actually return zero or just throw, because whoever called this probably doesn’t actually want to know the sum of even numbers in the range of one odd number.
@bloody_albatross
@bloody_albatross Жыл бұрын
@@catcatcatcatcatcatcatcatcatca It was a rhetorical question hinting at a bug. ;)
@zytr0x108
@zytr0x108 Жыл бұрын
@@Evan490BCno
@micc1211
@micc1211 Жыл бұрын
Because he uses assembly size as his metric, O3 in C and C++ optimizes for speed, the compiler will unroll your loop and inline aggressively if it thinks it can make it faster and won't really care about the size of the code. The reason adding the various library functions reduces code size in O3 is likely because it adds a lot of things that have to happen to now work with arrays instead of just a few stack variables and therefore can't unroll your loop to make it all that much faster. While I can't say for sure, this might be slower when not threaded. So who knows how the speed is actually affected, you would need to actually benchmark it to know.
@boody8844
@boody8844 Жыл бұрын
As a javascript developer I have never used rust before and I have gotta say, I understood the rust version of the sum function really quickly by just looking at it for 30 seconds. I've got to learn rust, such a neat looking language!
@dealloc
@dealloc Жыл бұрын
sum is also way more descriptive than "accumulate". Accumulation could be done in a number of different ways. Sum does what it says on the tin. Add up and get a result.
@thekwoka4707
@thekwoka4707 Жыл бұрын
Definitely. Just made sense right away while the cpp and Haskell stuff was like "wtf?"
@DBGabriele
@DBGabriele Жыл бұрын
​@@dealloc This is because `accumulate` is a function that iterates over any kind of iterator, rather than being a method (of a integer vector).
@dealloc
@dealloc Жыл бұрын
@@DBGabriele That doesn't explain why there isn't a sum method in C++ standard library (partial_sum is the closest but requires you to pass a range). Rust also has "accumulate" in forms of fold and reduce for more generalized accumulation (reduction).
@DBGabriele
@DBGabriele Жыл бұрын
@dealloc as already said, std::accumulate is "generic" while sum is specific. Since there is accumulate in std, sum is unnecessary and redundant.
@seancpp
@seancpp Жыл бұрын
Wait, you *don't* like seeing 2 or 3 ternary operators nested together with a bunch of inline lambda expressions? Log debugging is in the past, just guess the problem correctly the first time
@ionized8744
@ionized8744 Жыл бұрын
Considering how much you love rust I really suggest at least giving Haskell a chance. On it's own it's not the most useful language but it is really elegant and fun when written properly. And for some use cases, such as compilers, it is crazy good
@ea_naseer
@ea_naseer Жыл бұрын
Rust language creator even says the syntax is ML inspired
@Boxing_Gamer
@Boxing_Gamer Жыл бұрын
Haskell is brilliant but there's some annoying stuff in it. For example all the strange characters you can define to mean what you want. Good look understanding someone who went crazy using monads and the entire hierarchy of category theory using symbols and one liners. This is why it will never be really popular. I feel like they need to simplify it a bit, at least the syntax. Also there are annoying thing like name clashes when importing other Haskell files. Rust is easy and efficient to use which means a lot.
@romannasuti25
@romannasuti25 Жыл бұрын
@@Boxing_GamerI feel like Haskell is properly a research lang, perfect for exploring programming languages at depth but not for actually programming. If you need something practical right now that feels the same, use OCaml for a pure experience or Rust if you’re a performance junkie. If Unison ever gets off the ground, that’s much closer to pure Haskell with a lot of QoL improvements.
@Boxing_Gamer
@Boxing_Gamer Жыл бұрын
@@romannasuti25 I'm not sure, I think the ecosystem, compiler and package manager are very mature. Why not make projects with it? I know there are companies out there who use Haskell.
@thomassynths
@thomassynths Жыл бұрын
To make the Haskell code more explicit, here it is: calculate :: Int -> (Int -> Int) calculate = \bottom -> \top -> sum (filter (\i -> even i) [bottom..top]) This is literally equivalent to the code in the video because all functions in Haskell are implicitly curried. I also removed the dollar operator and made the even check more obvious that it is a function used for a callback. Anyway one major reason high-order functions are is not the Hellish Nightmare they are in JS is because all variables in Haskell are immutable and all functions are pure. (Haskell is able to model state and impurity through its type system and some primitive language-given types such as IO and ST.)
@guisande
@guisande Жыл бұрын
Another way to read it is just: Normal way: calculate bottom top = sum $ filter even [bottom..top] Way of reading: calculate(bottom, top) { return sum(filter(even, [bottom..top])) } The dollar sign is just a way of removing parentheses. So, instead of: sum (filter even [0..10]) you can write: sum $ filter even [0..10] Edit: I'm mostly writing this for prime
@biskitpagla
@biskitpagla Жыл бұрын
that, and the fact that the standard library is practically nonexistent in js in terms of data structures and algorithms.
@DryBones111
@DryBones111 Жыл бұрын
@@guisande Yep, to read it imperatively you go right to left. But it takes on a declarative meaning when read left to right, which is why the apply function ($) has its operands in that specific order. The declarative way of reading it is how Primeagen read it: "The sum of a filter of even elements from a range from bottom to top." The inclusive range is also a declarative approach to ranges since its essentially set notation from mathematics. The idea of the top of a range of integers being non-inclusive is something that's left over from an imperative loop approach using i < top.
@isodoubIet
@isodoubIet Жыл бұрын
@@DryBones111 " The idea of the top of a range of integers being non-inclusive is something that's left over from an imperative loop approach using i < top." Nope. Ranges being non-inclusive is the correct choice for any programming context because 1. the difference between the endpoints equals the length and 2. non-inclusive ranges compose together much more nicely since with two adjacent ranges the endpoint of the first is the first element of the second. Haskell is using the wrong convention.
@ДаниилРабинович-б9п
@ДаниилРабинович-б9п Жыл бұрын
@@isodoubIet nah, the correct choice is to have both with a syntax like `a..=b` and `a..
@david.cr96
@david.cr96 Жыл бұрын
When he mentions that he would need to relearn programming to understand Haskell: well, indeed you kinda do, and that is actually the point. Not a big fan myself of functional programming but one must recognize it is such an interesting paradigm and worth knowing (specially its theoretical foundation).
@mpogrzebski
@mpogrzebski Жыл бұрын
Love the steady stream of new videos on this channel ❤️
@ThePrimeTimeagen
@ThePrimeTimeagen Жыл бұрын
WE OUT HERE TRYING
@NithinJune
@NithinJune 10 ай бұрын
20:18 someone in chat said “how do we not have is_even [the node module] in rust” 😂😂😂
@ColorfirePluma
@ColorfirePluma Жыл бұрын
Honestly, the most cursed thing about the C++ example is the fact that *in C++20* they didn't even have a ranges overload for accumulate... or a general fold function
@Evan490BC
@Evan490BC Жыл бұрын
Ranges are not done yet.
@isodoubIet
@isodoubIet Жыл бұрын
The committee forces a 3-year cadence for language releases because apparently they're afraid of repeating the success of C++11
@JanuszKrysztofiak
@JanuszKrysztofiak Жыл бұрын
It's moving a bit slowly: design by the comittee and then waiting until tooling actually implements now. It's 2023 and C++20 is still not fully implemented. For instance, the compilers mostly support modules but the build systems are far behind. The barebone support for coroutines is there, but, again, the library support is off and one doesn't want to use it without libraries, because it is quite low-level and meant for... library creators implementing useful, easy-to-use stuff on top of it. One single thing about C++ I hate most is building. Whereas elsewhere it is matter of specific dependencies, in C++ it is a game of makefile generators on top of makefile generators trying to guess where dependencies are, these can from the OS or some package manager or manual inclusion.
@au._.79
@au._.79 Жыл бұрын
C++23 has std::ranges::fold algorithms
@trondenver5017
@trondenver5017 Жыл бұрын
O3 inlines more functions into the call site, which increases instruction count but *almost always speeds execution
@heron619
@heron619 Жыл бұрын
I just learned the term "React Andys" from chat and I'm gonna use it to harass Theo and his audience!
@ThePrimeTimeagen
@ThePrimeTimeagen Жыл бұрын
hahaha
@willful759
@willful759 Жыл бұрын
Expanding a bit on the haskell syntax, indeed haskell is a language that requires you to think very differently about programming, and as such, its syntax tends to look ugly, but once you start using it and understanding it, you can see that it is actually quite clean in haskell, functions are king, and as such, the syntax is worked around clean composition and use of functions ( to various degrees of success ) ignoring type signatures, functions are defined by naming them first, then listing the parameters calculate top bottom then, to apply it, you do the same calculate 1 100 this does cause a problem, filter takes a function to use as a filter, and the list you're gonna filter, if you tried to just list all of the arguments sum filter even list the parser thinks you're trying to apply sum to three arguments, in c-like terms: sum(filter, even, list) to solve this, you could just use parentheses sum (filter even list) but we also have the $ operator, which is simple function application (f $ x = f (x)) sum $ filter even list since $ is an operator, the parser now knows that filter is a function, and even and list are the arguments, and now it type checks neatly this does map directly to the rust solution: [bottom..top] = (bottom..=top) filter even [bottom..top] = (bottom..=top).filter(even) sum $ filter even [bottom..top] = (bottom..=top).filter(even).sum() as an extra note, the type system in haskell also tends to have an intimidating syntax, but is is because the type system is very rich and expressive for example, epressing filter in rust would look something like this (ignoring whatever complications might arise from lifetimes and such) fn filter (f: T -> bool, vect: Vect) -> Vect { … } while in haskell it would be: filter :: (t -> Bool) -> [t] -> [t] filter f list = ... (yes there is a reason for the arrows but this comment is very, very long as is) which one you prefer is up to you, but imo when you move functions left and right, haskell's syntax is quite ergonomic, while the parentheses of c-like languages gets in the way
@LtdJorge
@LtdJorge Жыл бұрын
The rust function would actually be: fn filter (func: fn(T) -> bool, vec: Vec) -> Vec{} :)
@haskellelephant
@haskellelephant Жыл бұрын
In haskell the right to left reading is because of function application. It's like doing f(g(x)), the g function happens first.
@fsharplove
@fsharplove 9 ай бұрын
@@nisonaticF# version (you can use a List instead of Seq): [bottom..top] |> Seq.filter(fun i -> i%2 = 0) |> Seq.sum
@cas1652
@cas1652 Жыл бұрын
Kotlin is also very nice: fun calc(bottom :Int, top: Int) = (bottom..top).filter { it % 2 == 0 }.sum() Differences to Rust: Return type is inferred and you can leave out the braces if your function is just one statement 'it' is always the name of the first unnamed lambda parameter
@mv2e19
@mv2e19 Жыл бұрын
Agreed! Very similar to the Rust solution. Though, I usually explicitly declare the return type for readability
@kyay10
@kyay10 Жыл бұрын
`it` is not for the first argument of a lambda, it's for the *only* argument of a lambda
@JanuszKrysztofiak
@JanuszKrysztofiak Жыл бұрын
Kotlin's syntax for lambdas is pretty clever, given how it eases creation of quasi DSLs.
@AndrewBrownK
@AndrewBrownK Жыл бұрын
The Haskell code is beautiful, I wish you could appreciate it 😅
@NithinJune
@NithinJune 10 ай бұрын
40:30 if you’re curious he uses powerpoint it’s confirmed
@igrb
@igrb Жыл бұрын
As the official intern (and future CEO) of The Startup™I'm legally obligated to say I'm loving this channel. A chance to watch something I missed from my genius CEO??? Perfect way to try harder.
@ThePrimeTimeagen
@ThePrimeTimeagen Жыл бұрын
LETS GO!! the CEO is going to put a good word in for you with Karen R.
@rumplstiltztinkerstein
@rumplstiltztinkerstein Жыл бұрын
I'm praying for your promotion to CEO intern of the startup soon Igor
@Parker8752
@Parker8752 Жыл бұрын
So, Haskell can be a bit of a brain bender. Every function in Haskell takes one parameter and returns one parameter. A function which takes more than one parameter is effectively a function which takes in one parameter, and returns a function which takes in all the other parameters (this happens recursively). So to use the example in the video, Int -> Int -> Int means that it takes an integer and returns a function that takes an integer and returns an integer. Higher order functions in Haskell are pretty nice for the simple reason that in order to deal with mutable state, you need to use monads (basically a means of passing the current state as a function parameter, and having the new state be returned). This means that if there's a bug involving mutable state, you automatically know which subset of functions it must be in, because you had to declare the use of the monad; much like how unsafe in rust reduces the surface area for memory or concurrency bugs.
@markosth09
@markosth09 Жыл бұрын
For those wondering iota is a term borrowed from APL, where there is a glyph represented by iota which gives an exclusive range from 1 to n. It is used like ⍳5 and this would give the sequence 1 2 3 4. It is represented by iota because the proper name for this is interval or index generator, with iota being the equivalent to the English letter i in Greek
@poppyjepson8906
@poppyjepson8906 Жыл бұрын
wow cool reference, what is this a marvel crossover or something? xD (why cant cunts just name it "range" or "inclusive range" or at least std::aids::inclrange)
@mskiptr
@mskiptr Жыл бұрын
This is cursed, but I guess I see why code_report thought it's so intuitive and readable
@markosth09
@markosth09 Жыл бұрын
Also code_report does a lot of APL(his favorite language), so this all seems very intuitive
@sebastiangudino9377
@sebastiangudino9377 Жыл бұрын
I mean, in the context of APL iota is a beautiful operator. It's just kinda bloated for C++. But the fact that it is even there just show some capabilities to perform declarative programing in C++. That's IMO kinda nifty
@isodoubIet
@isodoubIet Жыл бұрын
No idea why people keep copying syntax from esolangs but w/e
@somosworld
@somosworld Жыл бұрын
there's a big difference between higher ordered functions in haskell and javascript. one has a world-class compiler the other is a dumpster fire. debugging haskell is a wet dream. there's no state everything is pure. wake up.
@mskiptr
@mskiptr Жыл бұрын
I would actually enjoy seeing Primeagen trying to learn Haskell. Or well, something smaller like Elm or Idris. (Both are basically Haskell but done from scratch, with the focus placed on a slightly different use)
@ccgarciab
@ccgarciab Жыл бұрын
I've done some Haskell, but I have only heard about Idris. Isn't it harder with the dependent types?
@mskiptr
@mskiptr Жыл бұрын
​@@ccgarciab I'd say that they make the type system way simpler. Or maybe sleeker would be a better word. Tho its learning resources are sparse and usually assume you already know Haskell. I guess I would say that while some Idris features are more advanced and harder then what Haskell provides within the language, there are many topics in Haskell that are way more theory-heavy than what Idris adds. Still, these topics usually apply to Idris too. And finally, Idris tooling is basically limited to the compiler|interpreter and some editor integration. Though this includes being able able to write code semi-automatically (with a couple shortcuts to generate partial definitions, case split, search for a correctly-typed implementation, etc.)
@ccgarciab
@ccgarciab Жыл бұрын
@@mskiptr That sounds promising, maybe I should put Idris closer to the top of my todo pile
@mskiptr
@mskiptr Жыл бұрын
@@ccgarciab Btw, one pretty nice introduction to the language is a series of four lectures from 2017. You can find it by looking up "OPLSS Idris".
@anj000
@anj000 Жыл бұрын
I would like to see Prolog
@Jplaysterraria
@Jplaysterraria Жыл бұрын
The big problem with `else` and `else if` statements is that the condition to execute the code block is not at the start of the statement like for `if`s, so you have to mentally juggle with negating the `if` condition and applying the extra conditions from the `else if`. tl;dr: else's have code which is run on an implicit condition, unlike `if`s where the condition is explicit.
@vnshngpnt
@vnshngpnt Жыл бұрын
30:39 It's semantically equivalent. Yes syntax is different, but semantically you're just composing functions. And yeah, as other commenters said, Haskell can be weird, but it can teach you *a lot* about programming and give you many "WHOA" moments, once you get through initial learning curve.
@bloody_albatross
@bloody_albatross Жыл бұрын
About the C++ code: The initial for loop was perfectly fine! Easy to understand, easy to optimize by the compiler. Anyway, there is a problem with the C and C++ versions. The problem is when top is the maximum integer value. Assuming it is really running for that long the C version will overflow and never stop. Always cycling all the numbers. The C++ version starts by adding 1 to top and as such will immediately overflow and immediately stop (will do one loop if bottom is the minimum integer value). In reality that case might not happen, but maybe it can happen if user control the input and that situation would cause some security issue or something. So depending on your context it might be a good idea to handle that case. Hope I got that all right in my head. Rust ranges seem to be handling that case correctly when testing it on Rust Playground. And the difference between the Rust and Haskell version is just methods Vs functions. The -> syntax for the function type is maybe a bit weird when you see it the first time. In Haskell all functions are curried. Meaning if you pass in less parameters than possible you just get a function (closure) back that takes in the rest of the parameters. The -> basically means returning. As such the calculate function is a function that takes in an Int and returns a function that takes in another Int and returns an Int. A bit weird, yes, but handy if you like this high level stuff. E.g. IIRC you can define sum like this: sum = foldr (+) 0 Note that there is no parameter in the definition of sum because foldr takes 3 parameters, but I only pass 2 here. Meaning there is one remaining parameter: The list of numbers to sum. The product function would be: product = foldr (*) 1 foldr is usually called reduce in other languages. There is also foldl. It's about from what side the list is processed. Since addition and multiplication are commutative that is not important here, though I think foldr has better performance in Haskell because of lazy evaluation. Haven't touched Haskell since university, which was more than a decade ago. Btw. IIRC Haskell and currying is both named after the same person: Haskell Curry. So of course everything is curried in Haskell! XD
@NithinJune
@NithinJune 10 ай бұрын
9:30 i think in cpp23 you can get rid of the empty capture group
@yaksher
@yaksher Жыл бұрын
What the assembly comparison tells is that the early things all compile just fine and the compiler understands exactly what is going on, so when you compile with -O2, it can make things tiny, and when you compile with -O3, it can unroll the fuck out of everything and makes things ~blazingly fast.~ On the other hand, the fancier stuff where there's less of a difference, the compiler no longer understands what is going on and so it can't make the optimizations you would want out of it.
@oct_nate
@oct_nate 3 ай бұрын
8:31 it's iota because it's actually atoi backwards 🤔
@kametsu.
@kametsu. 6 ай бұрын
I watched this video year ago and thought "how would anyone on earth prefer his last C++ refactor over starting code" and now rewatching it after doing C++ and a lot of declarative programming stuff in Haskell/OCaml/Elixir and overall applying more declarative style of code for example when using Python I now find that version a lot more understandable and readable.
@realmimak
@realmimak Жыл бұрын
37:16 a call to a library function itself adds an overhead of a few instructions, like stack push/pops, call/jump instructions, returns etc. which can vary based on the calling convention
@sortof3337
@sortof3337 Жыл бұрын
i love haskel. It was one of the first langues i was taught. I am math person and it just makes sense to me. haskell programs read like proofs. i love rust too, been learning it for 6 years now lol. But I write cpp code for my telecom job, I must say that cpp code was just pp move. I work with deveopers that do this in real life, it just looks downright obscure and ugly to me. It is a nightmare to onboard new people if anyone in team write codes like that and doesnt write comments. that stood was awful as well. lol.
@isodoubIet
@isodoubIet Жыл бұрын
"that stood was awful as well." Extremely common pronunciation in the community, probably the most common. From your post it seems like you write C++ as C with classes. You should stop resisting the coworkers who want you to do better.
@gristlelollygag
@gristlelollygag 11 ай бұрын
nah@@isodoubIet
@iqwit
@iqwit 8 ай бұрын
​@@isodoubIetSay what you want about C, but you don't need to look through 5 million std functions documentation just to understand 1 code snippet
@Acetyl53
@Acetyl53 Жыл бұрын
You can't always just rename to cpp. Things like no implicit cast from void* breaks malloc, realloc, etc. There are some other oddities (with function pointers iirc) as well, but that's the primary one.
@QuantenMagier
@QuantenMagier 8 ай бұрын
Yeah they fucked up the C++ standard and compilers not to be synced any more with the C standard, but in former times every C code was also C++ code and C++ was just compiled to C before being compiled to assembly.
@pranavbadrinathan6693
@pranavbadrinathan6693 Жыл бұрын
I'm learning Racket here at University, a functional language similar to Haskell, and debugging is a nightmare. Recursion is such a prominent feature of a functional language, and it is very efficient, but very also hard to debug. We have a stepper to step through the code and it always explodes in lines of code being executed on each recursive call, making it hard to read and actually debug lol.
@geoffl
@geoffl Жыл бұрын
learn how to do it by hand, it will help you _see_ what's going on
@pranavbadrinathan6693
@pranavbadrinathan6693 Жыл бұрын
@@geoffl Alright I'll give it a shot. Anything to make it easier. Thanks.
@rogergalindo7318
@rogergalindo7318 Жыл бұрын
dont know about racket, but in my experience with haskell, the type system really helps, and though at the beginning it was very difficult, later it isn’t an issue that is, with modularity and clarity of what your functions are doing in your loops
@ipodtouch470
@ipodtouch470 Жыл бұрын
Racket is damn hard to debug just because of all the parenthesis 😂
@jacksonmagas9698
@jacksonmagas9698 Жыл бұрын
northeastern student?
@Yupppi
@Yupppi Жыл бұрын
I see the thumbnail and know it's Conor Hoekstra. His algorithm videos are just satisfying as hell. His convention talks are also just intense. And guy who does APL for fun must be pretty serious about languages. Sean Parent started it all, really in 2013. Then Baccara with 105 algorithms in 2018, and since then Hoekstra. They've been going on about how the STL has had algorithms that do things faster, more describingly and with less room for error since 98 and people still in 23 act like you spelled Voldemort if they see a single algorithm instead of bunch of indexed nested for loops. The message being: it's been 10-20 years, it's time you got more familiar with the STL algorithms so you didn't need to be a shocked assembly coder because it's not what you're used to. It's not at all that bad if you spend a little time to know the algorithms and becomes much more readable. Similar to the way Rust is often written with multiple methods ending up with something descriptive and pretty neat. Scary at first when you don't know it, but then rather satisfying. But I loved the whole chat going "this is not readable, it literally says accumulate, filter even while the previous code said for for if for which was painstakingly obvious to me what it was doing, personally I love messing up my for loops for trivial details". Like people don't get shocked when they see something like .reverse() or pow(a, b) or sqrt(). Or for god's sake a function call someone custom made that's all new to them. I would argue though that his reasoning is pretty solid about the bug, it's not just unclear intention if you write two loops contradicting in behavior, it's something you didn't pay attention to and make consistent. But I surrender that it's not guaranteed it was meant to do what he concludes. Basically every speaker in C++ says stud and it's weird. And I also wish everything convenient in C++ wasn't std::blahblah::yup::right::plus. For some reason they went with "iota" when they could've called it something like "range". It's literally just generating the range for you to iterate over. The beauty of Rust really is that no legacy to carry over and no need to follow ISO standard, it could just make this one so nice. But as long as you have to deal with C++, it's kinda nice to have some of the neat features implemented less nicely in C++ than not at all. Personally I'm still trying to understand the need for (|w| w.operation) and understand which and when does mutate the original and what makes a copy or something so I could intuitively write it correctly. And at some point I questioned why you have to always do the |w| manually when you don't have an option to not do it and it could just be done for you by the compiler, but I assume there's a good reason and exceptions. But Rust really doesn't allow you to do stupid things like manually configure iteration loops like you'd intuitively do, it allows you to do simpler and better things instead. Like I was really lost with rust vectors like vec.iter().map(|v| *v * *v).collect() or something, but it was also beautiful how .collect() just deduced the correct return type despite same syntax, different types. The closures were just unfamiliar and I didn't see the reason, but that's a lot of things with Rust: they're new and confusing because your previous language intuition might lead you astray if you don't read how to use the features. But the collect() with ints and strings, it just worked and once you got it into your head that with vector you use .iter() and you have to .map() it, you can even throw a function call inside the .map(). It was so nice even if a bit weird at first. I also saw something about enums in Rust and how they're rather different and powerful, almost like classes, but I haven't still really understood them. But people should be really scared if they don't like seeing this, Hoekstra is a research scientist at Nvidia. His work is quite literally in all of our computers sooner or later. You explained very well why the algorithms exist and are used, and what's the caveat of using them sometimes. Particularly on the Rust example about iterators.
@gogl0l386
@gogl0l386 Жыл бұрын
This has been an emotional roller coaster as a mathematician (so haskell feels the most natural for me). Like first he gets mad of the type declaration thingy and I'm like "wtf programmers don't know currying?" but then he gets it an appreciates it which is nice. BUT THEN HE SAYS "I wOulD hAndS dOwN haTE debUGGinG haskell". Bruh everything is pure functions and type-safe. It is literally the debugging dream.
@nan0s500
@nan0s500 Жыл бұрын
And we all know you cannot have bugs in pure, type safe functions.
@gogl0l386
@gogl0l386 Жыл бұрын
@@nan0s500 Mu point is that if you want to debug then a pure type safe function is the dream as you can just test all values you wanna test without having to think about anything else than it should return the right values and you can trace back exactly the source of the error as there are no global variables that you need to keep in mind.
@nan0s500
@nan0s500 Жыл бұрын
@@gogl0l386 Fair enough
@psd993
@psd993 8 ай бұрын
@@gogl0l386 As he said, you'll have to print everything to see where the bug is. And that is probably what's annoying about it.
@RootsterAnon
@RootsterAnon Жыл бұрын
Heyyyyyyy this was my "Prime should react" video suggestion! I'm so happy that this was on yt now since I missed the stream due to other stuff I had to do. Awesome, had a blast watching it!
@benjaminlieser8148
@benjaminlieser8148 Жыл бұрын
There is actually a second "bug" connected to inclusive ranges. for(int i = bottom; i
@HelloThere-xs8ss
@HelloThere-xs8ss Жыл бұрын
The comment section is always like having -Wall -Werror flags on.
@ThePrimeTimeagen
@ThePrimeTimeagen Жыл бұрын
always
@carlpittenger
@carlpittenger Жыл бұрын
-Wall -Wextra -Wpedantic for gcc and -Weverything for clang
@noredine
@noredine 9 ай бұрын
He took the C code and made it into a tangled ball of words
@simonachtnich4417
@simonachtnich4417 Жыл бұрын
You could flip the first if statement and return early in the case (top
@gtgunar
@gtgunar Жыл бұрын
You can manually reason about what constitutes the count of evens in a range, and find out that you do not need loops, just a few rithmetic steps. You calculate the half of the length of the even aligned subrange, and then correct it with the endpoints. Simple constant time goodness. int calculateCompact(int bottom, int top) {return !(bottom%2) + top/2-bottom/2;}
@Eivindbeivind
@Eivindbeivind Жыл бұрын
Coming from micro controller I get the C code and the rest looks horrible to me, probably cause of syntax I do not see anywhere else than here. But, in big O are any of these better than C? Will any of these performe better than the C solution? Or worse? Ps. English is not my native language so apologies.
@everynametaken
@everynametaken Жыл бұрын
Honestly, the biggest issue with the C solution is that it will blow up if you make one of the variables MAX_INT. This can be easily resolved by just checking for that, but otherwise none will perform all that better.
@moodynoob
@moodynoob Жыл бұрын
This brought back trauma of writing Haskell applications back in uni. Rust really looks like a practical implementation of functional concepts
@dancan4949
@dancan4949 9 ай бұрын
Haskell is a purely functional language while most programming languages are just imperative with some functional features. The thing with such a language is that it basically never sees any practical use outside of academia where it is used as a proof of concept. It is a very beatiful language however.
@dubble_g
@dubble_g Жыл бұрын
imagine me starting uni with 0 programming skills has to do a course in C and Haskell...now in my 5th semester i havent re-done the haskell exam and i am scared because it is probably on paper too... imagine coding haskell on paper to pass a university course
@RuslanKovtun
@RuslanKovtun Жыл бұрын
Comparing number of asm instruction is as meaningful as comparing number of lines in indian code to number of lines in "normal" code.
@joshuakb2
@joshuakb2 Жыл бұрын
In the Haskell code, that first line "calculate :: Int -> Int -> Int" means "calculate will be a function that takes an integer and returns a function which takes an integer and returns an integer." In Haskell, all functions take exactly 1 argument and return exactly 1 value. "calculate bottom top = ..." is really shorthand for "calculate = \bottom -> \top -> ..."
@itsacorporatething
@itsacorporatething Жыл бұрын
You could say calculate :: (int, int) -> int, but that would be against the grain.
@kellybmackenzie
@kellybmackenzie Жыл бұрын
I love Haskell so much, you should really give it a chance!! It's such a beautiful language
@lucaslugao
@lucaslugao Жыл бұрын
God, that C code could have been so much simpler: int calculate (int bottom, int top){ Int sum = 0; for(int i = bottom; i
@mortred4144
@mortred4144 3 ай бұрын
I agree, but I also think sum += (i % 2 == 0) ? i : 0; is more readable to sum += (i % 2 == 0) * i; In either case I wonder if the compiler recognizes adding 0 (in the first case) and multiplying by zero (in the second case) and optimizes these instead off actually performing these operations
@Chalisque
@Chalisque Жыл бұрын
The Int -> Int -> Int stuff makes more sense when you learn currying. If we had, say myMultiply x y = x * y then myMultiply x would give you a function that took one parameter, y, and multiplied it by x. That is, it is equivalent to \y myMultiply x y In e.g. Python, we have to write something like lambda y: myMultiply(x,y) It comes from the maths roots of Haskell. Things like if f:X→Y is a function and g:Y→Z is a function, then (g.f) is a function (g.f)X→Z where (g.f)(x) = g(f(x)). Haskell is a bit of a 'programming language for mathematicians' at times.
@Multifire
@Multifire 8 ай бұрын
You need to be a freaking NASA scientist to understand that C++ refactor, I bet it's slower too.
@noxagonal
@noxagonal Жыл бұрын
I'm mostly with you on this. I really like C++ though. I don't care about iota or filter much. I do like lambdas and some of the helper functions if they make the code more clear. I don't like operator overloading when it changes meaning depending on the context, it's fine if it's consistent across C++. I guess it's good we're all a little different, find the flaws in each other. XD
@funkdefied1
@funkdefied1 Жыл бұрын
The funny thing about the C++ example is that new lines and tabs are just for our benefit anyway. You’ll notice he chose to just include a whole block in one line between the curly braces after the auto statement.
@rogergalindo7318
@rogergalindo7318 Жыл бұрын
once you learn haskell, the code reads almost like poetry, though, the problem is learning haskell… haha gotta say, it’s a bit difficult, but it expands your mind like you never thought it would
@xBZZZZyt
@xBZZZZyt Жыл бұрын
is poetry readable?
@phazechange3345
@phazechange3345 Жыл бұрын
Learning Haskell to expand your mind is like diving in to flat earth communities to expand your mind. Like, yeah, you learned new things, but those things are all useless.
@enzoqueijao
@enzoqueijao Жыл бұрын
​@@phazechange3345 What about the Rust code that uses the same functional programming principles as Haskell?
@phazechange3345
@phazechange3345 Жыл бұрын
@@enzoqueijao I'd suggest that the rust implementation demonstrates that the very few loosely inspired by functional programming concepts are not functional in nature, they're just more often found in FP (ptooey) due to the earlier industry forming around OO (ptooey). One might view compiler level support for tagged unions (Algebraic Data Types) as an obvious step forward from C upon acknowledging that OO (ptooey) is bad, and the same goes for support for functions as first class citizens. Rust also borrows concepts more frequently found in OO (ptooey), such as tight grouping of state and behaviour, as well as their version of encapsulation.
@perigord6281
@perigord6281 Жыл бұрын
Learning Haskell makes Rust feel that much more clunky lol. Especially when it comes to state and error handling. Though Rust is a lower level language so that is to be expected.
@charlesd4572
@charlesd4572 Жыл бұрын
Optimisation typically will produce more instructions when dealing with loops (unrolling - essentially reduces the number of cmp and jmp instructions by making explicit instruction repetitions with the incremented pointer position or register[] value). If you're using library functions your assembly will be smaller as the looping is now reduced to a single call instruction (plus a few mov instructions for arguments) because the the loop work is done elsewhere - unless the functions are inlining the assembly. So the number of lines of assembly does not map to performance for a single function or executable. Furthermore, with CISC (e.g. x86) you can use the same complex instructions such as mul (multiply) and how you supplying the source and destination data can affect how well this performs. With modern CPUs how you supply data to certain instructions can affect how CPU graphs your instructions and this can affect execution speed. So again compilers may use a more verbose set of instructions because it helps the CPU firmware map your code more efficiently. How do I know this - because I code in C! Grrrrrrrr..........................
@torphedo6286
@torphedo6286 Жыл бұрын
I use newline braces in all of my indented code longer than 2 lines. But if it's 1 or 2 lines of indented code, I'll do a same line curly brace.
@isodoubIet
@isodoubIet Жыл бұрын
Honestly just pick one and stick with it. Ideally, use an autoformatter so you don't even have to think about it.
@Alkis05
@Alkis05 Жыл бұрын
I love these HR segments! super funny
@marlls1989
@marlls1989 Жыл бұрын
I learnt Haskell before learning rust and I don’t regret anything
@olaniyanayodele5986
@olaniyanayodele5986 Жыл бұрын
Do you recommend the same or just going for rust directly?
@marlls1989
@marlls1989 Жыл бұрын
@@olaniyanayodele5986 depends on your inclination, I don’t think the order alters the product here. Maybe learning rust first might be less daunting and them later learning Haskell as a step up on your game
@marlls1989
@marlls1989 Жыл бұрын
@@olaniyanayodele5986 I learnt Haskell as a summer project on the first year of my masters. After getting annoyed with Python’s type system.
@steveAllen0112
@steveAllen0112 Жыл бұрын
iota comes from APL, where it means "indices", and generates all the numbers from the index origin (0 or 1) up to the number of indices indicated by the argument.
@andrez76
@andrez76 Жыл бұрын
Ah, C++; the language everyone loves to hate. True, there are a lot of things that come out of the standards commitee that make you go "what?!". On the other hand, it's ~sad~ funny to see how little people know about the language before criticizing it.
@linuxguy1199
@linuxguy1199 29 күн бұрын
37:18 The C compiler likely either A) inlined the for loop, B) replaced the inside of the for loop with some mess of SIMD instructions, or C) done both.
@T33K3SS3LCH3N
@T33K3SS3LCH3N Жыл бұрын
Me at university: I love C++, it gives me so much control! Sure some concepts like pointers are hard for some people, but they're fundamental to programming. Me seeing actual C++ production code: Yeah no I'll never use this language again wtf
@everynametaken
@everynametaken Жыл бұрын
C is amazing, C with classes is also amazing. The things people turned C with classes into... Ye gawds.
@markkkkas
@markkkkas Жыл бұрын
Literally was dying with you at 9:00, great video! :D
@metalhead2476
@metalhead2476 9 ай бұрын
The C version is by far the easiest to read and fix.
@SirRichard94
@SirRichard94 4 ай бұрын
The neat thing about haskell type definitions is that eventually, you don't even look at the actual functions. You just look at the types definitions and see how it all connects.
@franek5309
@franek5309 Жыл бұрын
You have typo in title (react to rust)
@RedHandedBug
@RedHandedBug Жыл бұрын
^This guy reads titles
@ThePrimeTimeagen
@ThePrimeTimeagen Жыл бұрын
< this guy doesn't read titles
@spwim
@spwim Жыл бұрын
More assembly could lead to faster code actually. Say you have a slower general way of solving an algorithm that is quite slow, you could branch/match/switch depending on the actual input at runtime and choose an optimised algorithm based on the actual input. of course every branch needs it's own code leading to more lines but in the end you'll be executing quicker.
@banzobotic
@banzobotic Жыл бұрын
Looking at the generated assembly code he shows, there are some interesting observations I made. Due to the way he used godbolt the compiled rust code didn't even include the calculate function since the results were able to be calculated at compile time. The C and C++ code also calculated the result at compile time, but still included the calculate function. O3 produced more instructions than O2 because it made an attempt to vectorise the code. Using std::accumulate prevented the C++ compiler precomputing the result of calculate(5, 12) when using O2, although it still managed it when using O3. Trying to compare the speed of languages by looking at the number of generated instructions is flaky at best, but even worse when the code examples used can be trivially precomputed.
@augustodias1299
@augustodias1299 Жыл бұрын
$ in haskell is an operator. This operator will take a function on the left side and apply it to the parameters on the right side. It is often used to hide parenthesis
@arjix8738
@arjix8738 Жыл бұрын
i think the iota comes from the fact that most range loops use i as the variable, for i in range(...), and i is basically iota
@xBZZZZyt
@xBZZZZyt Жыл бұрын
what about the "ota"?
@trenwar
@trenwar 8 ай бұрын
​@@xBZZZZyt iota means range, idk what ota means but there's that
@lord_nikon_010
@lord_nikon_010 Жыл бұрын
About the curly braces in a new line... I feel you, bro!
@braincruser
@braincruser Жыл бұрын
13:30 Imagine you having to teach a junior programmer to read this code.
@zxuiji
@zxuiji Жыл бұрын
3:41, should the bile come up for swirly braces left at the end of a scope header? What happened to properly spacing out code so that it's readable as opposed to a giant wall of text? What happened to making scope headers easily distinguishable at a subconscious level by separating it from it's code? Every time I look at a scope header with a swirly brace next to it instead of under it my knee jerk reaction is always "ugh" instead of straight away having my attention drawn to the code instead of the header.
@lpanebr
@lpanebr Жыл бұрын
I feel that Code aesthetics target audience is less experienced.
@biskitpagla
@biskitpagla Жыл бұрын
True. He also focuses on relatively more oo and less multiparadigm languages and design patterns afaik.
@P3PPING
@P3PPING Жыл бұрын
Every time I see Rust, I think 'wow this is just like Ruby but with curly-boiis and typing' and I love that.
@fredbcruz
@fredbcruz Жыл бұрын
I'm so happy that except from types and the range rust's example is pretty much js TODAY
@adamih96
@adamih96 Жыл бұрын
From what Ive heard, the problem with haskell is dealing with modules, toolchains, etc. The language is designed by language researchers and not software engineers. Please correct me if im wrong.
@justgame5508
@justgame5508 Жыл бұрын
Don’t program in rust (want to learn) I’m a C# dev and that rust code is 100% readable. We have things in C# virtually the same so that helps, but any developer should be able to look at that and understand what it’s doing regardless if their primary language
@rusi6219
@rusi6219 9 ай бұрын
Then what's the point of rustranies pushing Rust when it's just a copy-paste C#
@cosmq
@cosmq Жыл бұрын
ya know what? just do this : ``` int calculate(int bottom, int top){ int sum = 0; for(int i = bottom; i top ? 0 : ((bottom & 1 ? 0 : bottom) + calculate(bottom - 1, top))); } ```
@daasdingo
@daasdingo Жыл бұрын
Maybe it is intentional, but it bothers me a bit that no one mentions that you don't even need the loop for this problem. You can solve this with algebra.
@everynametaken
@everynametaken Жыл бұрын
My algebra is a bit rusty, how so?
@yash1152
@yash1152 Жыл бұрын
30:07 32:00 that top definition is for "haskell currying". ur instinct of "Int, Int -> Int" requires the fxn to get 2 ints right there. But with this currying, u can supply one int, and the other can be say a list of ints, and this fxn would apply calculate over each element in that list iirc. there is computerphile's video on haskell currying.
@Gornius
@Gornius Жыл бұрын
That C -> CPP transition was HIDEOUS... No wonders how I almost abandon programming career because I thought everything more complex than simple loops looked like CPP. At this point I am pretty sure CPP people do these things to make their code so obscure that only they can understand what's going on, thus securing their jobs.
@voidwalker7774
@voidwalker7774 Жыл бұрын
you would not believe how often i actually observed this behavior in real life
@myxail0
@myxail0 Жыл бұрын
But it's basically the same as rust version, just poorer syntax
@bravegrumpy689
@bravegrumpy689 10 ай бұрын
So the original video used syntax explicitly meant to be language agnostic. All Turing complete languages have control flow, functions, and loops. While the code happened to have been C, the original code snippet is also runnable Java code. So the advice in the original video was helpful for me when thinking about my spaghetti-code python script. It also works for refactoring React components. And for simplifying my MATLAB scripts. (Data-science/ChemE background) Or for finding a bug in Julia. Or for simplifying and refactoring CSS. The refactor using rust or cpp specific features does not do as good of job getting the core programming concepts across as the code becomes unreadable by somebody using an unrelated language. Or by somebody using a DSL. Most reasonably modern programming languages have inspiration from C. So C can often look like pseudo-code, and therefore can be used as an example to talk about a more fundamental concept. While refactoring using modern language specific tricks is cool, I think it misses the point and reduces the audience that can accept the lessons about a happy path, early returns, and using functions when a script gets too messy. The original video is closer to a moderate and useful distillation of the lessons learned from clean-code.
@kipchickensout
@kipchickensout Жыл бұрын
new line braces are more readable and widely used in C#, i see it as a positive thing
@fg786
@fg786 29 күн бұрын
20:00 Not at all. I mean you have to kind of guess that bottom..=top is a range of numbers. No idea what |e| means specifically but you get the meaning, because the range gets filtered with %2 and summed up. 26:00 wouldn't you just write (bottom..top) to recreate the initial code? Or will this then cause an error as it's not handled by the "range object"
Prime Reacts: The Flaws of Inheritance
29:05
ThePrimeTime
Рет қаралды 392 М.
진짜✅ 아님 가짜❌???
0:21
승비니 Seungbini
Рет қаралды 10 МЛН
Caleb Pressley Shows TSA How It’s Done
0:28
Barstool Sports
Рет қаралды 60 МЛН
GIANT Gummy Worm #shorts
0:42
Mr DegrEE
Рет қаралды 152 МЛН
«Жат бауыр» телехикаясы І 26-бөлім
52:18
Qazaqstan TV / Қазақстан Ұлттық Арнасы
Рет қаралды 434 М.
Prime Reacts:  Building a Startup in Rust; I won't do it again
17:23
ThePrimeTime
Рет қаралды 228 М.
HaskLUL
25:25
ThePrimeTime
Рет қаралды 106 М.
I reimplemented REACT SERVER COMPONENTS in ASSEMBLY
20:35
Neo Goose
Рет қаралды 8 М.
Maintainability And Readability | Prime Reacts
20:22
ThePrimeTime
Рет қаралды 110 М.
I Hate Rust | Prime Reacts
23:00
ThePrimeTime
Рет қаралды 181 М.
Haskell Is Faster Than C | Prime Reacts
31:46
ThePrimeTime
Рет қаралды 140 М.
Faster than Rust and C++: the PERFECT hash table
33:52
strager
Рет қаралды 614 М.
Stop Recommending Clean Code
27:05
ThePrimeTime
Рет қаралды 564 М.
Leaving $450,000 a year Job | Prime Reacts
43:42
ThePrimeTime
Рет қаралды 386 М.
진짜✅ 아님 가짜❌???
0:21
승비니 Seungbini
Рет қаралды 10 МЛН