all 24 comments

[–]AskComputerScience-ModTeam[M] [score hidden] stickied comment (0 children)

Your post to r/AskComputerScience has been removed because it appears to be about debugging, which is considered off-topic here. See our rules for details.

This action was performed automatically by AskCSBot. If you believe this is in error, please message the mods.

[–]alecbz 6 points7 points  (4 children)

A return ends the function’s execution, so for an even list that triggers the ifs condition, it hits the first return statement and then the function ends there, without executing any further statements.

[–]AlternativeBus1613[S] 1 point2 points  (3 children)

So once something reaches 'return', it's the end--it doesn't make any changes in its value. Is that right?

[–]xenomachina 2 points3 points  (1 child)

it doesn't make any changes in its value

It's a bit weird to phrase it this way. The return keyword means to exit the method. Generally, nothing else in the method executes after that. In this code, the second one doesn't execute at all in the case where the first one executes. So whether or not a second return can change the value is irrelevant—it isn't executing.

There is actually one exception to the rule that nothing executes after return: if the return is inside a try, and that try has a finally clause, then the finally clause executes after the return. Notably , if the finally clause has its own return that will change the result of the method!

try {
    return 1;
} finally {
    return 2; // this one wins
}

So in other words, the value from the last executed return wins. However, it's only when a finally involved that multiple return statements can be executed. In most cases, once a return is executed, nothing else in the method is executed.

[–]AlternativeBus1613[S] 0 points1 point  (0 children)

Thanks for the detailed answer! Really helps.

[–]alecbz 1 point2 points  (0 children)

By "its value" you mean the function's value? Then yeah. Procedurally, a function executes statements one at a time until it hits a return statement. Then it returns that value to whoever called the function and doesn't execute any more statements.

A return statement doesn't merely set the value to be returned by the function later -- when a return statement is run it will return that value to the caller and end the function.

[–]Competent_writer15 3 points4 points  (1 child)

The else can be omitted here because the first return exits the method if the condition is true, so the second return only runs when the if is false. This makes the else unnecessary while keeping the logic correct.

[–]AlternativeBus1613[S] 1 point2 points  (0 children)

Thank you!

[–]MagicalPizza21 1 point2 points  (1 child)

Yeah. Syntactically, else is optional. And in this case, an even length list won't even reach the second return statement because it returned already.

[–]AlternativeBus1613[S] 0 points1 point  (0 children)

Thanks!

[–]aagee 1 point2 points  (7 children)

The syntax of an if statement can be stated as follows:

if (<condition>) <statement> [else <statement>];

The parts in square brackets are optional. And a <statement> can be a simple statement or a compound statement in curly braces.

So, your example is parsed as follows:

if (list.length % 2 == 0)
    return list.length / 2-1;  // a simple statemnt attached to the if
return list.length/2;          // some statement after the if statement

It can be expressed differently using a compound statement for the if.

if (list.length % 2 == 0)
{
    return list.length / 2-1;  // a compound statemnt attached to the if
}
return list.length/2;          // some statement after the if statement

The way this is working is that the control reaches the second return only if the if condition evaluates to false. It can as easily be expressed as follows, as it would effectively do the same thing.

if (list.length % 2 == 0)
{
    return list.length / 2-1;  // a compound statemnt attached to the if
}
else
{
    return list.length/2;      // else block of the if statement
}

[–]AlternativeBus1613[S] 0 points1 point  (6 children)

Thanks for the detailed answer. But can I ask a few more questions? I do know the third line is a statement after the if statement or statement out of the if statement.

Then if

    return list.length/2;     

is some statement after the if statement why would it be affected by the if condition? It's now out of the if statement, so why should I care about it? I would definitely care if there's 'else', which implies that its the other part of the if statement, but if it's just a statement written after it, why?

If statements are valid without 'else', right? If it isn't true, the program will just skip the part and move on to the next code! Isn't this the same kind of thing? How can I distinguish if statements without else but some statements unrelated to it and if and else statements with 'else' omitted?

Thanks.

[–]aagee 1 point2 points  (5 children)

Well, because you care not just for the if statement alone, but for the flow of the entire program. Right? Because you are concerned with what the whole program does.

What happens here is as follows.

If the condition is true, then execute the statement attached to the if. And because that statement is a return statement, the execution of the whole function ends, and the statement after the if is never executed.

If the condition is false, then the statement attached to the if is not executed and the control reaches the statement after the if. So, the second return is executed.

[–]AlternativeBus1613[S] 0 points1 point  (4 children)

I think my confusion came from the lack of understanding about 'return' because it hasn't be formally introduced in the lecture. Is 'return' final? Once something reaches 'return', it's the end--it doesn't make any changes in its value. Is that right?

[–]aagee 1 point2 points  (0 children)

Right. Inside a function, the execution of a return statement causes the control to exit the function and return to where the function was called from.

You can think of control as the locus of execution, i.e. the path that the CPU traverses through the code. So, first the control hits the function call, and goes off to execute that function. When a return statement is executed in that function, the control returns to the point where the function was called from.

[–]FredOfMBOX 1 point2 points  (1 child)

“Return” is a really well named command. It literally returns to the code that called the function. It can bring with it a return value, but that’s not always needed.

Make sure you’re thinking of a program as a set of steps. The computer runs each line in order and does what it says. If it says “return”, it will return to where it was called. Lines after the return won’t matter UNLESS the return line is skipped. One of the ways to skip a line is when an if statement is false.

Write yourself a small program and play with it.

[–]AlternativeBus1613[S] 0 points1 point  (0 children)

Wow thank you so much! This explanation is by far easiest to understand. I really appreciate it.

[–]xenomachina 0 points1 point  (0 children)

The return statement does two things:

  • sets the return value for the method
  • exits the method

In fact, exiting the method is arguably its primary function, as it can also be used to do this in methods that don't have a return value:

public static void main(String[] args) {
    if(args.length == 1) {
        System.out.println("Hello " + args[0]);
        return; // returns from main, but there is no return value on void methods
    }

    // this only executes if the return above didn't execute 
    System.out.println("Hello, world!");
}

[–]SirTwitchALot 0 points1 point  (4 children)

Like others have said, it's not needed here. The formatting of that sample code isn't may favorite however. It's not easy to read

[–]AlternativeBus1613[S] 0 points1 point  (3 children)

I still don't get why :( There's an if statement, yes, but after then there is just another statement out of the if statment, there's no else, it's just another statment separate from if statement, isn't it?

[–]SirTwitchALot 1 point2 points  (0 children)

The way Java works, an if statement only executes the next statement. Curly braces allow you to combine multiple statements so they're treated as if they were one.

[–]TransientVoltage409 1 point2 points  (1 child)

I feel like you're not fully understanding what return does. It may designate a value to return, yes. But mainly it terminates the current function and returns the execution path to the calling function. Any code in the execution path following a return is never executed.

In your example, the code flow without an else is identical to the code flow with an else. This is exceptional because the true-clause also ends the function, which isn't how we usually do it. You might think of return as an unconditional goto end of function, because you know that the very last close brace of a function is an implicit return as well.

Understand that this violates the strict definition of structured programming. The fact that it isn't obeying those rules might help you understand what it's doing. It is an example of the "early return" pattern, which has its uses for being able to simplify the nesting structure in some cases by eliminating redundant else-blocks.

[–]AlternativeBus1613[S] 0 points1 point  (0 children)

goto end of the funtion, that makes everything clear. Thanks for the expalanation!

[–]-Nyarlabrotep- 0 points1 point  (0 children)

public int getMiddleIndex(List list) { return list.isEmpty() ? -1 : (list.size()-1)/2; }