Ditch Your Favorite Programming Paradigm | Prime Reacts

Поделиться
HTML-код
  • Опубликовано: 5 май 2023
  • Recorded live on twitch, GET IN
    / theprimeagen
    Original: • Ditch your Favorite Pr...
    Author: / @codepersist
    MY MAIN YT CHANNEL: Has well edited engineering videos
    / theprimeagen
    Discord
    / discord
  • НаукаНаука

Комментарии • 518

  • @Xtermo
    @Xtermo Год назад +543

    Based and procedural-pilled take. OOP and FP are basically both attempts to make PP scale more nicely. Let us never forget that in the end, the core of programming is still PP.

  • @atalhlla
    @atalhlla Год назад +88

    The perfect functional program accepts no input besides power and produces no output besides heat.

    • @ea_naseer
      @ea_naseer Год назад +8

      Hold on we accept input... hold on the computer accepts power and moves the computer into another world where input has been received. 😂😂😂😂😂😂

    • @BudgiePanic
      @BudgiePanic 6 месяцев назад +1

      Finally a language to surpass Haskell

    • @pdd5793
      @pdd5793 Месяц назад +4

      i disagree with you: in this case the program is receiving power as input and releasing heat as output, also it's affecting a global variable called "Universe_Entropy".
      in that case, the perfect functional program is actually:

  • @davidandrewthomas
    @davidandrewthomas Год назад +262

    “You wouldn’t want `address` to be public, since any other class would be able to access and change it.”
    *immediately adds getAddress and setAddress methods as “best practice”*

    • @rj7250a
      @rj7250a Год назад +55

      Honestly, that is why i do not like devs that shill OOP as the best thing in the world.
      They just know how to copy and paste stuff they have seen in books, like "Clean Code™", and love to overcomplicate everything because it is a "Good design pattern".
      Getters and setters are perfect examples, they are useless in 90% of ocasions, but OOP shillers use them everywhere, even though it does the same thing as just acessing the variable directly.

    • @zacharychristy8928
      @zacharychristy8928 Год назад +30

      @@rj7250a it's not even good OOP in my view, it just adds noise. If you evaluate your objects by asking "what should each field/method be able to do" and not just add things because it's what you've been told, you wind up with OOP code that actually takes advantage of encapsulation instead of doing backflips to get around it.
      So for example, if you have a field with a get/set that just returns/sets the underlying property and NOTHING else... why wouldn't that just be a public field on the object? It's adding lines to just add lines, lol.

    • @AScribblingTurtle
      @AScribblingTurtle Год назад +6

      Setter- and Getter function are kind of a mess if you ask me.
      If changing or reading a Class property has to lead to a chain reaction, then they are mostly unavoidable.
      But, if the property is independed then having to define 2 extra methods just for the user to access them, bloats the Classes code.
      Its kind of a trade:
      For a Class user, knowing that changes to an object can only be done via methods is easier to understand. (hence why everyon thinks it is "Cleaner")
      But for the Class writer, it mostly boats the code and makes things harder to read/navigate.
      That is, why i love Javascripts 'get' and 'set' function attributes and PHPs __GET and __SET Magic Functions.
      They let you do all the stuff, that Setter and Getter functions can do, but still present them both combined just as one attribute to the Class User.

    • @wumwum42
      @wumwum42 Год назад +29

      There are some usecases :
      - the user should only get or set the value
      - you need to do data validation before setting the value
      In this example it makes no sense

    • @rj7250a
      @rj7250a Год назад +15

      @@zacharychristy8928 I have seen good OOP, but it has been done by pragmatic programers, not OOP shillers.
      Pragmatic programmers use whatever is the best for the current problem, they do not follow a strict set of principles in a book, as if it was a religious dogma.

  • @daniel-wood
    @daniel-wood Год назад +184

    Videos about OOP that start with a description of classes, methods, and inheritance are the CS equivalent of starting an essay with "Merriam Webster's defines [essay topic] as"

    • @colemanroberts1102
      @colemanroberts1102 Год назад +5

      Go read any lisp book ever written. I will bet a million dollars chapter one describes how s-expressions work.

    • @Cookiekeks
      @Cookiekeks Год назад +1

      What's wrong with describing it like thaf?

    • @Salantor
      @Salantor Год назад +11

      @@Cookiekeks Everyone does that. At this point, it is either just filler if you know what OOP and PF is, or a video for beginners, which you can find an abundance here.

    • @torphedo6286
      @torphedo6286 Год назад +30

      It always brings me pain, because they (almost) always give class examples of real-world objects. Code is not real life, classificiation is never that simple and clear in practice. I'm not writing code to deal with the different types of apples or fish. I'm handling files, or graphics, or compression, or strings.

    • @yjlom
      @yjlom Год назад +1

      @@colemanroberts1102 the emacs lisp book chapter one describes how to read the book; chapter 2 (the first real chapter) describes the data types
      in fact it says nothing about how the program is evaluated before chapter 10, and the term `s-expression' does not appear (outside of footnotes) before chapter 35 out of 42

  • @diadetediotedio6918
    @diadetediotedio6918 Год назад +46

    For me the question boils down to a few simple concepts,
    1. The object-oriented paradigm revolves around passing data between unified domains, not necessarily "classes" or "structs". That means you send information back and forth and try to make each specific domain responsible for interacting with that dataset within that scope of states.
    2. The functional paradigm revolves around making code immediately obvious in a declarative way, even if that involves using data encapsulation methods and the like. The code must read fluently and it must be immediately obvious the result of an expression not by an individual stream of parts, but by the complete expression (and, of course, it must be decomposable).
    3. The procedural paradigm revolves around ordering things in a specific, controlled way, not through statements or units, but through small, specific, determined logical steps that must modify or change the data as they are performed. The scope of a procedural code is always linear and it must be possible to read and understand linearly.
    To that extent, I can understand that all paradigms employ common concepts and can be summarized to common notions present individually in each of them, but which are not immediately reducible to these, as a complex system. Each of them has its place and I can understand why multi-paradigm languages won and purely functional or purely object-oriented languages became less and less popular.

    • @AnthonyBerlin
      @AnthonyBerlin Год назад +13

      You cant say that. A mature response is not for the internet! Here you need to pour gas on the fire and say "THIS PARADIGM IS TRASH, THE ONE I LIKE IS BETTER!!!!". Dont be sensible. It's the internet.

    • @aakarshan4644
      @aakarshan4644 Год назад

      can you please elaborate on declarative and imperative code ? is my thinking correct that all declarative code is always abstracting some underlying imperative logic? To me the functional paradigm seems declarative in a way that it abstracts imperative logic. for e.g even when writing an 'imperative' c = a + b, we are abstracting the logic of actual addition on bits away from us in the "+" operator, in turn making it declarative.
      Also if you've used react can you comment what kind of paradigm its following? is it functional UI or declarative JSX? or something else?
      I think its time for me to learn haskell lol

    • @matheusjahnke8643
      @matheusjahnke8643 11 месяцев назад

      I remember once... in haskell
      I was trying to manage "connection codes" on a server... kinda "low level" in the sense I only used the standard libraries to do it... no frameworks...
      You start client A, which asks to connect...
      The server accepts and sends a "code"...
      You could(out of the loop) send to your friend...
      Your friend starts client B which send that same code to the server...
      and then you( and your friend) start a session(in my case... a battleship game) managed by the server
      in particular... to manage the codes in a server... I essentially needed 2 functionalities:
      1. Create a brand new code associated with connection with client A(which just connected asking to make a new connection)... give out the code(so the server transmits to the client A so you can send to your friend)
      2. Given a code... return the connection you and your friend can play;
      I'm not using the haskell notation like I did there. I will do the equivalent in python;
      def codeManager():
      id = 0
      connections_to_be_paired = dict()
      def assignID(connection : TCPConnection):
      nonlocal id
      current_id = id
      id += 1
      connections_to_be_paired[current_id] = connection
      return current_id
      def pairConnection(pairing_id):
      try:
      connection = connections_to_be_paired[pairing_id]
      del connections_to_be_paired[pairing_id]
      return value
      except:
      return None# This function originally returned Option.... so it was not as sketchy as it is in python
      return (assignID,pairConnection)
      That's like.... very old school OO done via closures.
      People would use a class for this, with attributes "id" and "connections_to_be_paired" private(here they are encapsulated because there's no way to reach them from outside), and public methods "assignID" and "pairConnection" (in my bodge they are the return values).
      It's not bad... but you had to remember the order of the "methods" that were returned:
      assignID, pairConnection = codeManager() # assignID, pairConnection... just like the function returns
      Nowadays I would have wrapped them in a struct equivalent in haskell. The closest thing to class you can get without significantly more workarounds

    • @zyriab5797
      @zyriab5797 11 месяцев назад +4

      Woah woah, don't be writing Python out of nowhere like that! There are children around here!

    • @matheusjahnke8643
      @matheusjahnke8643 11 месяцев назад +1

      @@zyriab5797 do you really want it in haskell?

  • @daveisradicle
    @daveisradicle Год назад +114

    Anyone else make a bet with themselves how long it's going to take for the costco alert to go off and remind prime to turn off his alerts?

    • @simonced
      @simonced Год назад +3

      Nice idea, I'll try next time and give my result ^^

    • @complexity5545
      @complexity5545 Год назад +1

      This made me laugh more than it should've.

    • @tedchirvasiu
      @tedchirvasiu Год назад +1

      i love you

  • @capsey_
    @capsey_ Год назад +22

    9:42 fun fact, this code on the screen doesn't actually have any side effects. Python only assumes you use global variables when accessing, when assigning values it creates a local variable, unless you use global keyword

  • @IronEducation
    @IronEducation Год назад +11

    I almost spit out my drink at 'leave room for the Holy Spirit' and 'Fibonacci Indenting' 😂

  • @star_man
    @star_man 3 месяца назад +3

    As someone who grew up with procedural programming before OOP truly entered the mainstream, it was interesting and slightly humorous watching OOP grow, suddenly OOP was considered the cool kid, your programming language wasn’t worth considering if it wasn’t object orientated, people couldn’t gush enough over it, it was new and trendy, everything HAD to be OOP, and the young coders were told OOP was like some god that had to be worshipped… now people are realising that while OOP has its uses, it’s not the all singing all dancing paradigm they were told, and can be a steaming pile of hot garbage.

  • @GmanGavin1
    @GmanGavin1 Год назад +11

    14:23 yep, that was me. Until I started learning a little bit of Haskell I went "wait if this is rules of functional then what the heck is C" and that's how I learned about the "procedural paradigm"

  • @grawss
    @grawss Год назад +8

    I made a full GUI, multi-option/filter database searcher as my first program. Super snappy, fun to use, it would search "name 04" if you typed "04" etc. It even searched as you type! I asked how I could improve, and they said my use of "goto" was frowned upon because it makes the code hard to understand. It was 1 goto in 46 lines of code with zero functions or classes. To replace it would require breaking the whole thing up into multiple functions which would then "goto" each other.
    That's my issue with this debate. Functions are just "readable" gotos, and classes are just "readable" functions, and inheritance is just "readable" classes, and programming languages themselves are just "readable" versions of other programming languages. Seems like we're forgetting how to read!

    • @zeckma
      @zeckma 8 месяцев назад

      I remember encountering Basic when using a Commodore64 emulator, and found the goto keyword to be really cool and simple. I still kinda miss using it. Goto is just really simple and easy to understand! if condition, go here in this part of the code! if not, just continue on then perhaps when that not statement is done, jump to the end.

  • @farqueueman
    @farqueueman Год назад +11

    I invented a new paradigm called HBO - hairball oriented programming. It consists of one flat function that does everything. Who needs global variables?! ♥

    • @etodemerzel2627
      @etodemerzel2627 Год назад

      I mean this is how I program... But I avoid repeating the same code, so it becomes a separate function. And if something is clearly delineated from the rest then I also move it into a separate function.
      The resulting code is more performant, readable, and maintainable than what you get with OOP.

    • @farqueueman
      @farqueueman Год назад

      @@etodemerzel2627 yes, the most common pattern unfortunately is called the big ball of mud. I used to write like that back in the day before getting into clean code, architecture and design patterns.

    • @etodemerzel2627
      @etodemerzel2627 Год назад

      @@farqueueman Well, I'm moving away from Clean Code:tm:, etc. Over the years, I've seen plenty of codebases written with these approaches. All of these codebases are awful: hard to read and navigate, hard to change anything, and, on top of that, they're slow. My "ball of mud" is better in every way.

    • @farqueueman
      @farqueueman Год назад

      @@etodemerzel2627 lol

    • @4sxS307cAW
      @4sxS307cAW 6 месяцев назад

      DEZIGN BATTERN YAS

  • @kellybmackenzie
    @kellybmackenzie Год назад +3

    14:06 You absolutely NAILED IT, I love this so much. That's exactly it. This is why I love your channel, thank you so much

  • @mennovanlavieren3885
    @mennovanlavieren3885 Год назад +9

    3 Space indenting is going to be my new styling guide. It is the informal acknowledgement that you don't care about the well being of others.

    • @pharoah327
      @pharoah327 5 месяцев назад +1

      I can handle 2 or 4. I tolerate 8. But I've seen 1 space indenting and I wanted to curl into the fetal position and cry. With 3, you are just pissing off anyone with OCD, lol.

    • @Pompomatic
      @Pompomatic 2 месяца назад

      @@pharoah327 Aw man, I've started to really like the spacing with 3 space indenting. Did not know it was hated

  • @SimGunther
    @SimGunther Год назад +70

    Here's my paradigm step by step:
    1. Solve the problem with messy procedural prototype code
    2. Find where the state can be localized and calculated as part of an idempotent function
    3. Put const/final on everything I just added if the language is not const by default so I don't trip over myself changing something I otherwise shouldn't
    4. See which state is forced to persist after the important function calls and turn those bits of state into a "fake continuation stack" aka internal localized state in an object

    • @CYXXYC
      @CYXXYC Год назад +15

      Be careful though, as Prime noted in one of his previous video, this approach of incremental fixing toward some local optimum may lead you to find out that it needs a complete rewrite to get the best global optimum solution.
      However, in my opinion, following paradigms like FP or OOP, or maybe even some custom ruleset, can allow you to get to those local optima quicker, as you train yourself to write paradigm-following code more and more, thus saving you time on incremental fixing in the long run. I think this is also literally the point of Rust, which always seems hard and slow to write, but in the long run you would not only write more correct code first try, but also know writing what could get you more correct.

    • @SimGunther
      @SimGunther Год назад

      ​​@@CYXXYC The more sure the requirements are, the closer it gets to that last step. Unfortunately, an ever evolving product with even more unsure product folks keep me from going past step 3 most of the time anyway.

    • @aakarshan4644
      @aakarshan4644 Год назад

      @@SimGunther Hi can you please suggest me some program/system I could write to test different paradigms and even custom rulesets for their tradeoffs and to also upskill myself in different modes of programming/designing systems. TIA

    • @drygordspellweaver8761
      @drygordspellweaver8761 Год назад +5

      That’s pretty much just called “programming” and how it should always be done.
      1) do exactly what you need to do with data.
      2) abstract out the common state for compressed and efficient code.

    • @MrTyty527
      @MrTyty527 Год назад

      that's a nice analysis

  • @sync9827
    @sync9827 Год назад +2

    Please keep doing what you're doing! I love your content!

  • @TankorSmash
    @TankorSmash Год назад +8

    The 'look in less places during side-effect-free FP' is sorta true, in the sense that you don't need to look around for more and more things as you read through a function, the scope only gets tighter and tighter.
    Like if you write a django view, at any point the request could hit the DB and influence the state of the app, but with Haskell or whatever, unless you're doing side-effects (IO), you can be sure that you only have access to the variables you did at the start of the request. You don't need to check what state the database is in, because it wasn't passed in as a variable.
    Hard to put into words but it does feel simpler (in certain aspects) compared to the imperative style, even if there's tons of overlaps. Its all about picking your poison for sure.

    • @thekwoka4707
      @thekwoka4707 Год назад

      A Django app was my first large production OOP based thing to work on.
      It's awful.
      As you go into things to figure out what's going on it just goes everywhere.

    • @sk-sm9sh
      @sk-sm9sh Год назад

      "the scope only gets tighter and tighter."
      This is kinda the essence of composition in OOP. However it's not that simple, it's usually almost impossible to design code in purely hierarchical manner. Now OOP has produced plenty of great literature how to design your application that can achieve this property - onion/hexagonal/etc architectures are all born from applying the principle of composition to large apps.

    • @TankorSmash
      @TankorSmash Год назад

      @@sk-sm9sh Pure functional is all about composition because there's no way not to do it!
      Tons of purely hieracrchical projects exist using Elm or Haskell since they don't allow using something you don't pass in (with some tiny exceptions!).
      You should try out some FP languages if you're curious!

    • @sk-sm9sh
      @sk-sm9sh Год назад

      @@TankorSmash here we go again "you should try some FP". From my experience really more people tried it that FP zealots like to think. Just because I tried it doesn't mean I love it already. To me it falls short in many regards.

    • @TankorSmash
      @TankorSmash Год назад +1

      @@sk-sm9sh You're saying you tried one of them and didn't like it? That's totally valid too! There's unfortunately no silver bullet after all.

  • @mskiptr
    @mskiptr Год назад +29

    The vast majority of FP in the wild goes on in imperative languages. Functional-style code in Python and JS is still just a bunch of procedure calls. That's because these are the mainstream languages.
    (except Excel ofc)
    But the converse is also achievable. You can take a purely functional language and build stateful, imperative abstractions within it.
    Btw, you should really try expanding your view. Try learning some variant of Lisp (Scheme seems solid and small-enough) and something with its roots in ML (maybe Elm, since it focuses on FP novices and is very small too)

    • @colemanroberts1102
      @colemanroberts1102 Год назад +1

      Common Lisp is best lisp. Scheme is so small that tons of important functionality is implementation dependent. Common lisp has a big standard, but excellent facilities. Also, unhygienic macros, unwind-protect, CLOS, excellent exception handling, optional dynamic scoping, etc.
      Clojure has neat features and excellent java interop, and scheme is super small and really lets the implementor play around the design space. But common lisp's interactive development is top tier, even among lisp's.

    • @mennovanlavieren3885
      @mennovanlavieren3885 Год назад +2

      Also if your compiler/interpreter cannot collapse several chained map functions into a single loop it is not really functional programming. It is just functional style.
      Take SQL for example, you can nest SELECT clauses all you want, but it isn't going to create a bunch of temporary tables if it can evaluate the expression with one index traversal.
      SQL in that regard is much more functional than the functional part of JavaScript. Of course in SQL you can't store functions as values in tables, so that is where that ends.

    • @ultru3525
      @ultru3525 Год назад

      ​@@colemanroberts1102 Common Lisp definitely is more suitable for making relatively fast real-world applications, but for someone more interested in learning programming language paradigms & fundamentals, Scheme's minimalism & simplicity is actually a benefit, e.g. I couldn't wrap my head around the concept of an "object" until I had to implement them from scratch in Scheme as a CS freshman. Other things we implemented in it are a type system (using cons cells), lazy evaluation (using lambdas), DSLs, a filesystem, a relational database management system, a meta-circular evaluator, and just about every data structure known to mankind. It's the ideal teaching language imo.
      Also, Racket is a great scheme variant that offers the best of both, with a comprehensive standard library, package manager, build tool, and top-notch documentation, it even comes with its own IDE, the only thing it really lacks is speed.

    • @colemanroberts1102
      @colemanroberts1102 Год назад

      @@ultru3525 minus the meta-circular evaluator, all those things are just as easily done using the same techniques in Common Lisp. You are correct about scheme being a better platform for learning to implement a language though.

    • @ultru3525
      @ultru3525 Год назад

      ​@@colemanroberts1102 Oh yeah, I wasn't trying to imply you can't do those in Common Lisp, my point was that all of those can be done in Scheme, in spite of its limited facilities.
      And as a teaching language, I feel like Common Lisp suffers from the same problem as Java: too many options that are useful in production, but can only serve as a distraction when you're trying to focus on the fundamentals.
      Common Lisp was the second language I got comfortable with after Python, and while spending two days trying out all permutations of `loop` keywords was interesting, it wasn't really the best use of my time. With Scheme, it's practically impossible to "waste" time learning language-specific features, you'd have to delve deep into the intricacies of continuations for that.

  • @nieczerwony
    @nieczerwony Год назад +3

    Brian Will 7 years ago made a video on why OOP is not really OOP and ppl still discuss it.

  • @boredbytrash
    @boredbytrash Год назад +14

    I hate this generation of devs. Everyone and their mom want to be come „dev influencers“ when they are obviously either just BAD at it, just graduated or are just repeating the bad Medium posts of others.
    Saying „public static final“ is a OOP pattern is so stupid and then continuing „now I want to show the beauty of FP, but I never used it so sorry I’m advance for my bullshit“ is so ridiculous.
    „Engineers“, we are laughing stocks

  • @Max-bh8tg
    @Max-bh8tg Год назад +1

    "I already hate everything i see" made me spit out my coffee

  • @caddr
    @caddr Год назад +5

    Functional Programming can't work with side effects?, in Haskell (Advanced Pure Punctional Programming Language) you can work with effects using Functor, Monad and Applicative

    • @NathanHedglin
      @NathanHedglin Год назад +3

      Correct. Haskell manages those effects.

  • @JorgeDB
    @JorgeDB Год назад +5

    4:00 abstraction is such an abstract concept

    • @madsteeez
      @madsteeez Год назад

      Not it's not. It just means abstract methods as in eg interfaces.

  • @jsd4544
    @jsd4544 Год назад +12

    Lil bit o' both!

  • @ujjawalsinha8968
    @ujjawalsinha8968 Год назад +1

    "Abstraction is like everything..." Nailed it!

  • @theherk
    @theherk Год назад +9

    Yo! Fib or exponential indenting seems like a great idea. Arrow antipattern no more.

  • @ghosthookcc2050
    @ghosthookcc2050 Год назад +1

    Would somebody mind explaining what prime meant by properties being one of the big problems with OOP/classes? Im developing a language and I'm currently writing a EBNF/grammar for the language. I think some approaches I have come up with can avoid OOP confusion in some areas but I'm stuck on what prime meant by the properties comment, could be interesting?

  • @NathanHedglin
    @NathanHedglin Год назад +1

    04:15 yeah abstraction as a pillar never made sense to me either. They're all abstractions.

  • @wadecodez
    @wadecodez Год назад +1

    ff vs oop vs pp really depends on what you're making and how it should read when you're debugging it. IMO it should be natural. If you're hesitating on paradigms, patterns, syntax, etc. you need way more practice.
    If you need hierarchy use OOP, if there are clear steps, make it obvious, and I guess otherwise try to preserve immutability at all costs.

  • @henrymach
    @henrymach Год назад +1

    In the end, the good ole structured programming is still what works best

  • @steveoc64
    @steveoc64 Год назад +2

    Data Oriented design + manual memory management + imperative code with no hidden control flow, or GTFO

  • @Alexander-ns9yv
    @Alexander-ns9yv Год назад +1

    I drink your programming paradigm. I drink it up!

  • @hiromichiw
    @hiromichiw Месяц назад +1

    abstraction was more of an obstruction to me

  • @petrus4
    @petrus4 6 месяцев назад

    The great thing about Python is that if I manually set the recursion limit, I can choose which level of abstraction I live on. I can get most of FORTH's extensibility if I want it, or I can have completely pre-cooked loops if I want them as well.

  • @tyriceclark4283
    @tyriceclark4283 3 месяца назад

    I think the intention of Functional Programming is for solving problems in a mathematical way. Like you said mainstream functional programming is just organizing your code in procedures without side effects. Same with OOP where Alan Kay was like it's more about the messages than the objects themselves, but objects are just another way of organizing your procedures. Procedures FTW!

  • @s3rit661
    @s3rit661 Год назад +2

    0:55 Java is Multi-paradigm tho (Java has functional programming after Java 8, with streams and labmdas)

  • @RogerBarraud
    @RogerBarraud Год назад

    For a sort of hybrid-functional approach alternative to inheritance, there's an interesting YT vid by Peter Seibel on Multimethods.
    I forget whether he autogenerates them... been a while.
    OTOH you could probably consider multimethods as a procedural enumeration of the Cartesian product of class X action 🙂
    [So Prime is ahead of the curve :-)]

  • @scarecat
    @scarecat Год назад +1

    I think picom has a 'vsync' option which gets rid of screen tearing.

  • @laifsyn5347
    @laifsyn5347 6 месяцев назад

    5:20 I find it more senseful for Rust to use Wrappers(sounds pretty similar to encapsulation for me) not to protect sensitive data, but to safeguard the data's/ or type validity.
    For example, a non-empty string which is also a valid email. This Data-Type we will call it "Email". now, everytime you use Email as a func's argument, you can be a hundred percent confident that the function is both receiving a valid and non empty e-mail.
    And furthermore, when copy-pasting the function (let's say the version that use a String as argument instead of Email), you won't accidentally forget to parse the string, or even do a double/multiple parse(one inside the function, and another at the callsite(s) because you forgot the function would parse the String automatically for you)

  • @megetmorsomt
    @megetmorsomt Год назад +1

    Embrace no paradigm: all hail the mighty Nim!

  • @eitanseri-levi2169
    @eitanseri-levi2169 7 месяцев назад

    I love when prime freaks out over spaces and indents

  • @ea_naseer
    @ea_naseer Год назад +5

    Functional programming maps so well to many things in mathematics and Computer Science but OOP maps well to the real world.
    For me though, FP is good when I'm building and all the ideas are in my head but if I come back to it three days later I'm confused.

    • @etodemerzel2627
      @etodemerzel2627 Год назад +5

      OOP maps well to the real world?! We must be living in different worlds then.

    • @ea_naseer
      @ea_naseer Год назад +2

      @@etodemerzel2627 ehhhh...? I know you can create custom types and there is the data keyword in Haskell but... I don't use it... maybe that's the world I'm from.

    • @freesoftwareextremist8119
      @freesoftwareextremist8119 Год назад +1

      @@etodemerzel2627 On the fundamental level the living world around us is a bunch of cells communicating. Like a bunch of "objects" passing "messages".

    • @etodemerzel2627
      @etodemerzel2627 Год назад

      @@freesoftwareextremist8119 That's true OOP or Actor model as it's known these days.

    • @drygordspellweaver8761
      @drygordspellweaver8761 Год назад

      It’s a grave error to try and map the “real world” to code. Code exists entirely in 0’s and 1’s. There is no “chair” that inherits from “furniture”. There is only data.

  • @andythedishwasher1117
    @andythedishwasher1117 Год назад +1

    Procedural Programming Andy is a title I might be down with for a time. But I would defy it on occasion.

  • @JasonDoege
    @JasonDoege 5 месяцев назад

    Figuring out how not to have so many copies was one of the challenges of learning FP.

  • @just_smilez
    @just_smilez Год назад +20

    Design paradigms are tools, and become problematic when treated as dogma. It's a take I wish I would see more often.

    • @aoeu256
      @aoeu256 Год назад

      REACTIVE + DECLARATIVE (language oriented) is best

  • @frederic_millenial
    @frederic_millenial 10 месяцев назад

    At 5:00, can we talk how this guy animates the code ? It’s magic.

  • @rishavmasih9450
    @rishavmasih9450 Год назад +1

    The guy in the chat who said I just use global variables, is a menace to society.

    • @sillymesilly
      @sillymesilly Месяц назад

      Nothing wrong with global variables

  • @SpellsOfTruth
    @SpellsOfTruth 3 месяца назад

    Wasn't this Terry Davis' take years ago minus the rants about running over glowies with a car?

  • @RedOchsenbein
    @RedOchsenbein Год назад +5

    I think one of the most overlooked upside of pure functions and immutable variables is the ability to distribute (and cache) their workload. Since you don't have to track a shared state and the output is deterministic all the time it does not matter which machine (or processor, or core) works on your function, the result stays the same.

    • @ultru3525
      @ultru3525 Год назад +3

      This is basically the raison d'être of Erlang (and by extension Elixir), it's astonishing how seamless & lightweight process creation is. I'm not aware of any other language where you can be running thousands of threads without even batting an eye.

    • @RedOchsenbein
      @RedOchsenbein Год назад +1

      @@ultru3525 Unison would be another one.

    • @romelalexissuarez
      @romelalexissuarez 6 месяцев назад

      oop has a problem. creates redundant elements in memory. In many programming languages an object inherits from a base object. Therefore, every time it is instantiated, its elements, properties, methods, special methods, etc. are also loaded. fp doesn't do that. The data is separated from the methods, whether they are pure functions (calculation) or impure functions of actions. In addition, the Earlang virtual machine does one thing, and that is the virtualization of processes, so these are not loaded into the operating system with a life cycle and everything else, they are done within a virtual manager of processes and their Manager and process hierarchical trees

  • @sionramosmaquinola6195
    @sionramosmaquinola6195 Год назад +3

    9:05 he used brackets in python?

  • @esnunes
    @esnunes Год назад

    I've recently faced the same screen tearing issue on my desktop (nvidia rtx 3070). Arch linux wiki suggested to add a "metamodes" option on "Screen" enabling NVIDIA "ForceFullCompositionPipeline". The option did fix the issue but it also made the refresh rate feels slow (feels because it was still 60Hz but it was looking like it was 30Hz). In order to fix that, I've had to allow non-edid modes by adding the Option "ModeValidation" "AllowNonEdidModes" in the "Device" section, and I've had to set the resolution to an XServer resolution and not use the EDID suggested one.
    That was quite tricky, in the "Device" section I added an Option "ModeDebug" "true", read the /var/log/Xorg.log, and I've noticed there were 2 mode entries for the resolution 3840x2160: "3840x2160_60" and "3840x2160_60_0", the former was from EDID and the latter from XServer.
    The final config looked like this:
    Section "Device"
    ...
    Option "ModeValidation" "AllowNonEdidModes"
    EndSection
    Section "Screen"
    ...
    Option "metamodes" "3840x2160_60_0 +0+0 { ForceFullCompositionPipeline = On }"
    EndSection
    As my sight is no longer great, I've also set the DPI to 192 by adding the following line to my .Xresources file:
    Xft.dpi: 192
    I hope that it helps you (or anyone else)

  • @_david_mp
    @_david_mp 7 месяцев назад

    seeing this video 7 months later and knowing that he hasn't moved to wayland makes me think problably 2024 is wayland's year, as 2023, and as 2022, and as 2021...

  • @simoninkin9090
    @simoninkin9090 Год назад +1

    Not true about procedural. There is a thin mapping layer you can actually get to. So if you have a clear algebraic structure set up (association and id’s), you can pretty much get away with behavioral and dataflow modeling. But I get why one might perceive this as a procedural approach. The functions are pure, though.

  • @RyanTipps
    @RyanTipps Год назад

    @prime PLEASE do portfolio reviews on this channel - it'd be hilarious

  • @stefangarofalo3131
    @stefangarofalo3131 Год назад

    Noob question, how does declarative fall between this? I assumed declarative was functional

  • @carriagereturned3974
    @carriagereturned3974 Год назад +1

    10:17 this is why js is sometimes so slow: just a bunch of spread o\perators. spreading their filth all over the program. love it! LOVE IT

  • @romelalexissuarez
    @romelalexissuarez 6 месяцев назад

    oop has a problem. creates redundant elements in memory. In many programming languages ​​an object inherits from a base object. Therefore, every time it is instantiated, its elements, properties, methods, special methods, etc. are also loaded. fp doesn't do that. The data is separated from the methods, whether they are pure functions (calculation) or impure functions of actions. In addition, the Earlang virtual machine does one thing, and that is the virtualization of processes, so these are not loaded into the operating system with a life cycle and everything else, they are done within a virtual manager of processes and their Manager and process hierarchical trees

  • @nzeu725
    @nzeu725 6 месяцев назад

    If he sees this, to fix the screen tear you can use the picom composite manager, just turn off window in and out fading shit. Worked for me

  • @velho6298
    @velho6298 Год назад +1

    I think classes are ok way to abstract the different designs but the issue is when people teach these abstractions where you have to drive it from some real life concept and that doesn't work with software because you have to understand the context where your application is running. You abstract the application to memory etc and not some stupid animal that becomes ketchup.

  • @cw2727
    @cw2727 Год назад

    *Whispering from a dark place* Monadz

  • @lezzbmm
    @lezzbmm 3 месяца назад

    5:30 the name,, is “7layers_of_inheritance_is_the_only_way_to_program_agen”

  • @petep
    @petep Год назад +1

    The name... is the Procedureagan

  • @lollertoaster
    @lollertoaster 4 месяца назад

    Alan Key's OOP is not mutually exclusive with FP. I write basically the same code in C++ and in Haskell, just with different syntax.

  • @catcatcatcatcatcatcatcatcatca
    @catcatcatcatcatcatcatcatcatca Год назад +1

    Just write lisp and lose all ability to distinguish between the two consepts. Because the functions don’t share the same namespace with values - symbol can have both. And functions are valid values as well!

  • @FlaviusAspra
    @FlaviusAspra Год назад

    Prime, inheritance is not the only way of putting polymorphism to work.
    There are also interfaces for example, they too make your code polymorphic.

    • @mskiptr
      @mskiptr Год назад +1

      generics too ffs

  • @Luxcium
    @Luxcium Год назад

    In JavaScript I love how I can use function like the map *METHOD* on the array *OBJECT* this is why I love functional programming… [1,2,3].map((n, i, A)=>{ A.push(n + i); return void A}); ('do not forget to put the semicolon or you would be calling the array with this text as an argument… yeah it is not a parameter it is an argument') // 😅

  • @SirBearingtonSupporter
    @SirBearingtonSupporter Год назад

    Bro seriously said he prefers programming in spreadsheets than rust.

  • @Tymon0000
    @Tymon0000 Год назад

    These indentations are driving me nuts!

  • @heyyrudyy404
    @heyyrudyy404 Год назад

    All these languages ages are about handling complexity. Whenever paradigm is simple and accessible enough for people to take advantage of it, that’s what matters.

  • @grumpylibrarian
    @grumpylibrarian Год назад

    Most of my JS code these days is based upon async iterators. Stack a bunch of async generators on top of each other, pull an item from the bottom, and the generators yield all the way down. Each generator is self-contained and a mix of procedural and declarative. Debugging is easy.

  • @karaloop9544
    @karaloop9544 9 месяцев назад

    7:14 fibonacci-indenting should really become a thing, love it.

  • @user-ge2vc3rl1n
    @user-ge2vc3rl1n Год назад +2

    This could be extremely elitist but I don't trust someone's videos if they mess up their indenting and code so blatantly. Like I even doubt that they code at this point. There's just no way.

  • @Luxcium
    @Luxcium Год назад

    I am a functional programmer and I have created a functor class and a monad class… but I dont know how you could do a Monad class in OOP because it would be hard to do that only with Functions so I would argue that Functional programming is easier 😅😅😅😅 or maybe a I am just not pure enough haha I guess it is just like in Basketball only the best known how Currying works… I can only partially apply Currying so far…

  • @ReneSteenNielsen
    @ReneSteenNielsen 9 месяцев назад

    Help I'm looking for a previous prime video where he rants about the difference between "orientating/oriented" 13:25.

  • @NoX-512
    @NoX-512 Год назад +1

    And C++ is syntax sugar for machine code 😎

  • @joaoholz1010
    @joaoholz1010 Год назад

    OO theory theory theory, fp - 0 metions to uses of higher order functions

  • @NphiniT
    @NphiniT Год назад

    This man doesn't even use Python and he's more mad than me about careless indentations 😅

  • @ZsomborBerki
    @ZsomborBerki Год назад

    I'm a big fan of FP, but I do agree with the general idea that multiparadigm is probably the most optimal way. Engineers in all disciplines are taught to "pick the right tool for the job", but software engineers don't seem to take this to heart and they end up being hellbent on proving one approach right. You're taught to break down your complex problem into a bunch of simpler ones, and picking a paradigm is the same deal: some of these sub-problems will fit one paradigm better than the others. Procedural rules tho'

  • @liquidcode1704
    @liquidcode1704 Год назад +1

    "leave a bible width's space between the two of you!!"

  • @emjizone
    @emjizone Год назад +3

    2:37 Crazy default inheritance system in Python is precisely what made me avoid OOP in Python and almost made me quit Python as a programming language.
    *BUT*
    Multiple conditional inheritance in Lua, explicitly implemented in the program by using the Lua language itself and exactly according to my special needs, together with memoization, once made me write an elegant, fast and memory-friendly pool of procedurally-generated sprites for real-time visual effects for a video game. Because I designed and implemented the inheritance mechanisms myself, I used it as intended and wasn't struggling with some bad generic compromise made by language designers. *I made up my own OOP mechanism according to the type of problem I had to solve, and not the other way around.*
    Building your own inheritance system is very easy in some langages, requiring no special keywords nor classes, simply by using the available structures in order to define closures and conditional calls, and let your decide exactly what is inherited, under what conditions, and how exactly (priorities, copies, references, memoization…), even at runtime.
    But, yeah, what I have learned from this is: *use FPL to define OOP-like multiple - or even concurrent - inheritance as you like* , but *do not try to practice FP with a rigid OOPL* unless you plan to hate yourself.

  • @AftercastGames
    @AftercastGames Год назад

    I’ve actually stopped using encapsulation, at least in the explicit, language supported sense. Now I essentially make everything public and static, and I simply use organization and architecture to implicitly enforce simple rules about what code is allowed to call specific methods or access specific data. I like to think of it as Extreme Domain Development.

    • @sk-sm9sh
      @sk-sm9sh Год назад

      Implicit rules are ok if your team is small. How you're going to enforce it if there is 100+ people working on project? Java has so many access control keywords for large teams and indeed they are unnecessary for small teams but for large organizations being able to specify access-control is very helpful as it's makes enforcing ownership easier. For instance I tell that I own this class, and I put everything as private. Now it is easily guaranteed that no one will access the private vars without modifying the file. Since I observe changes to my file I can easily notice if someone tries to get stuff that I marked as private.

    • @AftercastGames
      @AftercastGames Год назад

      @@sk-sm9sh Having 100+ people working on a single codebase is becoming pretty rare these days. I only work on two types of projects right now - personal projects with one developer, or micro services with 1-3 developers.
      But, hypothetically, if you have more developers, you don’t want them checking in code that hasn’t been reviewed by at least one senior developer. At that point, it would be their job to ensure that the code is in the right file, and that it either has zero dependencies, or that it only references code that is located in its sub-domain.
      Think of it as an org chart. If everything is organized properly, you don’t normally have salespeople talking directly to developers. Technically, you can, and it’s not really the end of the world if it happens. But ideally, you want that information to go through some sort of management structure, so that resources can be prioritized properly.
      I essentially do the same thing with software architecture. I have components that actually do work (read files, send messages, query data, etc.) but make no decisions, and I have “management” components that wait for event notifications from sub-components, and then send commands to other sub-components. I also try to keep the number of sub-components managed by a single management component to a minimum, usually no more than 2.
      This makes design work fairly trivial, and when something doesn’t work properly, it’s pretty obvious where the problem is. Although I’d have to say that this approach really does make things so simple that code often works as expected on the very first try.

  • @jeffreybritton3338
    @jeffreybritton3338 Год назад

    12:15 you missed calling out the if (bool_expr) return true else return false horror.

  • @ijoyner
    @ijoyner Год назад +1

    Encapsulation is not about data at all. Encapsulation is about implementation hiding -- David Parnas called it information hiding, really meaning hiding the information about the detail of implementation.
    Thinking private is about encapsulation is wrong. But that is not the only reason private is wrong. Hiding fields from subclasses is wrong.

    • @pillmuncher67
      @pillmuncher67 11 месяцев назад

      People mostly use Information Hiding not to hide information, but to hide the the gross stuff they built when no-one was looking.

  • @heyyrudyy404
    @heyyrudyy404 Год назад

    This prime guy is really on type 🤦🏾‍♂️… 😂

  • @gr0nis
    @gr0nis Год назад +4

    I like DOP (Data oriented programming). Understand your data and the necessary transformations you need for that data. Then your code will solve your problem (and nothing else). Writing it will be straightforward.

    • @rj7250a
      @rj7250a Год назад

      I am learning DOP now, but is only popular between game devs now, since it uses very unconventional syntax and is harder to extend.
      I have seen languages like Zig, that are trying to make DOP more ergonomic, you can write a conventional struct, then use a function from the stdlib, so it will be converted to a data oriented pattern under the hood.

    • @aakarshan4644
      @aakarshan4644 Год назад

      @@rj7250a any resources you have for DOP ? thanks!

  • @jonaskoelker
    @jonaskoelker Год назад +4

    I heard an interesting take on this whole paradigm war:
    - Use object-oriented ideas (encapsulation, representation hiding) for your core data
    - Use functional programming (immutability and pure functions) for your business logic
    - Use procedural programming for the tasks that talk to external systems
    I might have forgotten a paradigm or two, but I got the central message right: use the central ideas of each paradigm in those parts of your code where those ideas accomplish some real, useful benefit.
    Also, OO people talk about data hiding. That is wrong: getDayOfMonth will return data. It cannot be hidden and it should not be hidden; it is the essential point of a Date object. What _can_ and probably _should_ be hidden is how this value is arrived at, and how this small integer is represented internally. Likewise, the exact representation of nodes in a red-black (or AVL, or B) tree is probably not something the user should know about; they should just have a Map interface and a logN performance guarantee provided the comparison function is sane. But the point is not to hide data, the point is to hide how data is represented.
    TL;DR: it's _representation_ hiding, not data hiding.

    • @sk-sm9sh
      @sk-sm9sh Год назад +1

      > Also, OO people talk about data hiding
      What people talk by data hiding is exactly what you mention later - hiding internal representation, thus establishing encapsulation. Nobody has ever said that you should not have methods that return values.

  • @RogerBarraud
    @RogerBarraud Год назад

    I'm sure we could find a better useless if we tried hard enough.

  • @coolemur976
    @coolemur976 Год назад

    What's up with the space thing? One time solution - linter. Problem solved and forgotten.

    • @coolemur976
      @coolemur976 Год назад

      Furthermore, we are learning from people, who can't even indent their code.
      Everything is fine with OOP if it's architected right and don't need remakes.

  • @andyk2181
    @andyk2181 8 месяцев назад

    JavaScript is syntactic sugar for punching yourself in the nuts

  • @goldenchimes68
    @goldenchimes68 Год назад

    Inheritance and polymorphism seem to get so much attention. I didn't understand behaviors until after college. They make object-oriented programming so much more manageable. Why don't we talk more about those?

  • @DummyFace123
    @DummyFace123 Год назад

    12:50 Yeah I like C# extension methods for this reason. print(derpNamespace.derpFormat("Surprise MF!"));
    becomes print("Surprise MF!".derpFormat()); and you don't need to remember which file/namespace derpFormat is in

  • @wise_bucket
    @wise_bucket Год назад +2

    Code formatting brought to you by Shittier

  • @reinoob
    @reinoob Год назад

    Just create a class for things like state management and program functionally so you don't have to instantiate whole classes just for basic operations. 😁

  • @cubbucca
    @cubbucca Год назад +1

    If you have to write the same line of code twice its ok, but if you do it three times you're playing with yourself.

  • @anandmahamuni5442
    @anandmahamuni5442 Год назад +2

    Lovely Screen tearing 🤌

  • @XfStef
    @XfStef Год назад +2

    That's why we'll all go for Data Orientated Programming ;)

    • @zacharychristy8928
      @zacharychristy8928 Год назад +1

      DOD: If premature optimization were an entire paradigm, lol.

    • @etodemerzel2627
      @etodemerzel2627 Год назад

      @@zacharychristy8928 "Premature optimization". I suggest you look up the full phrase and the context... This phrase is basically invalid these days. Please, stop using it.

    • @zacharychristy8928
      @zacharychristy8928 Год назад

      @@etodemerzel2627 Nope! Still totally valid. Optimizing your solution almost necessarily makes it less general. Doing so before you have a complete picture of the problem and requirements is at best a waste of time, at worst a disastrous foundation to build your program on.
      Your choice of paradigm should be shaped like the problem itself, and when the problem isn't easily modeled by simply abstracting it as "data and transformations" (which describes plenty of problems) then DOD isn't a great fit.

    • @diadetediotedio6918
      @diadetediotedio6918 Год назад +1

      @@zacharychristy8928
      So, I agree with you that the notion of "premature optimization" is still completely valid (actually, it just doesn't make sense to say that it's "invalid", it's not a timing problem). But at the same time I think your statement is complicated, all computing problems can be boiled down to "data and transformations", literally all of them. Data-oriented programming is an excellent way to solve many architectural problems while also solving performance problems (of course, it doesn't solve all or is ideal for all types of problems, but overall it can solve most of them efficiently and cleanly).

    • @XfStef
      @XfStef Год назад

      @@zacharychristy8928 Aren't all computing problems basically "Data and Transformations"?
      Also I do not see the problem will less generalized solutions. Indeed most solutions should be completely specialized in my opinion.

  • @KingJellyfishII
    @KingJellyfishII Год назад +1

    9:43 actually that python function has no side effects because python is dumb

  • @samhughes1747
    @samhughes1747 Год назад +1

    I strongly object to distinguishing OOP/FP on auto-completion. Packages export constants, functions, types, and even function-types (if you export mutable values, you gotta go see Karen, my man), where class instances export mutable values, and bound-functions (methods).
    It’s the same thing, with different flavors. It’s just namespaces, at the end of the day.
    What people who understand the issues are talking about when debating OOP/FP is whether the ideals of either are worth the tropes. You can write shallow OOP, preferring composition over inheritance. You can also write OOP with deep caverns of multiple inheritance, bottomless pits of overrides and monkey patching, and always the subaural drumbeats of doom beating out “Meta..classes…meta…classes…meta…classes…”. FP is more dependent on the compiler to do well, but Rust’s iterators are a FANTASTIC example of a functional paradigm that has great support from the compiler, is fast, and is still very clear and modular.
    Honestly the biggest thing for me: write the code you need to get the job done, keep it clean and responsible, pick up your errors like a decent human being, and check for null/nil before dereferencing. It won’t matter if you don’t have setters and getters on every public property or if you mutate data in place or return an altered copy. What matters is that future you and friends will be able to observe what is changing and where and why.
    So yeah. Hardcore object to insisting a pattern is too hard or unreasonable without understanding it or where the payoff is. That said, copying every value in your array to return a modified copy - or maybe even not - can obviously be an expensive price to pay for making your code more readable.

    • @simoninkin9090
      @simoninkin9090 Год назад +1

      Overall, I do agree, but maybe I’m just…not a developer? (I worked as a dev in the past, though)
      You see, for me, classes of equivalence matter a lot. So to keep track of that, you must follow stricter rules. Pure functions definitely help with that! Too much perfectionism..sorry. I don’t like (regular) dev work. Waay to much mambo-jumbo and spaghetti.. I’m more conceptual..😢 I suffer..

    • @samhughes1747
      @samhughes1747 Год назад

      ​ @simoninkin9090 , I think I'm saying that, but with more mumbo-jumbo. I'm pointing out that there are some real considerations, but if all you care about is being able to put a name followed by a dot, and have your IDE suggest completions, you can do that in either paradigm, not just by using classes.

    • @simoninkin9090
      @simoninkin9090 Год назад

      @@samhughes1747 I totally agree about the necessity of good namespacing. The question is ultimately about composition. Sure, objects can also compose (I did some of that a few times), but then these objects must comply with the similar rules as pure functions. And it is actually harder to work with.. you might want to call these “function objects”. There is an override in cpp for such cases.
      You can definitely do everything in either paradigm. In fact, as a _professional_ (the one I do not ever want to become…because screw the payoff! =)) ) you should be able to slide though the codebase, written by other people and follow the paradigms in the code itself. All significant modifications must be accepted by the tech lead, etc..
      What I’m talking about is kinda R&D…or whatever. Maybe it’s not that practical in real life (though, the finished code can be optimized and quite fast..just that nobody would understand it..that’s all..), but I honestly don’t care. There is no freedom in commercial programming. For some people it’s..well - just a job. (Don’t get me wrong though, I’m quite average). Yet, for me, it’s more like a tool for understanding deeper realms of our universe. Not freakin’ kidding! =))) FP maps very well onto many concepts in modern physics (I’m not a physicist, but I’m really curious and can’t stop digging for answers..or rather - more questions)
      P.s. never actually touched Rust myself, but the iterator pattern sounds like it’s the same as STL iterators. In fact, the essence of C++, the Standard Template Library is also functional! But it’s a mess! If you compare that even to F# (hate dotnet though..or any vm, which is not llvm. Bytecode really sucks!) or even better - Elixir (possibly the cleanest syntax I’ve seen in a programming language)

    • @samhughes1747
      @samhughes1747 Год назад

      @@simoninkin9090, gotcha. I was mostly complaining about the idea of dismissing FP based on auto-completion advantages, and emphasizing that OOP and FP both have namespaces that lend to that auto-completion. It’s one of the most common complaints about FP I hear, and it’s nonsense.
      Meanwhile, yeah, I work on a team with a variety of skill and discipline levels. We have a lot of code that drags a logger of some kind through the whole program, and same for whatever database or API client is being used. It’s nauseating, but I’d the program does what it’s supposed to, and if there’s tests to PROVE that pile of tech-debt does what it’s supposed to, I’ll sign off.
      I care far more about my coworkers doing good failure-mode analysis and proper error-handling. My team lead will back me up on complaints about squashed errors or untyped interfaces, but he isn’t going to back me up on holding work hostage to a paradigm that is generally widely misunderstood.
      I absolutely am convinced by the ideals of the FP paradigm. In practice, like you say, there’s everyone you work with, and you’re writing code for them to read too.

  • @rickdg
    @rickdg Год назад

    Wait till they find out about Scala.

  • @thomasvandervliet9387
    @thomasvandervliet9387 Год назад

    If some dumbass complains he cant read your code, is there a way to print out the compiled code in machine code and print it out? Im talking register and bitshift level. Asking for a friend.