When Tertiary Operators Become Confusing

Started by
5 comments, last by WozNZ 7 years, 9 months ago

So, I have learn the hard way that tertiary operators are confusing to some people. (Never was to me.)

At some point while I was developing a game, I was presented with the task of fixing a bug related to running backward & while strafing. I look at the code.

(pseudo code btw)

if(isRunning)

movespeed = normalSpeed * runSpeed;

else

movespeed = normalSpeed;

and so, I did the only thing that made sense to me to simplify the block of if-else that would ensue with restricting the run.

if(isRunning) ( if(isMovingForward) (normalSpeed * runSpeed) : (if(canRunSideway && movingSideway || canRunBackward && movingBackward) normalSpeed * runSpeed : normalSpeed ) ) : (normalSpeed);

In hindsight, I can see why someone wouldn't understand such a line.

There are 10 types of people in the world: Those who understand binary, those who don't and those who didn't expect this to be in tertiary.

Advertisement

*Waiting with bated breath for the continuation*

Hello to all my stalkers.

Now I understand why it's so prevalent:


implicit val timeout = Timeout(5.seconds)

Sorry about that, couldn't complete it before I had to lose access to the site. Conclusion is up.

There are 10 types of people in the world: Those who understand binary, those who don't and those who didn't expect this to be in tertiary.

Its "ternary", not "tertiary" -- though its an easy mistake I was once guitly of myself. "Ternary" means "composed of three parts", "tertiary" means "of the third order, as in primary->secondary->tertiary."

I've never seen this form of ternary operator before though -- what language is this? In most (all?) languages, ternary operators are expressions (meaning that they have a value which can be assigned, passed to a function or otherwise consumed directly), whereas if-else constructs in most* procedural languages (C, C++, and cousins) are not expressions, they're statements. If you don't take advantage of of their status as an expression, code using ternary operators usually is more ugly than if-else-style code, and its often the case that when if-else-style code changed into a ternary expression is still ugly, then it was probably better off as if-else anyways.

Using C-and-friends-style ternary operators, cleaner code might look like this:


auto move_speed = (is_running) ? normal_speed * run_speed : normal_speed;

Or even this:


auto move_speed = normal_speed * ((is_running) ? run_speed : 1);

* Many functional or functional-inspired languages have if-else expressions rather than statements.

throw table_exception("(? ???)? ? ???");

Yeah, the example replacement in the first post is not that great because it's actually adding more stuff (and indeed adding enough to be way too much for the ternary operator to stay readable).

That said, if it was up to me I'd do:

move_speed = normal_speed;
if (running)
   move_speed *= run_speed;

I'm lame =P

Don't pay much attention to "the hedgehog" in my nick, it's just because "Sik" was already taken =/ By the way, Sik is pronounced like seek, not like sick.

ternary operators are not the issue, i prefer to if flows for most simple stuff. Nesting them and not using suitable indenting to highlight what is going on is a real issue.

I would use one of these in C#, probably the last. Simple and readable

var speed = (isRunning && isMovingForward) || (canRunSideway && movingSideway) || (canRunBackward && movingBackward)

? normalSpeed * runSpeed

: normalSpeed;

or

var multiplier = (isRunning && isMovingForward) || (canRunSideway && movingSideway) || (canRunBackward && movingBackward) ? runSpeed : 1;

var speed = normalSpeed * multiplier;

or

var isRunning = (isRunning && isMovingForward) || (canRunSideway && movingSideway) || (canRunBackward && movingBackward);

var speed = normalSpeed * (isRunning ? runSpeed : 1);

This topic is closed to new replies.

Advertisement