Cofounded Host Collective (DiscountASP.net). Cofounded Player Axis (Social Gaming). Computer Scientist and Technology Evangelist with 20+ years of experience with JavaScript!
There seemed to be a theme forming so I attempted to come with with an example that held true to their original questions.
While that other article was simply to demonstrate how a ternary operator could replace all instances of if/else, I also didn't provide any functional alternatives.
So I guess you can see how this awkward example was born.
Javascript is an imperative language, with some features that allow functional programming. Quite a few libraries (like Sanctuary that you have mentioned) were written to levitate these features into a functional ecosystem - but it still looks forced compared to languages like Haskell that were created for FP, or even languages like Rust that were created with FP support in mind.
Notice that in the first two responses you have linked to (I'll touch the third one later) the if statement was used to do side-effects - mutate a variable or call a function without using it's return value. Side-effects are imperative programming - functional languages usually try to avoid them - or at least discourage them or work around them.
So, what you are trying to do is do an imperative task using a functional API that was forced on an imperative language's syntax. I would be surprised if it didn't turn out awkward...
Now, let us look at the examples from the responses to your article:
(purely functional random number generation is a bit complex, so let's ignore that part for a moment)
If I were to rewrite this into functional programming using the ternary operator, I would do this:
constj=0consti=(Math.random()>0.5)?j+1:j
We are doing FP - the point is not to mutatei, the point is to bindi to the result we want. Since JS does not support shadowing, I renamed the original value to something else.
In this case, I don't know what doSomething() does so I can't make it functional - but you can be sure it involves rewriting doSomething() to return a value instead of doing a side-effect. Asking what's the functional way to do a side-effect is like asking what's the vegan way to slaughter a cow - the answer is "you simply don't".
This, of course, needs to be put into context. What are you returning from? What would you have done had you not returned here? What would be returned otherwise?
In your reply you have given such context - but that context is a side-effect, and as I've been arguing repeatedly - side-effects don't fit well into the functional style!
Well, in functional programming you don't have "statements" - only declarations and expressions. Proper functional syntax allows you do declarations inside expressions. For example, in Haskell:
foovariable=-- `if` in Haskell is an expression, so there is no ternary operatorifvariable==0-- Haskell is statically typed, and I don't want to introduce pattern-- matching here, so I return 0 instead of nullthen0elseleta=variable+15b=a*17c=b-19inc
Javascript is not a functional language so you can't do a declaration in the middle of a statement (well, you can if you open a function just to call it, but let's not get into this...). So let's utilize that Sanctuary library:
See what I did there? I've rewritten a bunch of statements that work by mutating a variable into a series of expressions where each expression's value gets fed into the next expression as an argument. This is not just forcing imperative flow into functional syntax - I've actually converted the flow itself to be functional. And this is why I could fit it into a ternary operator.
Cofounded Host Collective (DiscountASP.net). Cofounded Player Axis (Social Gaming). Computer Scientist and Technology Evangelist with 20+ years of experience with JavaScript!
Cofounded Host Collective (DiscountASP.net). Cofounded Player Axis (Social Gaming). Computer Scientist and Technology Evangelist with 20+ years of experience with JavaScript!
Yes that is definitely a better example to start with. And again, I am in agreement with you.
I had come up with that initial imperative example based on the questions I was asked on another article I had written:
There seemed to be a theme forming so I attempted to come with with an example that held true to their original questions.
While that other article was simply to demonstrate how a ternary operator could replace all instances of
if
/else
, I also didn't provide any functional alternatives.So I guess you can see how this awkward example was born.
Cheers!
Javascript is an imperative language, with some features that allow functional programming. Quite a few libraries (like Sanctuary that you have mentioned) were written to levitate these features into a functional ecosystem - but it still looks forced compared to languages like Haskell that were created for FP, or even languages like Rust that were created with FP support in mind.
Notice that in the first two responses you have linked to (I'll touch the third one later) the
if
statement was used to do side-effects - mutate a variable or call a function without using it's return value. Side-effects are imperative programming - functional languages usually try to avoid them - or at least discourage them or work around them.So, what you are trying to do is do an imperative task using a functional API that was forced on an imperative language's syntax. I would be surprised if it didn't turn out awkward...
Now, let us look at the examples from the responses to your article:
Example One
(purely functional random number generation is a bit complex, so let's ignore that part for a moment)
If I were to rewrite this into functional programming using the ternary operator, I would do this:
We are doing FP - the point is not to mutate
i
, the point is to bindi
to the result we want. Since JS does not support shadowing, I renamed the original value to something else.Example Two
In this case, I don't know what
doSomething()
does so I can't make it functional - but you can be sure it involves rewritingdoSomething()
to return a value instead of doing a side-effect. Asking what's the functional way to do a side-effect is like asking what's the vegan way to slaughter a cow - the answer is "you simply don't".Example Three
This, of course, needs to be put into context. What are you returning from? What would you have done had you not returned here? What would be returned otherwise?
In your reply you have given such context - but that context is a side-effect, and as I've been arguing repeatedly - side-effects don't fit well into the functional style!
Now, if the context was a more pure function:
We could have used a ternary operator:
Simple enough. But as someone commented - what if you have multiple statements?
For example:
Well, in functional programming you don't have "statements" - only declarations and expressions. Proper functional syntax allows you do declarations inside expressions. For example, in Haskell:
Javascript is not a functional language so you can't do a declaration in the middle of a statement (well, you can if you open a function just to call it, but let's not get into this...). So let's utilize that Sanctuary library:
See what I did there? I've rewritten a bunch of statements that work by mutating a variable into a series of expressions where each expression's value gets fed into the next expression as an argument. This is not just forcing imperative flow into functional syntax - I've actually converted the flow itself to be functional. And this is why I could fit it into a ternary operator.
These are all excellent solutions!
Based on your feedback I have reworked this article. I have come up with a (slightly) better example and eliminated the comma operator as well as tap.
Thank you for your feedback!
Cheers!
I would have kept the
getItem
part. Without it, it's unclear why you can't just do this:Examples updated!