| View previous topic :: View next topic |
| Author |
Message |
randallf
Joined: 06 Jul 2009 Posts: 678
|
Posted: Fri Feb 12, 2010 1:48 am Post subject: No value when := used on recursive function? [solved] |
|
|
Was messing around and just want to try to understand the reason behind how this works or doesn't. Big thank you to anyone willing to take the time to explain it to me.
| Code: | ;This doesn't work
x := f(n)
msgbox %x% ;why is this blank?
msgbox %n%
;but this would work fine
;f(n)
;msgbox %n%
;why does the assignment operator seem to break it?
;n must evaluate to 100 or the function would go forever right?
return
f(byref n)
{
if n = 100
Return n
n++
f(n)
} |
Last edited by randallf on Fri Feb 12, 2010 4:06 am; edited 2 times in total |
|
| Back to top |
|
 |
System Monitor
Joined: 09 Mar 2007 Posts: 509 Location: Unknown
|
Posted: Fri Feb 12, 2010 2:08 am Post subject: |
|
|
| I think x is blank because you haven't declared n yet... |
|
| Back to top |
|
 |
randallf
Joined: 06 Jul 2009 Posts: 678
|
Posted: Fri Feb 12, 2010 2:11 am Post subject: |
|
|
| System Monitor wrote: | | I think x is blank because you haven't declared n yet... |
Interesting thought, that perhaps the exception to not having to declare/prime variables is when using ByRef... which as I understand it stores the result of the function variable back into the pointer address of the byref variable, (presumably that if it didn't yet exist it wouldn't have an address to store it in, which might be true in C) but adding n := 0 or even n := 1 to the top of the script doesn't change anything?
As I understand it expressions evaluate left to right? (am I plain wrong there?) so shouldn't it evaluate f(n) and then assign it to x? |
|
| Back to top |
|
 |
System Monitor
Joined: 09 Mar 2007 Posts: 509 Location: Unknown
|
Posted: Fri Feb 12, 2010 2:30 am Post subject: |
|
|
I really don't know why this doesn't work. What is odd though is this shows that it does go into the if statement
| Code: | ;This doesn't work
n := 95
x := f(n)
msgbox %x% ;why is this blank?
msgbox %n%
;but this would work fine
;f(n)
;msgbox %n%
;why does the assignment operator seem to break it?
;n must evaluate to 100 or the function would go forever right?
return
f(byref n)
{
if n = 100
msgbox in if, n=%n%
Return n
n++
msgbox n=%n%
f(n)
} |
|
|
| Back to top |
|
 |
Guest
|
Posted: Fri Feb 12, 2010 2:36 am Post subject: |
|
|
if f(n) is a loop function inside, it works
so it has to do with globe variables, i guess |
|
| Back to top |
|
 |
Guest
|
Posted: Fri Feb 12, 2010 2:39 am Post subject: |
|
|
| no, actually i think its because once u run the f(n) the 2nd+ time, the return doesnt know where to return, because the ELSE is just a normal calling f(n) |
|
| Back to top |
|
 |
System Monitor
Joined: 09 Mar 2007 Posts: 509 Location: Unknown
|
Posted: Fri Feb 12, 2010 2:43 am Post subject: |
|
|
| Ahhh, I agree with guest. Good catch. randall, if you wanted to do that I would recommend using a label instead of a function. |
|
| Back to top |
|
 |
randallf
Joined: 06 Jul 2009 Posts: 678
|
Posted: Fri Feb 12, 2010 2:49 am Post subject: |
|
|
| Anonymous wrote: | | no, actually i think its because once u run the f(n) the 2nd+ time, the return doesnt know where to return, because the ELSE is just a normal calling f(n) |
Ah, well, the ELSE is implicit (if that's relevant? probably doesn't matter) but the return won't fire unless it evaluates n to be 100! it then immediately returns n, which is what f(n) should evaluate to? This made me think that bracing was necessary at very first, but I tried that and it was no different.
I see where you are going, that the f(n) it calls at the bottom is local to the function but ... I keep coming back to, it's evaluating n to be 100! so why isn't it returning n as 100?
(not that I don't believe you but maybe I don't understand your explanation correctly)
And since n is byref, shouldn't the msgbox already have the value of n, even if it wasn't returned? |
|
| Back to top |
|
 |
jaco0646
Joined: 07 Oct 2006 Posts: 3113 Location: MN, USA
|
Posted: Fri Feb 12, 2010 3:05 am Post subject: |
|
|
| AHK Help File wrote: | | If the flow of execution within a function reaches the function's closing brace prior to encountering a Return, the function ends and returns a blank value (empty string) to its caller. | Your recursive calls don't return anything. No return values means nothing to assign to x. | Code: | ;This doesn't work
x := f(n)
msgbox %x% ;why is this blank?
msgbox %n%
;but this would work fine
;f(n)
;msgbox %n%
;why does the assignment operator seem to break it?
;n must evaluate to 100 or the function would go forever right?
return
f(byref n)
{
if n = 100
Return n
n++
Return f(n)
} |
|
|
| Back to top |
|
 |
randallf
Joined: 06 Jul 2009 Posts: 678
|
Posted: Fri Feb 12, 2010 3:26 am Post subject: |
|
|
I was originally thinking that
was basically equivalent to "goto top of function".
It does hit the end brace, because when it hits f(n) it simply does the evaluation once more, hits the end brace and returns nothing, just as if you had called:
So my mistake was believing that it was returning on my return command and not the end of the function.
In this example you will never get confirmation of the top return (because it doesn't fire) but you will get the value of n from the function because of ByRef.
| Code: |
;This doesn't work
n := 1
x := f(n)
msgbox %x% ;why is this blank?
msgbox %n%
;but this would work fine
;f(n)
;msgbox %n%
;why does the assignment operator seem to break it?
return
f(byref n)
{
if n = 100
msgbox my return is going to fire
Return f(n)
n++
f(n)
} |
So if I am now correct in my thinking, recursion works by the return value calling the function again?
Is somewhat equivalent to 'take the value of n as evaluated by the function so far and run the function with that value again'?
Thinking about it, I believe, specifically, that 'return' of course means, end of function, provide a value to the caller, but I didn't realize that return itself could call a function, I thought it had to be the end.
THANK YOU! |
|
| Back to top |
|
 |
jaco0646
Joined: 07 Oct 2006 Posts: 3113 Location: MN, USA
|
Posted: Fri Feb 12, 2010 5:34 am Post subject: |
|
|
Remember that a function call is just an expression. You can call a function anywhere that an expression is expected.
Also note that calling a function from Return's parameter is not synonymous with recursion. Your recursion was working all along, which is why the value of n was correct. You simply didn't return a value from any of your recursive calls, so there was nothing to assign to x. You do not need to assign any output/return value to perform recursion; in fact, using a ByRef variable would be a good reason not to.
You do need to return a value if you want to assign the output of a function (whether the function is recursive or not). For recursion, every call to the function must return a value to its caller. Your original code makes 101 calls to the function (every value from 0-100). The only call that was returning a value was the last one, f(100) but that value was not returned by the other 100 callers.
So, f(100) returns the value 100 to f(99) but f(99) reaches the end of the function since it doesn't satisfy the IF condition, so it returns nothing, as does every previous call. If you think of recursion like a ladder, the function calls every step on the way up the ladder until it reaches the answer (and stops calling itself) then it returns that value through every step of the ladder on the way down.
You can't climb to the top and then jump down.  |
|
| Back to top |
|
 |
|