Functional Programming IS NO BETTER than Object Oriented Programming

Поділитися
Вставка
  • Опубліковано 21 лис 2024
  • In this follow-up to the hugely popular video 'Object Oriented Programming vs Functional Programming', Dave Farley again expresses his thoughts on the argument. Including looking into the question, "ARE THEY ACTUALLY THE SAME THING?".
    Which of these software paradigms will offer you the best chance of success in which instances?
    -----------------------------------------------------------------------------------
    ⭐ PATREON:
    Join the Continuous Delivery community and access extra perks & content!
    JOIN HERE ➡️ bit.ly/Continu...
    -------------------------------------------------------------------------------------
    🔗 LINKS
    📧 Join the CD Mail List here ➡️ www.subscribep...
    🎓 Check out my CD: Better Software Faster Course - There are 7 ESSENTIAL techniques you need in order to succeed with Continuous Delivery. Learn to correctly allocate your precious time to the right things and build BETTER SOFTWARE FASTER ➡️ bit.ly/CDBSWF
    -------------------------------------------------------------------------------------
    👕 T-SHIRTS:
    A fan of the T-shirts I wear in my videos? Grab your own, at reduced prices EXCLUSIVE TO CONTINUOUS DELIVERY FOLLOWERS! Get money off the already reasonably priced t-shirts!
    🔗 Check out their collection HERE: bit.ly/3vTkWy3
    🚨 DON'T FORGET TO USE THIS DISCOUNT CODE: ContinuousDelivery
    -------------------------------------------------------------------------------------
    📚 BOOKS:
    📖 Dave’s NEW BOOK "Modern Software Engineering" is available as paperback, or kindle here ➡️ amzn.to/3DwdwT3
    and NOW as an AUDIOBOOK available on iTunes, Amazon and Audible.
    📖 The original, award-winning "Continuous Delivery" book by Dave Farley and Jez Humble ➡️ amzn.to/2WxRYmx
    📖 "Continuous Delivery Pipelines" by Dave Farley
    Paperback ➡️ amzn.to/3gIULlA
    ebook version ➡️ leanpub.com/cd...
    NOTE: If you click on one of the Amazon Affiliate links and buy the book, Continuous Delivery Ltd. will get a small fee for the recommendation with NO increase in cost to you.
    -------------------------------------------------------------------------------------
    CHANNEL SPONSORS:
    Equal Experts is a product software development consultancy with a network of over 1,000 experienced technology consultants globally. They increase the pace of innovation by using modern software engineering practices that embrace Continuous Delivery, Security, and Operability from the outset ➡️ bit.ly/3ASy8n0
    Roost, An Ephemeral DevOps Platform, automates your DevOps pipeline. It creates ephemeral DevOps environments on-demand or based on pull requests. Roost reduces DevOps complexities and shortens release cycles with fewer engineers. ➡️ bit.ly/CD2Roost
    Tricentis is an AI-powered platform helping you to deliver digital innovation faster and with less risk by providing a fundamentally better approach to test automation. Discover the power of continuous testing with Tricentis. ➡️ bit.ly/Tricent...
    TransFICC provides low-latency connectivity, automated trading workflows and e-trading systems for Fixed Income and Derivatives. TransFICC resolves the issue of market fragmentation by providing banks and asset managers with a unified low-latency, robust and scalable API, which provides connectivity to multiple trading venues while supporting numerous complex workflows across asset classes such as Rates and Credit Bonds, Repos, Mortgage-Backed Securities and Interest Rate Swaps ➡️ transficc.com

