It can be considered pure when you only give it one or two arguments (the second argument can be allowed because numbers are passed by value and not reference in JavaScript).
Default arguments make the code harder to understand. It's often better to make two functions. If they are closely related then you can implement one in terms of the other. Even worse if the function behaves completely differently depending on how many arguments it takes (take the D3 setters/getters as an example).
function pureFunction(data) {
return pureFunctionWithIndexAndResult(data, 0, []);
}
function pureFunctionWithIndexAndResult(data, index, result) {
...
}
It doesn't matter how many arguments there are.
My point was that calling the function will mutate one of its arguments and in fact, in the example the returned value of the function is irrelevant because nothing is assigned to the return value of the function when it is invoked. So it's actually just plain wrong. The function is called and a side effect of calling the function is the mutation of the supplied 'result' argument. Call the function 4 times and you get a different result every time. Not a pure function.
The functional boss micromanages you too, just differently than the imperative boss. The functional boss depicted in the article should really be called the declarative boss.
Notice how strange his or her requests are:
"Schedule a meeting whenever you feel it is necessary" - what if I feel that surfing facebook is more necessary?
"...after you get 3 sales leads by the end of the week" - what if I won't be able to get 3 leads by the end of the week? What is more important, getting 3 leads or getting something by the end of the week? I don't know. Maybe a Sufficiently Smart Employee will be able to figure it out, but he or she is not yet hired.
In the meantime the imperative boss gets a steady stream of leads. And the declarative boss goes out of business after some time.
"what if I won't be able to get 3 leads by the end of the week? What is more important, getting 3 leads or getting something by the end of the week? I don't know."
If you won't be able to get 3 leads by the end of the week, it means you get Nothing.
This reminds me of a blog post (about currying specifically) from an ardent FP proponent that I picked up on HN not long ago, where he back-pedals (his own word) from a much-shared pro-currying in JS article:
On a personal note, immutability is fine, but doing it in Javascript comes at a cost and it always feels like I'm fighting the system (have to deep-copy objects and possibly even `Object.freeze()` objects, space-saving write-on-copy needs to be done by myself, no pattern-matching). So I only do it when I'm sure it is useful. Similar with some other FP concepts that feel natural in "real" FP languages.
Also, very few of the functions that cause me any headaches benefit from being pure (in a way that would help me), because my problem is with the consistency and state of the data in (shared) storage. I rarely have issues within the app itself, so "purity" there does not help me all that much in my very I/O heavy applications. It seems much more suited for data processing.
My intention to write this article is for introducing FP concept to someone who never touch it. So, imho the best way to introduce FP to a beginner is by using the mainstream language, and for this case I use JS.
FP is not a silver bullet, so do imperative. By knowing those 2 paradigms you can get the right tool for the right job. I also don't want to do I/O heavy application with the "purity" thing. Hence in language like Clojure, we can still doing "the side-effect" thing.
The Scala course running (for free, if one ignores the IMHO useless certificate offerings) on Coursera and authored by the guy who also invented Scala in the first place seems to be a great pointer to send people new to FP to. Sure, teaching the parts that are useful (for that system) in Javascript is one more option, but maybe use several methods, and a "real" FP language and an actual FP course with exercises and course forum and all that stuff is probably one of the better options.
> Imperative programming is a programming paradigm that uses a sequence of statements to reach a certain goal. It focuses on how to perform actions to achieve the expected result.
But, but, but... I live my life like that. I focus on the next action to achieve my goal.
The two examples remind me a bad TV shop advert starting with the black and white trash old way of doing things.
The problem with these articles is that they are often biased towards one side which is often FP, because impreative programming is not sexy.
I'm not saying that FP is bad or inferior :) It just has its places and I still have to read an article which clearly states good use cases for FP rather then selling it me as a religion.
But...but...my life is like that macromanager Lol. Don't worry, sometimes I'm also doing micromanaging. I'm not trying to tell imperative is bad, because I'm still using it when I feel FP is not efficient.
I wrote that article to introduce FP to anyone who wants broaden their knowledge. By knowing another paradigm, we will get the right tools for the right jobs, right?
The micro/macromanager analogy is flawed IMHO. I can write modular, component based code imperative style. It won't be worse than please().do().this().for(me)
> I'm not trying to tell imperative is bad
"In another word, the imperative one is an annoying micromanager" ;)
> By knowing another paradigm, we will get the right tools for the right jobs, right?
Yes, if you not only introduce the paradigm, but tell them when it makes sense to use it. I haven't seen it in your article.
> According to sample number 2 above, we will read the loop 4 times to track the current value of sample. Imagine if you have an array with 1000 elements inside it.
That is one of that.
> ...made our code more concise
and also in the summary. Well, I know maybe "concise" is a subjective thing :)
I've read that, but it really depends on the bug. A simple console.log would catch it easily. I think you need debugging skills in FP right?
I don't always prefer concise code. It means that I have to keep everything in my head, what the function does exactly.
So what I miss is real use cases. Would you write a video editor in FP? Would you make Quake 4 in FP? Is it good for Todo apps? CLI apps maybe? Or is it best for 50 line microservices?
20 comments
[ 3.3 ms ] story [ 62.9 ms ] threadDefault arguments make the code harder to understand. It's often better to make two functions. If they are closely related then you can implement one in terms of the other. Even worse if the function behaves completely differently depending on how many arguments it takes (take the D3 setters/getters as an example).
> The concat() method returns a new array comprised of the array on which it is called joined with the array(s) and/or value(s) provided as arguments.
Taken from the MDN.
Notice how strange his or her requests are:
"Schedule a meeting whenever you feel it is necessary" - what if I feel that surfing facebook is more necessary?
"...after you get 3 sales leads by the end of the week" - what if I won't be able to get 3 leads by the end of the week? What is more important, getting 3 leads or getting something by the end of the week? I don't know. Maybe a Sufficiently Smart Employee will be able to figure it out, but he or she is not yet hired.
In the meantime the imperative boss gets a steady stream of leads. And the declarative boss goes out of business after some time.
If you won't be able to get 3 leads by the end of the week, it means you get Nothing.
https://hughfdjackson.com/javascript/does-curry-help/?utm_so...
On a personal note, immutability is fine, but doing it in Javascript comes at a cost and it always feels like I'm fighting the system (have to deep-copy objects and possibly even `Object.freeze()` objects, space-saving write-on-copy needs to be done by myself, no pattern-matching). So I only do it when I'm sure it is useful. Similar with some other FP concepts that feel natural in "real" FP languages.
Also, very few of the functions that cause me any headaches benefit from being pure (in a way that would help me), because my problem is with the consistency and state of the data in (shared) storage. I rarely have issues within the app itself, so "purity" there does not help me all that much in my very I/O heavy applications. It seems much more suited for data processing.
FP is not a silver bullet, so do imperative. By knowing those 2 paradigms you can get the right tool for the right job. I also don't want to do I/O heavy application with the "purity" thing. Hence in language like Clojure, we can still doing "the side-effect" thing.
But, but, but... I live my life like that. I focus on the next action to achieve my goal.
The two examples remind me a bad TV shop advert starting with the black and white trash old way of doing things.
The problem with these articles is that they are often biased towards one side which is often FP, because impreative programming is not sexy.
I'm not saying that FP is bad or inferior :) It just has its places and I still have to read an article which clearly states good use cases for FP rather then selling it me as a religion.
I wrote that article to introduce FP to anyone who wants broaden their knowledge. By knowing another paradigm, we will get the right tools for the right jobs, right?
> I'm not trying to tell imperative is bad
"In another word, the imperative one is an annoying micromanager" ;)
> By knowing another paradigm, we will get the right tools for the right jobs, right?
Yes, if you not only introduce the paradigm, but tell them when it makes sense to use it. I haven't seen it in your article.
> According to sample number 2 above, we will read the loop 4 times to track the current value of sample. Imagine if you have an array with 1000 elements inside it.
That is one of that.
> ...made our code more concise
and also in the summary. Well, I know maybe "concise" is a subjective thing :)
I don't always prefer concise code. It means that I have to keep everything in my head, what the function does exactly.
So what I miss is real use cases. Would you write a video editor in FP? Would you make Quake 4 in FP? Is it good for Todo apps? CLI apps maybe? Or is it best for 50 line microservices?
Btw, is using map, filter, reduce considered as using FP too? I always use it in my Swift and JS code.
One of the thing that I can't use FP is in embedded development (arduino and esp8266).