Classify UDF-wrapped and var-scalar stable expressions as TA lengths#54
Merged
Conversation
The stable-TA-length guard hard-rejected two bar-invariant shapes: a TA constructor length computed through a pure single-expression user-defined function (any UDF call was treated as series-valued), and a never-reassigned var scalar whose initializer is a stable per-run expression (all var names were treated as mutable state). The stability classifier and the reset-expression renderer now inline single-ExprStmt-body UDFs structurally (parameter substitution over the arithmetic/call grammar; cycle guard and depth cap at the shared choke-point, so recursive UDFs are refused without hanging), and a first pass registers never-reassigned top-level var/varip scalars with stable initializers as stable derived expressions without inlining their use-sites. Genuinely series-dynamic lengths (e.g. a ternary over an ATR-derived ratio) are still rejected with the same error. Note: block-form single-expression UDFs parse with is_single_expr set false; the inliner keys off the body being exactly one expression statement, not that flag. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
The stable-TA-length guard hard-rejected two bar-invariant shapes:
ta.lowest(low[1], f_bars(mins))withf_bars(m) => math.max(1, math.round(m*60/tfSec))refused to transpile.varscalar with a stable per-run initializer (e.g.var tfSec = timeframe.in_seconds()) — allvarnames were treated as mutable state.The stability classifier and the reset-expression renderer now inline single-ExprStmt-body UDFs structurally (parameter substitution over the arithmetic/call grammar; cycle guard + depth cap at the shared choke-point, so recursive UDFs are refused without hanging), and never-reassigned top-level
var/varipscalars with stable initializers register as stable derived expressions (no use-site inlining). Genuinely series-dynamic lengths (ternary over an ATR-derived ratio) are still rejected with the same error — pinned by a guard test and an end-to-end true-positive sentinel.Gates (author + independent fresh-context R7, both green)
Unsupported TA constructor length, pass post-fix; 4 conservative guards (series-dynamic, reassigned-var body, recursive, multi-statement) pass on both sides.🤖 Generated with Claude Code