
Why functional programming matters - antouank
https://medium.com/@mikolajszabo/why-functional-programming-matters-c647f56a7691
======
msimpson
> Imperative programming is like building assembly lines, which take some
> initial global state as raw material, apply various specific
> transformations, mutations to it as this material is pushed through the
> line, and at the end comes off the end product, the final global state, that
> represents the result of the computation.

This isn't the best analogy as functional and imperative languages are both
often used in a procedural fashion. If I simply replaced "global state" with
"immutable arguments", this analogy fits functional programming as well. The
fact that the arguments would be copied, however, would be implied.

> Each step needs to change, rotate, massage the workpiece precisely one
> specific way, so that it is prepared for subsequent steps downstream. Every
> step downstream depend on every previous step, and their order is therefore
> fixed and rigid.

This is more about tight coupling than imperative vs. functional paradigms. In
general, imperative methods can be just as loosely coupled as functional
methods. It basically comes down to what sort of data you're handling.

> Because of these dependencies, an individual computational step has not much
> use and meaning in itself, but only in the context of all the others, and to
> understand it, one must understand how the whole line works.

This, again, can be true of functional languages as well. You cannot always
guarantee that a method is individually useful given the data at hand.

~~~
developer2
>> functional and imperative languages are both often used in a procedural
fashion

Exactly.

The most common ELI5 definition of functional programming I get from other
developers is that you're piping multiple statements together into a single
chain of processing [input(s) > multiple levels of processing > output(s)],
without having to explicitly declare variables to hold the temporary inputs
and outputs between each sub-statement within the chain. I know just enough to
understand that this isn't the "proper definition", but that workflow is true
enough that it's what many people associate functional programming with.

The problem with that particular definition is that it tries to make the
primary benefit of functional languages seem to be this piping/chaining
mechanism. Yet these languages are still written procedurally, executing
_multiple_ such pipes in sequence. You still have variables holding the inputs
and outputs of each chain, so you can pass them to other unrelated chains. It
reduces the overall number of statements and the manual variable/memory
management required, but each statement is simply a compressed version of
multiple statements merged into one, enforcing "fake immutable" variables for
the inputs/outputs within the chain. You don't really have "immutability"; you
simply have automatic variable management between sub-statements in a chain.

Now, show me a functional language where the _entire program_ is written as a
_single piped chain_ , and I would classify that as its own genre. Literally,
the entire program would have to be written top-down as a single block of code
that chains every single required input from the top-level, all the way down
to a single output, without using a single explicitly declared variable. Only
the first line of code would be unindented at the first column, with all other
lines having to be indented as part of that primary block. Now _that_ would
satisfy me as being "unique" or "different than procedural".

What is the primary metric of a functional language? Is it to write write golf
code[1] that folds 10 "procedural statements" into a single 3-line "functional
block"? To me that's not "functional programming"; that's just writing less
code by chaining multiple operations into smaller blocks, reducing the
complexity of having to explicitly declare more global or widely scoped
variables.

Random thought association: is perl's well-known Schwartzian transform
(@sorted = map { ... } sort { ... } map { ... } @unsorted), applied as a
concept to an entire language, what makes a "functional language"? To me, that
doesn't seem like enough of a scope change to warrant a different language
"type".

