Swift - understanding return types in recursion: when should return the function vs. just return on its own - swift

This may be a little too general for this forum, but hoping someone can explain this in a way that makes sense to my brain. I've tried reading and researching and have found lots of examples - but I still don't understand the "why" which means that I am not understanding exactly how a program comes back from a function return.
Here is a very simple function I wrote that solves a puzzle using backwards recursion. It works well.
func solver(grid: [[Int]])->[[Int]] {
var returnGrid = constraintPropogation(grid: grid)
if contradictionCheck(grid: returnGrid) == false {
return returnGrid
} else {
if returnGrid.flatMap({$0}).filter({$0 == 3}).count == 0 {
print("SOLVED**********")
gridPrint(grid: returnGrid)
print()
stopFlag = true
stopAnswer = returnGrid
return returnGrid
} else {
let randStart = getRandomStart(grid: returnGrid)
returnGrid[randStart.x][randStart.y] = 0
solver(grid: returnGrid)
returnGrid[randStart.x][randStart.y] = 1
solver(grid: returnGrid)
}
}
if stopFlag == true {return stopAnswer}
return solver(grid: returnGrid)
}
My issue is understanding the returns. In the third line of the function if a contradiction check fails this means that we've gone down a path that would not be possible. Therefore we return. That makes sense. The second return in the middle of the function occurs when the puzzle is solved, so it makes sense to return there. But the last one at the end "return solver(grid: returnGrid)" is challenging to my understanding. Here we are returning but also calling this same function again. This is not going deeper into the potential solution path (that happens in the "else" section where the function is called). Why do we need to call the function again rather than just returning? What is happening under the hood? Does the return happen first where we "pop back up a level" and then we are calling the function again effectively one rung higher on the stack? When I write these words I realize that I have a vague understanding - but somehow it is not all clicking together for me.
Am at the point now that when I'm writing functions that involve recursion I just try both returning on own or returning and calling function again to see which one achieves what I want. But I'd really like to understand it rather than just guessing. If anyone had a simple explanation I would appreciate it.

Your function solver takes an array of arrays, and returns an array of arrays. Any call to return(something) returns that something to the caller.
Saying return(someArrayOfArrays) means you are done, and have a result.
Saying return(solver(someArrayOfArrays)) says "call this function again, passing in a new value. Return whatever the result is as the function result." The current call to solver() is done doing work, and passes its intermediate results to another call to the function. That's the recursion. You can think of this as nesting a function call inside a function call inside a function call, or stacking function calls on top of each other.
The call to solver(grid: returnGrid) does not make any sense. That is a recursive call, but you ignore the result. Thus, that call does nothing useful. If your remove that line, it won't make any difference to the outcome. That line is saying "Go do a bunch of work and find an answer for me, but I will throw away your answer". The compiler should give you a "function result ignored" warning at that line.
Beyond that, I can't tell what your code is doing. It appears to be modifying at least one global variable, "stopAnswer". That suggests it's not a pure recursive function.

Related

Bad practice for a method to call itself?

I've a question about good or bad practice.
I've created a function which will generate a random number. And if the random number is equal to the previous random number it should generate a new number. So my question is. Is it bad practice to call the same method from the method?
func getRandomNumber(){ //<-- Method name
let randomNumber = Int.random(in: 0..<allPlayers.count)
if lastRoundNumber == randomNumber{
getRandomNumber() //<-- Like this
}
print(randomNumber)
}
Or should I do this is another way? If yes, how?
So is it bad practice to call the same method from the current method like I've done in the code above? Thanks in advance.
If yes, why is it bad? And how can you do this to get a "better" code?
There is nothing wrong with having a function call itself. It’s called recursion. When not implemented properly, it can introduce some overhead, but sometimes it can be a very elegant solution.
That having been said, you might not want to do it like you have here. What if it guessed the same number three times before it got one that wasn’t equal to lastRoundNumber? You’d see four print statements for one new value. Do you really want that behavior? If you were going to implement getRandomNumber as a recursive function, at the very least I’d suggest inserting a return statement after it calls itself recursively, so that you don’t get print statements for the iterations where it ended up with the same value as lastRoundNumber.
That having been said, we often only reach for recursion (and the overhead that entails) when that implementation is appreciably more elegant or intuitive than the non-recursive rendition. But in this case, the non-recursive rendition is probably just as clear, and as such, we’d likely favor it over the recursive version. It might look like:
func getRandomNumber() {
guard allPlayers.count > 1 else { return }
var randomNumber: Int
repeat {
randomNumber = .random(in: 0..<allPlayers.count)
} while randomNumber == lastRoundNumber
print(randomNumber)
}
Note, I’m checking that you have more than one player to avoid the possibility of infinite loop.
But let's say there were 100 players. And let’s say you called this 100 times. Is it OK if it returned player 1, then player 2, then player 1 again, then player 2 again, repeating again and again, never returning any players 3 through 100. This is unlikely, but it’s possible. Is that OK?
Often we want to return all players, but in a random order. In that case, you’d “shuffle” the list, e.g.
let players = (0..<allPlayers.count).shuffled()
That will ensure that you have an array of integer values, shuffled into random order, but never repeating any given number. That provides randomness while also ensuring that each value is returned only once.
It just depends upon your desired behavior.
If you call a method from the same method, it is called recursion.
You can find here an explanation how recursion in swift works.
You should make sure that your method has an exit condition, so you are not stuck in your call.
Let's look at an example call of your method. lastRoundNumber is 1.
Your generated number is also 1. So it will call the method again. Then you will generate the number 2.
With print(randomNumber) you will get the following output:
2
1
It will happen, because the print-statement will be excuted, even if you call the method again.
So you need to rework your if statement to the following:
if lastRoundNumber == randomNumber{
getRandomNumber() //<-- Like this
} else {
print(randomNumber)
}
In this way, it will only print the last generated value

