Been coding for a bit, self taught, and this question has been nagging for a while and finally decided to ask. Why is "Mathf" so poor out of the box?

It’s called a ternary conditional operator and I would say a) not to use it in general, and b) if you must, keep it REALLY simple, like this:

a = b ? c : d;

or MAYBE, just maybe:

a = b < K : c : d

In a code review I would reject the code that Mr Miller posted above because:

  • it is infinitely easier to inadvertently introduce a bug
  • it is infinitely harder to reason about at a glance
  • it is infinitely harder to test exhaustively
  • it’s not fooling the compiler: the code will not be faster
  • nobody pays you to save code lines… we have #regions we can fold if need be
  • writing code like that is NOT actually being clever or better
  • it will make me MUCH more suspicious of all other code by an engineer who does this a lot

Break it up, practice social distancing in your code, one thing per line please.

“Programming is hard enough without making it harder for ourselves.” - angrypenguin on Unity3D forums

“Combining a bunch of stuff into one line always feels satisfying, but it’s always a PITA to debug.” - StarManta on the Unity3D forums

4 Likes

Hey, why do you think we call it “code?”

For the record, I would reject the code I posted above for all the same reasons Kurt listed. (BTW, I think you have a typo in your “just maybe” example.)

I posted that with tongue in cheek to see if it would draw his ire. I’m glad it did because getting obsessed with “improved” code in 2024 is usually a waste of time (at best), or an exercise in making something simple into something complicated (at worst, assuming it still runs at all).

If you look at the history of C and all its descendant languages, and you know the op-code lists for the machines used to create it, you can see that some of these cryptic operators were there to let simple compilers make use of efficient options in binary code. Modern compilers don’t need that kind of help anymore and will usually produce code as good any so-called “dirty” code written to serve the false god of optimization.

When I first learned to code in 1976, the way to increment a counter was with something like:

n = n + 1

Then along came C and we all started using this:

n++;

Then along came C++ and we all started using this:

++n;

Today, I am back to using this:

n = n + 1;

(Well, I have to add the semi-colon now. That’s progress for you.)

Why do I use that old-fashioned, Programming 101 way? Because it says what I am doing: I am adding 1 to n, and putting the result back into n. Does the compiler do a better job with any one of those? I neither know, nor care. It runs fast enough with any option, and I have other things to do.

2 Likes

I admit freely that my ire has been successfully drawn by Mr Miller. :slight_smile:

But I still love you!

In other news, this is my favorite swap two variables:

int a = 123;
int b = 234;

// now we swap them with bitwise XOR!
a ^= b;
b ^= a;
a ^= b;

// voila ... swapped without using any extra memory!

Outside of a managed language (such as in native C) you can actually use it on pretty much any type, including pointers (!!) and floating point and all kinds of stuff, because it is just bit flicking.

But no, I don’t use it. I just do it inline, usually with a local block around it:

{
 var t = a;
 a = b;
 b = t;
}

which goes nicely into what you wrote …

^ ^ This is really the main thing to strive for always, even in throwaway code. Who knows where it will end up and how far into the future someone will need to debug it.

“What is this code DOING!?”

Hah, back when we paid for memory by the byte, I actually used that XOR swap trick from time to time.

Yes, today, our first rule needs to be, “Thou Shalt Not Write Opaque Code.” This could be restated, for 99% of violations, as “Thou Shalt Not Write Clever Code.” (Its close cousin is, “Thou Shalt Not Covet Elegant Code.”)

For those of us who have gotten over the need to impress our colleagues, n = n + 1 seems to come naturally. What comes hard, I think, is knowing the difference between “self-documenting code,” and “undocumented code.” A frustrating number of my co-workers have heard of the former and somehow convinced themselves that it gives credence to the latter.

It’s only self-documented if it actually answers Kurt’s question: What is this code doing?

Now, here and there, I allow myself some cryptic code when that code has risen to the level of an idiom I can recognize on its own. For example, good practice today says that all conditional code must be inside curly brackets, even one line. But, sometimes a method needs to short-circuit itself to prevent things like two coroutines running at once. In that case, I allow myself this:

if (doorIsOpening) return;

But only if that’s the first line of the coroutine. It’s still clear (to me, anyway), and kind of calls out its special function of being a gatekeeper to the rest of the method.

One might make a case for using the ?: ternary here and there, on the grounds that it is untyped. But, mostly, I agree it is to be avoided. Note that it is not an alternative to if, as it does not condition code: it’s an operator that always returns a value. You could not, say, use it like this:

doorIsOpening ? return : // rest of your method

As an operator, its result must be part (or all) of an r-value that is assigned to an l-value. It would only cause needless confusion to attempt to think of it as a variation of the if statement, I think.

2 Likes

It’s so refreshing to see you guys talk no nonsense about how readability and iteration is king and that a lot of this modern day code logic isn’t actually better and just another means of us neckbeards to d*ckmeasure who knows the language best :rofl:

Too often we chase after what others have mastered just assuming everyone knows what they’re doing and it’s good to remind ourselves that just because some practice exists and people do it, doesn’t mean we should do it too.

“If all your friends were jumping off a bridge, would you do it too?” We’ve found the answer to that question and when it comes to code, 9 times out of 10 the answer is yes.

Anyhow, so glad I didn’t go overboard and inject that logic throughout my project yet and I’ll be taking it out going forward as it’s always confused the heck out of me, but I just figured i was a noob.