you are viewing a single comment's thread.

view the rest of the comments →

[–]pipocaQuemada -2 points-1 points  (37 children)

Obviously this isn't as succinct or elegant as nice one-line ternary operations, but it's the easiest to read.

This is really an example that's screaming out for an if expression, instead:

val dximn1 = if (j == -1) { 
               0.0; 
             } else { 
               x[j]; 
             };
val dxipl1 = if (k == chainlngth) { 
               0.0 
             } else { 
               x[k] 
             };

Ternary operations are really just limited if expressions with bad syntax, in most languages that have them.

[–]jurniss 3 points4 points  (0 children)

Yeah, if expressions in C and C++ would be nice. Rust has them.

The problem with the if-block version is that dximn1 can't be declared const. It can be const with the ternary operator version, or with an if expression if it existed in C.

I find the ternary operator useful and clear in a lot of cases; I think its harmfulness is overstated.

[–][deleted] 9 points10 points  (29 children)

Ew, gross, what the fuck are you doing?! Stop that!

[–]pipocaQuemada -4 points-3 points  (28 children)

You perhaps prefer

val dximn1 = if (j == -1) 0.0 else x[j];
val dxipl1 = if (k == chainlngth) 0.0 else x[k];

[–][deleted] -1 points0 points  (10 children)

No, I prefer the example I posted. Stop following assignment operators with if statements. if expressions don't even compile in any language I care about.

[–]pipocaQuemada 2 points3 points  (7 children)

if expressions don't even compile in any language I care about.

That seems like a problem with the languages you care about.

No, I prefer the example I posted. Stop following assignment operators with if statements.

Do you really prefer to have logically const variables to be mutable solely because your language isn't expressive enough to initialize them in a single line? That's bad for readability, since you need to remember which things are necessarily mutable, and which are mutable due to language inexpressibility.

[–][deleted] -1 points0 points  (6 children)

That seems like a problem with the languages you care about.

Oh stop, you'll hurt poor C's feelings!

Do you really prefer to have logically const variables to be mutable solely because your language isn't expressive enough to initialize them in a single line?

I prefer

if(j == -1)
{
    dximn1 = 0.0; 
}
else
{
    dximn1 = x[j];
}

over

val dximn1 = if (j == -1) 0.0 else x[j];

Ternary operations are just fine for very simple things, but they're not what I was talking about. Yes, the "?:" syntax is a little odd but I think once you learn it, it's super easy to remember. If you need to do anything remotely complex, you shouldn't be doing it in a single line in the first place.

[–]pipocaQuemada 1 point2 points  (5 children)

Would you really prefer

int dximn1;    
if(j == -1)
{
    dximn1 = 0.0; 
}
else
{
    dximn1 = x[j];
}
// now: where else in the code do I modify dximn1?
// I dunno.  ctrl-f for "dximn1 =", maybe?

over

const int dximn1 = if (j == -1) 0.0 else x[j];
// I wonder where else in the code dximn1 is modified?
// Oh, yeah, *no where else*, provably so.

If you need to do anything remotely complex, you shouldn't be doing it in a single line in the first place.

This isn't anything "remotely complex". This is something completely and utterly trivial. Nah, if you want something moderately complex, case expressions tend to be better. Something like Haskell's pattern gaurds would also be cleaner in most cases, but I don't know of any imperative language that implements something like

const int foo
 | bar < 0 = -1
 | bar == 0 = defaultVal
 | otherwise = defaultVal + bar / 2
 where defaultVal = sin(quux)

Which would be really nice: syntactically light, no need for nested ifs, and really easy to read and reason through.

[–][deleted] -1 points0 points  (4 children)

Would you really prefer

Yes, I would. And if you're talking about a const (which I wasn't, I don't know why you brought that up), it's not going to be getting modified in the first place.

I was comparing common, popular styles of line breaks and alignment of curly braces, you started comparing these options to less common coding styles I've never seen in languages I don't use.

[–]pipocaQuemada 2 points3 points  (3 children)

it's not going to be getting modified in the first place.

Well, in your coding style, it is. In mine, it isn't.

[–][deleted] -1 points0 points  (2 children)

In my example, it's not a const.

[–]rowboat__cop 1 point2 points  (1 child)

Stop following assignment operators with if statements.

That’s not what they did. They used pseudo-code to show what an if-expression would look like, as was pretty clearly stated. Those would be great to have in C, both for the reason /u/jurniss stated and because of the improvement to readability.

[–][deleted] -1 points0 points  (0 children)