Is a while loop already implemented with pass-by-name parameters? : Scala

The Scala Tour Of Scala docs explain pass-by-name parameters using a whileLoop function as an example.
def whileLoop(condition: => Boolean)(body: => Unit): Unit =
if (condition) {
body
whileLoop(condition)(body)
}
var i = 2
whileLoop (i > 0) {
println(i)
i -= 1
} // prints 2 1
The section explains that if the condition is not met then the body is not evaluated, thus improving performance by not evaluating a body of code that isn't being used.
Does Scala's implementation of while already use pass-by-name parameters?
If there's a reason or specific cases where it's not possible for the implementation to use pass-by-name parameters, please explain to me, I haven't been able to find any information on it so far.
EDIT: As per Valy Dia's (https://stackoverflow.com/users/5826349/valy-dia) answer, I would like to add another question...
Would a method implementation of the while statement perform better than the statement itself if it's possible not to evaluate the body at all for certain cases? If so, why use the while statement at all?
I will try to test this, but I'm new to Scala so it might take me some time. If someone would like to explain, that would be great.
Cheers!
The while statement is not a method, so the terminology by-name parameter is not really relevant... Having said so the while statement has the following structure:
while(condition){
body
}
where the condition is repeatedly evaluated and the body is evaluated only upon the condition being verified, as show this small examples:
scala> while(false){ throw new Exception("Boom") }
// Does nothing
scala> while(true){ throw new Exception("Boom") }
// java.lang.Exception: Boom
scala> while(throw new Exception("boom")){ println("hello") }
// java.lang.Exception: Boom
Would a method implementation of the while statement perform better than the statement itself if it's possible not to evaluate the body at all for certain cases?
No. The built-in while also does not evaluate the body at all unless it has to, and it is going to compile to much more efficient code (because it does not need to introduce the "thunks"/closures/lambdas/anonymous functions that are used to implement "pass-by-name" under the hood).
The example in the book was just showing how you could implement it with functions if there was no built-in while statement.
I assumed that they were also inferring that the while statement's body will be evaluated whether or not the condition was met
No, that would make the built-in while totally useless. That is not what they were driving at. They wanted to say that you can do this kind of thing with "call-by-name" (as opposed to "call-by-value", not as opposed to what the while loop does -- because the latter also works like that).
The main takeaway is that you can build something that looks like a control structure in Scala, because you have syntactic sugar like "call-by-name" and "last argument group taking a function can be called with a block".

clearer explanation of function level scope for recursion

This is an example from the book 'Matlab for Neuroscientists'. I don't understand the order in which, or why, g gets assigned a new value after each recursion. Nor do I understand why "factorial2" is included in the final line of code.
here is a link to the text
Basically, I am asking for someone to re-word the authors explanation (circled in red) of how the function works, as if they were explaining the concept and processes to a 5-year old. I'm brand new to programming. I thought I understood how this worked from reading another book, but now this authors explanation is causing nothing but confusion. Many thanks to anyone who can help!!
A recursive method works by breaking a larger problem into smaller problems each time the method is called. This allows you to break what would be a difficult problem; a factorial summation, into a series of smaller problems.
Each recursive function has 2 parts:
1) The base case: The lowest value that we care about evaluating. Usually this goes to zero or one.
if (num == 1)
out = 1;
end
2) The general case: The general case is what we are going to call until we reach the base case. We call the function again, but this time with 1 less than the previous function started with. This allows us to work our way towards the base case.
out = num + factorial(num-1);
This statement means that we are going to firstly call the function with 1 less than what this function with; we started with three, the next call starts with two, the call after that starts with 1 (Which triggers our base case!)
Once our base case is reached, the methods "recurse-out". This means they bounce backwards, back into the function that called it, bringing all the data from the functions below it!It is at this point that our summation actually occurs.
Once the original function is reached, we have our final summation.
For example, let's say you want the summation of the first 3 integers.
The first recursive call is passed the number 3.
function [out] = factorial(num)
%//Base case
if (num == 1)
out = 1;
end
%//General case
out = num + factorial(num-1);
Walking through the function calls:
factorial(3); //Initial function call
//Becomes..
factorial(1) + factorial(2) + factorial(3) = returned value
This gives us a result of 6!

