In computer science, functional programming is a programming paradigm where programs are constructed by applying and composing functions. (Wikipedia)
Need for Functional Programming(FP)
- The usage of Functional Programming provides us with separation of concern where we can separate data and logic separately. Hence, the code becomes clear and easy to understand to a developer.
- Functional Programming follows the DRY (Do not Repeat Yourself) principle.
- Code which follows Functional Programming practice is memory-efficient.
- The codebase which implements Functional Programming will also be easy to extend and maintain.
- One of the important concepts in functional programming is the usage of pure functions.
- A function is said to be a Pure function if:
1) Given the same input, the function will always return the same output.
2) The function must not produce any side effects.
- Side effects are things that a function does that affect the outside world, that is they change the state of the program.
- Changing the data in a variable, printing output can be considered as some examples of side effects of a function.
Consider the following simple example:
The function square will always return only the square of a given number and will not change anything in the outside world.
This type of functions are also called declarative functions
- But, technically it's not possible to use pure functions everywhere as we may need to change the state of the code.
- Although, it's a good practice to use pure functions as many places as possible.
- And the fact here is that it highly probable to face bugs and errors occur in non-pure functions rather than in pure functions.
- Python provides us with some useful pure functions which are built-in python.
Pure Functions in python:
- map() accepts two arguments - a function and an iterable.
- Consider the above example of square function, we can make use of map() function to quickly apply the function to a given iterable like a list of numbers:
[4, 36, 100]
- The most common and useful use case of map() function is to receive multiple unknown numbers of input from the user:
Enter some numbers: 2 5 3 7 4 Check your numbers: [2, 5, 3, 7, 4]
- filter() function filters any given iterable based on the specified function.
- Consider the following example where the filter() function filters only the items which satisfy the condition of the given
[2, 4, 6, 8, 10]
- When we need to zip two iterables literally, we use the zip() function.
- We can add as many iterables as we want inside a zip() function.
- Consider the following example with two iterables:
[('Iron Man', 'Batman'), ('Spider-Man', 'Superman')]
- zip() function binds together the corresponding index items in a tuple and inserts into a list function (as I specified as the list() function).
- reduce() function is part of a functools module - a standard python library.
- Consider the following example, where the reduce() function accumulates the given list values and provides a final output.
- Unlike other functions, the reduce() function accepts three arguments.
- From the example, you can see that the function accumulate() accepts two arguments
itemand returns the sum.
- Here, the reduce() function passes the last argument 0 as acc at first and the first item from the list, then it accumulates and passes the sum as acc for the next list item and so on until all the list items are accumulated and the result is displayed.
Latest comments (15)
Separation of concern and DRY apply to programming in general. That is not specific to FP. I even hear more about them in OOP.
FP code being more memory efficient is something I've never heard of, but if you got a source feel free to link it or explain yourself. There might be cases or languages where this is true, but I feel like in the general case it is not.
And a little correction on pure functions. Map, filter, and reduce are only pure if the function you give to it is pure. There's nothing stopping you from doing side effects inside the passed function (although you should not). One common case I see is people using
map(print, mylist)to print a list, and then ignore the return value.
@cappe987 , you are correct at the end that Map, filter, and reduce will be pure only if we pass it pure functions.
At the end of the day, what we need to understand is that these useful functions follow the properties of Functional Programming paradigm.
And any given code, here these functions, comes with pros and cons too.
So, it's all about how the developer approaches on coding these concepts.
Yes. I just wanted to point out that they aren't inherently pure. At least not in Python. In Haskell the type system can force purity of a function, so those functions would be guaranteed to be pure because side effects are encoded in the types.
Yeah, Haskell is a statically & strongly typed language
compared to python which is dynamically & strongly typed language.
So, in that case, you are right about Haskell.
Hence it all comes down to choosing a language proactively by understanding the trade-offs and should be able to clearly comprehend the pros and cons, to make sure that one can deliver quality software.
So at the end of the day, this is what makes a developer distinguished among the community, the one who don't form strong opinions on a particular technology rather understand the pros and cons of each technology.
@cappe987 Thank you for pointing that out and stay tuned to learn more on python from my future blogs :)
Again don't get confused with the properties of Functional programming,
when I say FP code is being more memory efficient I mean that
when we start to use functions we are reducing the number of repetitions in our code, right? That's why we observe the DRY (Do not Repeat Yourself) principle in FP code.
So imagine that you are computing the square of N numbers more than once in your code, now when you use functions in those places you get to reduce some number of lines, that right there reduces the usage of memory right?
You get to reduce the number of lines, and store less information.
So, there you have it. To summarize:
"Functional programming keeps our code DRY so that we are not repeating ourself as well as keeping our code memory efficient because we're not storing information all over the place."
Any language that has functions would encourage you to use functions in your example, because of DRY. So that's not really a good example to demonstrate FP. Functions does not mean it's FP. C is in no way am FP language, yet you should use functions to keep it DRY. FP means to use only functions to compose your code, generally coupled with immutability.
You are right that less code means less memory. But in terms of code size it may only be a few hundred bytes and should be the least of your concerns, especially since using functions is something you should do anyways. DRY focuses on writing maintainable and readable code, not efficiency.
Generally when talking about memory efficiency we mean space complexity, how much memory the code requires to run. Even if the code is only a few lines, if it creates a list of 1000 objects then that list has probably already exceeded the size of the code in terms of memory. And in terms of that I would say that FP is generally less memory efficient because of immutability (but if you know what you're doing you can still write efficient code).
If you're interested in learning an actual FP language I would recommend maybe F# or Clojure.
@cappe987 I can understand that there is more to functional programming with concepts like Recursion, Referential transparency, Functions are First-Class and can be Higher-Order, Variables are Immutable.
FP is well implemented in languages like Common Lisp, Scheme, Clojure, Wolfram Language, Racket, Erlang, OCaml, Haskell, and F#.
My point is that functional programming is sometimes treated as synonymous with purely functional programming, a subset of functional programming which treats all functions as deterministic mathematical functions, or pure functions.
In addition, many other programming languages support programming in a functional style or have implemented features from functional programming, such as C++11, Kotlin, Perl, PHP, Python, Go, Rust, Raku, and Scala.
Check out the Wikipedia page on Functional programming to understand that FP can be applied to python.
Functional programming is a programming paradigm, so FP can be applied to a language like python using pure functions concept.
And I never mentioned that python is an FP language or that if we use functions it becomes FP.
My point is that we can apply the FP concept of pure functions to implement the FP style.
So please don't confuse yourself about FP cannot be implemented in languages like python.
Casper, before making strong opinions and extreme use-case on Functional programming being not memory efficient, please look at the big picture.
When you write through functional programming, you store less information right?
You say that - "You are right that less code means less memory. But in terms of code size it may only be a few hundred bytes and should be the least of your concerns, especially since using functions is something you should do anyways."
But, consider a big project which has millions or billions of lines of code in its codebase, at those times you get to reduce a lot of memory in an exponential rate.
I'm well aware how FP concepts can be applied in non-FP languages. I never said anything against pure functions in Python (I just pointed out that map/filter/reduce aren't inherently pure as the purity depends on the function passed, I wasn't discrediting the use of them) But you talked about using functions to reduce code duplication as an FP concept when it's not. It's a concept of programming in general.
You could remove the "FP" from the quote above and it would still hold true.
OK, got it
I agree that Separation of concern and DRY are generally practices we observe in programming.
But, I have specified them as the properties of Functional programming and I have not written that it is only applicable to FP, so don't get confused.
And you're right that we can also observe this in OOP.
To give you more insight, when I say separation of concern in functional programming I mean that we package our code into separate chunks so that everything is well organized in each part of our code and each part is organized in a way that makes sense on functionality. So when I say separation of concerns I mean each part concerned the self with one thing that it's good at.
Just like in OOP where we divide up attributes and methods,
functional programming has this idea as well of separating concerns where we also separate data and functions because they are two separate things.
I agree with @cappe987 .
Functional programming is about the way you design your software, and not much just with the use of these built-in functions.
Anyway, it is a good start. Though, keep in mind that for many examples the filter and map approaches are not the best in Python.
I agree with you that Functional programming is more than the usage of pre-built functions in python.
I have demonstrated in a simple way to give a head-start to the people who are new to these concepts.
And filter and map may or may not be the best in python, but it gets our job done.
So it's all about trade-offs in programming.
Surely, I did not mean to disregard your post. I just wanted to expand @cappe987 comments further for the more advanced reader.
Some comments have been hidden by the post's author - find out more