Yes, I stated that. Those functions are impure. Purity is a lovely goal, but purity also isn't a defining characteristic of functional programming, it's a modern pursuit. I've met enough classic LISP practitioners that lived their whole programming lives in the most impure of functional programming, that I would never want to tell them to their face that what they did didn't count as functional programming because of all the leaky impurity in LISP (due to pragmatic considerations of the time).
My point is that the definition of functional programming is this purity you mention not using first-class functions. Pure means that something has more of that thing you want and impure means it has less - so pure functional programming has more 'functional programming' then 'standard functional programming'. Sure completely pure functional programming is impractical - there are degrees to how purely functional are the languages we use in practice - but this is the point practical languages are more or less functional and how much are they functional depends on how much they depend on state manipulation not on using higher order functions or having first class functions.
Defining functional programming as programming with first-class functions is a consistent definition and could be used if not the fact that more people use the other definition (at least that is what the wikipedia definition and other online material makes me believe).
Sorry, but you're missing the forest for the trees. This is what wikipedia has to say: "Functional programming is sometimes treated as synonymous with purely functional programming, a subset of functional programming"[0]
In FP as an umbrella, purity is not a hard requirement for the entire paradigm, only a predominantly pipeline oriented style based around expressions is (in contrast to, say, C, where one generally passes a pointer to the same state around to procedures that pick and choose what to modify in that state bag, as a series of statements). Common Lisp and OCaml are often cited as examples of functional languages that don't attempt to enforce purity guarantees even in terms of idiomatic usage, let alone at a compiler-enforced level.
Using higher order functions for, say, promises (remember, they're stateful!) doesn't mean you're not using functional programming, just like using Array.prototype.map doesn't mean you're not using OOP (it implements fluent interfaces, if you haven't noticed). It's the absence of functional tools/techniques that qualifies a program as not functional.
IMHO, the unfortunate situation is that most JS people don't understand there are different degrees of functional-ness and certain guarantees only exist within specific subsets (and React doesn't conform to that subset).
That blog post is tagged “functional”, but Lisp isn't a functional language - not even an impure one.
Functional programming is expressing computations as the evaluation of mathematical functions whenever it's possible. Sure, some operations are intrinsically not mathematical functions (like sending data over a network, returning the system date, you name it), but, in general, data structures and algorithms should be implemented as values and mathematical functions on them.
Mathematical functions are mappings from values of a domain to values of a codomain. Naturally, if we want mathematical functions to be a basic building block for programs, we need a rich set of values on which said functions may operate.
Now, here's the thing: Lisp doesn't have compound values. The only values Lisp has are numbers, characters and references to objects. All of them are primitive and indivisible.
“But, catnaroek, what the hell are you smoking? Aren't lists, structs and vectors compound values?”
No, in Lisp, they're not. They're mutable objects whose state at any given point in time may be interpreted as a value in your favorite metalanguage of choice. Maybe if the metalanguage isn't Lisp itself, you can interpret the object's state as a useful value!
In case the above wasn't too clear, let's review the difference between values and objects:
(0) A value is something you can bind to a variable. (At least in a call-by-value language, which Lisp most definitely is.) It doesn't matter, or even make sense, to ask whether “this 2” is different from “that 2”. There is always one number 2, regardless of how many times the number 2 is stored in physical memory. Nor does it make sense to ask whether 2 will suddenly become 3 tomorrow. 2 and 3 are always distinct values.
(1) An object is an abstract memory region. Every object has an identity and a current state. The identity is always a primitive, indecomposable value. The state may be compound, but it isn't always a value. (This depends on the language.) Even if the current state is a value, the state at a later point in time might be a different value. Objects with immutable state are largely impractical - why bother distinguishing the physical identities of entities that never change?
Now it becomes perfectly clear that, while Lisp has compound objects, it doesn't have compound values. Sadly, without compound values, you can't have functions taking compound values as arguments, or returning compound values as result. Since compound entities are unavoidable in practical programming, this means you pretty much have to use objects.
“But, catnaroek, what if we encode compound values as Gödel numbers?”
Hah! Have fun with that!
---
As an exercise for the reader, for each of the following languages, determine whether it's functional or not: Scheme, Racket, Clojure, Scala, F#, Erlang, JavaScript. Justify your answers.
Functional programming used to mean programming with first class functions and closures; they even put it in the name "functional"al programming (just like OOP meant program with objects, whether this involved classes or not).
So that is Lisp, the first FP in the 60s, and then the MLs of the 70s/80s. They knew about purity, and even preferred it (for things like list comprehensions, it is very useful), but were never very dogmatic about it.
> The functional aspects mean every function has no side effect.
This is not accurate. Any function can print, can call a DB or a web service.
"Purity" (as in referentially transparent) is tangential to function programming. It can be achieved with other paradigms. That being said, functional programming does encourage it.
I'll talk about Erlang for example. Functional purity is objectively beautiful because it solves or minimizes a large number of typical problems. These problems such as large mutable states, large mutable state modifications during high levels of concurrency. A good functional language, using closures can mimic other patterns while having a very small core set of rules.
Purity doesn't mean moral superiority (although it sounds like) purity means referential purity for example, where the function when called no matter how many times with the same argument returns the same result. That is beautiful because it allows for interesting compiler optimizations, good for testing. Other looser explanations of purity are -- confinement of mutable state (this could mean monads in Haskell modifications to shared global state), immutable data structures in Erlang or Clojure.
Now that said these are all tools. As I mentioned, in practice, a lot of these people in their day job will end up using Java or C++. But the fact that they decided and managed to learn a new paradigm is what is the key.
Heck it could have been data-flow programming or logic programming (Prolog is awesome too, especially when mixed with constraint satisfaction).
Yet another way of putting it, familiarity with these things point to a level of passion and sets someone apart, that is quite desirable. Now, yes, there is a self-referential quality to it all, the more we think functional programming is a proxy for developer quality, the more people will do tutorials just to put it on their resume. Well, then the next fashion will be something else -- quantum algorithms perhaps, who knows.
For many, functional programming is just as much about expressive type systems, purity, and immutability as is about robust first-class funtions and higher order functions.
Lisp is like the python version of Haskell (as compared to Java I guess?) It's a rough metaphor but I think it makes enough sense.
Pure functional programming is always about purity, functional programming is about first class functions. Pure functional programming is a subset of functional programming, not the other way around.
I'm not really sure where you are getting your information from but everything that I have read disagrees with this idea that functional programming is about purity.
I think in recent times the term functional programming has been overloaded to mean what you describe, and many people use it that way, but I don't think it should be used that way.
Maybe we should just say "non pure functional" or "pure functional" so it's always clear what we are talking about!
A language need not force purity to allow for purely functional programs. Besides, purely functional languages all need a way to cheat to actually do anything useful. Any nontrivial program needs a mix of paradigms.
I did appreciate your original 2014 version and I still love the way you speak of Lisps. About functional programming you write "Functional programming refers to a stricter style where functions receive certain data as input, process only that data, and return a result." and it's a common way of defining it. But most languages - and Lisps too - comes with closures and lexical scoping and (IMHO) that breaks the functional purity. Thanks to a closure an inner function can work on variables defined in the outer function, free variables can be defined and used out of the arguments list. It's nothing but side effects, the function is not isolated in a black box. Maybe you can think that the lack of closure is a strong weakness of a language. It is and it is not! You can see what can be done without closures in the [lambdaway project](http://epsilonwiki.free.fr/lambdaway/). And so with a true functional language. Your opinion is welcome.
I looks like alayne is using 'purely functional' to mean Pure + Functional, but you are using it to mean Everything is an Expression / First-class functions, etc.. The functional paradigm.
Lisp is definitely a functional language. It's just not as pure as Haskell, which is the poster child for Maximally Pure FP, if not for the functional style.
Could people please stop use "Functional Programming" as a
synonym for "Pure Functional Programming"? The author uses
them interchangeably even though his arguments do not apply
to the impure style.
Functional Programming is about purity. At the core of FP is pure functions. If you don't care about purity don't use FP. There is a lot to like about React, and Hooks and so on. Just don't call it FP though.
People are now trying to redefine what functional programming means. Lisp is as close to the lambda calculus as you can get, and Functional Programming is based on lambda calculus mode of computation (VS Von Neumann procedural model).
When you write Lisp, you're mostly composing functions. It's truly very functional, just not purely functional which is probably the motivation behind your refusal to include Lisp in the functional programming language family, which would horrify the founders of the field as it's a simple attempt at redefining a widely used, well understood term to become a small subset of it for reasons of gatekeeping what we should, according to you, include under the term without any real technical reason behind it.
Generally, yes. Some languages are really hardcore about it (notably Haskell), while others just strongly encourage you to write functions without side effects. Ed: that's the "purity" they're talking about in OP.
The other major neat thing about functional languages is how they let you treat functions like objects, but most modern programming languages have adopted that as well, so it's not a big differentiator anymore.
reply