DEV Community

alesbe
alesbe

Posted on

Does functional programming have any advantage in real environments?

I've been thinking about learning something new, so I went to Stack Overflow Surveys to see what technologies are people actually working on right now, and I saw this:

Survey

The top paying programming language is Clojure? Followed by F#, Elixir and Erlang, and a few positions below Scala and LISP, I'm impressed.

I don't have almost any knowledge in functional programming, I've heard that has better performance in certain situations (like managing big data), is more predictable, and more readable, but I don't see real use cases for functional programming instead of a traditional approach.

What are the advantages of the functional paradigm? In what situations are this languages used? For someone that wants to learn something new, what language do you recommend to learn first? I thought about Haskell or Clojure.

Thanks! 🙌

Top comments (29)

Collapse
 
ben profile image
Ben Halpern

Certain approaches to frontend development with declarative tools like React have a lot of functional programming even if it's not strict, purely functional.

I think if you're used to that kind of development, playing around with a more functional tool like Elm — to learn — will probably help give you some perspective.

Other than that, I'd say that Elixir seems like the friendliest "backend" way to get into the functional approach.

Collapse
 
codewander profile image
codewander • Edited

I agree that the majority of elixir programming involves thinking functionally, but at it's core implementation, the focus on actors reminds me of the contrast between akka and cats/zio/etc in scala. I have always considered actors to be the OO taken to it's logical conclusion, where each actor is an object that operates concurrently. In the context of scala, Akka seemed to represent the OO / java programmers coming to Scala, whereas cats and other Haskell immitations used other approaches to concurrency. (Maybe the best way to put it is the following: the local, happy path in actor processing is functional, the global and resilient path in actor systems is more imperative.)

Regardless, using elixir as a way to learn functional programming basics sounds useful, and similar to elm on frontend, phoenix provides a batteries included backend context for writing small functions and seeing them work together.

Collapse
 
codewander profile image
codewander • Edited

I would use a functional programming language if I were building something deeply complex such as a compiler or if I was building something which aimed for bulletproof correctness such as safety critical systems or systems dealing with financial transactions. For most other situations, where you are building something large but simple, I would only use functional languages if they were the dominant paradigm some day, because otherwise you will get small gains in exchange for sacrificing access to large sets of libraries or spending lots of time adapting libraries written with other paradigms to work within your functional programs. Huge ecosystems use and enormous numbers of engineers have been trained to use oo and imperative programming. In such an environment, it almost doesn't even matter that functional programming exists or if it's better or not. Some elements of node and reactjs have pushed industry slightly away from imperative or oo for everything, but I don't know if it will extend further.

If you want to learn functional programming, I would start with Elm, then clojure, and then go on to Haskell (or purescript if you want a more recent, fewer standard library warts version of Haskell). If I were looking to use something that uses some ideas from functional programming in production, I would learn rust.

Collapse
 
peerreynders profile image
peerreynders • Edited

I thought about Haskell or Clojure.

In my judgement Haskell as a first exposure to functional programming (FP) would be a mistake for most people.

Having to wrestle with recursion is par for the course with FP but with Haskell you also have to concurrently deal with purity, static type checking and laziness—all powerful stuff for sure—which can quickly ramp up the challenge to painful levels.

Clojure is what worked for me but I'd only recommend that to people who are already familiar with the idiosyncrasies of the Java ecosystem.

Exhibit A:

Transcript

The point here is to internalize that just because something isn't easy doesn't mean it's difficult (just different) and that easy doesn't imply simple or vice versa. Simple doesn't complect while easy often does.

Fall back on this anytime FP feels different enough to seem difficult—you're just not familiar enough with it yet.

Exhibit B:

Transcript

This highlights why FP seems so different:

Imperative programming describes the "flow of control" (think flowcharts) where program execution moves computation forward by manipulating values in place (PLOP - Place-Oriented Programming)