[1]
[https://en.wikipedia.org/wiki/Code_golf](https://en.wikipedia.org/wiki/Code_golf)

~~~
belovedeagle
> piping multiple statements together into a single chain of processing[]
> without having to explicitly declare variables to hold the temporary inputs

This is known as point-free style. I think point-free style implies functional
programming (at least locally; i.e., a point-free function will by definition
be functional, although it can call imperative functions) but functional
certainly does not imply point-free.

~~~
developer2
Please tell me you know of a functional language that does not incorporate
"point-free style", as you put it. I would love to look at such a language as
a way to redefine how I view functional languages in general. No sarcasm
involved, I am genuinely interested.

~~~
belovedeagle
Ah, well... point-free style is going to be more-or-less possible in any
decent functional language; it (or rather, functional composition) is one of
those things like "while loops" in imperative languages which, if absent,
would cause you to consider a functional language kind of rubbish. Functional
programming would be far too verbose to be comprehensible otherwise.

That said, Scheme is probably a good example. Lisps in general are a funny
case for functional programming: historically they were described as
"functional" but the word had a different meaning we would now call
"procedural"; I think Lisp may have predated Algol so the concept of having
functions at all was fairly notable. However, Lisps generally support
functional programming and Scheme has embraced it more fully than the others.
Note, for example, that Scheme doesn't actually have loops as a fundamental
concept in the language; it emulates them with obligatory TCO and convenience
macros.

------
patrickmn
Why compose classes, abstract base classes, etc. when you can compose simple
functions!

It's true that abstractions in functional languages can seem foreign and hard
to understand, but generally they have some purpose, being grounded in
mathematical practice. OO abstractions and patterns OTOH, taught essentially
in "elementary school" which possibly makes them seem easier to understand, do
a very poor job of solving more problems than they create.

Learning a functional language is often a transformative experience that lasts
throughout a career, whether you even use functional languages or not. It
might make you do something as simple as partitioning which functions have
side effects and which don't, even if the type system doesn't enforce it. Or
use a form of quick/fuzz testing, even if it's not the standard test suite. Or
make parts of the data immutable for scalability, auditability, etc. Or...

There really are few things as satisfying as developing a large codebase in a
functional language. A lot of the frustrating maintenance work just goes away.
But even if you don't, functional principles can yield similar benefits in
imperative languages.

~~~
mpweiher
> Why compose classes, abstract base classes, etc. when you can compose simple
> functions!

Because they allow you to compose higher level entities?

(Incidentally, one would generally compose _objects_ ).

"When programming a component, the right computation model for the component
is the least expressive model that results in a natural program." \-- Concepts
Techniques and Models of Computer Programming

So when a less expressive model (such as FP) is sufficient for a "natural"
program, _definitely_ use that. And of course that has been the general
recommendation. Switch to a more expressive model once this is no longer the
case. In my experience, FP tends to be good for "computation", at least if
performance isn't a primary concern. However, most of what "computers" (badly
named) do today isn't computation, and modeling communication and storage over
time tend to get awkward (though obviously possible).

~~~
louthy
> Because they allow you to compose higher level entities?

That isn't true. FP still uses data records, they're just not tightly coupled
to the functionality like OO. Pure functions + immutable types is a more
powerful programming paradigm than data and functionality encapsulation via
classes and methods.

Also more advanced techniques like combinators can encode more complex and
extensible patterns in a significantly more robust way than any OO class
hierarchy (see 'parser combinators' for an example).

~~~
mpweiher
> (see 'parser combinators' for an example).

Lots of parser-combinator libraries in OO languages.

~~~
louthy
Your point being?

------
zinxq
My apprehension comes from lack of seeing it in the wild (i.e. scaled
businesses).

Google primarily uses C++/Java. Facebook: Hack. Twitter tried Scala and as far
as I know, abandon it and went to Java. LinkedIn definitely tried Scala,
failed, and went to Java. Square is Ruby/Java.

I'd like to have something to point to as a success story of a company at
scale with functional programming. Anyone know of one?

~~~
andrzejsz
What is wrong with Scala that some companies seem to abandon it in favour of
Java?

~~~
hota_mazi
It's basically the C++ of the 21st century.

Designed to replace and address flaws of an older language but ends up being
huge and unmaintainable, with very questionable design decisions and a tool
chain that's simply not up to standards in the 21st century (slow compiler,
poor IDE integration that keeps breaking version after version, etc...).

In C++, some of these design decisions were driven by legacy pressure but in
Scala, a lot of design decisions were driven by the pressure on the team to
write research papers. Either way, both languages end up being monsters that
implement all known programming language features known on Earth.

