With this article, we will explore what pure/impure functions are and their differences in JavaScript. Let's dive in..
What is a funct...
For further actions, you may consider blocking this person and/or reporting abuse
Interestingly, due to the way JS works, it is possible that this function:
could cause side effects, and even return a different value each time it's called - even with the same inputs. It all depends upon what
a
andb
are. So, in a VERY strict sense it can be argued that it isn't pure. I'll explain further if you don't know what I'm getting at.Different values each time:
Side effects:
Well on the first example, the inputs are not the same in both executions, because
performance.now()
returns a value, hence you are callingadd(1, 22278);
the first time andadd(1, 49557);
the second one. By that meansadd
is still a pure function in the first example.I get your point on the other one and there are tones of nuances into this topic, in this specific use-case TS helps a lot:
So you end up with fine tuned control on how the given function is used. Of course you can still do dynamic stuff and trick everything in runtime but still you need to explicitly put effort into breaking it most of the time (specially if the types are well defined everywhere).
Best regards
Not at all, the inputs are identical each time. The second of which is an object, with an unchanged method. Nothing about the input to the
add
function has changed on the second call. JS itself will call thevalueOf
function during coercion - after it has been passed in.We both know each other from the community and I'm pretty sure you understand that abstracting an impure function such
performance.now()
doesn't avoid getting different values each time you call it (to a precision of 5 milliseconds in this case). I don't have time right now to discuss with troll statements to stress it further (even though you know I like it a lot)The usage of
valueOf
in the example is pretty neat, though πYou've misunderstood the code. I was just pointing out that the inputs to
add
on both calls are the same. I'm actually curious if it would be possible to write a 'true' pure function in JS that would take into account all the coercion quirks π€Yes, I understood that.
What I'm trying to point is that you did the weirdest function composition (as reference to the readers; an approach where the result of one function is passed on to the next function, which is passed to another until the final function is executed for the final result) I've ever seen to twist the topic π but it keeps being just that, and the
add
function keeps being pureThe "hack" if you will, of overriding the valueOf property referencing it to a function which happens to retrieve a different value each time... Was a pretty neat trick, I've to confess ππΌπ
I think you're confusing values and references. A pure function produces the same output if the input values don't change. In your example you dont change the input reference, but the reference can be a variable, which can hold different values. If you hard code the values into the pure function call, it will produce the same return value each time even in JavaScript.
The input values are not changing at all, but the values I use induce JS to call other functions (via it's coercion behaviour) - despite that not being entirely obvious. I'm pointing out that a seemingly pure function can (in JS) be made to behave in an impure manner.
Now lets try with some execution delay making performance.now() produce different values
As you can see, your example was entirely fabricated, which we have come to expect because you are a troll. Shit, I fell for it again...
Your example is entirely different - you are forcing the coercion to happen outside, resulting in something different to my example being passed in to the
add
function. The fact is I pass in identical values - a number and an object, and get different values out. I'm just pointing out some of the interesting behaviour of JS. Not trolling at all, educating.Also,
performance.now()
is entirely irrelevant. You could put anything here that returned a different value each time. This was just the first thing that popped into my head.Aww you messed up, you admitted in your last sentence that the value is different each time, thus the rules of pure functions are being respected. Different input, different output.
Didn't mess up - I said something that 'returned' a different value. What is being passed in is an identical object, with an unchanged method. The fact that JS calls that method after it is passed in doesn't change the fact that it was the same thing passed in.
Yes you tried to trick it by passing in an object with a valueOf method. Pretending the valueOf method doesnt mean anything, however it does mean something, it means the value of your variable changes, as you have already admitted. Therefor, different input value -> different output. I will admit that the moment the reassignment happens, is inside the purefunction, so its a clever trick, however, as was already demonstrated, if you force the reassignment outside the pure function, it becomes appearant that it is infact a variable with a different value each time.
If you force the coercion outside, then you are very definitely passing in a different value. My initial comment merely pointed out that if we take the definition of a pure function VERY strictly, then due to the way JavaScript works there are circumstances under which the function can be made to behave in an impure manner.
These aren't 'tricks', they're part of the way JS works and are valuable to understand π
Ok yes, I see the value of (pun intended) understanding how JS works. I still don't agree that it strictly violates the pure function rules though. Other languages have similar features, afaik pretty much every OOP language has a toString method that can be abused in the same way. The responsibility falls on the developer, when such methods are used to supply input values to a pure function imho.
I would say that quirks are not a desirable feature of a language. In fact, your example has highlighted a disadvantage of typeless languages.
Using TypeScript would have made your edge case, redundant.
Typed languages, even ones that are transpiled, allow every member of a team to understand precisely, how every data structure, should work. This makes it less likely that bugs will arise, in the code.
Possibly not desirable, but still a part of the language - not necessarily an advantage or a disadvantage. I also have long experience with typed languages (I've been programming for 39 years), and greatly enjoy the freedom that languages like JS give you. It's far easier to be creative, faster. When I first discovered them, it was like a breath of fresh air. Working with them requires a different mindset for sure, but I think it's worth it.
A valid point for typeless languages.. JS can be beneficial in certain situations and can do unexpected things due to some factors..
On otherside, TS don't completely stop the bugs. Let's say, With the strict typing, developers still can make mistakes in their code or have unexpected behaviors due to some factors..
I would like to add that the selection of language depends on the specific needs of a project. Both languages have their own strengths & weaknesses..
Thanks you for your feedback.
Thanks a ton to @jonrandy to come up with an interesting topic for this article..
Programming languages never do 'unexpected' things. They do precisely what they're told according to how they function. If anything seems 'unexpected'' it is mostly likely due to an error in your logic, or a gap in your knowledge of the language in question π
Yes of course, it's not a fault of programming language but developers. Due to misunderstanding of language. It can happen with many languages not just JS or TS..
It is unfortunate to hear that you are having a bad experience. There are many things that can be done to help improve the situation. First, make sure you have found the right resources to assist you.
Hello @jonrandy
Your statement is wrong in my opinion..
The use of
performance.now()
inb
is a special case that can cause the function to produce different results for the same inputs but this is not somethin that would typically be encountered in most real world use cases..Below is a Pure Function in JavaScript, designed to take the argument in number format only. If you pass
5
,5
it will return10
. Very simple example of pure function..when you pass the object/function as an argument which is completely wrong usage of
add
function. It's not designed to handle the object typed values. At the end,add
function is still a pure function..In most cases the inputs to a pure function will be primitives or immutable data types and the function will operate solely on those inputs without any side effects.. when we talk about the pure functions we assum that the inputs are of a reasonable type and that the function does not have any side effects beyond its return value.. the edge cases like the ones you have presented, they do not fundamentally change the idea of pure functions..
My comment was in no way designed to criticise your post, or to say that you were wrong. I just wanted to highlight that if we take the definition of a 'pure' in a very strict sense - then it is possible to say that (in JS at least) a lot of functions that look pure could actually be considered impure due to the language's nature.
These quirks of JS are not 'poison', or things to be avoided - they are an integral part of how the language works. Learning about them will bring you a deeper understanding and will benefit you when trying to work out the seemingly 'odd' behaviour that JavaScript sometimes exhibits. They can also be put to good use, and achieve things that you wouldn't even think were possible.
Over time there does seem to be a trend towards preaching 'readable' code at the expense of neglecting language features deemed 'difficult' or 'esoteric'. This is worrying as it can only ever lead to a diminishing knowledge of the languages, and decreasingly skilled programmers. Learn all you can about a language, embrace its quirks and inner workings, use them to your advantage - you'll be a much better developer for it. Also, remember that 'readability' is subjective.
@jonrandy
I respect you and your comment/feedback. I said your statement
const b = { valueOf: () => performance.now() }
was wrong in my opinion, not you or your concern.Your concern was correct but If you pass wrong values to a function, it may cause unexpected things.. A pure function can't handle every cases. There are so many ways to tweak the behavior of a pure function.
Thank you for bringing this scenario up..
I have fixed that pure function using
typeof
validation in JS only:Is above function a pure or an impure function? Your thoughts??
You may have designed it to take 'number' values - but with JavaScript's in-built coercion behaviours, it is perfectly possible to create other types of object that have a numeric value (can be co-erced to a number). There are completely valid use cases for this, and your function will still work perfectly fine with objects such as these.
I gave an extreme (non-practical) example to illustrate a point, but is not wrong to use functions such as
add
above with different types of inputs that actually have numeric 'value' via coercion. This is a key feature of JS.Yes correct.. Our function should be capable to handle such expected cases to bypass the coercion behaviours..
Maybe, but bypassing instead of embracing the coercion behaviours will reduce the utility of your function and make it unnecessarily complex.
Ofcourse it will become more complex..
Will it make sense for pure functions, if I write it down as below:
1) With function usage explanation in JavaScript
2) With function usage explanation + typeof validation in JavaScript
3) With function usage explanation in TypeScript
Thank you, that's insane, I hate and love JavaScript
@jonrandy
just like how a human body works smoothly when given healthy foods. On otherside, pure functions work as intended when given appropriate inputs and operated on without any side effects. But but but, just as giving a human unhealthy or poisoned foods can lead to negative consequences. Same way, providing impure inputs or using impure functions can lead to unexpected results. That;s why, it is important to use pure functions with appropriate inputs to ensure that the program operates smoothly as intended..
valuable article
Thanks for your feedback bro
This is a great walkthrough of pure functions.
This might not apply to JS but in some languages, e.g. C#, it's possible to change the next line that gets run in the debugger. Pure functions are great because of their idempotence (i.e. the same inputs give the same outputs, as mentioned in the article), meaning that they can be run over and over if necessary during the debugging process to understand what's going on.
By they way, how did you create the cool animated graphics?
Thank you my friend for bringing up an interesting point of pure functions with debugging.. BTW I use canva.com to create animated graphics..
Interseting article
Thank you bro
One more benefit of pure functions - they can be memoized, b/c of their nature to produce the same result for the same arguments
Make sense. Thank you for sharing your thoughts
Π‘ongratulations π₯³! Your article hit the top posts for the week - dev.to/fruntend/top-10-posts-for-f...
Keep it up π
Thanks a ton man
Interesting, thx!
Thank you boss