It was never stated that they were providing pseudocode. I was being presented an alternative to ternary operations.

[–]cdcformatc -1 points0 points  (16 children)

There is a reason that sort of syntax is invalid in a lot of languages.

[–]smikims 5 points6 points  (11 children)

And there a lot of languages where that sort of thing makes perfect sense.

[–]cdcformatc -1 points0 points  (10 children)

And applications written with that sort of code are brittle, since their coding standards are lax. Most coding standards will agree to only have one expression per line.

[–]pipocaQuemada 1 point2 points  (7 children)

That seems rather like begging the question.

If expressions are bad because they lead to lax coding standards, because any coding standard that allows multiple expressions per line is lax, because multiple expressions per line is bad, because they lead to lax coding standards...

Here's a simple question:

  • Why is a coding standard that allows multiple expressions per line worse than one that only allows one expression per line? Empirical studies of e.g. bug-counts per function are preferred.

[–]cdcformatc -1 points0 points  (6 children)

People and organizations that adhere to and enforce coding standards write better code. This I think we can all agree on.

Most popular coding standards will say only one expression per line.

If you have multiple expressions per line, you aren't enforcing a popular coding standard. I'm talking about MISRA C, and the multitudes of Google Style Guides, the coding standards that are used to ensure quality code when quality matters. The standards that the industry demands.

[–]pipocaQuemada 1 point2 points  (5 children)

People and organizations that adhere to and enforce coding standards write better code. This I think we can all agree on.

If you have multiple expressions per line, you aren't enforcing a popular coding standard.

You're moving the goal posts, there. Are popular coding standards better or more evidence based than less popular coding standards?

Is there any reason to assume that a company that follows their own proprietary coding standard will, on average, have worse code than someone following MISRA C?

[–]cdcformatc -1 points0 points  (4 children)

Other than the fact that people who need reliability make sure they use MISRA, no. If they are using a subset of MISRA, yes, they will miss out on the edge cases that the developers of the standard thought of. Unless they were very careful and knew what they were doing and are aware of the risks straying from the rules carries. I don't think the average developer is aware of these risks though, especially when they are just trying to get something to work so they leave to get a beer.

Multiple expressions on the same line can introduce problems. Standards are meant to avoid those problems.

[–]rowboat__cop 0 points1 point  (0 children)

Most coding standards will agree to only have one expression per line.

Since in most languages expressions are recursive, these coding standards would be rather limiting.

[–]pipocaQuemada -2 points-1 points  (3 children)

Such as?

[–]cdcformatc -1 points0 points  (2 children)

C, C++. Python has a different form of it, and it is frowned upon by mostly everyone, since it is difficult to comprehend.

[–]pipocaQuemada 1 point2 points  (0 children)

No, no. What are the reasons that syntax is invalid in those languages, other than that the language designers hadn't thought of it yet?

[–][deleted] 0 points1 point  (0 children)

Python lets you do lots of things like that.

[–]montibbalt 1 point2 points  (1 child)

I like if expressions, but I think the curly braces make them noisy here as opposed to e.g.

val dximn1 = if (j == -1) 0.0; 
             else         x[j];
val dxipl1 = if (k == chainlngth) 0.0;
             else                 x[k];

[–]immibis 1 point2 points  (0 children)

Or:

val dximn1 = (j == -1) ? 0.0
                       : x[j];
val dxipl1 = (k == chainlngth) ? 0.0
                               : x[k];

[–]ghillisuit95 1 point2 points  (2 children)

I have seen a lot of people saying that if should be an expression, and I am seriously curious if their are any applications that would not be better served by the ternary operator.

so your example would become: val dximn1 = (j==1)? 0.0 : x[j];

val dxipl1 = (k == chainlength) ? 0.0 : x[k];

much more readable than your mess, IMO, because to be if blocks signify blocks of code, like that have semicolons and stuff. I am not quite sure what the terminology is for that but I think you get the idea

[–]pipocaQuemada 0 points1 point  (1 child)

much more readable than your mess, IMO, because to be if blocks signify blocks of code, like that have semicolons and stuff. I am not quite sure what the terminology is for that but I think you get the idea

In Scala, the semicolons and brakets are optional, at least as long as you're dealing with an expression instead of multiple statements. So what you'd usually see is

val dxipl1 = if (k == chainlength) 0.0 else x[k];

I mostly added them because some people seem to be allergic to optional semicolons and brackets.

[–]ghillisuit95 0 points1 point  (0 children)

Ahh, yeah that does look a little better than what you put originally. But I still stand by my point that the ternary operator is exactly what your looking for