are function calls reentrant?
shadowphile
29 Jun 2013, 22:07I need a function to call itself... (part of a search tree that climbs up a parent of a parent of a...).
Right now it immediately hangs, and I can't get any msgs to print before it hangs up so troubleshooting is a problem...
I DO have terminating conditions, but I can't see if they are working right.
I tried a test case and I get a 'function not found' kind of message.
thanks
Right now it immediately hangs, and I can't get any msgs to print before it hangs up so troubleshooting is a problem...
I DO have terminating conditions, but I can't see if they are working right.
I tried a test case and I get a 'function not found' kind of message.
thanks
HegemonKhan
29 Jun 2013, 23:49here's an example of a function that calls itself (looping; loops):
<turnscript name="game_turns_turnscript">
level_up_function
game.turns=game.turns+1
</turnscript>
<function name="level_up_function"><![CDATA[
if (game.pov.experience_points >= game.pov.level * 100 + 100) {
game.pov.experience_points = game.pov.experience_points - (game.pov.level * 100 + 100)
game.pov.level = game.pov.level + 1
level_up_function
}
]]></function>

jaynabonne
30 Jun 2013, 00:37Recursion is definitely supported. If you're still having trouble, post the function! 

shadowphile
30 Jun 2013, 02:52Thanks guys.
When I got the bugs worked out of my simple test case, it also immediately hangs Quests.
Here's the entire test file.
When I got the bugs worked out of my simple test case, it also immediately hangs Quests.
Here's the entire test file.
<!--Saved by Quest 5.4.4873.16527-->
<asl version="540">
<include ref="English.aslx" />
<include ref="Core.aslx" />
<game name="test2">
<gameid>bb260e55-78d7-4835-a98e-8577930d2f5b</gameid>
<version>1.0</version>
<firstpublished>2013</firstpublished>
<attr name="autodescription_description" type="int">2</attr>
<attr name="autodescription_youarein_useprefix" type="boolean">false</attr>
<attr name="autodescription_youcansee" type="int">3</attr>
<attr name="autodescription_youcango" type="int">4</attr>
<autodescription_youarein_newline />
<start type="script">
StartRec
</start>
</game>
<function name="RecursionTest" parameters="i" type="int"><![CDATA[
msg ("parameter: " + i)
if (i > 3) {
return (i)
}
par = i+1
result = RecursionTest(par)
return (result)
]]></function>
<function name="StartRec">
i = 1
result = RecursionTest(i)
msg ("RESULT: " + result)
</function>
</asl>
HegemonKhan
30 Jun 2013, 05:23finally... figured out getting this bloody thing to work!
I hope this is what you wanted it to do! (LOL)
enjoy!
I hope this is what you wanted it to do! (LOL)
<asl version="540">
<include ref="English.aslx" />
<include ref="Core.aslx" />
<game name="Testing Game Stuff">
<gameid>d83ba5bb-2e3c-4f31-80c9-3e88a2dc082c</gameid>
<version>1.0</version>
<firstpublished>2013</firstpublished>
<start type="script">
StartRec
</start>
</game>
<object name="room">
<inherit name="editor_room" />
<object name="player">
<inherit name="editor_object" />
<inherit name="editor_player" />
</object>
</object>
<function name="RecursionTest" parameters="i" type="int"><![CDATA[
msg ("parameter: " + i)
if (i < 4) {
par = i+1
i=RecursionTest (par)
}
return (i)
]]></function>
<function name="StartRec">
i = 1
result = RecursionTest(i)
msg ("RESULT: " + result)
</function>
</asl>
enjoy!

