I strongly object the idea that allocating memory to local variables is a side effect. If that were the case, NO programming language could achieve zero side effects. Local variables are stored on the stack of function calls. Once the call is done, all local variables are wiped off. "Side effect" means causing changes to variables outside the scope of the function (by means of assigning different values to global scope variables, or member attributes of input parameter). Thank you for the video but please improve the example.
I guess it technically creates 'side-effects' in es5 when declaring with var due to hoisting. But yeah, bad example. I reckon introducing OOP first then showing how modifying object fields with methods is a side effect.
this is like comparing: a, b = b, a and c = a; a = b; b = c The difference is that in second case this helper variabie has to be declared explicitly, while inn first case it is only internal. But it is still here. Actually, 1st case requires more memory since internally a tuple of 2 variables has to be allocated.
... That's simply not how it works. Creating a new variable inside the function itself that doesn't even get muted afterwards is not a side effect. Both functions were functional approaches.
Also the variable-less version probably compiles to exactly the same machine code. The computer has to add x and y before squaring it, and the result goes somewhere - leaving registers aside for argument's sake that somewhere is going to be the stack, which is just memory.
@@Toon81ehv We need to be at an other level that just "compile to assembly language" or something like that. The problem about thinking with the code produces is : semantic is not important, we have the same output. In fact, restrict us to ours computers is very, very restrictive when we talk about programming language. Think with semantic, not code produce ;)
@@simonhauguel9806 the point of the video was that the computer generated machine code would cause problems in function written in 'non functional' way. That's just not true cause most likely similar machine code will be generated in both cases anyway.
Yes, the example of FP vs Imperative is horrible. Besides the technical arguments made here, it promotes the anti-pattern of inlining the body into a single expression where the multi-line form might be much more maintainable. Someone new to FP is going to create inscrutable nonsense doing this.
@@r0bertdenir0 Besides, how is the FP even implementable using, for instance, C language as the example shown here in this video, if I want to calculate the squared sum of two inputs ?! Is it even possible to implement this function using FP and without using any further variables inside this function ?! How may I even implement the square mathematics using programming ??
Does this TH-camr have at least a basic grasp of computer science? Under his definition, the computer sitting idle creates side effects, since the kernel is constantly changing the state of the program. Aside from the silly memory increase as a side effect, he doesn't even grasp that the inlined function and its expanded form are identical. The compiler will optimize away the variables needed for storage, if they can fit in the available registers. I hope no one is watching this video thinking the number of lines of code translates into more efficient code.
@@bobweiram6321 100% agree. Back in the day there was an impetus to minimize the number of characters used, since each one takes up 8 bits, and so there were physical limitations on the length of code prior to compiling, but those limitations are decades gone. Popping stuff in and out of the stack in creative ways was a skill worth having when people had to address registers directly, and as a recreational programming activity it still has some value. But you are correct, the interpreter or compiler doesn't care if you're creating tons of local variables, and doing so is actually good practice in my opinion as it makes the code more readable without overburdening it with comments. I'd much rather write and read: for item in masterlist: paintlist = [ ] name, sku, loc = item[0], item[1], item[2] paintobj = PaintObject(name, sku, loc) paintlist.append(paintobj) return paintlist Than for i in mlst: plst = [ ] plst.append(Pnt(i[0], i[1], i[2])) return plst They do the same exact thing but good lord is the first one legible. And actually the first one would be better if it used name, productID, and location instead of name, sku, and loc, but a certain amount of abbreviation and lingo is not too wild in this context. You can clearly glean that I'm generating a list of physical items, probably paint products, I'm doing so as objects (in this case dataclass objects in Python) and ascertaining their real world locations, probably for the purpose of fulfilling an order. Even line 2 of the for loop could be 3 individual lines if I really wanted to spell it out. The second one saves no memory, doesn't run any faster, and is only cryptic for the sake of being cryptic. name, sku, and loc are not only vanishing locals, they're also the names of the class attributes I'm assigning. I can do it blindly and have "no side effects" or I can be verbose and have confidence that another person could piece together wtf is actually happening. Nothing touches the global scope. No "side effects". Good code reads like an instruction manual for that code, and I'm not talking about comments.
Imperative programming (OOP) tells the computer how to do something, step by step. Declarative programming (FP) tells the computer what to do, without specifying how to do it.
So where is the declarative compiler that can convert "Write a website that gets visited 100 million times a month and makes $5 million in revenue!" into the desired product? ;-)
A side effect would be mutating a global variable from inside a function, but since the variables defined are in the scope of the function, it isn’t really a side effect...
@@cristianjuarez1086 That's because it's such an obvious piece of information that everyone is amazed the video creator didn't know this / it reveals that they have no clue what they're discussing.
Sorry but in the attempt at simplifying the topic ambiguity has been introduced. The side effects highlighted in the first example are only there because the scope of the variables extends outside the function, which was not explained . If the variables in the imperative example were declared inside the function their 'side effect' would be virtually zero. Yes memory would be used but memory is also being used to store the input values x and y as parameters. There is a good explanation of OOP but using classes is not the means of implementing OOP. However, the answer is to the question is sound, one paradigm is only better than another in specific cases. There is also the possibility that a blend of both might result in a better solution. Being aware of the strengths and weaknesses of both approaches is what is important. Finally, dark blue text on a black background is not a good combination for reading.
Well, as everybody has already pointed out the "memory side effect" error. I will add that the concept of not having to write the same code over an over again is called ABSTRACTION, and it's a feature that literally every single paradigm has, it's not a thing of OOP. The funniest thing about this video is that it's said to be "for dummies" lol, should have instead been "by a dummy"
@@markhathaway9456 Not only it's not even remotely impossible, but litteraly every programmer who has relatively advanced theoretical knowledge would know what I said. And talking about bets, I would bet there already are better videos than this one, only we didn't see them yet
Instances of classes are nominally typed by a class, but inheritance is a relationship that exists between classes, not classes and their instances. So the `Dog` class might inherit from the `Animal` class, then an instance of a Dog class is also an instance of the Animal class. Inheritance creates a type-hierarchy (sub-types).
In the same way that a function allows code reuse without including it whole in a program, the OOP system lets you create multiple things of a "type" without rewriting a ton of code. Techniques to allow code re-use are commonly good things. Concepts like "type", "inheritance", and "pure" functions is tough to relate to anyone in a short video.
Using variables inside a function is not a side effect. Side effects are effects that could change how the function works depending on external factors, like network, filesystem or random memory access.
Hold on a second! Calling a function pushes the return address and the arguments for the function into the stack memory. CPU resolving the formulas like x^2 is also using some memory for temporary storage of values during calculation. Hiding it all from a programmer sounds more like a psychological trick to me, not as a technical solution for sure. I'd rather have openly declared memory usage as a variable than having it done secretly behind the scenes pretending there are "no side effects". Pushing everything into the heap or stack is no different. It is all memory anyway.
In case you have been sleeping for like, the past 50 years, plenty of mainstream languages hide memory allocation from you. because it's just not relevant for the programmer whether X will be allocated on the stack or the heap. according to you we should all be writing assembly code because register allocation is a psychological trick, go back to your cave Cnile
In either case, I think it doesn't "count" as a side-effect because the variables will probably get deleted automatically. Either the machine code that is used to calculate (x+y)^2 will write over, if not separately delete, the intermediate variables, or the programming language will do that after the function call is over. I'm not sure, though, and it has to do with how the programming language compiler/interpreter works.
3:24 I don't know. I think its much easier to understand functions with the steps laid out than a function that does things in the fewest lines of code possible (obv context dependent)
It is kinda mentioned in the video but I think it's important to highlight again that OOP focuses on object creation and inheritance. FP focuses on pure functions and isolating side effects (including application state). Since they solve different problems it's actually possible to use classes and mostly pure functions simultaneously. Other, different solutions to object creation, inheritance, and particular side effects like state management exist as well. Furthermore, it's possible to program in a 'functional style' in languages that mainly support OOP. And though it's extremely awkward and generally unadvisable, it's possible to produce object-oriented code in a functional programming language.
You can focus on pure functions all you like, in a real program you cannot eliminate the need to manipulate persistent state, that's why the functional programming paradigm was abandoned 50 years ago.
@@ianrust3785 pretty sure the reason FP didnt catch on is b/c high barrier to entry. Very confusing to learn. You can just use monads like haskell's IO to encapsulate side effects like mutating persistent state. knowing that all state changes can only happen inside like 5% of your codebase while most of your code is pure functions means that you have tests covering all possible edge cases for 95% of your code. no deps, runs quickly. Then you can write integration tests on the remaining few or debug. Splitting up your data access from your business logic is also a "best practice" in OOP because we all recognize the advantage of not being able to mutate all over the place. In other words, you get this benefit if you use a functional style in oop code too
People confuse functional programming with functional-reactive programming and functional UI frameworks. Functional programming is a paradigm that predated OO, it was used mainly in the 60s and 70s. A functional program is just a giant hierarchy of functions which executes continuously until all the functions return. In pure functional programming (which is more of an ideal than an actual programming paradigm) there is no persistent state, only local state. Just functions with inputs / outputs but no side effects. As the functional paradigm evolved it became clear the ideal of pure functional wasn’t practical, and programs came to rely on more persistent state, which was usually global, though could also be non-local hooks. There were alot of problems with the functional paradigm which OO helped fix… The fragile top-level interface is one issue - when your program is just a giant function hierarchy, any change in an interface near the bottom tends to ripple up to the top, this makes changing the code difficult and require extensive refactoring. Different parts of the program accessing shared state meant extensive lifecycle management and/or locking became necessary. This state was also not encapsulated - and the data was separate from where it was used, this increased complexity. It leads to a spaghetti-code situation as the codebase grows in size / the amount of this persistent state increases. OO fixed these problems to a degree with encapsulation, lifecycle management, and polymorphism, but introduced a new problem - encapsulation means that the distributed local state is now persistent, so we now you have to go to extra lengths to maintain consistency. There’s also alot more persistent state to deal with. Functional reactive uses data bindings to drive updates to the distributed state of a graph of objects, to bring their state into consistency. These components are objects - regardless of whether your UI framework provides a functional API for creating them or not, behind the scenes they’re objects. Functional reactive programming is basically a remedy to problems inherent in OO. It is not dispensing with the OO paradigm, without OO it has no useful purpose. And it’s a completely different programming model than that of traditional functional programming. The word functional in functional-reactive is referencing the fact that functional-reactive programs glue together components into a cyclical data flow and drive updates, doing functional transformations at different points along the way. State also remains consistent between components, which connect together seamlessly, similar to traditional functional programs - you have persistent distributed state, but it no longer behaves that way. There’s also this idea that state should be immutable and the data structures should have value-semantics, and languages have been adding support for this. State behaves more like a local copy this way, you don’t end up with bugs from multiple threads accessing the same data during the update cycles. With FR we’re augmenting OO with all the best characteristics of traditional functional programs - we are getting the best of both worlds now. Functional UI frameworks are leveraging the ideas in functional reactive and providing a higher-level functional interface for creating UIs. The isn’t a reversion to the functional paradigm, or the introduction of a new general programming paradigm- you can build up a framework to provide any kind of API you like, we even have frameworks that allow you to construct your UIs using a GUI, but these frameworks are still just decorating a composition of objects and managing that state behind the scenes for you. That works within the limits of what the framework can create - it’s not a generic programming paradigm. Also… Javascript has its own unique reasons for not wanting to use objects, but that’s a language issue. Better designed, modern languages like Swift have powerful data structures with value-semantics which work very well in these contexts. Functional reactive is serving its useful purpose when combined with OO. Its purpose is to keep distributed state consistent. People who argue for choosing functional over OO… don’t really understand what functional reactive is and what makes it valuable. I’ve also seen an increasing number of programmers arguing for reverting to the bad programming techniques of the 60s and 70s lately, which is not good. I’ve done a little work in a codebase written by some devs resuscitating the old functional paradigm... I joined their team to help out because they were falling behind other teams. Looking at the code.. it became clear why - they’d just created a monolithic procedural mess in an attempt to be functional, convinced they were being innovative. Their code couldn’t adapt to our new use cases… it’d take 6 months to clean up the mess.
Parallelism and atomicity have nothing to do with either OOP or FP, though, and one should not mix different problem dimensions in such a clumsy way. Your comment about locking doesn't make any sense to me. Explicit locking IS NECESSARY. It's unavoidable if we have to deal with limited machine resources (like file IO) and of we don't do it, then the operating system will usually do it for us (and often not in a good way). This is a matter of architecture, not of programming paradigm. The idea that a coding style can get us around the hard problems of resource management is absolutely ridiculous. And don't get me started about what both OOP and FP are doing to memory layout (hello buffer overflow attack!) and cache misses (goodbye performance...).
@@lepidoptera9337 "Parallelism and atomicity have nothing to do with either OOP or FP, though, and one should not mix different problem dimensions in such a clumsy way" Of course they do, one of the biggest touted goals of functional programming was to eliminate, or at least minimize, the need for application state - because pure functions don't mutate state - and in so doing one eliminates the possibility of race conditions. You're correct that you will still have some application state in a functional program - that inability to eliminate state is the point of the post, this demonstrates the failure of functional programming to achieve its goals in most systems. "The idea that a coding style can get us around the hard problems of resource management is absolutely ridiculous." Yes, except that was your stupid interpretation, not anything I said. Nowhere have I even suggested this.
It is nice having all this info in one video, but I will say it took me several years to understand this concept. I don't think I would have understood this as a beginner programmer because I lacked the knowledge and experience.
i'm new to programming. This was the best well-spoken presentation with visuals. thank you. i want to learn more about programming one day so that I can also be arrogant with the rest of the programmers on programming comment sections as well.
The only reason why you think that this was good is because you are new to programming and you don't know frell about it. You also have a lot to learn about arrogance. ;-)
You could go a step further with the sum of squares and eliminate the arguments as well by using function combinators. (define sum-of-squares (psi + (w *))). And you can reuse code between different objects through function combination and bundle it with data through closures or partial application. Any of the techniques for reducing reuse in OOP can be done in functional programming.
i'm new to programming. so far i got this: oop is like a central management and distribution of methods and properties; but when you encounter vast number of unique and independent species in a world (like the world of animals), you are forced to describe each animal as a class(or may be you can expand the properties & methods of the parent class equivalent to the world of animals and make it available to all). good thing is that you allowed yourself to create (photocopy) n number of objects out of it, because of it everything got streamlined; when you change the definition of properties and methods of the parent class, all the objects reflect the changes beautifully(only you have to have a consciousness to understand that implications are on broader level) . oop asks you expand your knowledge on the subject from the beginning as opposed to functional programming which is problem specific (you can think for the new problem when it comes); I think its extremely difficult to keep the tracking of functional programming based project because it looks like a maze of independent functions somehow interconnected and working (useful for small requirements, definitely not for large problems). please correct me if my understandings went wrong!!
@@gugahaker2112 That's exactly my experience with OOP. An old and very respected programming pro told me once to pay close attention to state and to keep it all in one place (or as few places as possible). My code has become significantly better since I have been practicing his advice.
In the minute 3:37 you mentioned no side effects on computer memory when using functional approach however, I F# language and haskell functional approach does effect on computer memory for the sake of processing input data as per their explanation of how functional programming works. Your words had got me so close but I had to read and search for this piece of info just to see if I am in the correct paths. Dude thanks for your efforts yet I suggest full review and auditing your functional programming understanding. Peace 🙏
The functional side effect example is a bit janky but there are some compilers which still do variable assignment like that, I suppose. Here are my 2 cents: Both OO and FP are structured paradigms. Structured means that program flow goes along clearly noted boundaries. Unlike some languages in which you are able to do anything. The strictly structured nature of modern programing languages does not particularly protect you from creating a ball of mud, but it makes it a bit harder. The main difference between OO and FP is how the handle data. In a functional system you input the data to get the result, in an OO system you incorporate the data. Both paradigms let you easily create extendable applications. However FP does not handle changes very well. Subsequently, OO is designed to manage side effects but it can be less stable as a result. The mutability problem also brings into question performance. In general, stateless applications need to be fed with data which inevitably leads to extra memory operations which can incredibly costly without a well designed pipeline. OO does not have this issue. As for the real world. If you have a problem and need a robust solution, FP is the way to go. There are plenty such cases within a project. But generally speaking, again, in the real world, problems, solutions and desired outcomes change. Therefore, on the surface, OOP is the only viable option.
There is a very good chance that the two following codes will produce the exact same executable code: function f(x, y) { var sum = x + y; var sqr = sum * sum; return sqr } function f(x, y) { return (x+y)^2; } Compilers have optimizers that rewrite your code completely, in order to either store intermediate results when needed even if not explicitly written in the original code, or simply get rid of intermediate variables when they are not needed. Besides, OOP is more about encapsulation and polymorphism than inheritance. Inheritance is of course part of it, but the main point of OOP is to have a black box that does something with some input in a certain specified way, while another box will do something else with it, while both are called in the exact same way.
Unfortunately the example of side-effect in this video is incorrect. This is not side-effect since sum and squared are local variables and they are not changing any external state. In fact it is recommended to program like this to make the code easily readable. To make one liners like in the example is also bad approach. It works for calculating a simple square but real life functions are way more complex and can't be written so simply. In this case if sum and squared were global variables, then it would be considered side-effect. And side-effects are not always bad, sometimes functions do need to change external states.
So removing variables, which diminishes readability and makes it hard to access values during debugging, is a great solution against bugs and for large-scale projects? I don't think so ...
Smalltalk was built with Lambda expressions and it had first class functions. Smalltalk inherited many ideas from Lisp. On the other hand, Lisp (and Scheme) had extensions for doing OOP. So in practice, the distinction between OOP and FP is not always so clear.
That's just syntax. The difference between OOP and FP is NOT syntax. It's where the compiler keeps your data and how you access it, but almost nobody who talks about these paradigms seems to understand what this is really about: scoping and memory layout. Neither OOP nor FP are addressing these issues in a rational manner.
As soon as the imperative example was given as an example of non-FP function i just tought "oh these comment section will be ruthless". I wasn't quite correct, but yeah, people were quick to point it out :D
I see that you've taken a lot of flak about side-effects. Nevertheless, if we concentrate on the OOP portion of your video, I think it is EXCELLENT -- a wonderful and much-needed explanation in plain English that demystifies the creepy, sententious, ivory-tower jargon of OOP itself. A great public service for the novice!
It would be interesting to see how the dog example would typically be done using functional style only. How is the state changed in an acceptable manner in FP, nobody ever mentions this
@@lepidoptera9337 That's what it's creator Alan Kay said: messaging. He thought the "aggregation of data" in an object was much more common knowledge and not so profound, but it's still a huge part of OOP.
@@markhathaway9456 Dude, you can easily write OOP in plain C using structs and function pointers. C++ implements OOP with preprocessor operations. By the time the C++ preprocessor is done with your OOP code it's already reduced to trivial function calls. There is absolutely no "messaging" in any meaningful sense of the word going on. Any compiler that implements OOP with real messaging does only two things for you: it wastes most of your CPU's cycles on absolute bullshit and it makes your program virtually impossible to debug. In the arts they call that "form over function" and throw it in the garbage.
You can totally apply Functional Programming within OOP, I mean if you need to get the sum_squared, there is no reason to not apply the ideas of functional programming
From my point of view there is a reason for intermediate variables, and in fact it has to do with the intermediate variables in a function actually being used for debugging purposes. Let's a a function actually has ten steps. Having intermediate variables helps the programmer to step through each step and validate the variables as they are being processed. If there are conditions within the function, such as IF step 2 results in a value greater than 0 THEN do Step 3 like this, otherwise do it like that, then having the intermediate variables for debugging is actually helpful, and without them debugging would be more difficult, not easier. So I'm not sure I buy the argument that functions without intermediate variables improves debugging. At least not in all cases. Where the function is executing a simple formula, then yes, ok. Otherwise, not so much I think.
The FP version of the animal game example is very much a strawman argument. No sane programmer would write a full set of functions for each type of animal, and certainly not for each individual. You would rather save the state of their various attributes in arrays (or similar data structures) and then have shared functions that update those states on each cycle of the game loop. So you would only have a single "update_position" function (for example) that would iterate through all animals and recalculate their positions. If you need to create (or remove) animals, just add or delete them from the list of animals that the draw function iterates through. Then they would either be drawn or not drawn on the next frame. No OOP required. There are certainly arguments to be made for OOP when it comes to organizing larger code bases, but in general, it does not reduce the amount of code that needs to be written. For smaller games, I would even say that OOP is an unhelpful abstraction. The ubiquitous game loop actually lends itself very well to functional programming.
It would've been useful to show the farm game example approached in OOP as well as FP, to actually see how they would differ. No programmer would just write each new animal from scratch if they were using an FP approach.
There are already too many comments about "variable = side effect is wrong", so isntead I would disagree with OOP example against FP example comparison. At first I thought that so called "Blueprints" talk will be about inheritance, but it's just about classes. And there's no difference between OOP and FP, there are custom data types or records in functional programming. I believe F# or Scala support constructors, or you can create a simple pure function which accepts a bunch of required arguments and returns a new Dog record with initialized attributes, so it's the same one-line way. As game developer I can say that real reason why FP doesn't fit well in games isn't because of some language stuff, when you need to start each animal from scratch (even the same one), but because game is by nature requires a lot of state which mutates over time and which often queried from different places, and also because games have strict performace requirements, so immutability in most cases isn't possible and side-effects are essiential.
Sorry, side effects are long lived variables, database operations, sending emails etc... not memory allocation. All running software allocates memory This is why a pure FP solution is more theoretical than actual outside of mathematics. The real goal in FP in real life is to be aware of the side effects so to reduce their occurrences in your code in a logic and consistent manner. This will allow your code to evolve and take on new requirements with little or no further side effects.
@@BiologyIsHot Its really a definition thing, a function should be repeatable, consistent and not modify mutable data. Any form of IO is thought of as a "side effect" or a "procedure" as it breaks deterministic repeatability and consistency Getting back to your question, the sending an email is an IO interaction, any IO interaction is non deterministic so breaks the functional paradigm. An exception will be reported if the email server is down for example, and how do you know if the email was ever delivered? Off course we need side effects. Our software would be pretty useless without them, which is why no software is functional in its truest form, however limiting side effects is a good idea by limiting the areas of code where these touch bases happen So an acceptable solution to email sending would to write a function with side effect that sends an email. This "procedure" should be responsible for sending a single email, and should be used to send all emails within our system. We need to limit the number of areas where this code is called, as any "function" that calls this code loses its functional status by definition. Being aware of side effects in a functional paradigm makes you think a lot about how you design your code.
3:15 beyond your overly-simplistic “side effects” variable-setting example, there may be a problem with how you are naming methods at your corporate dev job that may be causing ongoing development issues and on-boarding problems
Let me say something that is really cursed: My code often contains both functional and OO formats. This however has its own reasons. When calculating for example the distance between two coordinates you will use the Haversine formula. Using an OOP -language, would you create an object only containing the calculated distance, or would you give it directly to an edge of an ADT Graph? In these instances I voluntarily switch to functional programming, since the named mathematical formula IS isolated from the code to start with, but used like a package. In Java the Class Haversine would thus contain no fields but the methods Haversine and Archaversine which both only return values. It can therefor be declared as a static Class. This approach could be due to a background with functional languages before taking a step into OOP. So what do you think about that "hybrid" Code?
this is the worse compare fp vs oop what i've seen, sorry from what you called a side effect to what you said about classes. You can't create animals any other way. You certainly don't know anything about functional programming.
good explanation on why OOP is useful for creating multiple objects of similar code though feedback for improvement, the video colors, text color to bg color could stand to be more contrasted. It's hard to see the blue font on the dark blue bg
One does not need OOP for that. Procedural libraries can do this easily. The factory pattern is completely independent of OOP syntactic sugar. A trivial example in C would be a function prototype like animalType* animalFactory() for a function that allocates the memory needed to store the data about an animal and that returns a pointer to that newly allocated memory. Technically OOP languages are all just syntactic sugar. All Turing complete languages are identical in what they can express. The main "invention" in computer science, if you will, is that of the pointer or, to use machine code lingo "indirect addressing". Once you have that, you got all of this. What an OOP language does for you is slight automation of name spaces for your type hierarchy. It's a completely trivial process that can be easily emulated with naming conventions. What all of this means, in the end, is that your compiler strips any and all OOP information out of your program... your CPU does, after all, not speak objects. It only speaks "indirect addresses". :-)
Can somebody please help me !!! I'm totally confused between what to use for my big project building from core PHP without any framework I can easily make small scale websites using simple function based PHP codes and it works pretty well for me But I'm still learning OOP in PHP but will it make any difference in performance or devlopment speed ???
I had been a good idea to see how long is the code for this farm example by written in both in FP and OOP, asumió the case scenario of multiple different & similar animals coming in to the farm.
Combination of dark blue text on black background is not a very good mix for reading, and for youtube compression. Compression just crushes this colors together making it hard to read. Even if it looks good in editing software it doesn't mean that it will look good on the internet with compression
Dude, you really need to brush up on how compilers work. Your examples of functional and non-functional plus/sum will yield the exact same code. There is no side effect or “leak” occurring. And I see you’ve misled at least 5k people as of this writing. ::sigh::
06:36 Dumb question time: Why would you create objects when you can use indexed variables instead eg dogs[0] = ("terrier", "Rusty".... etc) and then iterate over all dogs; dog_breed[dog] = dogs[dog][0], dog_name[dog] = dogs[0][1] ...etc.
Mostly because you are teaching OOP at the monkey-see-monkey-do level. A serious CS professor would not introduce it this way and there are examples of CS courses that deal with programming paradigms out there that explain these things far better. This is basically amateur level and what this will produce will be amateur programmers, at best.
I disagree that a pure functional function cannot use temporary variables on the stack. A pure functional function doesn't affect and isn't affected by global state. Side effects can occur when a function reads from and/or writes to global state. This can be shared global memory, memory mapped peripheral, IO, etc. This means function A might not always return the same output given the same input and a call to function B, might affect the output of function C. Some functions lack inputs and/or outputs. Order of function calls matter. The entire system can become a complex implicit state machine. A pure functional function can use stack (or even heap or static memory) as long as it doesn't affect or is affected by global state. Real world programs have external inputs and outputs and can therefore never be pure functional and require non-pure boundary functions. You can, however, implement all the logic in a pure functional way and put all state in data structures. If you count time/CPU tick as part of the global state all functions have a side effect as they take time to execute and delay functions do this intentional. Many systems have timing requirements. Even a simple user interface, but also real time control systems.
What if I need a new type of object which is a Monster dog object oriented programming will fail but functional programming can do that quickly using composition
I'm not sure what you mean, as (taken as it as written) your suggested requirement is easily accomplished in OOP. If you're working with a language that supports multiple-inheritance, you could simply inherit from both Monster and Dog. If you're working with a language like Java, you could define Dog and Monster interfaces, and then implement both in a MonsterDog class.
@@MortiferGnome no, modern languages I use do not support multiple inheritance as it was creating issues in old languages. Interfaces are just a group of undefined methods, if I implement the interface in two classes I have to define the same methods at two places. But in functional programming, this is very simple.
@@14vincentlabbe I completely disagree with you. I have decades of experienece with these technologies old and new. For how much time you are practicing these? And are you saying companies like Facebook are wrong who have changed there frameworks from class based to functional?
@@karansamra About 5 years. I like ReactNative for my side procject and i like React as my job. But I think Facebook create this framework because they were having difficulties to hire good programer that was able to write good quality OOP.
Can you make explanation on how Objects/Classes are actually working - meaning...the functional bare bones behind the abstraction? Everybody explains pointers with memory diagrams but nobody cares to elaborate on internal logic behind Classes. Which I find very useful for understanding the concept and use.
Ok, so, completely an infant in regards to these matters. It's why I'm here. I'm 3:37 in and see that the computation is made and returned without creating additional variable names to store, calculate the result, then return it. However, to say that "no side effects" makes me scratch my head. Obviously x and y are variables and they are stored and acted upon as well as the "return" value has a place in memory as well right? I could see how the functional method would be cleaner and I'd assume faster, etc.... I like the style for it's readability alone and of course, less code.
Brother, C language is also a procedure oriented programming but it does have or rather I would say it heavily relies on side effects, without side effects a procedure oriented programming cannot exist ! Consider strcat helper function (string.h) which lets your first argument's value changed, that's a side effect !
at 2:40 you explain that FP is all about writing one liner functions ? Mate this is a great topic but you need to correct this video that will confuse students !
A typical program today has tens of thousand to millions of lines of code. Imagine a FP implementation that has tens of thousands or even a million different functions... ;-)
Functional programming doesn't exist. A program needs to return, at least, one output. That's a side effect. In practice modern software often has to produce thousands, sometimes millions of side effects per second. The requirements for that alone violate functional programming principles. The squared sum example is also idiotic. If your compiler is any good, it will return exactly the same optimized machine code. In general, trying to force FP purity in the program code completely misunderstands what is happening on the machine level. The use of intermediate variables is usually for purposes of documentation. Breaking a long algebraic expression into several sub-expressions that get combined in a final step is usually much better than to rewrite the whole thing as a function of functions that then will pass values over the stack.
Great video. I still dont think anyone on YT has a clear answer on what functional programming is, all these youtube videos ive seen and you are the first one tht summed up the idea of functional programing by basically saying dont waste a "variable" in a method(). Even now im still confused tho.
Key is the dominance of functions. He made that clear. Second is avoidance of "side effects", so the logic of the program can't be interrupted or distorted by those effects. Further into it is abstraction of various kinds. It's hard to explain beyond that without hours.
That's not entirely true. The main goal of FP is to eliminate side-effects with a focus on immutability. There is pure and pure enough. You also have to think about current state and a new modified state. FP seeks to retain both states.... For example, the sum of 2+ 3 = 5, that's one state. The new state is that state squared. It's easy to do with math via declarative programming (Are you going to split hairs about that). Not so easy to do with files. For example take a series that has number values as strings. Guess what? You can't sum the value "5" + "5.01". Even with this (two strings) you have two different data types (5 which is int and 5.01 which is float or decimal).
To play devil’s advocate a little bit, storing the result of calculations in variables isn’t exactly idiomatic functional programming since it’s more imperative than declarative so I kind of see what the thought process was but it was explained rather poorly
I strongly object the idea that allocating memory to local variables is a side effect. If that were the case, NO programming language could achieve zero side effects.
Local variables are stored on the stack of function calls. Once the call is done, all local variables are wiped off.
"Side effect" means causing changes to variables outside the scope of the function (by means of assigning different values to global scope variables, or member attributes of input parameter).
Thank you for the video but please improve the example.
I guess it technically creates 'side-effects' in es5 when declaring with var due to hoisting. But yeah, bad example.
I reckon introducing OOP first then showing how modifying object fields with methods is a side effect.
@@ALLIRIX Well, hoisting is done within the function scope, so it does not matter, it does not create side effect.
I thought I was crazy when I heard it them being called side effects and disagreed with it.
this is like comparing:
a, b = b, a
and
c = a; a = b; b = c
The difference is that in second case this helper variabie has to be declared explicitly, while inn first case it is only internal. But it is still here.
Actually, 1st case requires more memory since internally a tuple of 2 variables has to be allocated.
I agree with @kahn and question the video's labeling the local variables as "side effects". But I still like the video's presentation.
... That's simply not how it works. Creating a new variable inside the function itself that doesn't even get muted afterwards is not a side effect. Both functions were functional approaches.
What matter is that every function is determined only by its inputs and the inputs are not altered in any way.
Also the variable-less version probably compiles to exactly the same machine code. The computer has to add x and y before squaring it, and the result goes somewhere - leaving registers aside for argument's sake that somewhere is going to be the stack, which is just memory.
@@Toon81ehv That's what I was thinking.
@@Toon81ehv We need to be at an other level that just "compile to assembly language" or something like that.
The problem about thinking with the code produces is : semantic is not important, we have the same output.
In fact, restrict us to ours computers is very, very restrictive when we talk about programming language.
Think with semantic, not code produce ;)
@@simonhauguel9806 the point of the video was that the computer generated machine code would cause problems in function written in 'non functional' way. That's just not true cause most likely similar machine code will be generated in both cases anyway.
Memory increase doesn't count as side effect in FP, otherwise, just calling a function would be a side effect.
Yes, the example of FP vs Imperative is horrible.
Besides the technical arguments made here, it promotes the anti-pattern of inlining the body into a single expression where the multi-line form might be much more maintainable.
Someone new to FP is going to create inscrutable nonsense doing this.
@@r0bertdenir0 Besides, how is the FP even implementable using, for instance, C language as the example shown here in this video, if I want to calculate the squared sum of two inputs ?! Is it even possible to implement this function using FP and without using any further variables inside this function ?! How may I even implement the square mathematics using programming ??
Does this TH-camr have at least a basic grasp of computer science? Under his definition, the computer sitting idle creates side effects, since the kernel is constantly changing the state of the program. Aside from the silly memory increase as a side effect, he doesn't even grasp that the inlined function and its expanded form are identical. The compiler will optimize away the variables needed for storage, if they can fit in the available registers. I hope no one is watching this video thinking the number of lines of code translates into more efficient code.
@@bobweiram6321 100% agree. Back in the day there was an impetus to minimize the number of characters used, since each one takes up 8 bits, and so there were physical limitations on the length of code prior to compiling, but those limitations are decades gone. Popping stuff in and out of the stack in creative ways was a skill worth having when people had to address registers directly, and as a recreational programming activity it still has some value. But you are correct, the interpreter or compiler doesn't care if you're creating tons of local variables, and doing so is actually good practice in my opinion as it makes the code more readable without overburdening it with comments.
I'd much rather write and read:
for item in masterlist:
paintlist = [ ]
name, sku, loc = item[0], item[1], item[2]
paintobj = PaintObject(name, sku, loc)
paintlist.append(paintobj)
return paintlist
Than
for i in mlst:
plst = [ ]
plst.append(Pnt(i[0], i[1], i[2]))
return plst
They do the same exact thing but good lord is the first one legible. And actually the first one would be better if it used name, productID, and location instead of name, sku, and loc, but a certain amount of abbreviation and lingo is not too wild in this context. You can clearly glean that I'm generating a list of physical items, probably paint products, I'm doing so as objects (in this case dataclass objects in Python) and ascertaining their real world locations, probably for the purpose of fulfilling an order. Even line 2 of the for loop could be 3 individual lines if I really wanted to spell it out.
The second one saves no memory, doesn't run any faster, and is only cryptic for the sake of being cryptic. name, sku, and loc are not only vanishing locals, they're also the names of the class attributes I'm assigning. I can do it blindly and have "no side effects" or I can be verbose and have confidence that another person could piece together wtf is actually happening. Nothing touches the global scope. No "side effects".
Good code reads like an instruction manual for that code, and I'm not talking about comments.
When the person creating the video cannot get even the most basic concept he's discussing correct it says alot about these paradigm debates.
Imperative programming (OOP) tells the computer how to do something, step by step.
Declarative programming (FP) tells the computer what to do, without specifying how to do it.
So where is the declarative compiler that can convert "Write a website that gets visited 100 million times a month and makes $5 million in revenue!" into the desired product? ;-)
A side effect would be mutating a global variable from inside a function, but since the variables defined are in the scope of the function, it isn’t really a side effect...
Dude if you know FP why are you here? Everyone's copying the same comment about the side effects
@@cristianjuarez1086 That's because it's such an obvious piece of information that everyone is amazed the video creator didn't know this / it reveals that they have no clue what they're discussing.
@enderstenders96 yeah you learn this in like... CS 101
Sorry but in the attempt at simplifying the topic ambiguity has been introduced. The side effects highlighted in the first example are only there because the scope of the variables extends outside the function, which was not explained . If the variables in the imperative example were declared inside the function their 'side effect' would be virtually zero. Yes memory would be used but memory is also being used to store the input values x and y as parameters. There is a good explanation of OOP but using classes is not the means of implementing OOP.
However, the answer is to the question is sound, one paradigm is only better than another in specific cases. There is also the possibility that a blend of both might result in a better solution. Being aware of the strengths and weaknesses of both approaches is what is important.
Finally, dark blue text on a black background is not a good combination for reading.
Well, as everybody has already pointed out the "memory side effect" error. I will add that the concept of not having to write the same code over an over again is called ABSTRACTION, and it's a feature that literally every single paradigm has, it's not a thing of OOP. The funniest thing about this video is that it's said to be "for dummies" lol, should have instead been "by a dummy"
Try to do a better video on this topic. I'll bet it's nearly impossible.
@@markhathaway9456 Not only it's not even remotely impossible, but litteraly every programmer who has relatively advanced theoretical knowledge would know what I said. And talking about bets, I would bet there already are better videos than this one, only we didn't see them yet
Instances of classes are nominally typed by a class, but inheritance is a relationship that exists between classes, not classes and their instances. So the `Dog` class might inherit from the `Animal` class, then an instance of a Dog class is also an instance of the Animal class. Inheritance creates a type-hierarchy (sub-types).
In the same way that a function allows code reuse without including it whole in a program, the OOP system lets you create multiple things of a "type" without rewriting a ton of code. Techniques to allow code re-use are commonly good things. Concepts like "type", "inheritance", and "pure" functions is tough to relate to anyone in a short video.
Using variables inside a function is not a side effect. Side effects are effects that could change how the function works depending on external factors, like network, filesystem or random memory access.
Hold on a second! Calling a function pushes the return address and the arguments for the function into the stack memory. CPU resolving the formulas like x^2 is also using some memory for temporary storage of values during calculation. Hiding it all from a programmer sounds more like a psychological trick to me, not as a technical solution for sure. I'd rather have openly declared memory usage as a variable than having it done secretly behind the scenes pretending there are "no side effects". Pushing everything into the heap or stack is no different. It is all memory anyway.
i dont like that shutup
@@basicoverflow555 LMFAO!!!🤣
In case you have been sleeping for like, the past 50 years, plenty of mainstream languages hide memory allocation from you. because it's just not relevant for the programmer whether X will be allocated on the stack or the heap. according to you we should all be writing assembly code because register allocation is a psychological trick, go back to your cave Cnile
In either case, I think it doesn't "count" as a side-effect because the variables will probably get deleted automatically. Either the machine code that is used to calculate (x+y)^2 will write over, if not separately delete, the intermediate variables, or the programming language will do that after the function call is over. I'm not sure, though, and it has to do with how the programming language compiler/interpreter works.
3:24 I don't know. I think its much easier to understand functions with the steps laid out than a function that does things in the fewest lines of code possible (obv context dependent)
A Struct and an array can accomplish the same thing as the OOP did here to create a small database of farm animals, OOP isn't needed.
It is kinda mentioned in the video but I think it's important to highlight again that OOP focuses on object creation and inheritance. FP focuses on pure functions and isolating side effects (including application state). Since they solve different problems it's actually possible to use classes and mostly pure functions simultaneously. Other, different solutions to object creation, inheritance, and particular side effects like state management exist as well. Furthermore, it's possible to program in a 'functional style' in languages that mainly support OOP. And though it's extremely awkward and generally unadvisable, it's possible to produce object-oriented code in a functional programming language.
You can focus on pure functions all you like, in a real program you cannot eliminate the need to manipulate persistent state, that's why the functional programming paradigm was abandoned 50 years ago.
@@ianrust3785 pretty sure the reason FP didnt catch on is b/c high barrier to entry. Very confusing to learn. You can just use monads like haskell's IO to encapsulate side effects like mutating persistent state. knowing that all state changes can only happen inside like 5% of your codebase while most of your code is pure functions means that you have tests covering all possible edge cases for 95% of your code. no deps, runs quickly. Then you can write integration tests on the remaining few or debug. Splitting up your data access from your business logic is also a "best practice" in OOP because we all recognize the advantage of not being able to mutate all over the place. In other words, you get this benefit if you use a functional style in oop code too
Don't local variables in functions usually get flattened in modern compilers?
That what I was thinking
Composition can be used in functional programming to resolve second issue of repeat code
my ice cost more than yo house
Not only that, nowadays, composition is considered the better approach in OOP languages as well, especially for game development.
People confuse functional programming with functional-reactive programming and functional UI frameworks. Functional programming is a paradigm that predated OO, it was used mainly in the 60s and 70s. A functional program is just a giant hierarchy of functions which executes continuously until all the functions return.
In pure functional programming (which is more of an ideal than an actual programming paradigm) there is no persistent state, only local state. Just functions with inputs / outputs but no side effects. As the functional paradigm evolved it became clear the ideal of pure functional wasn’t practical, and programs came to rely on more persistent state, which was usually global, though could also be non-local hooks.
There were alot of problems with the functional paradigm which OO helped fix… The fragile top-level interface is one issue - when your program is just a giant function hierarchy, any change in an interface near the bottom tends to ripple up to the top, this makes changing the code difficult and require extensive refactoring. Different parts of the program accessing shared state meant extensive lifecycle management and/or locking became necessary. This state was also not encapsulated - and the data was separate from where it was used, this increased complexity. It leads to a spaghetti-code situation as the codebase grows in size / the amount of this persistent state increases. OO fixed these problems to a degree with encapsulation, lifecycle management, and polymorphism, but introduced a new problem - encapsulation means that the distributed local state is now persistent, so we now you have to go to extra lengths to maintain consistency. There’s also alot more persistent state to deal with.
Functional reactive uses data bindings to drive updates to the distributed state of a graph of objects, to bring their state into consistency. These components are objects - regardless of whether your UI framework provides a functional API for creating them or not, behind the scenes they’re objects. Functional reactive programming is basically a remedy to problems inherent in OO. It is not dispensing with the OO paradigm, without OO it has no useful purpose. And it’s a completely different programming model than that of traditional functional programming.
The word functional in functional-reactive is referencing the fact that functional-reactive programs glue together components into a cyclical data flow and drive updates, doing functional transformations at different points along the way. State also remains consistent between components, which connect together seamlessly, similar to traditional functional programs - you have persistent distributed state, but it no longer behaves that way.
There’s also this idea that state should be immutable and the data structures should have value-semantics, and languages have been adding support for this. State behaves more like a local copy this way, you don’t end up with bugs from multiple threads accessing the same data during the update cycles.
With FR we’re augmenting OO with all the best characteristics of traditional functional programs - we are getting the best of both worlds now.
Functional UI frameworks are leveraging the ideas in functional reactive and providing a higher-level functional interface for creating UIs. The isn’t a reversion to the functional paradigm, or the introduction of a new general programming paradigm- you can build up a framework to provide any kind of API you like, we even have frameworks that allow you to construct your UIs using a GUI, but these frameworks are still just decorating a composition of objects and managing that state behind the scenes for you. That works within the limits of what the framework can create - it’s not a generic programming paradigm.
Also… Javascript has its own unique reasons for not wanting to use objects, but that’s a language issue. Better designed, modern languages like Swift have powerful data structures with value-semantics which work very well in these contexts.
Functional reactive is serving its useful purpose when combined with OO. Its purpose is to keep distributed state consistent. People who argue for choosing functional over OO… don’t really understand what functional reactive is and what makes it valuable.
I’ve also seen an increasing number of programmers arguing for reverting to the bad programming techniques of the 60s and 70s lately, which is not good. I’ve done a little work in a codebase written by some devs resuscitating the old functional paradigm... I joined their team to help out because they were falling behind other teams. Looking at the code.. it became clear why - they’d just created a monolithic procedural mess in an attempt to be functional, convinced they were being innovative. Their code couldn’t adapt to our new use cases… it’d take 6 months to clean up the mess.
Parallelism and atomicity have nothing to do with either OOP or FP, though, and one should not mix different problem dimensions in such a clumsy way. Your comment about locking doesn't make any sense to me. Explicit locking IS NECESSARY. It's unavoidable if we have to deal with limited machine resources (like file IO) and of we don't do it, then the operating system will usually do it for us (and often not in a good way). This is a matter of architecture, not of programming paradigm. The idea that a coding style can get us around the hard problems of resource management is absolutely ridiculous. And don't get me started about what both OOP and FP are doing to memory layout (hello buffer overflow attack!) and cache misses (goodbye performance...).
@@lepidoptera9337 "Parallelism and atomicity have nothing to do with either OOP or FP, though, and one should not mix different problem dimensions in such a clumsy way"
Of course they do, one of the biggest touted goals of functional programming was to eliminate, or at least minimize, the need for application state - because pure functions don't mutate state - and in so doing one eliminates the possibility of race conditions.
You're correct that you will still have some application state in a functional program - that inability to eliminate state is the point of the post, this demonstrates the failure of functional programming to achieve its goals in most systems.
"The idea that a coding style can get us around the hard problems of resource management is absolutely ridiculous."
Yes, except that was your stupid interpretation, not anything I said. Nowhere have I even suggested this.
It is nice having all this info in one video, but I will say it took me several years to understand this concept. I don't think I would have understood this as a beginner programmer because I lacked the knowledge and experience.
Are you sure you understand this concept? if you think this video tells this concept correctly please think again.
This video presents many incorrect information, be careful
i'm new to programming. This was the best well-spoken presentation with visuals. thank you. i want to learn more about programming one day so that I can also be arrogant with the rest of the programmers on programming comment sections as well.
The only reason why you think that this was good is because you are new to programming and you don't know frell about it. You also have a lot to learn about arrogance. ;-)
too bad this explanation is not only incomplete but is also incorrect.
Most comment sections are actually helpful, the information in this video is incorrect which is troublesome because it has 65.000 views
me when I purposefully spread misinformation on the internet :
You could go a step further with the sum of squares and eliminate the arguments as well by using function combinators. (define sum-of-squares (psi + (w *))).
And you can reuse code between different objects through function combination and bundle it with data through closures or partial application. Any of the techniques for reducing reuse in OOP can be done in functional programming.
i'm new to programming. so far i got this: oop is like a central management and distribution of methods and properties; but when you encounter vast number of unique and independent species in a world (like the world of animals), you are forced to describe each animal as a class(or may be you can expand the properties & methods of the parent class equivalent to the world of animals and make it available to all). good thing is that you allowed yourself to create (photocopy) n number of objects out of it, because of it everything got streamlined; when you change the definition of properties and methods of the parent class, all the objects reflect the changes beautifully(only you have to have a consciousness to understand that implications are on broader level) . oop asks you expand your knowledge on the subject from the beginning as opposed to functional programming which is problem specific (you can think for the new problem when it comes); I think its extremely difficult to keep the tracking of functional programming based project because it looks like a maze of independent functions somehow interconnected and working (useful for small requirements, definitely not for large problems). please correct me if my understandings went wrong!!
Yes, it's nothing like that. ;-)
@gugahaker2112 First time I see OOP and spaghetti in the same sentence, but it's spot on. Two thumbs up.
@@gugahaker2112 That's exactly my experience with OOP. An old and very respected programming pro told me once to pay close attention to state and to keep it all in one place (or as few places as possible). My code has become significantly better since I have been practicing his advice.
In the minute 3:37 you mentioned no side effects on computer memory when using functional approach however, I F# language and haskell functional approach does effect on computer memory for the sake of processing input data as per their explanation of how functional programming works. Your words had got me so close but I had to read and search for this piece of info just to see if I am in the correct paths. Dude thanks for your efforts yet I suggest full review and auditing your functional programming understanding.
Peace 🙏
The functional side effect example is a bit janky but there are some compilers which still do variable assignment like that, I suppose.
Here are my 2 cents:
Both OO and FP are structured paradigms. Structured means that program flow goes along clearly noted boundaries. Unlike some languages in which you are able to do anything. The strictly structured nature of modern programing languages does not particularly protect you from creating a ball of mud, but it makes it a bit harder.
The main difference between OO and FP is how the handle data. In a functional system you input the data to get the result, in an OO system you incorporate the data. Both paradigms let you easily create extendable applications. However FP does not handle changes very well. Subsequently, OO is designed to manage side effects but it can be less stable as a result. The mutability problem also brings into question performance. In general, stateless applications need to be fed with data which inevitably leads to extra memory operations which can incredibly costly without a well designed pipeline. OO does not have this issue.
As for the real world. If you have a problem and need a robust solution, FP is the way to go. There are plenty such cases within a project. But generally speaking, again, in the real world, problems, solutions and desired outcomes change. Therefore, on the surface, OOP is the only viable option.
There is a very good chance that the two following codes will produce the exact same executable code:
function f(x, y) { var sum = x + y; var sqr = sum * sum; return sqr }
function f(x, y) { return (x+y)^2; }
Compilers have optimizers that rewrite your code completely, in order to either store intermediate results when needed even if not explicitly written in the original code, or simply get rid of intermediate variables when they are not needed.
Besides, OOP is more about encapsulation and polymorphism than inheritance. Inheritance is of course part of it, but the main point of OOP is to have a black box that does something with some input in a certain specified way, while another box will do something else with it, while both are called in the exact same way.
How does declaring variables inside the scope of a function qualify as a "side-effect"?!
Unfortunately the example of side-effect in this video is incorrect. This is not side-effect since sum and squared are local variables and they are not changing any external state. In fact it is recommended to program like this to make the code easily readable. To make one liners like in the example is also bad approach. It works for calculating a simple square but real life functions are way more complex and can't be written so simply. In this case if sum and squared were global variables, then it would be considered side-effect. And side-effects are not always bad, sometimes functions do need to change external states.
So removing variables, which diminishes readability and makes it hard to access values during debugging, is a great solution against bugs and for large-scale projects? I don't think so ...
Nice explanation and comparison. The developer's favorite refrain: "It depends". :)
Terrific graphics and presentation.
Smalltalk was built with Lambda expressions and it had first class functions. Smalltalk inherited many ideas from Lisp. On the other hand, Lisp (and Scheme) had extensions for doing OOP. So in practice, the distinction between OOP and FP is not always so clear.
That's just syntax. The difference between OOP and FP is NOT syntax. It's where the compiler keeps your data and how you access it, but almost nobody who talks about these paradigms seems to understand what this is really about: scoping and memory layout. Neither OOP nor FP are addressing these issues in a rational manner.
As soon as the imperative example was given as an example of non-FP function i just tought "oh these comment section will be ruthless". I wasn't quite correct, but yeah, people were quick to point it out :D
fvcking awesome. Loved the video, Explanation is clear with easily understandable examples that drive home the point even further.
I'm subscribing.
Perfectly explained. Thanks literally. Good work 👍
Thank you so much for the simple explanation and very-well illustrated video!
I see that you've taken a lot of flak about side-effects. Nevertheless, if we concentrate on the OOP portion of your video, I think it is EXCELLENT -- a wonderful and much-needed explanation in plain English that demystifies the creepy, sententious, ivory-tower jargon of OOP itself. A great public service for the novice!
The dark blue text on a dark grey background is a little hard to see.
One small feedback, text colors are too dark over the dark background and it makes it quite hard to read
i dont like that so shutiup
It would be interesting to see how the dog example would typically be done using functional style only. How is the state changed in an acceptable manner in FP, nobody ever mentions this
This is why dislikes should be visible.
The basic idea of OOP is not a blueprint but messaging. The communication between components of a program.
That's bullshit.
@@lepidoptera9337 That's what it's creator Alan Kay said: messaging. He thought the "aggregation of data" in an object was much more common knowledge and not so profound, but it's still a huge part of OOP.
@@markhathaway9456 Dude, you can easily write OOP in plain C using structs and function pointers. C++ implements OOP with preprocessor operations. By the time the C++ preprocessor is done with your OOP code it's already reduced to trivial function calls. There is absolutely no "messaging" in any meaningful sense of the word going on. Any compiler that implements OOP with real messaging does only two things for you: it wastes most of your CPU's cycles on absolute bullshit and it makes your program virtually impossible to debug. In the arts they call that "form over function" and throw it in the garbage.
I think the text colour should be changed for better contrast.
Anyway, nice video 👍
Thanks for the feedback!
Great explanation, detailed yet easy to follow. I look forward to seeing more of your videos. Keep it up!!
The final part was so fresh.
You made me subscribe you so quick..! Thanks man.. you cleared 02 doubts..
FP and OOP
&
Method vs functions.
You can totally apply Functional Programming within OOP, I mean if you need to get the sum_squared, there is no reason to not apply the ideas of functional programming
Yes, and none of that is a valid example to explain to you the problems of OOP and FP, which is what you really need to understand to avoid them.
This...doesn't feel right. Something is off.
From my point of view there is a reason for intermediate variables, and in fact it has to do with the intermediate variables in a function actually being used for debugging purposes. Let's a a function actually has ten steps. Having intermediate variables helps the programmer to step through each step and validate the variables as they are being processed. If there are conditions within the function, such as IF step 2 results in a value greater than 0 THEN do Step 3 like this, otherwise do it like that, then having the intermediate variables for debugging is actually helpful, and without them debugging would be more difficult, not easier. So I'm not sure I buy the argument that functions without intermediate variables improves debugging. At least not in all cases. Where the function is executing a simple formula, then yes, ok. Otherwise, not so much I think.
The FP version of the animal game example is very much a strawman argument. No sane programmer would write a full set of functions for each type of animal, and certainly not for each individual. You would rather save the state of their various attributes in arrays (or similar data structures) and then have shared functions that update those states on each cycle of the game loop. So you would only have a single "update_position" function (for example) that would iterate through all animals and recalculate their positions. If you need to create (or remove) animals, just add or delete them from the list of animals that the draw function iterates through. Then they would either be drawn or not drawn on the next frame. No OOP required. There are certainly arguments to be made for OOP when it comes to organizing larger code bases, but in general, it does not reduce the amount of code that needs to be written. For smaller games, I would even say that OOP is an unhelpful abstraction. The ubiquitous game loop actually lends itself very well to functional programming.
It's a good video, but it leaves out some crucial things like mutability-immutability and polymorphism.
It would've been useful to show the farm game example approached in OOP as well as FP, to actually see how they would differ. No programmer would just write each new animal from scratch if they were using an FP approach.
There are already too many comments about "variable = side effect is wrong", so isntead I would disagree with OOP example against FP example comparison.
At first I thought that so called "Blueprints" talk will be about inheritance, but it's just about classes.
And there's no difference between OOP and FP, there are custom data types or records in functional programming.
I believe F# or Scala support constructors, or you can create a simple pure function which accepts a bunch of required arguments and returns a new Dog record with initialized attributes, so it's the same one-line way.
As game developer I can say that real reason why FP doesn't fit well in games isn't because of some language stuff, when you need to start each animal from scratch (even the same one), but because game is by nature requires a lot of state which mutates over time and which often queried from different places, and also because games have strict performace requirements, so immutability in most cases isn't possible and side-effects are essiential.
What about procedural?
All programming is procedural. Even functional programming is, it's just a very screwed up way to program procedurally. ;-)
Why didn't you explain the farm example with FP style??
Because he doesn't seem to understand either fp or oop.
Sorry, side effects are long lived variables, database operations, sending emails etc... not memory allocation. All running software allocates memory
This is why a pure FP solution is more theoretical than actual outside of mathematics.
The real goal in FP in real life is to be aware of the side effects so to reduce their occurrences in your code in a logic and consistent manner. This will allow your code to evolve and take on new requirements with little or no further side effects.
How is sending an email a side effect if that is the intended function?
@@BiologyIsHot Its really a definition thing, a function should be repeatable, consistent and not modify mutable data. Any form of IO is thought of as a "side effect" or a "procedure" as it breaks deterministic repeatability and consistency
Getting back to your question, the sending an email is an IO interaction, any IO interaction is non deterministic so breaks the functional paradigm. An exception will be reported if the email server is down for example, and how do you know if the email was ever delivered?
Off course we need side effects. Our software would be pretty useless without them, which is why no software is functional in its truest form, however limiting side effects is a good idea by limiting the areas of code where these touch bases happen
So an acceptable solution to email sending would to write a function with side effect that sends an email. This "procedure" should be responsible for sending a single email, and should be used to send all emails within our system. We need to limit the number of areas where this code is called, as any "function" that calls this code loses its functional status by definition.
Being aware of side effects in a functional paradigm makes you think a lot about how you design your code.
shutup
Well that is certainly a take. 🤣. I'm not wrong, so i won't "shutup". I imagine if your content was more accurate people wouldn't be correcting you
3:15 beyond your overly-simplistic “side effects” variable-setting example, there may be a problem with how you are naming methods at your corporate dev job that may be causing ongoing development issues and on-boarding problems
what if we could reconcile the two and perfectly control spammed blueprints at high speed with no side effects and always achieve the result desired?
Using Dark Blue on a black background was a bad choice. Have to crank my monitor brightness just to see the text and I'm still leaning in.
Let me say something that is really cursed: My code often contains both functional and OO formats. This however has its own reasons.
When calculating for example the distance between two coordinates you will use the Haversine formula.
Using an OOP -language, would you create an object only containing the calculated distance, or would you give it directly to an edge of an ADT Graph?
In these instances I voluntarily switch to functional programming, since the named mathematical formula IS isolated from the code to start with, but used like a package. In Java the Class Haversine would thus contain no fields but the methods Haversine and Archaversine which both only return values. It can therefor be declared as a static Class.
This approach could be due to a background with functional languages before taking a step into OOP. So what do you think about that "hybrid" Code?
other than the FP part, the explanation is clear and excellent.
Hmm, but when translating to assembler or machine code, won't there be side effects or the use of variables in the stack?
this is the worse compare fp vs oop what i've seen, sorry
from what you called a side effect to what you said about classes. You can't create animals any other way. You certainly don't know anything about functional programming.
good explanation on why OOP is useful for creating multiple objects of similar code
though feedback for improvement, the video colors, text color to bg color could stand to be more contrasted. It's hard to see the blue font on the dark blue bg
One does not need OOP for that. Procedural libraries can do this easily. The factory pattern is completely independent of OOP syntactic sugar. A trivial example in C would be a function prototype like animalType* animalFactory() for a function that allocates the memory needed to store the data about an animal and that returns a pointer to that newly allocated memory. Technically OOP languages are all just syntactic sugar. All Turing complete languages are identical in what they can express. The main "invention" in computer science, if you will, is that of the pointer or, to use machine code lingo "indirect addressing". Once you have that, you got all of this. What an OOP language does for you is slight automation of name spaces for your type hierarchy. It's a completely trivial process that can be easily emulated with naming conventions. What all of this means, in the end, is that your compiler strips any and all OOP information out of your program... your CPU does, after all, not speak objects. It only speaks "indirect addresses". :-)
I have a very importan question!! Why is the dog's name "Porky" and pig's "Roady"??
Can somebody please help me !!!
I'm totally confused between what to use for my big project building from core PHP without any framework
I can easily make small scale websites using simple function based PHP codes and it works pretty well for me
But I'm still learning OOP in PHP but will it make any difference in performance or devlopment speed ???
It's best to have both in one function object like with C++ lambdas or function-objects.
I had been a good idea to see how long is the code for this farm example by written in both in FP and OOP, asumió the case scenario of multiple different & similar animals coming in to the farm.
good content, but the color of the font makes some text almost impossible to read
Didn't see the point in continuing after his initial description of local variables causing side-effects was blatantly wrong.
Combination of dark blue text on black background is not a very good mix for reading, and for youtube compression. Compression just crushes this colors together making it hard to read. Even if it looks good in editing software it doesn't mean that it will look good on the internet with compression
Dude, you really need to brush up on how compilers work. Your examples of functional and non-functional plus/sum will yield the exact same code. There is no side effect or “leak” occurring. And I see you’ve misled at least 5k people as of this writing. ::sigh::
I finally got it, so oop is just giving a template format for objects instead of using individual functions or fp
No, you didn't get it. ;-)
Breaking down the steps in to two is not a side effect. It is just cleaner coding.
I don't understand the use of classes, I always just used structs in c, does that I'm a oop programmer?
You can think of classes as structs with functions - which are then called methods.
@@TheTruthAboutLemmings Yep, that's where it came from. C with Classes was something like that.
06:36 Dumb question time: Why would you create objects when you can use indexed variables instead eg dogs[0] = ("terrier", "Rusty".... etc) and then iterate over all dogs; dog_breed[dog] = dogs[dog][0], dog_name[dog] = dogs[0][1] ...etc.
Mostly because you are teaching OOP at the monkey-see-monkey-do level. A serious CS professor would not introduce it this way and there are examples of CS courses that deal with programming paradigms out there that explain these things far better. This is basically amateur level and what this will produce will be amateur programmers, at best.
I disagree that a pure functional function cannot use temporary variables on the stack.
A pure functional function doesn't affect and isn't affected by global state.
Side effects can occur when a function reads from and/or writes to global state. This can be shared global memory, memory mapped peripheral, IO, etc.
This means function A might not always return the same output given the same input and a call to function B, might affect the output of function C. Some functions lack inputs and/or outputs.
Order of function calls matter. The entire system can become a complex implicit state machine.
A pure functional function can use stack (or even heap or static memory) as long as it doesn't affect or is affected by global state.
Real world programs have external inputs and outputs and can therefore never be pure functional and require non-pure boundary functions.
You can, however, implement all the logic in a pure functional way and put all state in data structures.
If you count time/CPU tick as part of the global state all functions have a side effect as they take time to execute and delay functions do this intentional. Many systems have timing requirements. Even a simple user interface, but also real time control systems.
What if I need a new type of object which is a Monster dog object oriented programming will fail but functional programming can do that quickly using composition
I'm not sure what you mean, as (taken as it as written) your suggested requirement is easily accomplished in OOP. If you're working with a language that supports multiple-inheritance, you could simply inherit from both Monster and Dog. If you're working with a language like Java, you could define Dog and Monster interfaces, and then implement both in a MonsterDog class.
@@MortiferGnome no, modern languages I use do not support multiple inheritance as it was creating issues in old languages. Interfaces are just a group of undefined methods, if I implement the interface in two classes I have to define the same methods at two places.
But in functional programming, this is very simple.
@@karansamra Then the problem is your mordern languages not OOP.
@@14vincentlabbe I completely disagree with you. I have decades of experienece with these technologies old and new.
For how much time you are practicing these?
And are you saying companies like Facebook are wrong who have changed there frameworks from class based to functional?
@@karansamra About 5 years. I like ReactNative for my side procject and i like React as my job. But I think Facebook create this framework because they were having difficulties to hire good programer that was able to write good quality OOP.
This explanation is wrong. The guy doesn't understand the topic at all. Please be aware
th-cam.com/video/wyABTfR9UTU/w-d-xo.html
This is a trusted source
This is so good! Can you make a video on procedural programming too?
this explanation is not only incomplete but is also incorrect.
Would Please add procedure-oriented programming ?
Can you make explanation on how Objects/Classes are actually working - meaning...the functional bare bones behind the abstraction?
Everybody explains pointers with memory diagrams but nobody cares to elaborate on internal logic behind Classes.
Which I find very useful for understanding the concept and use.
The "internal logic" of which you speak is somewhat like electricity. Don't worry how it works. Just use it.
Ok, so, completely an infant in regards to these matters. It's why I'm here. I'm 3:37 in and see that the computation is made and returned without creating additional variable names to store, calculate the result, then return it. However, to say that "no side effects" makes me scratch my head. Obviously x and y are variables and they are stored and acted upon as well as the "return" value has a place in memory as well right? I could see how the functional method would be cleaner and I'd assume faster, etc.... I like the style for it's readability alone and of course, less code.
Thanks, you explained it better than other videos on this topic!
This is so good explanation!!!
not to be obtuse, but what you mean then is to put objects and then operate?
I think defining a local variable cannot be a side effect. Side effect happens when we change global variables.
On a real computer even a local variable creates side effects. It changes the memory allocation and timing of the program.
Crystal clear explanation.. Thank you.
Except it's wrong
Brother, C language is also a procedure oriented programming but it does have or rather I would say it heavily relies on side effects, without side effects a procedure oriented programming cannot exist !
Consider strcat helper function (string.h) which lets your first argument's value changed, that's a side effect !
f(x) = x + 5 is not high level calculus wtf... mathematics is very important and please give it the respect it deserves
at 2:40 you explain that FP is all about writing one liner functions ? Mate this is a great topic but you need to correct this video that will confuse students !
A typical program today has tens of thousand to millions of lines of code. Imagine a FP implementation that has tens of thousands or even a million different functions... ;-)
Functional programming doesn't exist. A program needs to return, at least, one output. That's a side effect. In practice modern software often has to produce thousands, sometimes millions of side effects per second. The requirements for that alone violate functional programming principles. The squared sum example is also idiotic. If your compiler is any good, it will return exactly the same optimized machine code. In general, trying to force FP purity in the program code completely misunderstands what is happening on the machine level. The use of intermediate variables is usually for purposes of documentation. Breaking a long algebraic expression into several sub-expressions that get combined in a final step is usually much better than to rewrite the whole thing as a function of functions that then will pass values over the stack.
Superpower: using both FP and OOP together.
1:59 ^ is xor
The font is really hard to see
2:20
define squared_sum (x, y):
return (x + y) ^ 2
No variables, WTAF are you talking about?
Great video. I still dont think anyone on YT has a clear answer on what functional programming is, all these youtube videos ive seen and you are the first one tht summed up the idea of functional programing by basically saying dont waste a "variable" in a method(). Even now im still confused tho.
Key is the dominance of functions. He made that clear. Second is avoidance of "side effects", so the logic of the program can't be interrupted or distorted by those effects. Further into it is abstraction of various kinds. It's hard to explain beyond that without hours.
@@markhathaway9456 I believe months later this idea of FP is just to simply not have abstraction.
That's not entirely true. The main goal of FP is to eliminate side-effects with a focus on immutability. There is pure and pure enough. You also have to think about current state and a new modified state. FP seeks to retain both states.... For example, the sum of 2+ 3 = 5, that's one state. The new state is that state squared. It's easy to do with math via declarative programming (Are you going to split hairs about that). Not so easy to do with files. For example take a series that has number values as strings. Guess what? You can't sum the value "5" + "5.01". Even with this (two strings) you have two different data types (5 which is int and 5.01 which is float or decimal).
Beginners BEWARE! This explanation of 'side effects' is either mostly or completely wrong.
To play devil’s advocate a little bit, storing the result of calculations in variables isn’t exactly idiomatic functional programming since it’s more imperative than declarative so I kind of see what the thought process was but it was explained rather poorly
why I can't just create a function that creates animals?
Dark blue text on a black background. Interesting choice.
I like this explanation. It's simple but gives you the information you need as well.
Except for the parts that are wrong. He doesn't know what FP is, and is confused about a lot of OOP too.
But it's wrong. Please find another video.