You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
refactor/feat: changes and additions to ReplaceOptions ('form', 'direction') (#305)
* feat: ReplaceOptions.direction
* refactor (+fix): update ReplaceOptions.canonical to 'form'
Retain canonical as a deprecated alias, accept both option names for one release, and keep the replacement-form transition separate from the replacement-sameness change.
* fix: when considering replacement expr. sameness, also consider expression 'form'
Treat form changes as meaningful during recursive replace iteration so eager form propagation can surface even when structural equality stays the same. This keeps the replacement-form behavior separate from the ReplaceOptions API transition.
* fix (workaround): ensure intended canonical - non-canonical - match pattern variant comparison (rule application)
(this change is marked as a *workaround* rather than a 'fix' per se, since the issue it tackles instead likely has its root in the current behaviour regarding the binding of 'wildcard' symbol variants (-outside the context of pattern matching / replacement.
(See the closing of this message for a further remark on this point.))
Explanation:
- Currently, because canonicalization of expresssions involves wildcard binding as part of symbol binding (this may be undesirable / a bug), it is presently necessary that a new scope be created upon 'match' pattern canonicalization (performed for optimization purposes) in rule application: with this otherwise running the risk of present wildcard symbols being bound to definitions in the current scope...
For example, before this change:
```
ce.expr(['Add', 'x', 3]).replace({ match: ['_', '__'], replace: 'y'});
// →Expectedly captures wildcards, and replaces
// top-level expression.
// *However*, the canonical-request of the 'match' expression within 'applyRule'
// results in symbol/wildcard '_' being attributed a function-definition
// (type='function'): within the scope in which this 'expr.replace()' was called
// Consequently, a subsequent replace call involving a universal wildcard
ce.expr(['Add', 'x', 3]).replace({ match: ['Add', 'x', '_')], replace: 5 });
// → Returns 'null'... (assuming this call made with an unmodified/same scope as the previous)
// Ultimately because the same point-of-canonicalization results in the Universal
// Wildcard in this instance uptaking the previous, 'function' definition, resulting
// in a MathJson-internal type-error for the canonicalized match-pattern variant
// in this instance, resulting in an absent wildcard in the canonical variant,
// and leading to an early exit from rule-application 'applyRule()'
//For illustration, the canonical-variant of the initial, non-canonically boxed
// `['Add', 'x', 3]` pattern results in the canonical-variant as:
[ "Add", "x", [ "Error", [ "ErrorCode", "'incompatible-type'", "number", "function", ], ], ]
```
*Note*:
- This 'fix' may no longer be necessary, if canonicalization of wildcard-containing expressions were to no longer perform name-binding on these (this may be unintentional?)
* doc: ReplaceOptions; and CHANGELOG
---------
Co-authored-by: Arno Gourdol <arno@arno.org>
0 commit comments