shadowphile
30 Jun 2013, 07:10thanks, it works.
Now.....why? The only main difference I can see is the lack of multiple return statements.
My real application using recursion is much more complex and I need to understand what won't fly.
Now.....why? The only main difference I can see is the lack of multiple return statements.
My real application using recursion is much more complex and I need to understand what won't fly.
HegemonKhan
30 Jun 2013, 07:27it took me a long time to figure out to do this:
i=RecursionTest (par)
as before when I had it just as this:
RecursionTest (par)
~OR~
x=RecursionTest (par)
I kept getting:
parameter: 1
parameter: 2
parameter: 3
parameter: 4
RESULT: 1 or 2
and even before this, with an earlier code set up, I got this:
parameter: 1
parameter: 2
parameter: 3
parameter: 4
error: ~"could not do return script"
RESULT: 0
-----------------------
I was able to get the parameters:
parameter: 1
parameter: 2
parameter: 3
parameter: 4
to work correctly pretty quickly, with this:
but, I was having a hard time trying to figure out why it wouldn't then work with the "return (i) for the RESULT: 4", as it had seemed that it should with it correctly updating for each of the parameters' values.
this is what was happening (as best as I understand it... barely at all, lol):
but, as can be seen, we've got no connector~link to~for the "return (i)", so quest sees a~the missing function's return value, thus the error: ~"could not find function, no return value"
AND, we've never set the updating of the "i", hence the (still mysterious) return of "0 (zero)", and (non~less-mysterious) return of "1" or "2", within the "RESULT: X"
--------------------------
tinker with my code yourself, to see how you can mess it up, and maybe understand better what is going on than I can, and it's easier for you to see the bad results yourself from tinkering with my code, than me trying to explain this to you without you getting confused from me not being able to recall exactly what I had coded when I got these bad results of mine, and nor do I want to re-tinker with it myself, as I've already done so long enough just to finally get my working code done for you, lol.
i=RecursionTest (par)
as before when I had it just as this:
RecursionTest (par)
~OR~
x=RecursionTest (par)
I kept getting:
parameter: 1
parameter: 2
parameter: 3
parameter: 4
RESULT: 1 or 2
and even before this, with an earlier code set up, I got this:
parameter: 1
parameter: 2
parameter: 3
parameter: 4
error: ~"could not do return script"
RESULT: 0
-----------------------
I was able to get the parameters:
parameter: 1
parameter: 2
parameter: 3
parameter: 4
to work correctly pretty quickly, with this:
<function name="RecursionTest" parameters="i" type="int"><![CDATA[
msg ("parameter: " + i)
if (i < 4) {
par = i+1
RecursionTest (par)
}
]]></function>
but, I was having a hard time trying to figure out why it wouldn't then work with the "return (i) for the RESULT: 4", as it had seemed that it should with it correctly updating for each of the parameters' values.
this is what was happening (as best as I understand it... barely at all, lol):
<function name="StartRec">
i=1
result=RecursionTest (i -> 1)
<function name="RecursionTest" parameters="i -> 1" type="int"><
edit: I replaced the line "return(i)" with "return(par)" which you would think should be just as harmless but I then get an error. Methinks this is some kind of tomfoolery with local variables and parameter stacks. I think I might be able to work out exactly where the limitation is. Probably right about the time one of the other guru's wakes in his own time zone and knows exactly what the issue is.

edit: I replaced the line "return(i)" with "return(par)" which you would think should be just as harmless but I then get an error. Methinks this is some kind of tomfoolery with local variables and parameter stacks. I think I might be able to work out exactly where the limitation is. Probably right about the time one of the other guru's wakes in his own time zone and knows exactly what the issue is.

