AutoHotkey Community

It is currently May 27th, 2012, 2:31 am

All times are UTC [ DST ]




Post new topic Reply to topic  [ 11 posts ] 
Author Message
PostPosted: February 12th, 2010, 2:48 am 
Offline

Joined: July 6th, 2009, 9:58 pm
Posts: 678
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 February 12th, 2010, 5:06 am, edited 2 times in total.

Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: February 12th, 2010, 3:08 am 
Offline

Joined: March 9th, 2007, 2:47 am
Posts: 509
Location: Unknown
I think x is blank because you haven't declared n yet...


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: February 12th, 2010, 3:11 am 
Offline

Joined: July 6th, 2009, 9:58 pm
Posts: 678
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?


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: February 12th, 2010, 3:30 am 
Offline

Joined: March 9th, 2007, 2:47 am
Posts: 509
Location: Unknown
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)
}


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: February 12th, 2010, 3:36 am 
if f(n) is a loop function inside, it works
so it has to do with globe variables, i guess


Report this post
Top
  
Reply with quote  
 Post subject:
PostPosted: February 12th, 2010, 3:39 am 
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)


Report this post
Top
  
Reply with quote  
 Post subject:
PostPosted: February 12th, 2010, 3:43 am 
Offline

Joined: March 9th, 2007, 2:47 am
Posts: 509
Location: Unknown
Ahhh, I agree with guest. Good catch. randall, if you wanted to do that I would recommend using a label instead of a function.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: February 12th, 2010, 3:49 am 
Offline

Joined: July 6th, 2009, 9:58 pm
Posts: 678
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?


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: February 12th, 2010, 4:05 am 
Offline

Joined: October 7th, 2006, 4:50 pm
Posts: 3157
Location: MN, USA
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)
}


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: February 12th, 2010, 4:26 am 
Offline

Joined: July 6th, 2009, 9:58 pm
Posts: 678
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!


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: February 12th, 2010, 6:34 am 
Offline

Joined: October 7th, 2006, 4:50 pm
Posts: 3157
Location: MN, USA
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:


Report this post
Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 11 posts ] 

All times are UTC [ DST ]


Who is online

Users browsing this forum: Alpha Bravo, Bing [Bot], LazyMan, rbrtryn and 18 guests


You can post new topics in this forum
You can reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Powered by phpBB® Forum Software © phpBB Group