Enough languages that are popular today have accrued important ideas from functional programming that the disparity is much lower now than it used to be. Going from C to Haskell is a big jump, but I was shocked at how similar Ruby and Common Lisp are. Even C++ and Java have lambdas now. JavaScript is popular and pervasive and has blatant roots in Scheme. Once you learn how to compose functional iterator methods like map, filter, etc, the inferiority of for loops becomes blatant (eg this is why I have little interest in go).
There are FP options these days that aren't shrouded in mathspeak. JavaScript calls it a "function" rather than a "lambda", Elm calls it "union types" rather than "algebraic data types" gist.github.com/evancz/06fe634245a...
FP has a basis in math, making it declarative and immutable. It turns out that most of the problems that most of us have with most of our programs simply disappear when we write code in a way that is congruent with this constraint. As evidence, I present the popularity of React.js
I think it's because state management is becoming one of the biggest issues in modern development. Debugging large applications with tons of distributed state is a huge challenge. Isolating and controlling state in a functional, immutable way makes this a much more manageable problem.
I'm getting into FP via Elm and Elixir. Both are quite accessible and have helpful communities. Elm is a gem, I think. Static typing and Elm architecture (not to mention whitespace, bracket forest-free environment, elm-format, helpful compiler and a good handful of other things) feel like a cure to the front-end madness. I'm still wrapping my head around Elixir, but -- damn -- is pattern matching nice :)
Because many programming problems are easier to model as a series of data transformations, as opposed to a set of mappings of real-world objects. React and Elm show that it's intuitive for creating stateful UI apps. Phoenix (Elixir's web framework) shows that a typical web app can be represented as a pipeline of functions transforming the received connection. We have chained functions (commands) on terminals for as long as I could remember.
What Josh Cheek mentioned really rings true for me: "FP has a basis in math, making it declarative and immutable. It turns out that most of the problems that most of us have with most of our programs simply disappear when we write code in a way that is congruent with this constraint."
Furthermore, over the years I've built very very large applications in a functional programming style, and I've found almost no need for class abstractions and inheritance.
Personally, I've really enjoyed Javascript. Objects, Arrays, and functions are all that's needed to build very expressive, bug-resistant, massive applications.
1) We now have machines with enough resources to support it.
2) People have begun to notice how much "best practice" software engineering is just complete and utter rubbish, and have latched onto functional programming in desperation, as if it could save them from the cesspools they helped create.
Many functional languages enforce usage of exactly the types a function needs with no implicit casting which makes it harder to make mistakes. I work in the .NET world and love F#. I heard that one team moved their business application from C# to F# and for 6 months got no bug report of any kind. That's how powerful FP can be.
The pushback I get from seasoned C# devs is that they don't know F# and FP. Or rather they don't want to invest in another language (let alone paradigm).
I've seen this before when VB/VB.NET developers didn't want to learn C# back 10yrs ago. Though this time around is more than just syntax.
I believe as more C#/OOP devs see FP/F#'s power, they will convert. I'm one of them. I've seen the light, and it's good.
FP knowledge is kind of universal. You can write pure code in just about any language.
The experience I herein describe is from my time with Haskell.
In FP you don't modify anything yourself, you just tell the compiler how to make convert data from type a to type b.
My mindset is that every program only converts some data into a different representation, be it input from the user and some database that is being converted into an HTML document or just some input that is converted to it's base64 representation.
Especially if you adhere to Unix philosophy you end up writing little "subprograms" that just do a simple job like base64.
FP then gives you a huge set of readily available functions to achieve exactly that.
It also forbids you to do anything impure, so you end up with small little functions that transform some a to some b and bs to cs. Then you just call them along the lines of foo(bar(baz)) and return the result to the user.
Why is this so popular you ask?
Well, it makes a lot of things disappear: race conditions, irreproducible behaviour, unintended side-effects just to name a few.
It also makes a lot of things easier.
There is for example the maintenance. You can easily replace a function that does not perform as it should and, once it works, it probably keeps on working forever.
How about testing? If you have a high unit-test coverage then you have actually tested everything that could go wrong because there are no side-effects in pure functions.
If you profile your application you see how long each function takes and how often it's called. This makes it easy to find a bad performing function and simply rewrite it, if possible, or reduce it's usage or the way it's used.
Adding a feature is as easy as adding the new functions and putting a call to them somewhere. You cannot break any of the existing parts of the program if you do not touch them due to the complete lack of side-effects.
Just for the FP people some corrections:
Yes, there are side effects, for example IO, but you either have some Monads do the job or abstract over them using e.g. the interact function in Haskell.
FP is super useful for distributed computing. Managing state across hundreds of servers is a nightmare and forcing devs to reduce state and side effects to the barest minimum turns out to work pretty well in this domain.
I think one reason functional language features are making their way into languages is just because they're shorter for a lot of situations! If a programmer is used to using functional features on lists, having to jump back into using for loops feels like such a hassle, so it makes sense that they would implement those features.
It's not all laziness though, it often goes with being more 'expressive', closer to a human explanation of what you're trying to do.
Top comments (38)
I think it's because state management is becoming one of the biggest issues in modern development. Debugging large applications with tons of distributed state is a huge challenge. Isolating and controlling state in a functional, immutable way makes this a much more manageable problem.
Bingo! :-)
I'm getting into FP via Elm and Elixir. Both are quite accessible and have helpful communities. Elm is a gem, I think. Static typing and Elm architecture (not to mention whitespace, bracket forest-free environment, elm-format, helpful compiler and a good handful of other things) feel like a cure to the front-end madness. I'm still wrapping my head around Elixir, but -- damn -- is pattern matching nice :)
Because many programming problems are easier to model as a series of data transformations, as opposed to a set of mappings of real-world objects. React and Elm show that it's intuitive for creating stateful UI apps. Phoenix (Elixir's web framework) shows that a typical web app can be represented as a pipeline of functions transforming the received connection. We have chained functions (commands) on terminals for as long as I could remember.
What Josh Cheek mentioned really rings true for me: "FP has a basis in math, making it declarative and immutable. It turns out that most of the problems that most of us have with most of our programs simply disappear when we write code in a way that is congruent with this constraint."
Furthermore, over the years I've built very very large applications in a functional programming style, and I've found almost no need for class abstractions and inheritance.
Personally, I've really enjoyed Javascript. Objects, Arrays, and functions are all that's needed to build very expressive, bug-resistant, massive applications.
Immutability makes everything easier as well.
1) We now have machines with enough resources to support it.
2) People have begun to notice how much "best practice" software engineering is just complete and utter rubbish, and have latched onto functional programming in desperation, as if it could save them from the cesspools they helped create.
I know I should not but I completely LOLd at this.
Many functional languages enforce usage of exactly the types a function needs with no implicit casting which makes it harder to make mistakes. I work in the .NET world and love F#. I heard that one team moved their business application from C# to F# and for 6 months got no bug report of any kind. That's how powerful FP can be.
I've heard similar stories.
The pushback I get from seasoned C# devs is that they don't know F# and FP. Or rather they don't want to invest in another language (let alone paradigm).
I've seen this before when VB/VB.NET developers didn't want to learn C# back 10yrs ago. Though this time around is more than just syntax.
I believe as more C#/OOP devs see FP/F#'s power, they will convert. I'm one of them. I've seen the light, and it's good.
FP knowledge is kind of universal. You can write pure code in just about any language.
The experience I herein describe is from my time with Haskell.
In FP you don't modify anything yourself, you just tell the compiler how to make convert data from type
a
to typeb
.My mindset is that every program only converts some data into a different representation, be it input from the user and some database that is being converted into an HTML document or just some input that is converted to it's base64 representation.
Especially if you adhere to Unix philosophy you end up writing little "subprograms" that just do a simple job like base64.
FP then gives you a huge set of readily available functions to achieve exactly that.
It also forbids you to do anything impure, so you end up with small little functions that transform some
a
to someb
andb
s toc
s. Then you just call them along the lines offoo(bar(baz))
and return the result to the user.Why is this so popular you ask?
Well, it makes a lot of things disappear: race conditions, irreproducible behaviour, unintended side-effects just to name a few.
It also makes a lot of things easier.
There is for example the maintenance. You can easily replace a function that does not perform as it should and, once it works, it probably keeps on working forever.
How about testing? If you have a high unit-test coverage then you have actually tested everything that could go wrong because there are no side-effects in pure functions.
If you profile your application you see how long each function takes and how often it's called. This makes it easy to find a bad performing function and simply rewrite it, if possible, or reduce it's usage or the way it's used.
Adding a feature is as easy as adding the new functions and putting a call to them somewhere. You cannot break any of the existing parts of the program if you do not touch them due to the complete lack of side-effects.
Just for the FP people some corrections:
Yes, there are side effects, for example IO, but you either have some Monads do the job or abstract over them using e.g. the
interact
function in Haskell.FP is super useful for distributed computing. Managing state across hundreds of servers is a nightmare and forcing devs to reduce state and side effects to the barest minimum turns out to work pretty well in this domain.
I think one reason functional language features are making their way into languages is just because they're shorter for a lot of situations! If a programmer is used to using functional features on lists, having to jump back into using for loops feels like such a hassle, so it makes sense that they would implement those features.
It's not all laziness though, it often goes with being more 'expressive', closer to a human explanation of what you're trying to do.