HegemonKhan
30 Jun 2013, 08:35I just edited my post, so refresh and look at it again, well just the "this is how I think it works" section anyways, as I think I got it hopefully explained correctly now... lol
-----------
I meant to take my working code, and change things ("tinker") to try to get my bad results, as I might not be posting correctly what coding setup produced those bad results of mine that I was trying to explain about. Easier for you to change things, and see what bad things result from your changes to my code, then me trying to remember what I had done (what my code setup was like) to produce those bad results of mine (I went through a lot of code setups, with small tweaks, thus, I can't remember what caused what, lol).
-----------
I meant to take my working code, and change things ("tinker") to try to get my bad results, as I might not be posting correctly what coding setup produced those bad results of mine that I was trying to explain about. Easier for you to change things, and see what bad things result from your changes to my code, then me trying to remember what I had done (what my code setup was like) to produce those bad results of mine (I went through a lot of code setups, with small tweaks, thus, I can't remember what caused what, lol).

jaynabonne
30 Jun 2013, 09:14The problem here is something I consider a flaw in Quest - the "return" statement does *not* cause execution flow to exit the function. It just sets a return value and then plods on.
I really wish Alex would fix this. It's counterintuitive to every other language that I know of that has a "return" statement, and it causes grief like this. And it doesn't serve any useful purpose as it's currently implemented.
Try this and you'll see:
Both msg's will execute.
I really wish Alex would fix this. It's counterintuitive to every other language that I know of that has a "return" statement, and it causes grief like this. And it doesn't serve any useful purpose as it's currently implemented.
Try this and you'll see:
msg("before return")
return (something)
msg("after return")
Both msg's will execute.
shadowphile
30 Jun 2013, 09:50...and that explains why I studied physics and not programming. But it clarifies SO much. The scientific method only goes so far in the world of software...
I took my original code:
and just inserted a flow-controlling ELSE:
and it works great!..
I can go to bed now and fall asleep with dreams of productive coding caressing my troubled brow.
thank you
thanks
I took my original code:
msg ("parameter: " + i)
if (i >= 3) {
return (i)
}
par = i+1
result = RecursionTest (par)
return (result)
}
and just inserted a flow-controlling ELSE:
msg ("parameter: " + i)
if (i >= 3) {
return (i)
}
else {
par = i+1
result = RecursionTest (par)
return (result)
}
and it works great!..



thank you

thanks
shadowphile
30 Jun 2013, 09:54jaynabonne wrote:The problem here is something I consider a flaw in Quest - the "return" statement does *not* cause execution flow to exit the function. It just sets a return value and then plods on.
I really wish Alex would fix this. It's counterintuitive to every other language that I know of that has a "return" statement, and it causes grief like this. And it doesn't serve any useful purpose as it's currently implemented.
Try this and you'll see:msg("before return")
return (something)
msg("after return")
Both msg's will execute.
Upon reflection I seem to remember some language way back that operated like this, Fortran maybe? I just recall the need to account for the 'fall through'.

jaynabonne
30 Jun 2013, 09:56Well that explains it - I never studied Fortran 

george
30 Jun 2013, 17:32You could make the case that breaking control flow in the middle of functions leads to less clear and possibly confusing code. I guess you could say that about making return's behavior different than nearly every other language too though
.

HegemonKhan
30 Jun 2013, 18:19whoa... I thought I had tried doing that Shadow, and it didn't work for me... obviously, I must not have done it exactly as you have (a small difference maybe, though I did try putting in the "else"... GRRRowles, laughs), or it woulda worked for me, lol.

jaynabonne
30 Jun 2013, 18:28George, I agree. I do try to have my functions (as much as possible) with single exit points. I think to really make that easier, Quest needs the ability to break out of a loop. (And even add "goto" - ok, I'm kidding.)
HegemonKhan
30 Jun 2013, 18:37why are you kidding about a script "goto" (like in command prompt language*), as wouldn't that be useful for us?
*Command Prompt:
(well, this isn't an example of breaking out of a loop, but it is of what a "script goto" does, I hope we're talking~thinking about the same thing anyways, lol)
:start_character_creation
echo What is your name?
set /p player_name=
(etc etc etc coding)
echo Is this the character that you want?
echo Type 1 for yes or 2 for no
set /p result=
if %result%==2 goto start_character_creation
*Command Prompt:
(well, this isn't an example of breaking out of a loop, but it is of what a "script goto" does, I hope we're talking~thinking about the same thing anyways, lol)
:start_character_creation
echo What is your name?
set /p player_name=
(etc etc etc coding)
echo Is this the character that you want?
echo Type 1 for yes or 2 for no
set /p result=
if %result%==2 goto start_character_creation

jaynabonne
30 Jun 2013, 19:27Because "goto" is considered the bane of structured code design, a jumping around in the code that results in hard-to-follow "spaghetti" code. I used to use "gotos" back in the BASIC days, as there were no loops structures back then, for example. But I haven't used a "goto" in perhaps 20 years now. 

shadowphile
30 Jun 2013, 21:23funny...this issue had nothing to do with recursion 
It also suggests that any other functions I have may not be working right and I don't even now it! Scanning all my code starting..now.

It also suggests that any other functions I have may not be working right and I don't even now it! Scanning all my code starting..now.
HegemonKhan
30 Jun 2013, 22:49Ah, I see now, I didn't realize how messy and convoluted it can make your code structure, hehe. I've got a lot to learn about coding and its "logic theory" still, lol. I wasn't sure if you were being sarcastic in your remark about the "goto" so I had tried to ask about it in a neutral way, though I see I was right in my feeling that you were being sarcastic about using a "script goto", and now I know why, too! 