~~~
pkolaczk
Quite the opposite. Scala is a language designed around a very small core of
very powerful, and sometimes hard-to-grasp features like implicits or higher-
kinded types. It is a different language than Java and was not designed to
replace Java or to be a better-Java.

Your C++ to C analogy doesn't hold, because C++ is an (almost) superset of C,
while Scala is not a superset of Java at all. Modern C++ compiler can compile
most of C code with at most minor, cosmetic changes.

As for the toolchain - I'm working in it daily and so far it has been great.
Ok, compiler is not as fast as Java (point taken), but this doesn't matter as
long as I can compile my code fast enough. IDE support is stellar compared to
most other popular languages, particularly dynamic ones like Python or PHP.

~~~
Phil987
He wasn't saying it's the same as C++ to C. He was saying it's like C++ in
that it has way more features than it should.

~~~
pkolaczk
Oh, so "Scala / C++ is too complex" again. Many people say that, but most
can't name even a single thing that should be removed.

~~~
hota_mazi
It's not just too complex (we're talking more complex than C++ and Ada) but
also poorly designed overall, with so many features that they interact with
each other in ways that are pretty much unpredictable.

Odersky himself gave up on scalac and he's writing a compiler and a new
language from scratch.

~~~
pkolaczk
Scala more complex than C++? O'rly?

* C++ language specification: 1374 pages (and still includes plenty of "unspecified behavior" / "undefined behavior")

* Java language specification: 788 pages

* Scala language specification: 191 pages

> Odersky himself gave up on scalac and he's writing a compiler and a new
> language from scratch.

Odersky created a new language to be able to do research without sacrificing
Scala stability, which is already mainstream and should not undergo any more
major revolutions. So Dotty is for research / incubating language features,
while Scala stays on the stable side of things, letting companies like Twitter
or LinkedIn develop without fear that 2.13 will not compile their 2.12 code.

> also poorly designed overall

This is an opinion, not a fact.

> With so many features that they interact with each other in ways that are
> pretty much unpredictable.

Name three. I'm coding in it for several years, and didn't notice a single one
issue. I heard this complaint about Scala being too hard a few times very long
time ago (when Scala was at version 2.6, and its tooling was in fact
terrible), but it was always from programmers, who had also major problems
coding in Java, so I never treated this seriously.

------
munchor
I thought this was the famous paper by John Huges[1].