Functional Programming advances computation by creating new values through the transformation of existing values (value-oriented programming). A functional program's description focuses on the "flow of values" (not to be confused with dataflow programming) rather than the "flow of control" .

I would go as far as saying that value-oriented programming is often what is meant when people talk about functional programming.

The Structure and Interpretation of the Computer Science Curriculum

This paper makes the case that it is often easier to learn FP before imperative programming as opposed to the other way around. This could go some way towards explaining why people who became familiar with imperative programming first, claim that imperative programming is more natural—it really is a case of what you were familiar with first.

One language that has been extensively used to teach FP is Racket; together with something like the "The little Schemer" it can be used as an introduction moving towards value-oriented programming (Systematic Program Design).

That said both in Clojure and Scheme the parentheses can take some getting used to; for most people it just takes some determination and persistence.

Personally I found Erlang to be a good way to learn FP (syntax notwithstanding), unfortunately some learning opportunities seemed to have dried up. Elixir could be a good substitute as long as you are vigilant and not let its Ruby-ish syntax guide you to more imperative implementation patterns.

Elm has already been suggested—these days I would tend more towards ReScript as that can also be used server side. I'd combine it with an exercism track to become familiar with it.

An earlier, very similar comment of mine.

Collapse
 
alesbe profile image
alesbe

Thank you so much for the detailed answer! This clarified a lot of misconceptions about FP, I'll definitely look into all the resources provided, I was using functional programming without even knowing it, I now understand why it seems more readable, because it's more predictable. Thank you again for your time 🙏

Collapse
 
codewander profile image
codewander

I would vote for Elm over Rescript for learning functional programming basics. The backend Rescript landscape is very early days and I wouldn't take it into consideration when choosing between Elm and Rescript. For backend, I would learn more established backend functional languages as my first exposure to backend functional programming.

Collapse
 
quoll profile image
Paula Gearon

Others have pointed out: FP controls complexity. This leads to the ability to develop faster, with fewer people, and greater reliability.

As an example, I was on a team of about 8 devs, building a database in Java over several years. It was released as open source, and I maintained it for several more years. It was about 100k lines of code.

In recent years, I wanted to explore some more ideas, and implemented another, similar database using Clojure. This time, I was on*my*own, and did much of it in my spare time. The end result is about 7k lines. It’s been deployed in products with over 120k installations, and it works. I’m not the only one who’s done this either.

As for availability of developers, FP is so much more fun to use, there tends to be a sense of evangelism around the languages that provide it. Developers are also enthusiastic about getting more people to use their language, since the more it’s in use, the more likely they are to find a job using it. There are lots of resources for learning these language, and many people happy to teach it.

Clojure used to be very niche, but it really has expanded. It’s used by Cisco, Walmart, Target, several major banks (Capital One, Citi, Deutsche), and many more. NuBank relies on it so heavily that they bought the company that supports core development of the language. So there are many developers using it, and many companies in the real world relying on it.

Collapse
 
mojo2012 profile image
Matti

Are the two DBs comparable feature-wise? Would you have been able to develop your DB before the old one with the same outcome?
Can someone else understand your code as well?
You can write super tiny code in an OO language too, but noone would be able to decipher it. (I once got a project like that ...)
I've seen small functional codebases. They were smaller because like in a typical java project you have 1000s of lines of code defining DTOs, entites etc. Guess what, the functional projects just didn't have that. It was all some generic form of lists and objects being passed around - pure guessing, no proper autocomplete etc.
I hated it. It felt so unproductive.

Collapse
 
quoll profile image
Paula Gearon

