AutoHotkey Homepage AutoHotkey Community
Let's help each other out
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

No value when := used on recursive function? [solved]

 
Reply to topic    AutoHotkey Community Forum Index -> Ask for Help
View previous topic :: View next topic  
Author Message
randallf



Joined: 06 Jul 2009
Posts: 678

PostPosted: Fri Feb 12, 2010 1:48 am    Post subject: No value when := used on recursive function? [solved] Reply with quote

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. Smile

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
View user's profile Send private message
System Monitor



Joined: 09 Mar 2007
Posts: 509
Location: Unknown

PostPosted: Fri Feb 12, 2010 2:08 am    Post subject: Reply with quote

I think x is blank because you haven't declared n yet...
Back to top
View user's profile Send private message Visit poster's website
randallf



Joined: 06 Jul 2009
Posts: 678

PostPosted: Fri Feb 12, 2010 2:11 am    Post subject: Reply with quote

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
View user's profile Send private message
System Monitor



Joined: 09 Mar 2007
Posts: 509
Location: Unknown

PostPosted: Fri Feb 12, 2010 2:30 am    Post subject: Reply with quote

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
View user's profile Send private message Visit poster's website
Guest






PostPosted: Fri Feb 12, 2010 2:36 am    Post subject: Reply with quote

if f(n) is a loop function inside, it works
so it has to do with globe variables, i guess
Back to top
Guest






PostPosted: Fri Feb 12, 2010 2:39 am    Post subject: Reply with quote

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

PostPosted: Fri Feb 12, 2010 2:43 am    Post subject: Reply with quote

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
View user's profile Send private message Visit poster's website
randallf



Joined: 06 Jul 2009
Posts: 678

PostPosted: Fri Feb 12, 2010 2:49 am    Post subject: Reply with quote

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
View user's profile Send private message
jaco0646



Joined: 07 Oct 2006
Posts: 3113
Location: MN, USA

PostPosted: Fri Feb 12, 2010 3:05 am    Post subject: Reply with quote

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
View user's profile Send private message Visit poster's website
randallf



Joined: 06 Jul 2009
Posts: 678

PostPosted: Fri Feb 12, 2010 3:26 am    Post subject: Reply with quote

I was originally thinking that

Code:
    f(n)
}


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:

Code:
f(n)
{
}



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?

Quote:
Return f(n)


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
View user's profile Send private message
jaco0646



Joined: 07 Oct 2006
Posts: 3113
Location: MN, USA

PostPosted: Fri Feb 12, 2010 5:34 am    Post subject: Reply with quote

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. Wink
Back to top
View user's profile Send private message Visit poster's website
Display posts from previous:   
Reply to topic    AutoHotkey Community Forum Index -> Ask for Help All times are GMT
Page 1 of 1

 
Jump to:  
You can post new topics in this forum
You can reply to topics in this forum


Powered by phpBB © 2001, 2005 phpBB Group