DEV Community

Discussion on: A simple tip for cleaner code

Collapse
 
joelnet profile image
JavaScript Joel

For some reason the younger devs in the team prefer to write code this way ☝️, but the truly enlightened devs will write code like this:

const foo = bar =>
  bar > 0 ? 'YES'
  : bar === 0 ? 'MAYBE'
  : 'NO'
Enter fullscreen mode Exit fullscreen mode

or like this:

import { always, cond, equals, gt, T } from 'ramda'

const foo = cond([
  [gt(0), always('YES')],
  [equals(0), always('MAYBE')],
  [T, always('NO')],
])
Enter fullscreen mode Exit fullscreen mode

Use a single return!

p.s. also be careful of ageism ;)

Collapse
 
sergioluigi profile image
Sérgio Luigi Alves da Silva

I have personal restrictions about ternaries within ternaries

Collapse
 
tunaxor profile image
Angel Daniel Munoz Gonzalez

while I personally go for the first one, I tend to be a little bit more explicit by doing the OP's last example, because I've worked on code bases where there's a lot of new devs and they tend to break (and some times don't even touch them by fear) too much these ternary/single return statements, while I don't think they are bad, some times I just care more about explicitness for the rest of the team/teams, on my personal projects tough you will find more ternary/single return samples :smile:

Collapse
 
srsholmes profile image
Simon Holmes

That second one with ramda is a prime example of garbage code from a developer proving theyve read some functional programming books / blog posts. Why would you ever do that as opposed to the nested ternary? Functional programming is great but the use of ramda is complete nonsense for that example.

Collapse
 
borisozegovic profile image
borisozegovic

Joelnet, those two are not as readable as last example from Sasa, they have a higher mental load.

But I agree with you, better style comes with age and experience. :)

Collapse
 
joelnet profile image
JavaScript Joel

This is due to familiarity bias.

It's easier for you to understand OP's examples because you have been exposed to them.

It's like reading a new word for the first time. You have to sound out every letter. But as you see that word more often, you can understand it at the quickest glance.

This does not mean that word is harder than other words you have already learned. You just haven't become familiar with it yet.

Learning more words will only improve your mastery over the language. And who knows, there may come a time when that word will be the one that will perfectly convey your message.

Cheers!

Thread Thread
 
borisozegovic profile image
borisozegovic

No, no, I use arrow functions daily, but my mantra is that shorter is not always better. For me, double ternary is not readable and has higher mental load and we don't have any advantage over simple 'if else'. Writing is cheap and quick, reading is not. :) You also must take in consideration other developers who might not prefer ternary and double ternary and they will not be happy reading this. :)

Thread Thread
 
alainvanhout profile image
Alain Van Hout

It’s an incredibly important skill to be able to say something in a simple way. A large vocabulary is useful, but doesn’t guarantee (or can even decrease) clear communication.

Collapse
 
blackcat_dev profile image
Sasha Blagojevic

Looks like the simplicity of my example stands in the way of the message I'm trying to convey.

If we take the examples literally there is no issue, a single line ternary

   return $bar > 0 ? 'YES' : ($bar === 0 ? 'MAYBE' : NO)

But if we have code between the condition and the return statement, you cannot use a ternary oh enlightened one ;)

Collapse
 
joelnet profile image
JavaScript Joel

Yes your example was a simple one, though simplicity is not a factor as any program can be expressed as a single expression, regardless of the simplicity. Therefore any example can be converted into a conditional ternary. Though it may is possible not look the cleanest or be the best solution.

But if we have code between the condition and the return statement, you cannot use a ternary oh enlightened one ;)

☝️ This statement can be proven false with this block of code:

const foo = bar =>
  bar > 0 ? (
    console.log('Execute some code here for YES'),
    'YES'
  ) : bar === 0 ? (
    console.log('Execute some code here for MAYBE'),
    'MAYBE'
  ) : (
    console.log('Execute some code here for NO'),
    'NO'
  )

To demonstrate my point that you can write any application as a single expression, you can read my article where I have written a fully functional Promise library, a fairly complex program, as a single function expression. dev.to/joelnet/challenge-program-w...

The good thing about using a ternary operator is that when the operator becomes complicated, it is a signal that your function needs to be broken down into smaller pieces. Where as with the if statement, you can easily add too many statements without receiving this signal and end up with a function that breaks the Single Responsibility rule.

  • The Enlightened One

mic drop

Thread Thread
 
blackcat_dev profile image
Sasha Blagojevic • Edited

Just because you can do something does not mean you should, have fun maintaining your library :)

Thread Thread
 
aramix profile image
Aram Bayadyan

Just because you shouldn't do something it doesn't mean you can't ;)

Thread Thread
 
blackcat_dev profile image
Sasha Blagojevic

True as well :D

Collapse
 
jbristow profile image
Jon Bristow • Edited

I’m fine with the quick return for validation or a guard as long as it’s right at the beginning of a function.

I’d rather have one single exit point for my function though since having multiple outs adds to the chances that someone will add code between the two exits without realizing it.

A “better” solution:


# python 2 only. Cmp was taken from the code golfers in python 3.
def silly(bar):
    output = {"-1": "NO", "0": "MAYBE", "1": "YES"}
    return output[str(cmp(bar,0))]

# LATE EDIT FOR MAXIMUM UNREADABILITY:
def silly(bar):
    return {"-1": "NO", "0": "MAYBE", "1": "YES"}[str(cmp(bar,0))]

If your function is equivalent to a nested ternary, then that’s a good use of early return. Anything more complicated needs to have the contents of the If statements extracted into methods to more clearly show off your now ternary equivalent ifelse

Thread Thread
 
joelnet profile image
JavaScript Joel

I think OP's original example uses the conditions == 0, > 0 and < 0, so a hash table wouldn't work for 2 or -2.

Thread Thread
 
jbristow profile image
Jon Bristow • Edited

I think if you look closer, you'll see that my solution is equivalent in output to the OP's example.

Here's a nastier one (also with a py3 equivalent)


# python2
def really_silly(bar):
    return ["MAYBE","YES","NO"][cmp(bar,0)]

# python3
def extremely_silly(bar):
    return ["MAYBE","YES","NO"][(bar>0)-(bar<0)]

God, I love how awful python can get sometimes!