In order:

  • Yes. The older one has some data import functionality that the new one doesn't have, but this is a very small area of the code base. Most of that functionality was provided by 3rd party tools.
  • No. It was my years of experience that got me to where I am. I would not have even thought that I could attempt such a thing on my own if I didn't have that experience. On the other hand, it was only a FP language that gave me the confidence to try. OO would either lead to state complexity. Alternatively, if I took an FP approach in an OO language, it would come with performance concerns with functional structures that aren't implemented as well, and a constant battle with language idioms and syntax that was not designed for FP (I've done this with some success, but it's pushing uphill)
  • The new code is significantly easier to follow, and several people have. It took 3 weeks of training to do a handover of the previous database code (I did one of those weeks, and 2 other colleagues did the other 2 weeks)
  • You can try to compress your code in any language. I could have done that in FP too, but clarity, maintainability, and extensibility were all primary concerns.
  • The definitions in Java are verbose with little benefit. Scala can offer the same with less boilerplate. Generic lists, maps, etc, offer a lot of power if you have a lot of functions that operate on those few structures (and a good FP language will have this). But you also have the choice of describing structures for compilers in performance critical code. My own DB code has a lot of datatype descriptions, so even when simple things like vectors are passed around, they have to meet conformity constraints. These apply during compilation (so that correct types are passed), and testing, but are removed from runtime code for performance.

I did feel less productive in my earlier days. But this shifted over time. It's the complete inverse for me now, and that's despite having 20 years of OO experience.

Collapse
 
codenameone profile image
Shai Almog

When a technology is less popular it's hard to find a developer, you need to pay for relocation, etc. Salaries go up but job security is down. You want to change jobs and you're stuck.

You should very much learn functional programming as well as OOP and give yourself a well rounded education. But I would suggest correlating the salary information with the popularity information and the job listings in the area where you want to live.

Collapse
 
codewander profile image
codewander

The best salary information that I have found so far is levels.fyi and the "trimodal" article.

Collapse
 
hnrq profile image
Henrique Ramos

One real-world application of functional programming (Mainly immutability) is in Redux's reducers. They receive pure functions (Functions that have a predictable output Y, given an input X) and should always return a new state, not modify the current.

Collapse
 
neifranci profile image
NeilFranci • Edited

As a Junior Front-end, I see people nowaday use FP in React more than Class thing. Because it make me write less code, easy understandable hooks thing. But 60% answer from stack overflow is class thing on 2019-2021. And React docs also show Class thing instead of function. Time will change, but maybe some old project from some random company still use class and the dev just too lazy to rewrite whole thing to Function base and hooks. And because in javascript function are also like object so I don't mess with Class anymore in mylife for javascript.

Collapse
 
codewander profile image
codewander

Interestingly, someone recently noted to me that the beta react docs highlight hooks more

Collapse
 
fen1499 profile image
Fen

Concepts of functional programming like Immutability and pure functions are very desirable for most kinds of backend applications as it naturally leads to thread safe and decoupled apps.

My theory is that object oriented got really popular because it made monoliths manageable (thanks to design patterns and clean architecture) but in the age of microservices and parallelism, FP is occupying a space that used to be OO exclusive.

Collapse
 
tuliorodrigues profile image
Tulio Rodrigues

Here has a good article explaining why OOP and C syntax got popular
cs.stanford.edu/people/eroberts/co...

Collapse
 
bobdotjs profile image
Bob Bass

I'm usually writing typescript and I opt to take inspiration from FP and opportunistically use pure functions or recursion when it makes sense but overall my style is very procedural.

I believe that procedural code with a functional influence is usually the most readable and self documenting, as well as easy to maintain code.

If I'm writing elixir or elm, I feel like my hands are tied and I need to do things in very unnatural and unintuitive ways, and I have trouble making sense of purely functional code after I spend a week away from the codebase.

Similarly, I share the same criticisms of OOP. It's okay to take influence from OOP like encapsulation or polymorphism, but a purely OO codebase is a nightmare to debug and figure out because everything becomes so fragmented and abstracted for the sake of abstraction instead of practicality. There no reason to nounify all of our verbs. OOP is only good if you know exactly what you're building and exactly how to get there but usually the things we build have constantly changing scopes.