[1]:
[https://www.cs.kent.ac.uk/people/staff/dat/miranda/whyfp90.p...](https://www.cs.kent.ac.uk/people/staff/dat/miranda/whyfp90.pdf)

~~~
mpweiher
Same here. My favorite part of that paper:

"However, there is a very important point that is often missed. When writing a
modular program to solve a problem, one first divides the problem into
subproblems, then solves the subproblems, and finally combines the solutions.
The ways in which one can divide up the original problem depend directly on
the ways in which one can glue solutions together. Therefore, to increase
one’s ability to modularize a problem conceptually, one must provide new kinds
of glue in the programming language."

We need more kinds of glue. He argues that FP provides one (function
composition, a Good Thing™) and lazy FP another (lazy eval, a bit more
controversial).

But that's not a whole lot, is it?

~~~
marcosdumay
The last couple of decades we've seen the rise of exactly two kinds of glue
(objects and frameworks) into mainstream use. Two extra may not be a lot, but
you aren't getting many more anywhere else.

There are also high order types polymorphism, that normally comes with FP but
it not inherently linked to it.

~~~
mpweiher
Well, there's dataflow/pipes-and-filters. Constraints, especially (one-way)
dataflow constraints are awesome for gluing stuff together. I've done some
work on making messaging more flexible, messaging is pretty powerful glue.

But yes, overall, it's been fairly abysmal. Which is why I personally think we
need to really, really focus on flexible glue:
[http://objective.st](http://objective.st) :-)

~~~
nickpsecurity
I suggest looking up Paul Morrison's stuff on Flow-based Programming. He's
been using it in enterprise a long time.

Also, if looking for glue, check out Wikipedia's list of programming paradigms
or types of programming languages. Quite a few including some styles you may
have not heard of.

~~~
mpweiher
> Paul Morrison's stuff on Flow-based Programming

Yep, have the book. In fact, my own OO/dataflow stuff[1] (also a good 20 years
old now) is similar in some ways, and I am trying to merge ideas from Morrison
as much as I can.

Have also started trying it out in GUI settings[2]

[1]
[https://github.com/mpw/MPWFoundation/tree/master/Streams.sub...](https://github.com/mpw/MPWFoundation/tree/master/Streams.subproj)

[2] [https://github.com/mpw/FlowChat](https://github.com/mpw/FlowChat)

------
bischofs
I have read a lot of articles about learning functional programming to make
you a better programmer with conventional OO or imperative languages - but
this does not make sense to me.

The argument is "learn these concepts that are not available in other
languages to make you better at those languages". Can anyone explain?

~~~
ht85
Many people doing OO have trouble structuring their classes, splitting
functionalities and responsibilities properly.

OO kind of lets you do anything you want, allowing you to store data anywhere
and having any kind of flow you want. It's very easy to do something that
"just works", and while there is a lot of value in that, you can keep bad
habits for very long.

FP is a lot more constraining, and will force you to adapt how you think to
fit said constraints.

Having to think differently offers a different perspective on code
architecture, that will eventually give you ideas applicable beyond FP
languages.

~~~
Raknarg
Many would argue the exact opposite, that OO is contraining and FP is much
more free, allowing you to change your design model without having to redesign
the entire model.

------
jackmott
Does article contain references to any enpirical evidence that particular
language features or programming idioms have a benefit?

Have you noticed that these articles almost never do?

they have argument from authority and anectdote. Language research is still in
the phase of bad humors and blood letting.

~~~
cholantesh
>Language research is still in the phase of bad humors and blood letting.

Love this. Practically all the claims I've seen are just small code samples
accompanied by the author's vague endorsement.

~~~
goalieca
I've seen an number of papers focusing on the mathematical side of things.
While I'm not a PL researcher, it does seem to me that math is the universal
language and it seems reasonable to focus on that rather than non-sense
concepts like objects.

~~~
cholantesh
How would we mathematically represent usability?

~~~
goalieca
By capturing relations. If we define an algebra it will have certain
properties (eg commutative, associative). You don't think twice when writing a
physics equation on how to factor, compose, or compute a value. It comes
naturally from the rules of algebra.

In category theory we might have different categories. Some might instruct the
compiler and programmers that the function obeys certain rules when applying.
It could be trivial to parallel or perhaps it specifies a strict sequencing
for computation. Following Haskell research, you can really see the evolution
as people find more useful generalizations (which in the end, has made things
simpler!)

------
crush_xc
Does anyone have a solid place to start with functional programming? Don't
really care too much about the language it's associated with but would really
like to jump into learning the concepts behind it.

~~~
artimaeis
If you come from a C# background I really enjoy the book Real World Functional
Programming [1]. The way it lays out samples side by side with C# and F# is
pretty great and really helped me start to understand functional programming
and F#.

[1] - [https://msdn.microsoft.com/en-
us/library/hh314518.aspx](https://msdn.microsoft.com/en-
us/library/hh314518.aspx)

~~~
douche
That is a pretty excellent book, and definitely agree that it is helpful
seeing the C# and F# code for the same example laid out side-by-side to
compare. It helps a lot for those situations where you can't just switch to a
functional-first language, but you want to use more functional constructs in
your code.

After all, if you try hard enough, you could code in a functional style in C.

------
panic
_> If a company hires software engineers, there’s a good chance that critical
parts of their business exist in the form of computer code. Therefore the
growth of that business is closely linked to the maintainability of that code.
Businesses adapt and grow constantly, they perpetually change. New features
and new offerings to customers are added every day. Existing features are
revisited, strategies are revised, whole business models are pivoted._

There are advantages to functional programs, but I wouldn't say they're any
easier to change than imperative programs. In fact, it's often more work to
change a program where all functions depend purely on their arguments. Instead
of adding a single imperative state update, you have to add a new argument to
a whole group of functions and thread state through them appropriately.

Patterns like monads and monad transformers can make this easier, but massive
stacks of monad transformers have their own issues
([http://blog.ezyang.com/2013/09/if-youre-using-lift-youre-
doi...](http://blog.ezyang.com/2013/09/if-youre-using-lift-youre-doing-it-
wrong-probably/)).

(And besides, most functional programming languages apart from Haskell support
mutable state (e.g. ML ref cells, Scheme set!) -- pure functions aren't
fundamental to the functional paradigm.)

~~~
efnx
Refactoring Haskell code has been the best refactoring experience I've ever
had, and I've worked with "a lot" of imperative languages. IMO the biggest
boost in maintainability is by adding a (typed) compilation step - after that
the stronger the type system, the better.

------
hota_mazi
I wish someone would one day write a more objective article, such as "Why some
aspects of functional programming are useful while some other aspects are an
inconvenience to produce good code".

~~~
developer2
Because there are no valid _objective_ qualities as to why functional
programming is any "better" or "worse" than the alternatives. At the end of
the day, you're instructing the machine to do the same work, regardless as to
the structure of the code you're writing.

Functional vs. an alternative is nothing more than visually different styles
that result in developers having a personal preference. Some languages offer
optimizations for certain constructs, but even those depend on the
implementation found in each language. A functional language doesn't
automatically grant objectively better qualities, whereas a specific
functional language might provide advantages that have everything to do with
that specific language rather than the fact it happens to be functional.

Functional languages are interesting and the right tool for the job for many
people. But they are not better, and when you have developers fighting hard to
defend their language as "better", recognize that has a lot more to do with
their ego than anything based on facts.

------
disantlor
i'll say on any post here that's even slightly related: learning functional
reactive programming (in my case via Bacon.js) improved my code, and my
thinking about code, by orders of magnitude. Now, the only bugs are related to
me not fully understanding/encoding the business logic and i can make
complicated changes with extreme confidence, and as you can see i'm eager to
tell people about it.

------
jorgeleo
functional is simple, oop is easy

[https://www.infoq.com/presentations/Simple-Made-
Easy?variant...](https://www.infoq.com/presentations/Simple-Made-
Easy?variant=show&utm_expid=14598459-9.T3WK-0v0SHy21kchz98AYg.1&utm_referrer=https%3A%2F%2Fwww.google.com%2F)

------
aglavine
The irony is that Haskell had sorting wrongly implemented for awhile

------
iLemming
Functional programming is here already and even in OOP languages. What really
matters though - is why we should be using languages like Clojure, Haskell,
and Ocaml.

------
BuuQu9hu
This misguided blogger thinks that object-based programming is necessarily
about members and inheritance. It isn't. It's about message-passing and
uniform interfaces and bundles of state and behavior. It's about ravioli code
and modules and separation of concerns.

~~~
weatherlight
Then Erlang is the Ultimate OO language, amirite?

... Alan Key, who coined the term "Object Oriented Programing" identified the
following his definition of "object oriented":

"OOP to me means only messaging, local retention and protection and hiding of
state-process, and extreme LateBinding of all things."

Alan Key though Java and C++ were abominations. However he may feel, THAT is
the state of Object Oriented Programming today. Objects are instances of
classes, which typically also determine their type. :/

~~~
BuuQu9hu
There's an entire branch of the Smalltalk family with no classes, just
prototypes, with Self, Python, JS, etc. and there's another branch without
prototypes or classes, with E, Monte, etc.

You're not wrong that Erlang and Scheme are just as much about objects and
message-passing as they are about actors.

Kay may or may not agree with me, but I like to require a facet he mentioned
in another discussion once: The _uniform calling interface_. This is the
property of objects that you may send any message to any object. If you
require this, then Java and C++ disqualify themselves neatly.