return inside a switch block yields "unreachable code" warning

I'm writing UnityScript code and at one point in my program, I want to terminate a function from within a switch block. This is a boiled down version of my code:
function Move(target: int) {
var targetTransform : Transform;
switch (target) {
case 0:
// do something including assigning targetTransform
break;
case 1:
// do something including actually moving my object
return; // since I moved already, I want the function to terminate here
default:
// do something including assigning targetTransform
}
object.Move(targetTransform); // object is locally available
}
Now for whatever reason, the Compiler gives me a
Assets/Scripts/GameMaster.js(490,9): BCW0015: WARNING: Unreachable code detected.
The line is the one containing the switch.
From my previous research, I found many similar problems, but all of them had actually unreachable code, like for example break statements after the returns or a return at the end even though each and every case returned at some point. This is not the case here, I just want one of my cases to return out of the function altogether, while the others shall break out of the switch and go on from there.
Is there a way to get rid of this warning? What is causing it in the first place, is this just a bug?
If at all possible, I'd prefer not to use a boolean and check for it after the switch block... This just seems like overkill only to terminate one case early.
This bug exists at least since 2010. Although it's perfectly legal to use a return statement instead of a break, the compiler will complain about unreachable code.
You have basically two options
ignore the warning and keep your code nice and clean
work around the warning by replacing the return with a boolean + break and check for the boolean after the switch block
As far as I know you can't even disable or suppress the warning. It's possible in C# but UnityScript seems to lack this feature. So this would result in a third possible solution: convert your code to C# :-)

Breaking when a method returns null in the Eclipse debugger

I'm working on an expression evaluator. There is an evaluate() function which is called many times depending on the complexity of the expression processed.
I need to break and investigate when this method returns null. There are many paths and return statements.
It is possible to break on exit method event but I can't find how to put a condition about the value returned.
I got stuck in that frustration too. One can inspect (and write conditions) on named variables, but not on something unnamed like a return value. Here are some ideas (for whoever might be interested):
One could include something like evaluate() == null in the breakpoint's condition. Tests performed (Eclipse 4.4) show that in such a case, the function will be performed again for the breakpoint purposes, but this time with the breakpoint disabled. So you will avoid a stack overflow situation, at least. Whether this would be useful, depends on the nature of the function under consideration - will it return the same value at breakpoint time as at run time? (Some s[a|i]mple code to test:)
class TestBreakpoint {
int counter = 0;
boolean eval() { /* <== breakpoint here, [x]on exit, [x]condition: eval()==false */
System.out.println("Iteration " + ++counter);
return true;
}
public static void main(String[] args) {
TestBreakpoint app = new TestBreakpoint();
System.out.println("STARTED");
app.eval();
System.out.println("STOPPED");
}
}
// RESULTS:
// Normal run: shows 1 iteration of eval()
// Debug run: shows 2 iterations of eval(), no stack overflow, no stop on breakpoint
Another way to make it easier (to potentially do debugging in future) would be to have coding conventions (or personal coding style) that require one to declare a local variable that is set inside the function, and returned only once at the end. E.g.:
public MyType evaluate() {
MyType result = null;
if (conditionA) result = new MyType('A');
else if (conditionB) result = new MyType ('B');
return result;
}
Then you can at least do an exit breakpoint with a condition like result == null. However, I agree that this is unnecessarily verbose for simple functions, is a bit contrary to flow that the language allows, and can only be enforced manually. (Personally, I do use this convention sometimes for more complex functions (the name result 'reserved' just for this use), where it may make things clearer, but not for simple functions. But it's difficult to draw the line; just this morning had to step through a simple function to see which of 3 possible cases was the one fired. For today's complex systems, one wants to avoid stepping.)
Barring the above, you would need to modify your code on a case by case basis as in the previous point for the single function to assign your return value to some variable, which you can test. If some work policy disallows you to make such non-functional changes, one is quite stuck... It is of course also possible that such a rewrite could result in a bug inadvertently being resolved, if the original code was a bit convoluted, so beware of reverting to the original after debugging, only to find that the bug is now back.
You didn't say what language you were working in. If it's Java or C++ you can set a condition on a Method (or Function) breakpoint using the breakpoint properties. Here are images showing both cases.
In the Java example you would unclik Entry and put a check in Exit.
Java Method Breakpoint Properties Dialog
!
C++ Function Breakpoint Properties Dialog
This is not yet supported by the Eclipse debugger and added as an enhancement request. I'd appreciate if you vote for it.
https://bugs.eclipse.org/bugs/show_bug.cgi?id=425744