If you're building something like Zapier, you probably want your code to be as functional as possible because you're forcing the end user through functional workflows and the paradigm is probably best represented in a functional style, but for the 99% of us building web, desktop, mobile, bor business CRUD applications, procedural with a functional influence is the most natural and intuitive way to write and manage our code.

Elixir is less frustrating than elm, but people would argue that elixir isn't a functional language on the pure sense of the word. Meanwhile, we all hate elm and Redux. Redux was modeled after Elm and elm is dead now. Redux is a nightmare to use compared to Vuex which is state management done correctly.

Languages become higher and higher level, well probably write more functional code in the future, but with the languages we have right now, it rarely makes sense as a developer to build out a purely functional codebase.

Collapse
 
mindplay profile image
Rasmus Schultz

This article provides a nice overview of some of the advantages of functional patterns over the typical "enterprise" style of object-oriented programming - in my opinion, there are a lot of real benefits to a "more functional, less enterprise" approach.

antman-does-software.com/functiona...

Collapse
 
jay8142 profile image
Sir Broddock

With all things, there is a balance. To answer your immediate question, why do clojure devs command such a high income, it's because it is considered a "niche" language, and imagine an important system was developed in clojure and you need to hire a clojure dev to maintain it. Of course they will be able to command a greater salary if they have a history of specialization with clojure.

To your broader question about functional programming. It's great! There are a lot of benefits to it in terms of mocking, other types of testing, etc. Personally, I think that javascript & go have very "balanced" implementations of functional programming. They both allow for many functional programming patterns without going overboard and still enable many object oriented patterns. Following a "mixed" approach to object oriented and functional is a very mature orientation in my opinion as you begin to learn which technique is modeled best by which approach.

Collapse
 
sirseanofloxley profile image
Sean Allin Newell

I would also pile on the Elm recommendations. FP has many faces and iterations, and varied benefits across those incarnations. I'll focus on Elm.

I think Elm offers a more pleasant developer experience compared to JS and its various libraries/frameworks. It also leans into value or data driven design and programming which lends itself to pipelines and transformations. Imagine Javascript promise chains (.then...) or array manipulations (.map . filter) or C# linq queries or Java 8+ style code if youvet seen any of those examples. Elm/FP also offer more powerful compilation checks that can lead to generative testing that automatically check boundary conditions and increase your confidence in your code. Because of those checks, global and local refactorings are common, encouraged, and extremely low risk. I think this is particularly valuable in product saas companies where markets and products can change so much we need a way to accomodate change.

FP, to me, affords me more tools to write more reusable code than compared to a more OO language.

Collapse
 
webbureaucrat profile image
webbureaucrat

I'm going to plug my own stuff here--I wrote a deep-dive series on functional monads in (primarily) object-oriented languages.

I wrote one on replacing nulls which is sort of similar to the null-object design pattern in object orientation and another brief one on extending that functionality to list processing with missing data.

But if you read any of them you should read Safer Data Parsing with Try Monads in which I argue that runtime exceptions are always entirely avoidable because you can chose to wrap all unsafe data in try monads which in effect causes the type system to enforce try/catch behavior to define all possible code paths.

I don't just want to plug my site for its own sake but because these are all libraries I've written for work and use on the regular, and they make my life so much easier.

Collapse
 
alesbe profile image
alesbe

Thank you so much for all the answers! There are a lot of them and I can't answer every single one, but I'm reading everything.

Functional Programming it's so interesting and a completely different paradigm that a lot of programmers overlook, but has pretty unique implementations. Right now pure functional languages like Elm seems a bit unnatural to me, but it's probably because I'm not used to it. As some people said, something in between (except for certain cases) seems the best approach for general use, I used a lot of React using functions instead of the old classes and everything seems more clear and intuitive, also makes the code less fragmented. Thanks! 👨‍💻

Collapse
 
coder_mohan profile image
MOHAN👨🏻‍💻 • Edited

I would like to share an article, where DoorDash developers tells how they use Kotlin to leverage functional programming to write better, cleaner code. Thats a really nice article, go ahead and read it.