DEV Community

Discussion on: Functional programming and pure functions

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.

Thread Thread
 
pentacular profile image
pentacular

A procedure is never a function, but it can implement a function - we call this an algorithm.

If map were a pure function you would not be able to compose it with a procedure in the first place.

Thread Thread
 
macsikora profile image
Pragmatic Maciej

If function is not a part of language then we can only make it from procedure by making it referencial transparent. If procedure is referencially transparent then it can be called a function. If not then we cannot name anything a function outside of pure FP languages. But this is more about naming, I have no problem to name everything a procedure as it would be at least better than naming everything a function , what is in a most false in imperative languages.

The thing is that map usage is referencially transparent if we pass to it another referencially transparent function. If we don't the composition is a procedure as you have stated, but IMO if function itself doesn't make side effects we can name it a function, it is fully ok and should not be confusing. As I stated before your opinion makes every HOF not pure even though it's implementation has nothing impure.

Thread Thread
 
pentacular profile image
pentacular

A procedure can never be called a function.

However, as I've said, you can use a procedure as a way to implement a function.

It's important to understand that it's still a procedure, and it's still executing a series of operations over time, as opposed to being a time-invariant relationship.

HOP (higher order procedures) can implement functions, while not being functions -- but the distinction remains.

I don't think we're particularly disagreeing, except on your use of "is" vs "implements".

Thread Thread
 
macsikora profile image
Pragmatic Maciej

Ok, yes I think your way of stating that is correct. Function can be implement by procedure. And .map can be co considered as HOF implementation if we use another transparently referencial procedure as an argument.