Choice to not use 'else'

Hi all,

I’m just interested to know if there’s a reason for this. I note the way we’re being guided to construct the body of ClimbLadder(). In Pseudocode:

If Not (Player Touching ladder)
{ 
Put stuff back to non-ladder behaviour
return out of this function
}
Do the ladder climbing behaviour stuff - animation, physics

To me this seems a little bit turned-on-its-head. Firstly the use of the ‘not player touching’ - sort of a double negative, but - and what would help avoid that: refraining from using if / else. This seems to me to be a much more logical construct to use:

if (Player touching ladder)
{ 
Do the ladder climbing behaviour stuff - animation, physics
}
else
{
Put stuff back to non-ladder behaviour
}

If / Else is such a widely used construct that I automatically put it in when doing the challenge, even though this course is my first brush with C#. I guess this is just a stylistic choice, but to me it would have seemed to be a really good opportunity to introduce if/else for anyone who hasn’t seen the construct before.

This is not a criticism! I’m really enjoying the Tilevania lectures. I’m just wondering if there’s a reason to avoid if/else that I can’t see yet.

2 Likes

Haven’t done the whole course yet, but I checked some of the final code of previous projects before Tilevania and there are If/Else statements, I suppose there’s no need to introduce them again.

As for why Rick did it that way, your guess is as good as mine, but I suppose he didn’t want to confuse the students with that refactor. Remember that this course is made with beginners in mind, that means people that haven’t code anything in their lives, if you start moving things around, a lot of the students will get lost. I’ve seen that, in the previos version of the course a lot of the students would get lost in a very specific part of a very specific section, and it was because of something similar to what you are describing.

I suppose your way is better, there might also be bug, Why not check it out and share your findings?

Thanks, that’s a good point. I may have jumped the gun a bit commenting on it, it may be the course will get to if/else.

It’s currently working for me. This is my ClimbLadder() method:

    void ClimbLadder()
    {
        if(PlayerCapsuleCollider.IsTouchingLayers(LayerMask.GetMask("Climbing"))) 
        { 
            Vector2 ClimbVelocity = new Vector2(PlayerRigidBody.velocity.x, MoveInput.y * ClimbSpeed);
            PlayerRigidBody.velocity = ClimbVelocity;
            PlayerRigidBody.gravityScale = 0f;
            PlayerHasVerticalSpeed = Mathf.Abs(PlayerRigidBody.velocity.y) > Mathf.Epsilon;
            PlayerAnimator.SetBool("IsClimbing",PlayerHasVerticalSpeed);
            
        }
        else
        {
            PlayerRigidBody.gravityScale = DefaultGravity;
            PlayerAnimator.SetBool("IsClimbing",false);
        }
    }
1 Like

It looks great, just one thing. Are you using PlayerHasVerticalSpeed somewhere else? Do you need that variable cached?

I know this is an old thread but I’ve got a pretty good idea why he did it the way he did. It has to do with boolean short circuiting. Basically you’re gonna test for the condition that will most likely be true first - in his case that’s the “not going up a ladder”.

It helps with code readability by eliminating an entire else-block of code. Well, it doesn’t really eliminate it but it does eliminate the extra lines of text “else” with the associated brackets {} by implying the else related code below it.

Some people/teams don’t like this approach though since it provides for multiple exit points in a function which comes with its own positives and negatives.

In short, his else condition is implied in his code below where as your example explicitly declared the else block. Both are perfectly acceptable and do the same thing.

1 Like

This is not boolean short circuiting. It’s generally called ‘early exit’ or ‘early return’.

A boolean short circuit is when you have multiple conditions in a single expression where one condition depends on the result of another being true.

if (obj != null && obj.isActive)
{
}

This is a boolean short circuit. The obj.isActive will not be checked if obj is null. The expression is ‘short circuited’ and does not check obj.isActive because it doesn’t matter. It will not change the result. In fact, the code would fail if it didn’t short circuit because if obj was null, the next condition would throw a null reference exception.

Short circuiting is when an expression is ‘stopped’ mid-evaluation because nothing that is still to be evaluated will change the result.

2 Likes

This is a thing that happens when you get into the habit of exiting functions early in this way. Sometimes it just looks silly. Like in your example. One of the main reasons - at least from my point of view - is that it will reduce a lot of nested if’s and thereby improve readability

Take for example this totally-made-up-but-not-outlandish bit of code

if (player == null)
{
    Debug.Log("No player found");
    return;
}

float sqrDist = (player.transform.position - transform.position).sqrMagnitude;
if (sqrDist > sqrDetectionRange)
{
    MoveToRandomPosition();
    return;
}

List<Vector3> path = FindPathToTarget(player.transform.position);
if (path.Count == 0)
{
    return;
}

FollowPath(path);

There are a lot of ‘early exits’ here. Without it, it may look something like this

if (player == null)
{
    Debug.Log("No player found");
}
else
{
    float sqrDist = (player.transform.position - transform.position).sqrmagnitude;
    if (sqrDist > detectionRangeSqr)
    {
        MoveToRandomPosition();
    }
    else
    {
        List<Vector3> path = FindPathToTarget(player.transform.position);
        if (path.Count != 0)
        {
            FollowPath(path);
        }
    }
}

I would much rather read the code with the ‘early exits’

1 Like

Boy did my wires get crossed on that one. lol. That is what I was trying to say but boy was it way off base.

Thank you for pointing that out. I’d hate to be the cause of someone else’s confusion especially as a result of trying to help.

And thanks again for clarifying and providing an excellent and relevant use case scenario as well.

1 Like

Privacy & Terms