Closed Slasy closed 3 years ago
FUNC is working as intended in NSTK mode, but I should update the documentation to explain what exactly it does in that mode, since it is a bit different from what it does in 4STK mode.
The problem with NSTK mode is that it isn't practical for FUNC to back up the entire stack. The stack can become arbitrarily deep, and in recursive functions, backing up the entire stack would lead to O(n^2) memory usage just for the stack.
What it does instead in NSTK mode is to back up only the parameters. That is, in the case of FUNC mn, it backs up levels 1 through m. The idea is that a function that takes m parameters will not modify or delete levels m+1 and higher, and so, those levels don't need to be backed up. Your test functions tstX1, tstX2, tstX3, and tstX4 all violate that assumption. Generally speaking, CLST, R↑, R↓, and anything that consumes any stack level above m, will cause FUNC to fail.
As long as levels m+1 and higher are left intact, FUNC will work correctly. Note that it is not necessary to avoid causing clutter on the stack: when a function with FUNC mn returns, having been called with original stack depth d and finishing with stack depth d', RTN will assume that levels 1 through n contain the results, levels m+1+d'-d through d' contain the original stack contents above the parameters, and levels n+1 through m+d'-d contain garbage and should be discarded.
4STK mode is completely different. Because of the fixed stack depth, FUNC cannot assume that stack levels m+1 and higher will be left alone by the function, since they may be lost off the top, and so it has to save the entire stack.
Thank you for detailed explanation. It makes sense that it could blow through memory really quickly if it would have been saving entire stack as in 4STK mode. So in the end I was just confused by the documentation or rather by the lack of this piece of information.
That's understandable!
I'm writing up a diagram to explain exactly what FUNC and RTN/RTNERR do in 4STK and NSTK modes, and will add that to the FUNC documentation on my web site as soon as it's done, probably tomorrow.
https://thomasokken.com/free42/images/FUNC.pdf
Let me know what you think... I haven't linked this from the documentation page yet.
Things get even more complicated when FUNC is combined with LNSTK or L4STK. I guess I should create diagrams for those scenarios as well... 🤔
I think this is understandable diagram and explanation.
Great! Thank you for checking. I'll create versions for FUNC+LNSTK and FUNC+L4STK as well and then link to those from the main page.
I updated the main Free42 page with a link to the diagram under the description of FUNC.
I decided not to cover the cases combining FUNC with LNSTK and L4STK; what's complicated about those is all behind the scenes, because of the way the effects of FUNC and L[4N]STK are combined and then rolled back together, but conceptually, what they do is pretty straightforward and intuitive, so I don't think it's useful to document that separately.
I changed my mind and added a paragraph about FUNC+LNSTK and FUNC+L4STK in the Big Stack section, and created a diagram covering those cases: https://thomasokken.com/free42/images/FUNC_L.pdf
Awesome, it looks great.
Hi, I really like big stack mode, but FUNC is not working in the same way as in 4STK mode. I'm not sure if this is a bug or some kind of limitation.
Here are some test programs, all should have same result in 4STK: Y: 10 X: 25 and respectively in NSTK: 2: 10 1: 25 But only first one (tstN) is behaving same in both modes, all others are unable to restore stack to expected state.