Is Functional Programming a Good Idea?
HTML-код
- Опубликовано: 7 окт 2024
- In this video I talk about the benefits and challenges of functional programming
I compare functional programming versus imperative programming, and the maintainability benefits of having code written in a functional style. I talk about pure functions some of the key methods used in functional programming, including map, reduce, recursive methods, and higher order functions.
I'm planning to make a future video about immutable data structures and the techniques that go with them, as well as functional programming vs object oriented programming. Stay tuned!
subscribed, very nice video :) although, the recursive function you showed does not meet requirements for tail call optimization - last call of the function must be the recursive call, in your case it was a call to + . Otherwise, can't wait for the next part :)
ooh, you’re right, I messed this up, it needs to use an accumulator here
@@sammytalks7215 no worries, concept was correct!
This made fp so much clearer to me. I've been struggling to really grasp it. Thanks!
Thats the best explanaiton to side effects i have ever heared
"If you send your robot in again"
I will eagerly wait for part 2. I´ve been learning how to program and functional programming always seems like an interesting approach. Up to now i´ve been doing mostly procedural programming (as far as I can tell), and it mostly works for simple scripts, but once I need to take care fo edge-cases and higher-order functions and multiple returns, it quickly devolves into a messy code.
I think you explain the concepts very clearly to people who don't know about functional programming. What's good is how you talk about the concepts without talking about any functional language and express ideas in C-style syntax and diagrams. I will use this video to introduce people to the paradigm.
I'm fascinated by FP, and have tried to incorporate aspects of it. Unfortunately, a lot of my work is stochastic simulation of epidemics, where you have a population that changes *randomly* over time, and you want to capture various bits of information about it (e.g. maybe poll the population at regular intervals, record the time(s) an individual gets infected and recovers etc.). This is so natural in procedural, e.g. population X=X0; t=0; while (t
I watched many on FP. This is nice explanation
amazing video! this is what I'd call a very hard stuff exposed in a very easy way. Thanks a lot
Functional Programming is a very important tool in every developer's toolbox. But to try and *only* use it, IMHO, is throwing away the object-baby with the bathwater.
Purely functional code is really nice for modeling things tho
Especially if you have an expressive type system at your disposal. It's not a coincidence that some consider Haskell to be their favourite imperative language
Yes but what you call OOP is probably just procedural code with objects shoved in. Actual OOP looks nearly the same as FP except has value extensibility as a concern over behavioral.
9:11 nice, similar to "why lisp" in "lisp vs algol family" video, you cleared "functional programming" too!
resursive implementation of fib() in 6:30 is functional as well, no?
I'd also argue that pure functional programming is not practical when applied religiously. If you localize side effects, the function can act as pure, but have a mutability associated with it. e.g. with recursive fibonaci implemntation, if you add memoization with cache private to fib(), it's no longer technically pure, but from caller's perspective it has no side effects, and better performance.
ah -- meme was meant to be attached to the audio "some implementations are more efficient"
i.e. it's two implementations of fib with the same external behavior, but one implementation is more efficient.
memoization is useful, especially alongside functional programming, because pure functions are always memoizable. this is gonna be in part 2! :D
This is very well put together and informative. Your audio consistency could still use some work, but the audio quality was overall very good. I'm looking forward to the next one!
Hmm... Good job! Most people when they assume that I havs a question: I either do not have a question at all, but you actually assumed the correct question. The question was: "Wouldn't I have to copy the entire array?"
spoilers
It really depends on the language. In some, you do copy the whole thing and it gets slow. But oftentimes the data structures you're using are designed to be pretty efficient when used like that.
But, many compilers can often rewrite your code into one that doesn't allocate all that memory. This is called stream fusion and in this case it would consists of taking your map followed by reduce and replacing it with something similar to reduce that also does the mapping on each element during every iteration.
Some purely functional languages have one other trick up their sleeve: lazy evaluation. Thanks to it, even if they didn't do the fusion, the intermediate list wouldn't get allocated as a whole at any point in time.
Let's say we want to get a sum of squares of numbers from 1 to 4. Here is code that does that:
reduce (+) 0 (map (^2) [1,2,3,4]) =
-- lists are either empty: []
-- or not: x :: xs
-- I.e. they contain an element x (head)
-- and another list xs (tail)
-- [1,2,3,4] is a syntax sugar for 1::[2,3,4]
reduce (+) 0 (map (^2) (1::2::3::4::[])) =
reduce (+) 0 ((1^2) :: map (^2) (2::3::4::[])) =
reduce (+) (0 + 1^2) (map (^2) (2::3::4::[])) =
reduce (+) 1 (map (^2) (2::3::4::[])) =
reduce (+) 1 ((2^2) :: map (^2) (3::4::[])) =
reduce (+) (1 + 2^2) (map (^2) (3::4::[])) =
reduce (+) 5 (map (^2) (3::4::[])) =
reduce (+) 5 ((3^2) :: map (^2) (4::[])) =
…
reduce (+) 30 (map (^2) []) =
reduce (+) 30 [] =
30
@@mskiptr WOW, thank you!
I am loving it
Who compares two lists by removing their elements instead of iterating through them?
Nobody, but it was just an example for the danger of mutability, but of course he could have chosen a better one
The people who functional programming appeals to.
7:48 > _"languages offer optimization - tailor recursion"_
wow, thats interesting.i was going to say exactly that - I like recursion, but the book always say to reduce function calls for performance.
Yes and it turns out that is some cases optimizer is so good at optimizing recursion it can generate faster code then with imperative approch, mainly bsc it can prove that some bound checks or conditions cannot occured / are unreachable.
Ofc it depends
This video is quite a while ago now, but if I may give my 2 cents here, I would like to say something about the old debate of purity.
I believe the most important point about purity is that it's all about Separation Of Concerns.
Pure languages as a whole like Haskell have some problems in how practical they are to use in real life software development.
So what I believe is that at function level, you want to decide if it becomes a pure function or not, and express that clearly in the name and type of it.
You can often keep most code in pure functions, which just yield values in predictable ways.
Actual `work`, like modifying environmental things, files, stored data, etc. can be placed in decidated, centralized procedures in a program. And such a procedure may return void or unit (this depends on the language), or when applicable rather a success or error result status.
So I strongly believe in well organized, mixed paradigm programming. I believe Rust does this totally right for example.
looking forward to part 2. subbed
Looking forward to part 2!
I don't care if FP is "on a hype", or "is trendy" or something, I really damn like it, not to mention lambda calculus, which is just so awesome that it doesn't even need traditional numbers. Or booleans. Or strings. Or anything besides the way to declare a function with its params and apply it. So concise, yet so powerful.
Really nice video, I thought functional programming was hard but your explanation was good
In mathematics, a function is not just a "set of points in the space". For example, the function:
f(x) = 1, if x is irrational; 0 if x is rational
cannot be represented as s set of points in the space by definition
Hi! I appreciate the feedback, but I think the video is correct here. Remember that (mathematical) sets can contain an infinite number of points!
In mathematics, you could represent the function above as
{(x, 0) | where x is rational} Union {(x, 1) | where x is irrational}.
What's cool is this is how the concept of a function is defined in most of mathematics (using Zermelo-Fraenkel set theory).
from wikipedia:
"In mathematics, a function from a set X to a set Y assigns to each element of X exactly one element of Y"
hope this helps!
-- Sammy
How would it not work?
@@biblebot3947 because is not continuous and you should do some trick for it to "work"... my point is that the representation doesn't tell you much without all the information, that's why between f(x) = x for x real or for x irrational, the plot looks the same, thus it is not a correct way of describing it
@@antronixful well, Sammy’s reply Linda answers your concern there. You’re appealing to an informal notion of “graph” while the mathematical definition is-translated into pseudo code-the following:
Def in_f(x,y):
If rational(x) and y==0:
Return True
Elif irrational(x) and y==1:
Return True
Else:
Return False.
This is the idea behind the concept of “being in a set”: satisfying the property which defines it. In this case, it’s being a pair of numbers which have a number as the first entry and an appropriate output as the second entry. This is a precise notion which doesn’t appeal to a notion of “looking at a graph”. Hope this helps.
Very informative but not boring.
I've always thought that FP can be achieved via any of the other programming paradigms if and only if you write them correctly. BUT the _point_ of FP is that a functional rubric is *enforced* by the grammar and runtime, therefore guaranteeing code safety. Does that sound right?
Hi Sammy, just checking if you actually do read all your comments.
I do!
@@sammytalks7215 hahaha, nice, subbed.
"importantly the return statement is a complete description"
So?
Everytime I watch a video on functional programming, I am left with one of two questions "what is functional programming" or "what is the benefit of functional programming".
I sometimes wonder if I am already programming in a functional style and just don't see a reason to call it "functional".
If the return statement is a complete description of everything that happens in a function call (no mutability or global state), then certain optimizations are guaranteed to be safe, like
- Caching
- Parallel calls
what's important is that in the functional world, it doesn't matter _how_ the function is implemented, as long as the mapping of inputs to outputs stays the same. you can't get this in the mutable world, because of the way the specific implementation might interact with the outside world.
it also makes the function easier to understand and test, because the API surface is smaller. i.e. you don't have to test the function for every possible context/state of the world, you only need to test the mapping of inputs -> outputs.
I also answer this more specifically in part 2 of this video:
ruclips.net/video/6Ggc1BKN8gw/видео.html
"Caching"
This constitutes mutating state. Also, at least for the things I work with, caching isn't going to help as the amount of memory needed for the hash map exceeds the available amount of RAM.
After watching your second video, I am left with the conclusion that functional programming contradicts itself and is fundamentally impure. There is state somewhere, that state has to get mutated and all that functional programming accomplishes is moving around where the state is that gets mutated.
I'm wondering, what is the functional programming guidelines when you absolutely need to change the state of a variable? Where or how do you change it?
It's like OO programming, the OO paradigm is sooo restrictive that a really simple dummy design pattern gives you the impression that it's a mind blowing solution to a really hard problem while if you try to solve the exact same problem with a multi paradigm language and with a free (as in freedom) mindset you'll laugh so hard due to the simplicity of the solution.
2:40 umh, just use in function variables then? passing the arguments as const?
that would still not be "purely functional" but will address the problems outlined here! so??
there's some confusing semantics going on here:
A pure function is a function which has no side-effects or external state. If you do a defensive copy, then this becomes a pure function, which gives us the nice properties we like.
it's possible to create a pure function which is _implemented_ using impure functions/non-functional style.
under some definitions, for something to be "purely functional programming" it has to be pure functions all the way down, but the main goal of this section is to show that from the perspective of someone _using_ a function it's easier if the function is pure.
hope this helps! -- Sammy
its called a drawer
Functional programming is not about purity or immutability, it is truly about referential transparency, where stateless functionos or immutable data structures are just helping tools.
Example is new functions lang called Koka, in which mutable variables exist (with restictions).
You get a like just for sushi dog
No
there is no evidence that these properties are better. functional programs measurably have as many bugs as imperative and oo programs. If these things are not producing a benefit, why make things more difficult for you and for the computer?