If you have never heard about *functional programming* before, I’ll have the honor to instill in you my view on it.

If you have, you might know that it’s usually defined by some of its features, such as: reification of functions, avoidance or banning of functions with side-effects, use of higher-order functions and so on. But, doesn’t that sound like a collection of random features? What’s the motivation behind them?

I’ll present you a view which, at least to me, makes that set of features seem coherent; and functional programming, like a deep and beautiful paradigm:

Functional programming attempts to *reduce programs to equations*.

### An example

Say we have a list of real numbers and we wish to calculate the geometric mean of the positive numbers in that list.

#### Good old C

# include <math.h> // the caller of this function must keep track of // the length of x and pass it explicitly, // otherwise we couldn't know how long it is double geometric_mean(double * x, int length) { int n = 0; double prod = 1.0; int i; for(i = 0; i< length; i++) { if( x[i] > 0 ){ n++; prod = prod * x[i]; } } return pow(prod, 1./(double) n) }

#### Python

def geometric_mean(x): positives = [ e for e in x if e > 0 ] product = 1 for p in positives: product *= p return product ** (1./len(positives))

#### Functional Python

def geometric_mean(x) : positives = filter(lambda a: a>0, x) product = reduce(lambda a, b: a*b, 1, positives) return product ** (1. /len(positives))

“Well, that’s supposedly functional code, and it still doesn’t look like an equation” – I can hear you say

It does, we only need to change the syntax (semantics will stay the same), and the underlying mathematical structure will flourish before your eyes.

#### Meet APL

Yes, that’s code. It’s a language and you can actually write your next program in it. Its called APL.

This is beautiful twofold:

1- makes mathematical structure of programs explicit (so it’s easier to check its correctness) and makes code super concise (less room for bugs)

2- extends the mathematical language so that you can use it to express algorithms (if you are a mathematical savvy, think: how would you describe how to sort a list, using the standard mathematical language alone?). This was the original intent of Ken Iverson, the creator of APL. Only later were computers able to execute it. (Isn’t it weird that we have to resort to natural language or pseudo-code to express algorithms, which are inherently mathematical entities?)

thus effectively blurring the line between mathematics and code.

#### J

People looked down on APL for its non-ascii character set. Therefore, Ken Iverson created *J*, a successor of APL which restricts to the ASCII character set, and incorporates more powerful concepts along the way, such as *tacit programming*

Here are the 3 *pythagorean means* implemented in J:

arithmetic_mean := (+/ % #) geometric_mean := (+/ % #) &. ^. harmonic_mean := (+/ % #) &. %

Those are not totem-pole smileys, they are wonderfully abstract and concise *tacit functions*.

### Conclusion

I hope I have wet your interest in functional programming. Remember you don’t need to learn APL or J to think along the lines of this paradigm, as long as you can see through the syntax of imperative languages.

(* Just in case all that wasn’t enough to convince you about the superiority of the functional gospel, take this threat: FP will displace OOP, so start thinking along our lines our you will eventually lose your job)

There are more functional and Pythonic ways of writing a geometric mean function:

>>> from statistics import mean

>>> from math import exp, log

>>> data = [3, 9, 14, 18, 27]

>>> geometric_mean = exp(mean(map(log, data)))

via https://twitter.com/raymondh/status/943019371768586241

LikeLiked by 1 person

Certainly. Note a few things, however:

1- you are not filtering out the (potentially) negative values in “data”, as the python samples did.

2- Your implementation is doing the same as the J sample (it doesn’t filter values either). That’s the magic ‘under’ operator (&.)

3- I’m not sure how ‘pythonic’ would it be to map a log (possibly expensive function?) to a large ‘data’ list to partially undo it with exp later, just because it’s algebraically suitable (performance? I don’t know). I think the first sample gets the trophy as the most pythonic of the lot

Cheers 🙂

LikeLike

To get even more functional use composition instead of storing values to variables

LikeLiked by 1 person

True! I thought it would overly complicate the code since Python is not the best for that style… Specially the “max 80 characters per line” rule of pep8

LikeLike

his method is less likely to overflow for large numbers or a large set of numbers.

LikeLiked by 1 person

True, thanks for noting it

LikeLike

> I hope I have wet your interest

I hope you mean “whet”.

LikeLike

I would love to know which data led you to the conclusion that “FP will displace OOP”. I love FP. I really do. But as much as I love it, I have to recognise that some things are more suitable for OOP than FP. Having a state might be a good thing, typically when you want to represent… stateful things. Like the real world. That’s why languages like Scala, that mix OOP/FP have such a great success for video games: OOP for representing the stateful world, FP for computing.

Oh, by the way… LISP was released in 1958. It’s definitely not something new. So if FP is so great, why 59 years after it still didn’t took over OOP, which appeared with Simula 67 9 years later ?

Please don’t be like those FP fanatics that reject any other paradigm because they found an expressive and elegant way to write their code. FP is amazing, but it is not perfect and definitely not suitable for everything.

LikeLiked by 1 person

There are some obstacles that FP has to overcome. Stateful computation might be one, I don’t know if it can be considered overcome or not yet. Do you know about Haskell monads? It is also true that many of us, taking C as our first language, used to create and rely on state more than innecesary.

I don’t have all the answers regarding FP. May it be that the aparent lackings of FP are due to not yet know abstractions? Time will tell.

LikeLike

FP is about controlling state, true it’s more work, but it also gives more reliability on state modifications. The trick is to properly localise state and if possible inject it as a dependency or wrap the operation in a monad. Quite often you don’t even need explicit state! (Common) LISP is multiparadigm that does not promote FP. Furthermore, the simula and Smalltalk type of OOP is not what you find in, say, Java, C# or Python.

LikeLiked by 1 person

In clojure it’s way more understandable

(defn geometric_mean [xs]

(let [positives (filter pos? xs)

product (apply * positives)]

(power product (/ 1.0 (count positives)) ))

LikeLiked by 1 person

“understandable” is quite subjective. “Concise”, less so. And it’s easy to see that clojure is not a clear winner by that metric.

That said, I like clojure and look forward to do cool things with it. I’m waiting for the lisp lights to shine on me.

LikeLike

@bubixl If you look at the “stateful world” as a series of causally related immutable values over time, then FP is definitely up to the task of representing and interacting with the real world.

Of course there will be some impurity at the “effecting edges”, but that in no way requires an OOP approach to handle it.

I suggest you take a look at this seminal talk by Rich Hickey (creator of Clojure) for more on the topic:

http://www.infoq.com/presentations/Are-We-There-Yet-Rich-Hickey

https://github.com/matthiasn/talk-transcripts/blob/master/Hickey_Rich/AreWeThereYet.md

LikeLike