DEV Community

Functional programming and pure functions

Shirley on August 20, 2020

I have had interviewers ask me what functional programming is. I have heard of the term but never known what it really was until recently. Functi...
Collapse
 
pentacular profile image
pentacular

Well, the map method performs a series of operations in a particular order over time.

So it's not a pure function -- but with discipline it can be a procedure that implements a pure function.

However, there's no requirement that it does -- consider the following.

let n = 0;
const sums = [1, 2, 3].map(a => n += a);
console.log(n);
console.log(sums);
Enter fullscreen mode Exit fullscreen mode

Which demonstrates its procedural nature clearly.

Collapse
 
rsa profile image
Ranieri Althoff

map is as pure as the function you pass as an argument, what you have there is just a very poor usage of what should be reduce.

Also note comment from Iven below about how pure functions interact with the scope it is closed over.

Collapse
 
pentacular profile image
pentacular • Edited

It might be, if map were not specified to perform a series of operations in a particular order.

This makes map in javascript resolutely procedural -- it's not a time invariant relationship.

But sure -- with discipline you can avoid making any of this procedural behavior visible to the user.

Iven's comment does not seem relevant to this.

Thread Thread
 
macsikora profile image
Pragmatic Maciej

You have no access to map and what it does (until you change the Array prototype). What you are showing is that you have passed procedure as predicate to the map function - .map(procedure). It means that you didn't change the map, and map doesn't make any side effects, the procedure makes them. In language with allowed mutation it is natural that you can do that whenever you want, but it doesn't change that map is pure function.

Thread Thread
 
pentacular profile image
pentacular

I know what map is specified to -- it's in the language specification.

callbackfn should be a function that accepts three arguments. mapmap calls callbackfn once for each element in the array, in ascending order, and constructs a new Array from the results. callbackfn is called only for elements of the array which actually exist; it is not called for missing elements of the array.

So we know that map is a procedure that executes a series of operations in a particular order over time.

[...]

mapmap does not directly mutate the object on which it is called but the object may be mutated by the calls to callbackfn.

And we know that map must be composed with another procedure to be called.

Which means that it's not meaningful to talk about map by itself, you need to talk about how it may be paramterized.

So, the best that you can say is that map can be a procedure which implements a pure function providing you pass it a procedure implementing a pure function for it to call.

But outside of this special case, it's just another procedure.

Thread Thread
 
macsikora profile image
Pragmatic Maciej

Yes map is a procedure but it is a procedure which doesn't make any side effects, and such procedure is a function. Saying that map is impure because you can pass to it statefull procedure is the same as saying every higher order function is impure as you can pass to if smth impure. That is not true - your call of map is impure because you pass to it smth impure, but map itself is a pure function.

Collapse
 
iquardt profile image
Iven Marquardt • Edited

independent (do not use values in surrounding environment)

Not exactly. A pure function may be also a closure and read from free variables of the parent scope it is closed over.

Please note that FP also means programming with values, because side effects and other computational effects are encoded as values.

Another perspective is that FP is about local and equational reasoning. Saying that FP is about purity and higher order functions is okay as well but it is a rather technical perspective.

Collapse
 
macsikora profile image
Pragmatic Maciej

Yes, that is why for example global values are fully ok in FP as they don't change in time. Also encapsulation by closures is still FP until we don't mutate, when we start mutation of what we have closed in a closure we change paradigm into OOP, as object can be considered as closure with private state and exposed behavior.

Collapse
 
samrocksc profile image
Sam Clark

great quick reference article!