КОМЕНТАРІ • 417

  • @ContinuousDelivery
    @ContinuousDelivery  Рік тому +3

    There are 7 ESSENTIAL techniques you need in order to succeed with Continuous Delivery. Learn to correctly allocate your precious time to the right things and build BETTER SOFTWARE FASTER ➡ bit.ly/CDBSWF

    • @tongobong1
      @tongobong1 Рік тому

      I agree about OOP and FP but this doesn't mean everything is like that. Classical style unit tests are much much better than London style unit tests.

    • @witchedwiz
      @witchedwiz Рік тому

      @@tongobong1 let's agree to disagree..
      The whole premise of Detroit school Tdd is highly debatable.. a solid design doesn't emerge from the testing.. you write a solid design, and you do that.. you do solid testing and you do that.. but thinking that the test should enforce the design this strongly, and not mocking stuff is.... Bad..
      Nowdays software is not an isle, so the chances that your software is filled with calls to external systems is a very reasonable one..
      Heck, how do you test a bff without mocks using Detroit style testing?

    • @tongobong1
      @tongobong1 Рік тому

      @@witchedwiz I didn't say you should never use mock. You should mock all calls to external systems. What you shouldn't do is to mock all calls outside the "class under test" because such unit tests are terrible.

    • @witchedwiz
      @witchedwiz Рік тому

      @@tongobong1 that's fine, but that's not how pure detroit tdd works sorry..
      personally i do onion style london..
      starts by lowermost level, mocking external resources//systems..
      and then i start doing the unit tests for each layer on top and iterate the process until i arrive at the top-most layer (e.g. for an api microservice the controller layer).

    • @tongobong1
      @tongobong1 Рік тому

      @@witchedwiz it is better to go top down without mocks except when mocking calls outside the system. You don't need to write unit tests for a class that is already covered by unit tests of its client classes.

  • @wchen2340
    @wchen2340 11 місяців тому +8

    Most of the stuff i write strictly follows dysfunctional programming paradigms.

  • @matthiasberndt7897
    @matthiasberndt7897 10 місяців тому +6

    This is what it sounds like when somebody without a clue about FP talks about FP.
    I can't be bothered to go through all the misconceptions that he appears to be holding, but one of them stood out in particular:
    15:25 “some [functional programming languages] support ideas like monads that allow us to break the pure functions' rule by adding side effects”
    Yeah, no, just no. Monads have absolutely nothing to do with side effects. They're an abstract notion of sequential computation that applies to a wide variety of data types like List, Option, Either, Reader, Writer, State, Parser etc. Yes, the Haskell type that gives us side-effecting programs, IO, happens to have a monadic structure, but it also forms an Applicative Functor and a Semigroup, yet nobody seems to think that those abstractions have anything to do with side effects, so why do people think that Monads do?
    I don't care if you have 50 years of programming experience, but if you don't understand what a Monad is, then you're not in a position to lecture other people about FP.

  •  Рік тому +25

    One has to shed the pride of understanding the complexities of OOP to appreciate the simplicity of FP and see its benefits. ;-)

    • @baka_baca
      @baka_baca Рік тому +7

      Learning many complexities of OOP made me feel so cool, and then so strange when I realized there are so much easier and faster ways to write good code. I'm glad I learned it, and even more glad knowing to never really use it.

    • @eskii2
      @eskii2 Рік тому +4

      OOP is a bit like "The Emperor wears no clothes". It offers no rigid guidance to write sound programs while preaching to do so. Haskell gives you a good straight jacket. Maybe it's not optimal in many situations, but atleast it helps you find the most comprehensible approach.

    • @D4no00
      @D4no00 10 місяців тому +3

      @@eskii2 I would disagree, this argument that immutability hinders performance, it is not true in all contexts, especially nowadays. Nowadays with the amount of concurrency we have, having immutable values delivers almost the same performance with some strong guarantees of safety, and trust me you don't want to debug concurrency as you will never have a good time. This safety will always outweigh that small performance gain from having mutable values.
      Having both written professionally in OOP languages and FP, there is just no problem that OOP languages like java can solve better (at least I didn't found it even to this day). The sheer amount of complexity, bad concurrency, nullability these languages introduce are not worth any of these OOP abstractions.

    • @amigalemming
      @amigalemming 11 днів тому

      @@D4no00 Modern CPUs also do not like mutation anymore.

  • @softwareminimalist
    @softwareminimalist Рік тому +41

    I find it musing how terrified professionals are of stating their opinions. It is my opinion that functional programming is not only a little better than oop, but loads better. And it has nothing to do with “modeling reality”, encapsulation with objects etc. its all about mutation, and lack of control over it. By-reference passing of objects is the trillion dollar disaster. It is a by product of the limited computing resources of early computers, and led to horrible local optimum we are now trying to get out of for 30 years… java, c++, c#, all languages passing objects by references and allowing spooky action at a distance mutations are guilty. The FP way of solving it by controlling the flow of data and using immutability - thats the killer feature. And for this FP is strictly better.
    Thats also the killer feature of Rust btw.

    • @tokiomutex4148
      @tokiomutex4148 Рік тому +12

      Functional programming makes state management explicit, oo makes it ...complicated.

    • @alexandersnider734
      @alexandersnider734 Рік тому +7

      Yup, this is it; the problem with OOP is you are mutating everything, and have no idea where it comes from. What a mess.

    • @antoni2nguyen
      @antoni2nguyen Рік тому +2

      I program C++ for microcontrollers (limited resources), and use Elixir for networking applications. I strongly agree with the above opinion. Passing by reference in C++ is just a trick to save memory resources (heap), and it causes countless painful consequences for programmers. The C++ (or OOP programmer in general), often consoles himself that it's okay to pass by reference, it's good, to be able to continue his work, or else he'll have nightmares thinking about unexpected cases in the code they wrote. Also in other popular OOP languages such as Python and Javascript, the programmers pretent themself that the reference they are passed (some time they don't aware of them at all) are the value itself (it was ok in many cases, but when it's not ok it will be a catastrophe).

    • @baka_baca
      @baka_baca Рік тому +2

      I've become perfectly comfortable validating the opinions of others at work while also stating my own that OOP is good to learn so we can deal with the mess we have, but we should avoid adding to that mess as much as possible.
      I'll add procedural to this too, but yeah functional programming was WAY EASIER to learn, even with some of its functor'ed up lingo than OOP. I legit had a better command over functional programming within a month than I had over OOP after multiple years. Been coding much faster, with fewer bugs, and much better readability ever since.

    • @markhathaway9456
      @markhathaway9456 Рік тому +1

      @@baka_baca When I first learned about C it was obviously appealing because it was just FUNCTIONS. Is FP appealing primarily for that? Simplicity is very important to people.

  • @cccc2740
    @cccc2740 Рік тому +91

    Code readability is one of the most important factor, which depends more on the programmer who wrote the code rather than paradigm. I am a java programmer, working on a scala codebase for last 2 years and my exp in these 2 years has been pathetic. I daily have to work with methods 500 lines long, classes 1000 lines long, function chaining going endlessly without any idea what part does what, lambdas 100 line slong being passed to HoFs...and this all is norm. Clearly someone misused FP powers. A task which can be completed in 3 hours takes 1-2 days, just because reading code is a nightmare. Cognitive complexity is over the charts. Who to blame?

    • @jamieshelley6079
      @jamieshelley6079 Рік тому +5

      I'm so sorry you're working on such a project :s

    • @dovahkiin2259
      @dovahkiin2259 Рік тому +7

      Some programmers seem to think the best way to go from Washington to New York is first go to London, then South Africa, India, Beijing, LA and finally NY.

    • @trevoro.9731
      @trevoro.9731 Рік тому +1

      Code readability is an important factor to get you money for the code you write. It should be unreadable, but look readable so that people won't steal it or your employer won't replace you. It is readability VS money mostly. Never write readable code for promises, little or no money.

    • @leftaroundabout
      @leftaroundabout Рік тому +10

      “Who to blame” - well, certainly not functional programming, because things like 100-line lambdas are _not_ good practice in FP. If anything, what you're describing is blatant disregard for one of the big advantages of FP: that it's so easy to refactor, since any subexpression can immediately be pulled out of it's context and given a descriptive name. (Of course OO can be refactored as well - often easily too, not in the least thanks to good IDEs. But it can still require more thinking because mutable state is more difficult to track.)

    • @cccc2740
      @cccc2740 Рік тому +8

      @@leftaroundabout I agree. After all this experience I now strongly believe that vilifying languages is a useless stuff. All those issues which programmers talk about like verbosity, readability, maintainability, ease of reasoning etc are down to individuals who write the code. People tend to declare new language/framework/tech as god's gift, but truth is that very same tool in hands of callous and careless people can give horrible results.

  • @TheDevcoach
    @TheDevcoach Рік тому +27

    FYI: you CAN call print() inside a lambda in python - the print statement was changed to a function in Python 3.0. e.g.
    list(map(lambda x: print(x), range(10)))
    N.B. map returns a lazy generator, so you need to convert it to a list or iterate over it for the lambda to be called.

    • @Ziggity
      @Ziggity Рік тому +4

      Also, just use a list comprehension =]

    • @lbj2277
      @lbj2277 Рік тому

      I was looking for this!

    • @vladimirljubopytnov5193
      @vladimirljubopytnov5193 Рік тому

      Its sad as he uses the stream for things its not designed to... Even in java this is a one liner with lambda passed to forEach method... I want to see him argue how it is better to look at a pyramid of doom of ifs and nested loops against the builder of filter and flatmap calls...

  • @robertlenders8755
    @robertlenders8755 Рік тому +34

    I think the main benefits of FP are the defaults are nicer to use in FP languages. Immutability by default, trivial definitions of new data types, first-class functions, algebraic data types, equality by value rather than by reference, no or limited nulls, etc.
    Doing FP in languages designed with procedural or OO programming in mind is clumsy, as is doing OO things in FP languages for the most part.
    The problem of inheritance comes as your system grows. When you find that your interface or abstract class has too many methods for the new subtype you want to create you are forced to insert additional interfaces between the inheritance hierarchy or implement a crippled version of the interface which throws exceptions for the unimplemented methods. Then the correct way to use the new class isn't obvious from its available methods. You have to read the docs to get it right.

  • @florian1477
    @florian1477 11 місяців тому +4

    In my experience, there's two big issues with FP. One is the impression that you need to understand category theory before you can write any code. The other one is that people desperately want to mutate state, but can't figure out how, so they assume that you can't write useful systems in an FP language.
    I guess it would help FP a lot, if people would talk more about state management than about monads.
    The interesting thing in this talk is that Dave's a big fan of the Alan Kay's idea of OO, and the Actor model, and this is exactly the way Erlang / Elixir processes work. Processes protect mutable state and communicate through messages. However, Erlang and Elixir are FP languages.
    It's also worth noting that in most Java architectures, the logic is not in the objects anymore, but in services, which are stateless. In essence, these services are only namespaces + configuration for functions that operate on immutable data and ultimately push mutable state to a database. You can do the exactly same thing in an FP language, and it's just much simpler.

    • @AndreiGeorgescu-j9p
      @AndreiGeorgescu-j9p 8 днів тому

      No the issue is with software "engineers" avoiding anything to do with math. The entire reason fp is better is because it's denotational

  • @pchasco
    @pchasco Рік тому +13

    I find most bugs are due to misunderstanding of requirements, incorrect implementation of requirements, logical errors, and “the unexpected.” And with the null safety features of modern languages, that entire category of bug is almost eliminated. The sorts of bugs I see are not going to be dramatically different in an OO or functional code base.

  • @BosonCollider
    @BosonCollider Рік тому +6

    @continuous delivery I was surprised that you didn't immediately pick up on the one big advantage of functional programming: being easy to test. It is just much harder to end up with untestable code when writiting purely functional code.
    It is not mutually exclusive with OO, and using DI for any outside side effects so that they are explicit at the call site is pretty close to FP monads. But overall, controlling side effects is probably the single most important thing that has made TDD/BDD workable for me. Here I am specifically talking about FP in the big, not just at the level of individual functions. The main architectural benefit of FP at the large scale is _reproducibility_.
    For an OS level example, compare a system that uses APT as the package manager (which is imperative and where installing something means it can get in the way of installing something else one year later) to one that uses Nix (which is functional/declarative and where you can make a package available without mutating the system), the easy reproducibility of the latter makes it way more suitable for a CI/CD environment with reproducible builds.

    • @ContinuousDelivery
      @ContinuousDelivery  Рік тому +3

      I think that "easy to test" is MUCH more about design than paradigm. My code is nearly always easy to test, because I change it if it isn't. I am not sure that I see a difference in practice.

  • @thefluxlife
    @thefluxlife Рік тому +7

    Admittedly I am biased towards FP however after having the OOP vs FP argument for several years now I have come to 2 realizations and a similar conclusion to you.
    - Realization 1: My distaste for OOP was born from misinformed choices made in OOP codebases from previous experiences rather than the actual OOP paradigm. Seeing more OOP mistakes in codebases is an effect of OOP being more prolific, not because it's a poorly designed paradigm. As I learned more, I also found a lot of those 'misinformed choices' were actually OOP anti-patterns.
    - Realization 2: A good SOLID OOP app is just as well as an FP app.
    Conclusion: Learning both paradigms helps you write better, safer, and well designed code as long as you have a good understanding _why_ you are using one paradigm over another.
    I find FP advantageous over OOP as my preference, but I no longer will claim it superior to other paradigms. Back to the frustrating typical dev answer of 'it depends'

    • @amigalemming
      @amigalemming 11 днів тому

      If we follow all the Clean code advices around for imperative programmers we will actually program functionally.

    • @AndreiGeorgescu-j9p
      @AndreiGeorgescu-j9p 8 днів тому

      You know very little about fp then

  • @gljames24
    @gljames24 Рік тому +18

    I like how Rust makes excellent use of both in its design and even manages to solve inheritance problems with traits.

  • @UrsEnzler
    @UrsEnzler Рік тому +15

    I value your content a lot, especially your work on continuous delivery. Your videos provide a lot of knowledge about that topic.
    However, I struggle a lot with your videos on OOP and FP.
    I guess much of it comes from you not being familiar with building systems in a FP way. Maybe reading "the Programmers' brain" by Felienne Hermans can give you some insights.
    I fully agree with your statement that we should use OOP and FP when they match the problem at hand best. And that's the reason why my favourite programming language to write business applications in is F#. F# supports OOP and FP to a great extent. So I can choose whatever paradigm fits best in any situation.
    Your arguments around side effects are weird. Of course, any meaningful program must have side effects, regardless of the paradigm it's programmed in. Different paradigms use different methods to accomplish these side effects.
    We migrated parts of our system from C# to F#, and the business logic code got much easier because the syntactic possibilities around computation expressions and discriminated unions allowed the code to show its intent much clearer. But one has to see it, to believe it, I guess.
    One thing I like to mention is about "map". Sure, in your example, there is no big difference. It's just too small to make a real difference. The real difference is that the concept of "map" is found in many places in an FP language. You can map over a list, over the result of an async computation, over optional values, over results, and so on. But instead of having a concept for each case, FP languages have a more general concept of "map". Once you get used to it - I guess that's where you are struggling at the moment - the code gets easier to understand because there are fewer, a bit more abstract concepts at play.
    So while I agree that the answer is OOP + FP, you can't achieve this in most well-known (OOP-based) languages like Java, C#, and C++. The reason is that they support FP just not well enough. One can apply functional concepts, but the code gets unreadable quickly.

  • @brendanhansknecht4650
    @brendanhansknecht4650 Рік тому +9

    I think this is missing a big point. All because OO languages support functional programming features does not mean they do it well. So showing off map in python or Java or similar languages is showing off a bad implementation of map in many cases. Also, having the option to do something two ways, can be problematic. As in, if you can mutate or be immutable, you loose all of the benefits of guaranteeing something is immutable.
    Lastly, saying functionally programming languages can't do things is wrong. There can be effects in functional programming. They just are not side effects. You can make them pure effects that are return and documented. This still keeps all of the functional programming reason. It is not all effects that are the problem. It is just arbitrary side effects that can happen randomly in code and are totally undocumented that are the problem.
    I think this is taking a really bad view on what proper functional programming actually is.

  • @tapasdatta6222
    @tapasdatta6222 11 місяців тому +2

    I worked with OOP using Java for ten years before switching to Functional Programming (FP) three years ago. I'm still helping out with old projects. Honestly, OOP can be quite challenging and distressing in programming. As the codebase grows, it gets more complex, even if you follow design patterns. The tricky part is that dealing with mutability can be mentally taxing when you're trying to understand how you get there.

  • @georgehelyar
    @georgehelyar Рік тому +36

    FP has some great ideas like immutability and pure functions, and I frequently use these in other languages, but I find the conciseness of many functional languages makes them hard to read.
    I think Rust offers a good alternative to both OO and FP.

    • @hellowill
      @hellowill Рік тому +4

      I love how Immutability and lack of side effects is being adopted in other languages like C# and Java!
      But yep... pure FP is hard to read, especially for the average programmer. It'll never be mainstream and thats OK.

    • @MatthewFerrin
      @MatthewFerrin Рік тому +9

      I like your comment because I love Rust.
      In functional pipelines, I find that if I use named functions instead of unnamed lambdas and name all the things meaningfully, that functional is equally readable. Unreadable code is more a cultural problem than a language or paradigm problem I’ve found.
      The . operator in Haskell is hard to remember for me because I’m infrequent in my use of Haskell. Most other languages probably don’t have an equivalent.
      But either way, I just write imperative code that passes my tests recently and then ask ChatGPT to refactor it until I like it.

    • @fennecbesixdouze1794
      @fennecbesixdouze1794 Рік тому +4

      It doesn't, you're just not used to it.

    • @YumanoidPontifex
      @YumanoidPontifex Рік тому

      @@fennecbesixdouze1794 exactly. more often than not the problem isn't a FP lang or lang feature. it's the non-FP habits dominating one's brain when encountering FP for the first time.

    • @georgehelyar
      @georgehelyar Рік тому +4

      I agree with the cultural explanation.
      It is usually possible to write readable code in most functional languages, but it may just be that functional languages lean more towards writing code that looks like an equation and other languages lean more towards writing code that looks like sentences or a recipe, and the author of the code is inclined one way or the other.
      If you like equations, you are more likely to use functional languages, and you may even find them easy to read, but I think the majority don't find equations easy to read, and prefer sentences.
      There is a lot of variation between languages though even within the same paradigm, so I'm trying not to make sweeping statements.
      At the extreme, you have languages like APL and BQN, which are very difficult to read and write. You can do a lot in a few symbols, but it takes time to work out what it's actually doing.

  • @polyglotusamericanus4163
    @polyglotusamericanus4163 Рік тому +4

    You actually can print from a lambda in python in a couple different ways for instance by putting the print into a tuple with the return (assuming you need the output) and then accessing the index that contains the output. E.g lambda x: ( print(x), x )[1]

  • @scvnthorpe__
    @scvnthorpe__ Рік тому +4

    I think I'm a fan of both functional and OO constructs, but I tend toward composition. That being said it takes more effort for me to architect at least in python, whereas Ruby gives you mixins which helped me DRY out my Rails code

  • @therealjordiano
    @therealjordiano Рік тому +2

    Rly informative stuff here and made very digestible in my opinion. I strongly agree with the general stance here that it's a nuanced problem, as I've heard a couple of times people saying things like 'wed love to make our code a bit more functional' implying that its simply superior, and because of some unknown reason that is apparently so obvious that it doesn't even need to be stated.
    Especially interesting point at 18:13 with this comparison, it'd be interesting to see each common code pattern in OOP form vs in functional form, i bet there's always a way to do a pattern in both.

  • @danielwilkowski5899
    @danielwilkowski5899 Рік тому +2

    @Continuous Delivery I always believed OO and FP aren't exclusive. Your code can be both functional and object oriented. The misunderstanding of the paradigms may come from the fact that amaterous tend to naively think: "if my code uses class, then it's oo. if it uses functions, then it's functional". When we correctly understand that FP means "don't redefine variables" and OO means "enacapsulate your data in objects" then we can clearly see that we can easily achieve both.

  • @ApprendreSansNecessite
    @ApprendreSansNecessite Рік тому +5

    What makes the reactive messaging system you describe closer to FP in my opinion is that the developer is giving up control of execution to some framework. It's what enables immutability in FP in the first place: there is an effects system, a messaging system, a monad, that takes care of the dangerous impure stuff so that you get to write the nice, pure and composable code.

  • @ianbarton1990
    @ianbarton1990 Рік тому +8

    06:59 python3 is more than happy to run a print in a lambda.
    WORDS = ['apple', 'banana', 'cherry']
    for _ in map(lambda word: print(word + ':'), WORDS):pass
    works fine in Python 3.10.9

    • @phenanrithe
      @phenanrithe Рік тому

      I think he just took a bad example. Replacing a Python comprehension assignment by a loop, for ex, looks much worse and is less efficient. In any language, method chaining is better suited at building collections or processing them than calling print functions.

    • @jjtt
      @jjtt Рік тому +1

      @@phenanrithe Exactly, I think it's quite a bad example actually, because it mixes computation with I/O, so it's not very representative of good FP. In proper FP, it'd look a bit more like this
      for_(map(lambda word: word + ':', WORDS), print)
      I'm stealing for_ from Haskell, you can guess what it does. My point is that for_(..., print) is nothing but I/O and everything else is nothing but pure computation. Functional core, imperative shell.
      Also the computation part would probably be on it's own function in real code so you can compose it without the side effects (not just for better separation of concerns)

    • @markhathaway9456
      @markhathaway9456 Рік тому

      @@phenanrithe Method chaining is beautiful and I have to wonder whether FP chaining came before or after Unix pipes.

    • @TobyChampion
      @TobyChampion Рік тому

      I tried to improve on Ian's code and ended up with an obfuscated horrible thing.
      # 1) First, Ian's code, but "fixed" so it does the same as Dave's code (he has the "
      ", which in Python means you get two newlines)
      for _ in map(lambda word: print(word + ':
      '), WORDS):
      pass
      # 2) Now, use a generator expression instead of map(), just because it's less code and prettier
      for _ in (print(word + ':
      ') for word in WORDS):
      pass
      # 3) Now, instead of the for statement to unpack the generator, use the splat ('*') operator to unpack the explicit loop:
      _ = *(print(word + ':
      ') for word in WORDS),
      # So that's the obfuscated horrible thing.
      # 4) In real life this would be better:
      print(':

      '.join(WORDS) + '
      ')
      # 5) In production I would avoid all this and use a template engine, and if the template changes often, I'd be reading the template from a separate text file.
      from jinja2 import Template
      template = Template("""\
      {%- for word in WORDS -%}
      {{ word }}:
      {% endfor %}
      """)
      print(template.render(WORDS=WORDS))
      # 6) Although again, if collection of words was very long, I'd avoid the O(n) memory usage and rejig things so I'm iterating over the generator and printing each word separately. Or in batches...

  • @AdrianDiaz-ob8qn
    @AdrianDiaz-ob8qn Рік тому +13

    wrong model design is not the main problem of inheritance, diamond of death is. But most of the time you can not forsee this problem coming, because you enter in it when your client asks for a change that completely breaks your initial model. inheritance can get pretty messy even with good design

  • @TheVampWillow
    @TheVampWillow Рік тому +22

    The Functional Programming and Domain Driven Design video Dave mentions around 7:30 can be found at ua-cam.com/video/56j8kLMdkyQ/v-deo.html

    • @TheVampWillow
      @TheVampWillow Рік тому

      p.s Looking forward to seeing you wear the "OO Bad, FP Good" t-shirt sometime soon, Dave!

  • @acidangel162
    @acidangel162 Рік тому +22

    Great video!
    The problem with object oriented programming is that it was used too much. We have moved too far to the OO side and that's why promoting functional programming is the right thing to do.
    The best way is to use a little bit of both and not go overboard with either.
    I find it easier to think in functional way. It comes easier to me. It's almost like the functions in math.
    Reading object oriented code is quite hard because the the logic is all over the place usually in separate files. That's easy for computers to parse through but not humans.
    Perhaps others find it easier to think in object oriented way. I have a handicap that I have a really small working memory in my brain. Maybe object oriented is easier when you can have more things in your mind at the same time.

    • @markhathaway9456
      @markhathaway9456 Рік тому +5

      I've discussed this kind of thing with other people and I agree it's a very real phenomenon and a serious issue for the business of creating languages. Similarly, the different levels of abstraction one faces when writing an algorithm really challenges the human mind. In one statement you may be saying "run function f(x)" and the next "increment pointer y". One is quite high level and the other is microscopic. Thus, even when you're using imperative language functions (I don't know about the FP side), as in C or Python or others, you have the same strange questions about what a function does. As Dave said in the video, simplifying the syntax is good, but far from a complete solution.

    • @Christobanistan
      @Christobanistan Рік тому +1

      OO languages have adopted a lot of functional features, particularly monads. Look at LINQ in C#, that's pretty darned useful! I like the simplicity and hierarchies of OO, and the fact it's closer to the metal, but the functional stuff have certainly made things easier.

    • @absalomdraconis
      @absalomdraconis Рік тому +2

      OO style should really be treated as a way to create the nouns in a language, and FP as a way to create the verbs in a language. If you try to stick purely to one or the other, you'll reliably get stuck with a poorly designed mess.

    • @acidangel162
      @acidangel162 Рік тому

      @@absalomdraconis
      Agreed. You can have functions and data types even without having objects to tie them both together. I would rather do that when I can and use objects sparingly.

  • @artxiom
    @artxiom Рік тому +1

    I think the misinterpretation is on your side: they are not two opposing paradigms, FP and imperative programming with side-effects and mutable state is. FP also isn't some kind of evolution but like a genius grand-grandfather that no one listened to for decades but people finally start to appreciate. It predates even C by over a decade (Lisp was introduced 1960, C 1972).
    I've been working for 25 years in the programming industry and I've seen the rise and fall of OOP hype and the slow and silent but steady raise of FP concepts in pretty much every programming technology (lambdas, map, reduce, immutable data types, popular tools like React/Redux, etc.). Pretty much every programmer nowadays is using FP in some form - knowingly or not.
    FP is way more fundamental than OOP, you can build OOP on top of almost any FP or imperative language. You can also use FP-paradigms in almost any turing complete language.
    It's a completely different level of abstraction and these two things have little in common. You can have immutable objects and perfectly side-effect free methods - OOP doesn't care about that, all it does is group data and functions, hide information, and compose through inheritance and polymorphism. It's "just" a paradigm that should (theoretically) help manage code complexity. FP on the other hand doesn't care so much about that: you have data and you have functions, how you compose these two is up to you (some FP languages add of course constructs for that such as modules but that's not an essential element of FP).
    OOP in my opinion just adds unnecessary complexity and abstractions (in FP or imperative languages) just for the sake of it without any added benefit (in most cases). It just isn't particularly good at it and doesn't lend well into most real-life programming problems. Clamping data and functions together just rarely makes sense because there are so many subsystems using the data. It's maybe good for certain applications like containers and similar stuff. Also polymorphism isn't anything specific to OOP and inheritance is just a fancy name for data and function composition - all things FP has been doing long before OOP was even invented.
    FP on the other hand has a ton of benefits and the examples shown in the video are naive at best, the multi-threaded case for example: I have used the thread-split and then merge pattern only once (for multi-threaded audio processing) and it gives you a huge boost when the merge isn't the slowest part of the system but you need to do some heavy processing in the threads. Which is the main reason you would use multi-threading in this case. Having here immutable data without locks increases performance a lot. That's one of the most common patterns in programming: you have a lot of different subsystems that need to read some state and react in some way (rarely merging afterwards - that's just one case of many).
    Another advantage is having everything side-effect free: it's just completely ridiculous how much this helps with: testability, reasoning, modularity. It may seem counter-intuitive but OOP makes everything less modular while thinking in just functions and simple data makes everything way more modular - it's already abstract, putting it into classes makes it more "concrete".
    Nowadays more and more programming languages are anyway multi-paradigm so it's easy to use FP. But I also think it's overkill sometimes and using an imperative solution in certain (enclosed!!) cases is simpler and more straight-forward, especially when dealing with side-effects. The idea is to have the "core" be functional but have side-effects dispatched that can do all kind of I/O stuff but if they want to change the core-state they have to do it through a functional "barrier" again. Internal state in functions you can mutate however you want. Pretty much how Redux is doing it ;)

  • @hfspace
    @hfspace Рік тому +3

    while i agree, that it is possible to do both and that domain driven design is always an important thing, i feel like how expressive the language is, that you are using really makes a difference in how likely it is that you actually use a certain paradigm (even get the idea to use one paradigm). Being able to pass functions for example in a convenient way is really important that you actually use it. And without actually using it, you will never really learn this part of functional programming.
    So while i agree with you in principle, in the practical sense i would say that the importance of a way to use a paradigm that is convenient and easy to learn and memorize is underrated by you in this video.

    • @alxjones
      @alxjones Рік тому

      It really depends on how you're coming at the problem. If you're designing a system to be built (or re-built), then you will pick the language which best handles your problem and how you want to solve it. If you're modifying an existing system, then the language is fixed and so will be a determining factor in your solution.
      If my existing code is Java 7 or Haskell, I'm not going to try to do functional or object-oriented programming, respectively. But if I'm building a system that I want to use one or both for, I will choose a language which does well what I want.

  • @phenanrithe
    @phenanrithe Рік тому +26

    I never understood the drama around inheritance. Composition or encapsulation can be misused too, and produce code that is as messy as misused inheritance. Any feature can be misused, really, that's not a reason to make such a fuss. It always makes me smile when I see this last-century debate about composition vs inheritance. It's just a set of tools. A carpenter will make a mess if he uses a screwdriver instead of a chisel, that's not a reason to ban screwdrivers.

    • @gJonii
      @gJonii Рік тому +10

      The point is that inheritance is always wrong, the same way using the knife as a hammer is. You can do it, maybe you can come up with contrived scenario where it's not entirely stupid, but even if someone with amazing imagination might be able to come up with scenarios where it's not entirely stupid, it doesn't really matter. Any carpenter practicing hammering nails with a knife is doing their profession wrong. Any programmer using inheritance is doing their profession wrong.
      The key problem with inheritance, done similar to Java, is that it does a lot of things, implicitly, allowing you countless of ways to create non-local errors. Changing internal implementation of a class can now break another class, not to mention public interface being tweaked. Creating a class can now break functionality, sometimes even in cases that class isn't used at all. You now have to look at every instance someone has variable of type Superclass, and think of ways Subclass can break things. These errors at least in Java are also completely invisible to the compiler so have fun waiting for the runtime errors as your inheritance mess collapses.
      You can avoid all of this by just not using inheritance, and using more restricted approaches to gain the benefits. You can split functionality by composition, so you will not be able to break things by changing implementation. You will get compile time error if you use the component class wrong, your blast radius for errors is always limited to the usage of class you create or delete. Without inheritance, you are unable to make such a large spectrum of mistakes all the while having your code be much more explicit and easier to read.
      If you use inheritance, you're doing programming wrong.

    • @bobbycrosby9765
      @bobbycrosby9765 Рік тому +3

      Inheritance is the goto of the OOP world. Now on top of that, imagine a world where the first control flow mechanism we introduced to new programmers was goto.

    • @AdrianDiaz-ob8qn
      @AdrianDiaz-ob8qn Рік тому +7

      There is no such debate, composition is better, just more verbose in most languages, actually the main problem of inheritance is not addressed in this video, the inheritance diamond problem, I've found this problem so many times in my career it is insane people keep preferring inheritance over composition just out of pure lazyness

    • @markhathaway9456
      @markhathaway9456 Рік тому +2

      @@gJonii The phrase "non-local errors" is scary.

    • @KManAbout
      @KManAbout Рік тому +2

      @@bobbycrosby9765 I mean that used to be the case. Goto was the first thing. It's was the only thing. In a lot of assembly languages there is only goto

  • @Immudzen
    @Immudzen Рік тому +1

    I tend to use a hybrid of OO and functional code. I use features like python dataclasses or attrs to create objects that mostly just hold data. I then have functions that depend on that interface and return objects of an interface. I found this made the code easier to test and more flexible because the dependencies move to the interface. So plotting can take a result object, a simulation evaluation function can depend on a parameter set objects and return a set of results etc.
    It has made the code more testable and also easier to teach to people because they can see from the interfaces how the functions can be chained together.

    • @jrgalyen
      @jrgalyen Рік тому

      Yes! OO applies to data-centered code. Functional (specifically functional purity) applies to behaviors. We should decouple dat-centered and behavior centered (keep close together in same file). And pass OO data-centered into behaviors (encapsulation/composition)

  • @airman122469
    @airman122469 Рік тому +1

    FP is in fact better than OOP, and there is one simple reason why: programmers abuse OOP. It’s very hard to abuse FP.
    When disciplined programmers use OOP it can be a wonderful (though flawed) paradigm. But there are vastly more undisciplined programmers than disciplined ones.

    • @ContinuousDelivery
      @ContinuousDelivery  Рік тому

      I have heard that before, but I don't see any evidence for it. It is not obvious to me that programs written as functional systems are more or less buggy than systems written as OO systems. I have looked for this, and the data that I found from academic research said that there is a tiny advantage to FP, but that could be statistical noise if the FP systems are simpler than the OO systems.
      Good OO programmers tend to limit "side-effects" and I think that is the real advantage of FP, and some things I think are much easier to model in OO than FP. I use both, but think of myself as an OO programmer.

    • @lepidoptera9337
      @lepidoptera9337 Рік тому

      @@ContinuousDelivery The main problem with FP is readability IMHO. Absolutely nobody (not even the original author) can read an FP program ten minutes after its creation. The main flaw of OO is that it requires a lot of boilerplate that does only one thing: it satisfies the architect's OCD and micromanaging needs, but as soon as you hand that over to the compiler it strips all of it out. CPUs don't speak object language. They only have arithmetic, logic, branch and subroutine call instructions. So in the end your OO code is just program documentation. Why are you spending so much time on a really poor documentation paradigm?

  • @vanlepthien6768
    @vanlepthien6768 Рік тому +2

    "Flavor of the Day" has been a problem forever.
    Another consideration is what programmers you have. I used to work with systems written in COBOL (not my favorite language), and there were a lot of
    good COBOL programmers who could write to decent specifications, but who, mostly not prepared to use languages that required more abstraction.
    My suspicion is that it's easier to find decent OO programmers than funtional.

    • @selocan469
      @selocan469 Рік тому

      Very well put. Besides I do not get the comments about mutation hell in OOP languages or inheritance being evil as if it is the reason that OOP language direct a gun to the programmers head and do bad shit. Java designer James Gosling stated that operator overloading is abused by programmers so it should not be available, I laugh the byproduct of this mentality in how String class "+" operations are secretly converted to StringBuffer.Append code than compiled. As IP Man said, "No, it's not a matter of northern or southern style. The problem is you."

  • @elharo
    @elharo Рік тому +8

    Set does not extend Vector. You’re thinking of Stack.

    • @absalomdraconis
      @absalomdraconis Рік тому

      The idea of an OOP stack inheriting from either a vector _or_ a set (as opposed to just using them behind the scenes) seems insane to me. "Random access" is innate to both vectors and sets, so you can rationalize the attempt to have one inherit from the other (even though it's probably the wrong idea), but having your "default" stack (remember, the inherit concept of a stack isn't Random Access, it's LIFO/push&pop) inherit from either just doesn't make much sense.

    • @elharo
      @elharo Рік тому

      @@absalomdraconis It absolutely is a mistake. This one goes back to Java 1.0 almost 30 years ago, before anyone was paying attention, probably by some programmer who hadn't fully groked OO yet; and now we're stuck with it for backwards compatibility. :-(

  • @markhathaway9456
    @markhathaway9456 Рік тому +1

    Reading the comments I see FP and OOP programmers, but also a lot of Scala programmers who haven't looked at the language. It offers both paradigms and more. But the more all these paradigms get bashed the more I think these programmers should be forced to write assembler for each and every platform to learn how good it was to have a paradigm, any paradigm.

  • @sicariusleif1992
    @sicariusleif1992 Рік тому +1

    There is one thought I've come across with functional programming languages which I find interesting, an implicit constraint to state has a distinct effect on code readability. Though multi-paradigm languages can maintain pure functions, there is no guarantee a given function is pure. As a result, you do not know whether calling a function with the same parameters will produce identical results. This could be circumvented if there was a keyword similar to "virtual" which could be used in a pure function declaration but which forces a change in how a call itself is written for pure functions.

    • @tommyliu7020
      @tommyliu7020 Рік тому

      You could adopt a convention for your code where if a function is meant to have no side effects, then you add a “_FP” at the end or something?

  • @ilovepickles7427
    @ilovepickles7427 Рік тому +4

    What is it about programming methodologies that creates zealotry. Speaking as a former professional studio guitarist, I saw the same thing with musicians (e.g. flame wars over Fender vs. Gibson). Imagine showing up at a flamenco gig with an Ibanez and a Marshalll stack. These are all just tools.
    Great video as always.

    • @markhathaway9456
      @markhathaway9456 Рік тому

      I have no idea what you're going on about F*** or G*** when Gretsch is obviously best. 🙂
      My brother makes his own guitars, so I have to assume they're really best.

    • @user-sl6gn1ss8p
      @user-sl6gn1ss8p Рік тому +1

      just an observation, but I think in all sorts of professions it's not uncommon for people to take pride in their tools, their choice of tools, their use of them and their philosophy around them.
      It's pretty common for people to reflect on this stuff and also to argue over stuff they've reflected a lot about. Some people may even have fun with it.
      Programming methodologies are pretty deep, complex tools, and I'd guess there may be a superposition between the people who might care about them and the people who might care/like to discuss minutia of this sorts of topics.
      Also, other people's opinions may affect in a deep level how you get to do your work, which compounds with possible negative experiences with one methodology or the other, etc.
      So yeah, I'm kinda rambling, sorry for that, but just saying, add education and all that as well, and I don't think it's too surprising that when you get to certain circles this zealotry appears : p

    • @ilovepickles7427
      @ilovepickles7427 Рік тому

      @@markhathaway9456 ha. I played a custom axe most of the time 😝 Warmoth. It's great. Fender body with humbuckers at the neck, and single coil at middle and bridge. Could get really warm for jazz and really bright for funk and rock.

    • @ilovepickles7427
      @ilovepickles7427 Рік тому +1

      @@user-sl6gn1ss8p Rambling always welcome.

    • @bradleyturek
      @bradleyturek Рік тому +1

      I wonder if it can be explained by the human tendency to create in-groups and out-groups for everything.

  • @michelemesiti8906
    @michelemesiti8906 Рік тому +5

    Just a pedantic comment: one can use prints in lambdas in python. They return none, so they can be used in expressions, followed for example by and 'or' and a proper expression that them takes the value of the lambda.

  • @mskiptr
    @mskiptr Рік тому +1

    Yes, we do hate subtyping from the bottom of our hearts /s
    But seriously, you can do GUI without inheritance quite easily. React-like design (Elm-like actually) is now widespread - especially in Rust where you don't have built-in inheritance.
    Show me something solved with inheritance and I'll rewrite it as either interfaces or tagged unions.

  • @baka_baca
    @baka_baca Рік тому +9

    My current stance in OOP after working with that model over the last 4ish years is that unless OOP offers a clear advantage over other approaches, then it's best to not use it. OOP so often turns into a giant mess because of how much harder the learning curve is and how much harder it is to read/write and do correctly. I've had way too many times that the problem can literally be solved in less time using functional or procedural programming than the required OOP design time. Way too often there's endless "what ifs" that delay even the start of this design process which just causes further delays. At the end of it, OOP can get these problems solved, but why bother unless you truly need it for a problem?
    I used to be much more in favor of OOP in general, these days I look it at as a tool I rarely need or want to use for the kind of work that I do.

    • @rdean150
      @rdean150 Рік тому +4

      Let's say you have a system that holds information about a collection of customers who have each purchased some collection of products. The customers all have a variety of attributes, as do the products they purchased. This information comes from 3 different services - one for customer details, one for product details, and one for transaction details, which provides the links between the customers and the products.
      Your goal is to gather up this information, present it to a user, and let them arbitrarily filter, sort, and choose a subset of these customers to perform some action with (say, to issue a refund to, or email about a new offer or something).
      My brain automatically models this problem in an object-oriented way. It is just conceptually suited to the problem space. How would you model this reasonably without stateful objects?

    • @fabio.1
      @fabio.1 Рік тому

      @@rdean150 good question, following

    • @Charles-pm4so
      @Charles-pm4so Рік тому

      What design patterns did you use in oop ? What about unit tests ?

    • @absalomdraconis
      @absalomdraconis Рік тому

      ​@@rdean150 : I would start from a database query, or maybe logic programming, perspective for that sort of thing. For OO, I would need to be looking at a system where I have discrete "things" (the objects) that are capable of acting as a self-contained and "seamless" whole... _object._ When you're trying to tie together a lot of only semi-related things, as in your example, the only rational object is the interface to the system that does the work, and even then it's only fit for an object if your api is designed to make it act as I described above.
      A perfect example of where to use objects is to make a arbitrary sized number class- once you've done it well, it will act as a complete implementation of a number that you don't have to peek inside of, so you can just act like it's a normal float or something, aka it'll be seamless and complete.

    • @flyingcircle526
      @flyingcircle526 Рік тому

      Yes, but how do you get over your teammates who insist that OOP just seems more intuitive and think filters are too hard to read.

  • @brownhorsesoftware3605
    @brownhorsesoftware3605 Рік тому +5

    The difference between functional and oo programming is point of view. In functional programming code is data. In oo programming data is code. This from the point of view of someone who's native language is assembler. All points of view are useful in the right context. Arguing that one is better than the other simply misses the point.
    Thanks for another great thought-provoking video!!

  • @mungojelly
    @mungojelly Рік тому +1

    it took me way too long to understand that the logical simplicity of FP is achieved by abstracting away what actual resources are actually statefully being used to accomplish the computation,, i had to figure that out myself and figure out myself when it's more useful or more confusing to have that particular abstraction, b/c it isn't presented that way at all, it's presented as if FP is just magic, by all sides, but it's neither black magic nor white magic it's just that you simplify by packing everything away into the "function" interface, very useful except in those cases when you need or could make use of the stuff packed away

    • @ContinuousDelivery
      @ContinuousDelivery  Рік тому

      I agree, and when you do that in OO, it works just as well too!
      This seems to me to be not so much about OO vs FP and is a lot more to do with abstraction and good design in general - whatever the programming paradigm.

    • @lepidoptera9337
      @lepidoptera9337 Рік тому

      If you have state, then you are not using FP but are procedural. All you are "abstracting away" here is the bullshit that FP is a programming technique. It's not. It was a mathematical proof technique and is highly useful for that purpose. It never was meant to and can never be used to write actual programs.

  • @DePadreAHijo
    @DePadreAHijo Рік тому +6

    Btw, OOP startegy pattern + DI is FP in essence. Used properly provides the best of both paradigms!

    • @markhathaway9456
      @markhathaway9456 Рік тому +1

      What is the DI ?

    • @MathCoreMan
      @MathCoreMan Рік тому +1

      @@markhathaway9456 dependency injection

    • @paterantonios6498
      @paterantonios6498 Рік тому +1

      Not really?? Dependency injection is not an FP way of thinking at all. FP tries to keep most functions pure and only at the edges of the system you can have side-effects. If you "inject" functions to other pure functions there's a good chance you can pass a non pure function and make what was a pure function now impure and therefore unpredictable. That is in languages like F# that there's no compiler enforcement like Haskell for example.

    • @ContinuousDelivery
      @ContinuousDelivery  Рік тому +2

      Yes, exactly!

    • @ContinuousDelivery
      @ContinuousDelivery  Рік тому +4

      @@paterantonios6498 Not sure how a functional language works without the ability to pass functions as arguments? That is certainly one way to use DI.

  • @udishemesh4171
    @udishemesh4171 Рік тому +4

    FP and OO are tools in the toolbox. I like using both as long as the result is readable and maintainable.

    • @jboss1073
      @jboss1073 Рік тому

      So what does it take NOT to be "a tool in the toolbox"? Because OOP has NO agreed-upon definition and NO theory behind it. If that doesn't suffice to make it a non-tool, what would make it a non-tool?

  • @dansanger5340
    @dansanger5340 10 місяців тому

    t seems like there might be a mathematical duality between an FP view on a problem and an OOP view on a problem. And, one view might be helpful in some instances, and another view might be helpful in another instance. For example, consider a drawing program that uses shapes that are either circles, rectangles, or triangles. An FP approach might put all the drawing code for all three shapes together, while an OOP approach might put all the operations for Circle together. If you are going to edit all the drawing code for every shape at once, an FP view might be more convenient. If you are going to add a Hexagon shape and implement all its related operations, an OOP view might be more convenient where all the related code is in once place. A language and development system that didn't require you to make a final FP vs OOP choice up front, but let you start with either, dynamically generate either view on demand, and let you edit the code in that view, and let you switch to another view and do the same thing, could be very interesting.

  • @cherubin7th
    @cherubin7th Рік тому +3

    I like loops, I don't much like map and fold and so on in general.

    • @absalomdraconis
      @absalomdraconis Рік тому

      Loops and map are roughly the same, but I think of map as "looping that you make another program do"- thinking of it happening inside the program you're writing feels weird.

    • @airman122469
      @airman122469 Рік тому

      I felt the same until I understood what map and fold do. Now I honestly hate using loops when a gold or map would do.

  • @ayaya-ayaya
    @ayaya-ayaya Рік тому

    11:48 about the claim that you can just have some FP attributes in OO imperative languages. It might be true if you have full control over your code. But usually the data eventually goes into some library that you have no control over. In FP languages you know for certain that the library won't do anything spooky, unless it's doing some interaction with IO. In OO you have to believe and you often end up disappointed.

  • @toooldtobejunior
    @toooldtobejunior Рік тому +1

    OOP allows (I'd even say encourages) incapsulation of data and flow inside the same class.
    This is what I see as a problem. Especially, when the domain is slightly more complex than windows and buttons.
    On the other hand, FP allows to incapsulate data (inside types) and flow (inside functions) but not altogether. This is much better approach.

    • @lepidoptera9337
      @lepidoptera9337 Рік тому

      Neither solves a single hard problem in software engineering.

    • @toooldtobejunior
      @toooldtobejunior Рік тому

      @@lepidoptera9337 what do you mean?

    • @lepidoptera9337
      @lepidoptera9337 Рік тому

      @@toooldtobejunior Algorithms solve hard efficiency problems. Data structures solve hard questions of data organization. Compilers provide abstraction and automatic local optimization. Operating systems allow the sharing of system resources etc. OOP does none of that. It's a software documentation technique. FP is even less than that. It's a theorist's delusion that an approach that works in mathematical proofs should also be applicable to software development.

    • @toooldtobejunior
      @toooldtobejunior Рік тому

      oh, I see

  • @MonochromeWench
    @MonochromeWench Рік тому +1

    I mostly do OO but if I see code with a FactoryFactory I'm going to groan, thats taking things too far which I think causes many people have great issue with OO, taking it to the extreme . Same thing with functional taking it to the extreme scares people off. It also doesn't help that people get very loud and opinionated on both sides.

    • @ContinuousDelivery
      @ContinuousDelivery  Рік тому +1

      Bad code is bad code, and changing paradigm doesn't change that. Most OO code is bad, but then again most FP code is bad too!
      Good design is more important that the paradigm in my opinion. Some paradigm ideas can help, but you still need to do a good job to take advantage of those advantages.

  • @onursahin7970
    @onursahin7970 Рік тому +2

    I think instead of discussing between OOP and FP we should talk about concepts that make up those paradigms separately. Discussing between paradigms implies that you need buy in all the aspects of the paradigm or none at all. That's usually not the case. Reality is usually you mix some parts of the two. So if we start talking about those specific aspects and their trade offs I think it will be much better for the community.

  • @fennecbesixdouze1794
    @fennecbesixdouze1794 Рік тому +1

    It's unfortunate that OO has come to mean those things you referred to, although you're quite right that it has. I think those ideas are better understood as Class-oriented programming, where Classes serve as the object factories and double-purpose inheritance for type hierarchies and polymorphism.
    If we think of "objects" as simply integral units that encapsulate their own behavior and data, with the primary idea being that they pass messages between themselves and decide for themselves how to handle messages they receive rather than being manipulated by external forces, then I think you get to the essence and the power of what Alan Kay was describing much more directly.

    • @what42pizza
      @what42pizza Рік тому

      The biggest problem with that is that behavior basically always involves multiple objects. One feature might involve objects A, B, and C, then another feature involves B, C, and D, then another feature involves C, D, and E, and so on. One line of control flow needs an object to act a certain way, then another line of control flow needs that object to act in another way, then a new feature needs that object to behave in a new way, which then breaks the first two control flows. And since those control flows aren't explicitly laid out anywhere, it's extremely hard to have everything coordinated correctly
      My point is that splitting up behavior into atomic and self-contained objects isn't actually possible because of how interconnected everything is

    • @markhathaway9456
      @markhathaway9456 Рік тому

      @@what42pizza And the better solution to keep that simplicity of action and reduced complexity of understanding code is what?

    • @what42pizza
      @what42pizza Рік тому

      ​@@markhathaway9456 Have you seriously never heard of procedural / FP or are you conveniently forgetting about it to sound witty?
      OOP may have simpler actions and better understanding on a surface level, but once you need to figure out how a feature ACTUALLY works, your only option is a debugger. With procedural / FP, you don't even need a debugger because of how clearly the control flow is laid out. OOP's claims of encapsulation and abstraction are all smoke and mirrors, only true on a surface level
      In my first comment I talked a lot about control flow, and that's because it's the only thing that really matters. When a user clicks a button, they don't care what the factory factories are doing, they only care about the sequence of actions (aka control flow) that happens as a result. Likewise, the process of debugging is almost entirely about inspecting control flow, because, again, that's the only thing that really matters. The entire process of programming is just defining control flow, which inevitably involves inspecting and understanding control flow
      OOP's idea of splitting up control flow into objects that don't know the control flow of other objects is absolutely absurd. Obfuscating control flow is practically the point of OOP, and if control flow is as import as I'm saying it is, then OOP is undeniably a bad way to write code

    • @markhathaway9456
      @markhathaway9456 Рік тому

      @@what42pizza OOP is about separation of concerns, hiding implementation, polymorphism, and a divide-and-conquer programming strategy. Where it obfuscates control flow is one of the key issues deciding its utility. Everyone who comments on FP code says it's clear program flow, but entirely unreadable and unmanageable. There has to be a happy way of doing things somehow.

    • @what42pizza
      @what42pizza Рік тому

      @@markhathaway9456 When you say FP is unreadable and unmanageable, are you thinking of Haskell? FP code doesn't have to be any more or less readable than other paradigms, it's only the weird FP languages like Haskell and APL that give FP a bad reputation. If you want a good introduction into practical FP, I highly suggest this video: ua-cam.com/video/1_Eg8KYq2iQ/v-deo.html (especially the part at 31:26)
      As for the first thing you said, none of those benefits are limited to OOP, you can have the exact same advantages with procedural / FP. Instead of an object with a specific, separated concern, you have a function with a specific, separated concern. Instead of an object hiding implementation, you have functions that hide their implementation. Instead of dividing-and-conquer by dividing into objects and sub-objects, you divide-and-conquer into functions and sub-functions
      When people came up with the 4 pillars of OOP (encapsulation, abstraction, polymorphism, and inheritance), it was just based on the possible benefits of OOP. As someone who's tried both OOP and FP, I can say that those supposed benefits absolutely do not hold up. When I first tried procedural with a bit of FP philosophy, I was completely blown away with how much better it was. With OOP I was having problems like events in objects that need to happen in the middle of events in other objects, but that problem (and many more types of problems) literally aren't even possible in other paradigms
      I'm pretty sure people have stuck with OOP for so long because it's comforting to know that your program is just a bunch of objects you can work with. Switching away from OOP means losing that comfort, but it's worth it. Please just give it a try, I personally promise that you'll have a better time programming

  • @JorgetePanete
    @JorgetePanete Рік тому +1

    In Rust it compiles down to loops and ifs as it's usually mentioned, with more opportunities for optimizations

  • @ericsnell3040
    @ericsnell3040 Рік тому

    Once again I find myself in the choir shouting, "Amen!"

  • @djgreyjoy1495
    @djgreyjoy1495 11 місяців тому

    I think the talk misses one important point: it's not about how state is managed, it's that OO forces everything to be inside classes/prototypes and that is often too restrictive, as the same real world object has to have some methods in some context and others in other contexts, and OO can't capture that without violating the interface segregation principle.

  • @kriss1_
    @kriss1_ Рік тому +2

    Hi, you should update your Java examples. In Java 17+ A Set is not a Vector, but both are Collections. You most definitely cannot call rehash() on a Properties object, rehash is protected and a no-op implementation. Also nobody today should probably use Properties.

    • @Adowrath
      @Adowrath Рік тому

      I really wonder how he even came up with "Set inherits from Vector" in the first place. That has never been the case as far as I can tell, and thus, there's also no indexOf on a Set.

    • @volkerswille
      @volkerswille 6 місяців тому

      @@Adowrath I guess, Dave confused Set and Stack. Replace Set with Stack and everything he says makes sense.

  • @Kenbomp
    @Kenbomp 8 місяців тому

    I've spent years doing both and both are very different but very similar than most believe. It's just a style difference and depends on the application and environment and communities. but have to admit that I prefer lisp cough! Functional languages. Glad to go oop first then lisps. At the end of the day it's what your program does.

  • @mskiptr
    @mskiptr Рік тому

    Even though all general purpose languages are mostly equal in their possibilities, writing in imperative languages is very different from using purely functional languages. And both of these are very different from logic programming languages.
    Some people say that functional programming is about getting rid of mutability or state, and because of that it's better|more predictable|less buggy|etc. But imo that really misses the point.
    Here's the essence of purely functional programming:
    0) time and execution don't exist. there's only evaluation
    1) basically everything is an expression
    You will usually pair that with:
    2) each valid expression has a precise type
    3) data types are expressions too and so you get polymorphism (generics, interfaces, etc.)
    You don't get these properties when emulating the functional style in your typical languages like Python, C++ or Rust. Yes, itertools can get pretty close to FP's data processing capabilities, templates can be comparable with type-level functions and Rusts awesome Enums are basically the same as algebraic data types, yet these are all but a fraction of what pure FP has to offer.

  • @sf2998
    @sf2998 Рік тому +1

    In terms of simplicity, flexibility, and readability, functional could have a big advantage over OOP
    In some situations, i see OOP having absolutely NO advantage over functional...

    • @ContinuousDelivery
      @ContinuousDelivery  Рік тому +1

      Well, nearly all of the bigger, more complex, higher-performance code bases in the world are OO (operating systems, programming languages, flight-control systems, trading systems etc etc. This may be an effect of history, but Functional came first, so why is that?

    • @sf2998
      @sf2998 Рік тому

      OO is by no means obsolete or useless. Its just that i cannot think of a situation where functional can't be used instead of OO. That being said, OO does have a big advantage over functional or procedural because OO forces the entire team to write code in OO-specific rules, which has benefits, but only if the rules are being implemented correctly....

    • @lepidoptera9337
      @lepidoptera9337 Рік тому

      @@sf2998 OO is simply a code documentation technique. The compiler strips every bit of OO information out of your code during the initial compilation cycles. There is not a shred of it left by the time you get a binary back. So why in the world do you want to write so much hard to modify boilerplate for documentation purposes? That does not make FP an alternative, of course. FP simply doesn't exist, at all, except as a mathematical proof technique in theoretical CS.

  • @edwardvermillion8807
    @edwardvermillion8807 Рік тому

    OT: missread thumbnail as "extravagant clams" and thought you had started up a cooking channel when i wasn't looking...

  •  Рік тому

    You can put print() in a lambda in Python 3, e.g.
    print2 = lambda x: print(x)
    print2('hello world') # prints hello world
    ...but why would you? print is already a function, so you can simply do:
    list(map(print, ['a', 'b', 'c']))
    or even simpler:
    [print(x) for x in ['a', 'b', 'c']]
    if you really want to put print in a lambda for some reason, here print2() will be equivalent to print():
    print2 = lambda *args, **kwargs = print(*args, **kwargs)

    • @lepidoptera9337
      @lepidoptera9337 Рік тому

      Yes, and that is NOT functional programming because print() changes state. ;-)

  • @jonaskoelker
    @jonaskoelker Рік тому

    > Functional programming yields fewer bugs
    > Empirical evidence: only about 1% and it may not be statistically significant(?)
    I can imagine a world where FP yields a sizeable benefit in terms of bug reduction, yet we still see what we see: if project scope is limited by the bug load and always increases up to its limits.
    That is, FP projects are more ambitious than OO projects, and achieve their higher ambitions. That is, FP does eliminate some class of bugs which OO doesn't eliminate (to do with state management), and as a result people have the courage and resources to tackle more complex application logic with more logic bugs, which makes up for the difference. As a result of the benefits of FP, more ambitious projects exist which wouldn't otherwise exist.
    Do I claim that this is the case? I don't know. Like, I _really_ don't know. I guess the way to try to test this hypothesis is to classify the bugfix commits by bug type, and only count the kind which FP proponents say FP fixes. Or count total LOC, or some complexity measure, or... try to detect some kind of other difference between the FP and OO projects used in the study.
    But... here's an analogy: does automatic memory management eliminate a class of bugs and make developers more productive? Is the proportion of bugfix commits (of all kinds) a good empirical measure of the truth of these claims?
    I seem to recall that programmers on average product one bug per X lines no matter the language. I would not be shocked if a similar truth holds about bugfix commits (per total commits, in any language, with or without garbage collection or object orientation or whatever). If true we should not expect this empirical measure to tell us much (if anything) about the differences between OO and FP, or between manual vs. automatic memory management.

  • @Laggie74
    @Laggie74 Рік тому

    Well presented. All who speak in absolutes don't know anything about programming, OO, FP or otherwise.

  • @kmac499
    @kmac499 6 місяців тому

    The big thing for me with OO. which often seems to be overlooked, is instantiation of an object from ita class. Taking the GUI button example you gave, Write one class, instantiate 10 copies, set their 'values' to 0-9 and you've got the beginnings of a calculator..

    • @salameez
      @salameez 2 місяці тому +1

      @@kmac499
      OOP: "for (int i = 0; i < 10; i++) { var button = new Button(); button.Value = i; buttons[i] = button; }"
      FP: "buttons = button [0..9]"
      FP > OOP

    • @kmac499
      @kmac499 2 місяці тому

      @salameez OK I can see that, now can someone tell me what a monad is, cos after watching numerous videos I still have no clue

    • @kmac499
      @kmac499 2 місяці тому

      @salameez How about setting the size, colour, font etc of the button, and then three months later the client says can it go beep when pressed...

  • @venky-vj5fz
    @venky-vj5fz Рік тому

    its never ending you point at one people come up with other. and its vice-versa. crazy world of developers.

  • @YumanoidPontifex
    @YumanoidPontifex Рік тому +1

    1. parallelism - if i have 100 work units each of which takes 1 minute to complete, are you telling me that running this workload spread across 32 cpu cores will show no benefits compared to running it on a single core?
    2. picking python as an example of a functional language... really???

  • @IARRCSim
    @IARRCSim 6 місяців тому

    3:35 "It may be a bad idea to write an operating system in Python but we could." How would you define interrupt vectors, context switching between processes and use special system level machine code instructions in Python? You can't even compile Python to machine code. PyPy does some JIT compilation and compiles a restricted subset of Python called rPython that PyPy was implemented with. Even if you're willing to create new compiler tools for Python that don't exist yet, you likely can't compile it no matter how hard you try. Using restricted versions like rPython or changing the language for your operating system would mean you're just not using Python. Also, if you mix Python with assembly or c, again your operating system won't be made with Python then. Turing completeness doesn't make a language general purpose.

  • @fennecbesixdouze1794
    @fennecbesixdouze1794 Рік тому

    @6:55
    You can call print in a lambda. Perhaps you were thinking of Python 2 where print is a statement. But you wrote Python 3 code.
    Anyway, in Python the map version of your code would be: `[print(word+":
    ", end="") for word in WORDS]`. Python uses comprehensions to express most mapping operations. More properly, the code would be `[print(word+":") for word in words]`, since Python's `print` already adds the newline to stdout for you.
    Another way to mangle it that's closer to the Java example would be:
    `[_ for op in map(lambda word: print(word + ":"), WORDS)]`

  • @mateovalenciaminota5067
    @mateovalenciaminota5067 Рік тому

    I can't fully express the emotions this video stirred within me. It might sound strange, but listening to this, sir, brings healing to me. I used to be someone who saw things in a very binary manner, either black or white. However, now I can blend those colors and gain a deeper understanding of programming and, more importantly, my decision-making process.
    Thanks Sr.
    :)

  • @anasouardini
    @anasouardini Рік тому

    And toke away this:
    1. each of the approaches is a tool; each with its own use cases.
    2. you can do OO in non-OO language and same can be said for Functional Programming due to turing completeness of the modern languages.
    3. FP programmers do use OO concepts in some form and vice versa, it's just not as explicit.
    4. 100% OOP or FP is almost never the best solution: you, mostly, want to break the rules here and there and also use approaches from other paradigms.
    In Short: Use the good parts from both realms depending on the problem you're trying to tackle.
    One question that comes to mind is: is it better to have multiple ad-hoc approaches for each area in one app, or is it one generic and consistent solution that would make programming the app easier?

    • @ContinuousDelivery
      @ContinuousDelivery  Рік тому

      I think that is a reasonable summary of how I think about it. Zealotry either way, is almost always wrong.
      My guiding principle in picking what solution to use where is always readability. I will optimise to make my code as simple to understand as I can. That's it. I use TDD to drive design-decision-making, and that helps me to prefer certain kinds of designs (modular, cohesive, good separation of concerns, nice abstraction between parts, and appropriate levels of coupling).
      I never intentionally prefer code that is more difficult to read. I mostly use functional structures in OO code to avoid repetition in code, using small functions to make a particular use of something more generic, more specific.
      My stylel, even in OO, tends to prefer minimising side-effects anyway.

    • @lepidoptera9337
      @lepidoptera9337 Рік тому

      Mixing two or more bad paradigms doesn't lead to better software design. It just shows that the architect/programmer doesn't like to think. Many are happy to apply pre-canned solutions in a reflex-like manner in their work and paradigms fit that unhealthy engineering style. Is that how a real engineer should think? No. A real engineer should start with the problem and deliver a solution that is correct, on time and on budget, no matter how that is being done.

    • @anasouardini
      @anasouardini Рік тому

      ​@@lepidoptera9337 I wouldn't say real/not, but time and budget are factors to be considered. Sometimes the patterns and paradigms might also help suffice those criteria really well without the need to think as much as the first time trying to understand the pattern.
      Although the already-baked solutions are made to make the process efficient, I agree with you: focusing on the pre-made solutions too much can happen and lead to deviating from the goal.
      But calling a whole paradigm "bad", is not a wise take tbh.

    • @lepidoptera9337
      @lepidoptera9337 Рік тому

      @@anasouardini Take "statelessness" as a paradigm. That's outright delusional from the start. Why? Because most software is actually tooling to change the state of (somewhat) persistent storage. Uploading a video changes the state of the server drives. Sending email changes state because we want persistent records of past emails on our devices. Playing a computer game is the constant change of state of the representation of the player's avatars etc... How can one achieve change of state with a theological belief that the code should not create state/change?
      The engineering problem with state is not that it should be avoided, rather we have to make sure that all state change is well defined and that these changes can only happen in guaranteed atomic units to preserve the integrity of the state.
      The correct definition and handling of a program's state is an architectural problem. By the time we hit the code level it's already too late to try to fix bad architecture with language syntax.
      One can say similar things about other aspects of OOP/FP, but in general they mostly seem to come down to the belief that hard problems (and, yes, system design is a very hard problem) can be simplified automagically at the language/code level. Even a cursory book into an entry level computer science textbook will invalidate that belief easily.

  • @jonathanwinandy
    @jonathanwinandy Рік тому

    Again ? FP is a paradigm different from *imperative* or *logic programming*. We do FP with (or not) OOP.
    So the difference, if there is, OO is good for "simulation/modeling", FP works with clear relationships between input and outputs.
    You can use clear relationships for modeling, or not."it depends on your team, astrology, ..."

  • @PierreThierryKPH
    @PierreThierryKPH Рік тому +1

    Beware that it is entirely false that functional programming is a stateless programming model. FP is a model where state is explicit, not absent. Now that I'm proficient in Haskell, I prefer to write I/O heavy or stateful code with it, because the way state and side effects are handled makes it easier for me to write correct and performant code.

  • @nickbarton3191
    @nickbarton3191 Рік тому

    It's got to be a mixed approach. Wrapping function call within function call is what most think of as FP is horrible. The structure offered by OOP combined with FP features like chaining, train track, extension methods is the way to go.

  • @bjorn1761
    @bjorn1761 Рік тому +15

    The only way to write loose-coupled software between modules/objects is by using observer/publish-subscribe/event/signal-slot paradigms, in other words: callbacks/functions as parameter. The point is that people practicing OO often don't realize that (and it is btw a necesetty when practicing TDD), whereas in functional programming that is the default/is forced by the language (looking at Haskell), so you end up in scalable software by default in functional languages. Btw OO languages nowadays support lambda's/functions as a parameter.

    • @toopkarcher
      @toopkarcher Рік тому +7

      I'm not 100% clear on how event driven architecture is like passing lambdas as arguments 🤔

    • @AdrianDiaz-ob8qn
      @AdrianDiaz-ob8qn Рік тому +2

      I don't get it either, what do async messages have to do with functions as parameters?

    • @alexkfridges
      @alexkfridges Рік тому +5

      Um, what

    • @johnjackson6262
      @johnjackson6262 Рік тому +1

      This is hard to understand. In functional dependency injection is passing it in as a parameter and in classes it’s the same just through a constructor or method. The difference is maps,streams,pipes vs inheritance, loops, mutations ect. Dependency injection makes unit testing easy, agree, but you can do dependency injection and even events through both.

    • @hfspace
      @hfspace Рік тому +1

      @@AdrianDiaz-ob8qn well, i think he means, that on an event a function is called. And if you have certain classes/modules that are handling the events, then it is good to be able to pass the functions as parameters to them as this makes it very easy to split your code in a loosely coupled way into the "event handling" code and the "business case solving" code (= the function that is passed). Observables in rxjs are a perfect example for this kind of loose coupling by design. And in all functional programming languages i know, it is possible to pass functions as parameters. And it is so easily done that it becomes second nature. In OO you are more likely to mix the event handling code and the business case solving code into one big ball of mud :-)

  • @dmmeyourpoem
    @dmmeyourpoem Рік тому +1

    Sorry but some of the claims made in the video are just wrong.
    1. You can in fact call print in a lambda in python.
    2. Set does not inherit from Vector in Java. It is an interface.
    3. Event handlers are not an OOP idea. We've been using event handlers for events like hardware interrupts since long before OOP.

  • @jrgalyen
    @jrgalyen Рік тому

    Fluent API / function chaining vs procedural is spaces vs tabs. I hope people understand functional purity & functional programming have nothing to do with this. Pure functions means you don’t access parent or any data not passed in via parameters. It also doesn’t modify anything. Function simply returns data.
    (haven’t watched the whole video. But this was a huge misunderstanding when I first learned about functional programming)

    • @lepidoptera9337
      @lepidoptera9337 Рік тому

      Exactly. Pure functions are useless except as a tool to reuse code snippets. An entire program can NEVER be a pure function because it would always return nothing (since it is not allowed to change the state of the world even at the end of the computation).

  • @ross825
    @ross825 Рік тому

    In Python >=3.8:
    lambda x: print((y:= x,)[0]) works if I remember right.

  • @jrgalyen
    @jrgalyen Рік тому

    OOP applies to data - metadata/schema of joining data is inheritance. Multiple joins, multiple inheritance.
    View in a relational database handles OOP. You don’t have to have it in code. In fact, SQL is a functional language consuming OOP.
    Behaviors built on functional programming use encapsulation/composition to act upon OOP data
    Decouple data-centered code from behavioral in the same file. Keep purposes/responsibilities close to each other.
    Data in databases are domain collectors
    Stories, Features, Epics are functional domain collectors
    Our code should be driven by both. Behaviors ultimately being driven by data.
    This reduces side effects
    Allows for the compiler to optimize for the stack (functional with pure function inlining) and heap (data-centered)
    Data will have functions
    Behaviors will have static never-changing data like enums
    I don’t see how so many developers and influencers miss this

    • @jrgalyen
      @jrgalyen Рік тому

      Get data -> functional programming/pure functions -> save or return state
      I think CQRS like this helps. CQRS is usually modeled after using a single database (CQRS against multiple databases is not CQRS, but SAGA which requires us to create distributed locks and is an antipattern). But ignore the database. Query, Command(s), Request (save or return), select matches above.

    • @ContinuousDelivery
      @ContinuousDelivery  Рік тому +1

      I don't think that you can ignore message passing in OOP and still call it OOP, that is the dimension that a data oriented view of things lacks. There are events that happen, and in OOP we model the events too. That makes a BIG difference in terms of design. The storage of data in RDBMS certainly does not reduce side effects, and is not at all functional, since it is all about side effects. Sharing data via RDBS is a risky way to share data because of this, it is fragile and we have decades of experience of the mess that results from relying on this model. The messages matter, because they add a mechanism for isolating and coordinating access and interactions.

    • @lepidoptera9337
      @lepidoptera9337 Рік тому

      Wow, that was a lot of bullshit. ;-)

    • @jrgalyen
      @jrgalyen Рік тому

      @@lepidoptera9337 how is saying that helpful? Regardless of who you are replying to. Just plainly say what is wrong

    • @jrgalyen
      @jrgalyen Рік тому

      @@ContinuousDelivery > I don't think that you can ignore message passing in OOP and still call it OOP - you absolutely can and should
      "Object Oriented" doesn't entail anything other than Objects. Do two different rocks talk to one another? no. But are two rocks object, yes
      OOMPP - Object Oriented Message Passing Programming would include message passing, by definition
      Data works best with single source of truth. A single transaction. ACID. Relational database, object-relational db, document store object db, graph, eventual-consistency/snapshot-isolation, or other...
      It is more about the transaction and single source of truth and if the technology can uphold that truth
      I'm not telling you anything you don't already know. Just the clarity of the terms you use are not there. And I am sure there is some unnecessary $$$ certificate, book, or course to learn intricate detail. And I am sure there is some unnecessary $$$ certificate, book, or course to learn intricate details.

  • @nueythepyasuwan
    @nueythepyasuwan 9 місяців тому

    Wow mind expanding. Thank you

  • @GamingDemiurge
    @GamingDemiurge Рік тому

    Mixing data with functions while taking encapsulation seriously is a recipe for disaster. What end up happening is that encapsulation goes out the window and the code gets filled with "managers". The problem are not classes.

  • @ApprendreSansNecessite
    @ApprendreSansNecessite Рік тому

    When I hear "there is always state changing somewhere" I cringe because that's playing down the importance of managed effects. The fact that there are side effects in FP does not make it equivalent to OO. As you say, it's where things are allowed to change that matters, and a FP programmer would say that it matters a great deal.
    I think you did a good job explaining your position but you were also kind of blowing hot and cold with this way of phrasing things. I would only use such a construction as part of a misconceptions rundown.

  • @Maaruks
    @Maaruks Рік тому +1

    Last time I was doing OOP we still had to write Spring XML files. It is absolute rubbish and waste of time.
    I have never been forced to do all this boilerplate since I switched to Clojure.

    • @ContinuousDelivery
      @ContinuousDelivery  Рік тому

      Spring is nothing to do with OO. That is rather like saying "last time I used Clojure, I had to use a Database" and then reject Clojure because you didn't like the database. Spring is a framework, one I have used a lot and dislike quite a lot. It is not an OO idea nor a fundamental of OO thinking.

    • @Maaruks
      @Maaruks Рік тому

      @@ContinuousDelivery Are they not using DI because of OOP? Or is it because something is missing in Java? Why does it need XML files if not because of OOP? Developers don't use DI in FP. I have never seen people having to write XML when using FP like Clojure or something similar.

    • @ContinuousDelivery
      @ContinuousDelivery  Рік тому

      ​@@Maaruks It doesn't that is just how Spring works. You can do a better job in the language in my opinion. This is not a Java limitation. Developers do use DI in FP, envy time you pass a function as a parameter to another, that is a form of dependency injection.
      Dependency Injection is not defined by Spring, or any other tools, it simply means that we pass dependencies into the code that will use them, rather than that code being responsible for creating those dependencies. This is just a good programming practice.
      It sounds to me as though the thing you disliked was Spring not OOP, which I'd agree with.

    • @Maaruks
      @Maaruks Рік тому

      @@ContinuousDelivery In FP that is called higher order function. And there is no XML involved at all LOL

    • @ContinuousDelivery
      @ContinuousDelivery  Рік тому

      @@Maaruks In OO & FP it is called "dependency injection" (not really an OO idea) and there is no XML involved either, unless you make the mistake of doing DI with Spring 😉

  • @dionbridger5944
    @dionbridger5944 7 місяців тому

    I respect everyone's right to be wrong.

  • @orange-vlcybpd2
    @orange-vlcybpd2 Рік тому +1

    Thank you, it was great for understanding why i intuitively find java confusing. Now i know why. Because of the inconsistent design choices in base language (primitive vs object types dichotomy) as well as in the standard library.

  • @NathanHedglin
    @NathanHedglin Рік тому +1

    You say a lot without saying anything.
    Syntax? Sum types and pattern matching and GHKT are NOT just syntax.

  • @DummyFace123
    @DummyFace123 10 місяців тому

    I'm not married to either, but which one is more memory/heap efficient (if there is a difference), and which one is more cpu/power efficient? (again, if there is a difference)
    Full disclosure I am a .net stack developer and I know that our apps can get very garbage collector dependent when doing a lot of work because of objects going into the heap.
    So when our apps do a lot of processing, a lot of objects are getting created and disposed of.
    I also don't know much about functional programming other than it seems like mathematical streams. And I know that if you have a program the flows like a stream, and don't need to call multiple objects/functions deep and then bubbling back up to the top, then you might not need to keep those contexts and can afford to throw things into the stack instead because the context isn't going to live long.
    If that is the case (again just an ignorant assumption), then I think functional would be more resource efficient at least. Maybe not developer time efficient

    • @ContinuousDelivery
      @ContinuousDelivery  10 місяців тому

      Unfortunately, it isn't that simple. It really depends on the nature of your code, much more than the difference between Functional and OO. Function incurs more costs copying things, or providing the illusion of copying things in order to sustain immutability, OO tends to create more transient state so, as you say, garbage collection is more of an issue, but how those things play out in different bits of code, is very specific to those bits of code. The real secret to high performance code is to understand what is going on, so, for example, learn how garbage collection works in your tech, learn how to profile and tune it to meet the needs of the system. I used to write ultra high performance financial systems, 2 spring to mind here, in one we tuned the garbage collection so that that the really costly stop the world kind of sweep would happen less than once per day, and then we reset the system daily so in practice it never happened. In the other we write our oo code so that it was immutable and allocated on the stack, so no CG at all. Neither of these were written as Functional systems.
      Functional systems in general are not high performance by default, because of all the work that that the languages and compilers do behind the scenes, like enforcing immutability, but I am sure that there are ways of using them and tuning them to do better than the default. It did cross my mind to implement something high performance both ways and see which worked better, but it would be a lot of work and even if I did that I don't think it would help. Performance is more about what we called "Mechanical Sympathy" - understanding how the underlying system works hardware, os,. language, frameworks etc, and using those things efficiently.

  • @Nors2Ka
    @Nors2Ka Рік тому

    > CTRL + F "performance"
    > 0 hits
    Right on!
    Hey, at least you can cope that you are productive (an unfounded statement presented as fact, which was never been quantitatively proven).

  • @davivify
    @davivify Рік тому

    I find the whole functional vs OOP discussion to be ridiculous. Why? Because they're not contending with each other. Functional programming works at the functional/procedural level. OOP is a container architecture. Which means functional code will work quite well within an OOP context. Remember when "structured programming" was all the rage? What happened to it, did it disappear? Do we no longer use Code blocks? If/then/else? Are loops and iteration a thing of the past? Of course not. Structured code just took its place within OOP and nobody said "boo".

  • @misium
    @misium Рік тому +1

    18:30 main problem that this example is not showing is all the additional code you have to write to make that example work with an explicit MyCalc class. Many lines of empty weight of code, most often one or two more files. You can cut down all that unnecessary cruft with a few functional features.

  • @BojanPeric-kq9et
    @BojanPeric-kq9et 8 місяців тому

    Examples of functional programming in Java and Python. Compare that to OOP design implemented in 8086 assembler with "joy" of segments...

  • @apolloapostolos5127
    @apolloapostolos5127 Рік тому

    Here because a comment on @Coderized recommended it.

  • @styleisaweapon
    @styleisaweapon Рік тому

    Inheritance IS bad, Reason: because its the wrong tool for what you actually needed, its the hammer driving in screws and staples.

  • @mskiptr
    @mskiptr Рік тому

    for (String words : WORDS) {
    System.out.println(word + ":
    ");
    }
    is imo more readable than
    WORDS.stream().map(word -> word + ":
    ").forEach(System.out::println);
    but that's because Java's wasn't designed for that.
    On the other hand,
    WORDS
    |> map (++ ":
    ")
    |> unlines
    |> putStr
    is more readable in the end.

    • @markhathaway9456
      @markhathaway9456 Рік тому +1

      Is it really more readable? It looks strange to me. Just using imagination I'm sure other ways of presenting it would be more readable.
      forEach word

  • @marna_li
    @marna_li Рік тому +1

    I think that an error of software developers is to think in binary: Yes - No, Good - Bad, This - Not that. In most cases they just state their preference and not whether or not something they don't like could still be suitable for some problems. OOP har its strengths, so do FP. They don't exclude each other. You can mix practices and styles without for instance pick a primarily FP language. It doesn't make you a hypocrite. If you know what you are doing, that makes you a productive person.

  • @HoSza1
    @HoSza1 Рік тому

    "You can't call print from a lambda in Python"... maybe that was the case in a really ancient version of it, but not anymore. Lifelong learning is still a thing.

  • @5thElem
    @5thElem Рік тому

    Lambda functions in Python are typically used for concise and functional-style programming, where the emphasis is on pure functions that don't have side effects. So, this example is a bit contrived, I'd say.

    • @lepidoptera9337
      @lepidoptera9337 Рік тому

      Pure functions don't exist in real life. Every useful program exists to automate side effects.

    • @5thElem
      @5thElem Рік тому

      @@lepidoptera9337 Don‘t confuse programs with functions 😉. I agree that programs without I/O probably don’t make much sense. Undoubtedly functions do exist which are producing the same output given the same input (in the context of larger programs) without accessing external state.

    • @lepidoptera9337
      @lepidoptera9337 Рік тому

      @@5thElemThe engineering role of functions is the same as that of loops: they are code reuse. Instead of replicating the same code endless times (which would be mathematically equivalent), we use the same code to act on different data. Other than that they are irrelevant to the operation of software. A good compiler will perform loop unrolling and function inlining automatically these days. In other words... whatever the programmer writes will be translated into a better performing machine code equivalent anyway.
      Let me give you another important tip about side effects: the only side effect relevant to your boss is how much money he makes with your code. How you code and what religious beliefs about coding you hold are entirely irrelevant to him. Your main role as a software engineer is to make money for the company. Unless you understand that, you don't understand anything about what you are doing. :-)

  • @byronjones5902
    @byronjones5902 Рік тому

    Is your application making you $$$? Are people using it? If yes, congratulations, your way works.

  • @PythonPlusPlus
    @PythonPlusPlus 6 місяців тому

    6:55 This is just plain wrong. You can call print from a lambda. I think you may have been confused because map is a generator, so just doing map won’t execute any code, you have to iterate over the map to have it run the lambda.

  • @ddanielsandberg
    @ddanielsandberg Рік тому +2

    In my view good OO is very close to FP in many aspects and well constructed objects are nothing but a set of partially applied functions.
    Typical OO in the wild tend to be more "class-oriented programming" (in lack of better terms) than OO.
    I don't know. Feels like the "object thinking" was lost in translation and became "boxes of procedures" and then "program to an interface" became "implements IThing". Which is why we get crap like IThing (.Net yuck) and ThingImpl (WTF?) and AbstractUserManagerProvider (enterprise job security).

    • @markhathaway9456
      @markhathaway9456 Рік тому

      What seems to be lacking is FP within a class/object. Using FP style over imperative might improve the type safety and limit side effect while getting better composition.

  • @tiansivive
    @tiansivive Рік тому

    didn't watch the whole vid so take my opinion with a pinch of salt
    In the bits I saw he brushes aside FP vs OO distinctions as matter of preference with syntax or problem modelling, but really, it's not so simple. FP, and by that I mean committing to immutability, reducing state and managing side effects, forces devs to more carefully model their code.
    OO just does not work, its way to easy to go astray, especially with changing requirements. We used to say OO was good for UI, yet React dominates UIs these days...
    Just an one example, that for loop vs map/foreach. The fact is the loop deals with statements and any dev can go there and add one line that mutates something or performs a sideeffect using some outer scope variable. People often say that won't happen because it's an obvious bad practice, but in practice, it happens all the time! Whereas with the lambdas, people tend to not add too much and separate them out into separate, more pure, functions.
    It's not so much about any inherent advantage of one vs the other, but rather, following FP principles just tends to encourage better code, while OO encourages sloppy code

    • @lepidoptera9337
      @lepidoptera9337 Рік тому

      State can not be reduced. State is that which the program has to modify to do something useful. The problem of software engineering is to define the state space of a program properly and to prevent it from modifying its state in an uncontrolled manner. FP does not thing to address either concern. OO is mostly in the way of rational software engineering strategies that handle state safely because it makes it very hard to modify state consistently if the requirements change and the class hierarchy does not reflect the requirements any longer.

    • @tiansivive
      @tiansivive Рік тому

      @@lepidoptera9337 sure it does! For example, you can't really have global mutable state, so you have to parameterize your functions with the current, local state. That's forcing a safer model, so it does help.
      An imperative loop that adds up an array of ints is inherently stateful. A sum fold over an array is not.
      So yes, FP does help reduce state.
      That said, Devs can fuck up state in both FP and OO, so it's not a silver bullet

    • @lepidoptera9337
      @lepidoptera9337 Рік тому

      @@tiansivive What you are describing is programming with kiddie safety wheels. If you don't even trust yourself with the atomism of an array arithmetic function, then you are nowhere close to the level of an actual software engineer. Not that FP would help you in an environment in which you need re-entrant functions that are being called from inside multiple asynchronous hardware interrupts... which is exactly what one of my programs has to provide.
      I have a hardware product out there (selling for the better part of 20 years now) that has zero known bugs and 100% uptime that is entirely written using global variables for state. That was a deliberate design choice. The solution to this mix of hard real-time and unsafe parallel operations was a custom round-robin scheduler that has full visibility of EVERY system variable. Because it knows the full state of the system (there aren't ANY local variables!) it can always decide what not to do. It doesn't do unsafe operations immediately but instead puts them in a circular call buffer. Only after all functions that could possibly interfere with each other have been cleared can the system perform certain "unsafe" operations. That worked like a charm... ;-)

  • @hstrinzel
    @hstrinzel Рік тому

    Somehow I'm just as confused as before. I probably need to study much more basics before I can understand this.

  • @von_nobody
    @von_nobody Рік тому

    Funny that in work I use C# that belong to OO camp but 50% of code I write is pure functional (like LINQ)
    I even added helper function `static R callback(this T t, Func c) => c(t);` to "feel" more functional.
    How much this one simple function can simplify code, even simple condition like:
    ```
    if (x < 0 || 100 < x)
    ```
    could be improved. How it could be possible? answer is `x` is like `dto.Foo.Bar.X` and `Bar` is optional.
    ```
    if (dto.Foo?.Bar.X.callback(x => x < 0 || 100 < x) != false)
    ```
    Try write this condition without functional helpers like `?.` and this `callback`.
    I still stuck on .Net 4.8 but newer versions of C# add even more features to make it easy to write in more functional way.