fyngyrz / aa_macro

Power up your text processing via macros
15 stars 4 forks source link

Recursion Overflow #8

Closed Quantum-Electrodynamics closed 2 years ago

Quantum-Electrodynamics commented 2 years ago

Hi, I found an overflow when I tried to run recursion. After looking at the code, I noticed that your code is computing the parent element after all the child elements have been computed, but in fact in both the if and else cases, some of the child elements do not need to be computed first. I hope the author can make a special case for these two elements.

fyngyrz commented 2 years ago

First, Python is pretty conservative when it comes to allocating stack space, and recursion is one of the most demanding of this resource.

The thread import allows you to change the amount of stack space; I suggest you try that, then run your recursive function in a new thread.

Second, as far as computing elements goes, there's no way to know if something needs further computation until it has already been computed. Also, as the language is subject to revision, some elements that do not now require computation, may require it in the future. Consequently this feature of the design is not going to change.

Quantum-Electrodynamics commented 2 years ago

First, Python is pretty conservative when it comes to allocating stack space, and recursion is one of the most demanding of this resource.

The thread import allows you to change the amount of stack space; I suggest you try that, then run your recursive function in a new thread.

Second, as far as computing elements goes, there's no way to know if something needs further computation until it has already been computed. Also, as the language is subject to revision, some elements that do not now require computation, may require it in the future. Consequently this feature of the design is not going to change.

No, I'm talking about infinite recursion, as in the following line of code, [style fact [if [b] 1 1][else [b] 1 [mul [b] {fact [sub [b] 1]}]]] {fact 1}, which goes to {fact 0}. But if the else branch does not continue to expand under that condition, infinite recursion will not occur. If that's how the language is designed, then the language has lost recursion, or at least I don't know how to recurse.

Translated with www.DeepL.com/Translator (free version)

Quantum-Electrodynamics commented 2 years ago

First, Python is pretty conservative when it comes to allocating stack space, and recursion is one of the most demanding of this resource.

The thread import allows you to change the amount of stack space; I suggest you try that, then run your recursive function in a new thread.

Second, as far as computing elements goes, there's no way to know if something needs further computation until it has already been computed. Also, as the language is subject to revision, some elements that do not now require computation, may require it in the future. Consequently this feature of the design is not going to change.

Also, it makes sense that some branches do not operate, for example, C's int a=b && c++, the later c++ does not execute. python has a similar mechanism, print(1 if 1 else 0/0) will return 1 instead of reporting an error. :)

fyngyrz commented 2 years ago

I think to do what you want to do here, you'd have to explicitly use [push] and [pop]; the contents of [b] are not stacked the way you are probably thinking. styles and built-ins can call each other, and that is stacked, but [b\] is intended to be persistent.

Quantum-Electrodynamics commented 2 years ago

I think to do what you want to do here, you'd have to explicitly use [push] and [pop]; the contents of [b] are not stacked the way you are probably thinking. styles and built-ins can call each other, and that is stacked, but [b] is intended to be persistent.

I don't think it has anything to do with [b] here. Because the unfolding is running correctly, it just won't stop. Even with [push] and [pop], it ends up relying on "if" to determine if the stack length or whatever is zero, and "if" doesn't stop the recursive expansion.

fyngyrz commented 2 years ago

[else] generates regardless of if the condition is met; the condition test only occurs when the decision is made to emit the generated content, or not. Same for [if]

Quantum-Electrodynamics commented 2 years ago

[else] generates regardless of if the condition is met; the condition test only occurs when the decision is made to emit the generated content, or not. Same for [if]

Okay.

fyngyrz commented 2 years ago

Quantum-Electrodynamics If you set up the operand portion of the else or if with a style instead of a direct statement, the style is not evaluated if the match is false and would not generate content. So in this way, you can have non-generating, non-emitting results.