uCalc API Version: 2.1.3-preview.2 Released: 6/16/2026
Warning
uCalc API Preview Release Notice:The documentation describes the intended behavior of the API. The current preview build contains incomplete features, unoptimized performance, and is subject to breaking changes.
TraceTransform
Method
Product:Â
Class:Â
Captures each intermediate step of a cascading or recursive transformation, returning a list of strings for debugging and analysis.
Syntax
Parameters
Return
String
A uCalc.String object that acts as a list. Each item in the list is a string representing one step in the transformation process.
Remarks
The TraceTransform method is a powerful debugging and introspection tool that executes a transformation and returns a complete history of every intermediate step. It is particularly useful for understanding how rules with the RewindOnChange property create cascading or recursive transformations.
How It Works
Instead of returning just the final transformed string, TraceTransform captures the state of the string after each successful rule application. It returns a uCalc.String object that acts as a list, where each item in the list is a snapshot of the string at one point in the transformation sequence.
This is invaluable for debugging complex rule sets where the output of one rule becomes the input for another.
Handling the Result: A List-like uCalc.String
The returned uCalc.String object is a collection of strings. You can format its output using its list-formatting methods before retrieving the final text:
- ListSeparator(): Sets the separator string to be inserted between each step (e.g., a newline
"{@nl}"). - ListFormat(): Provides advanced control over the output, allowing you to define prefixes, postfixes, and a custom formatting expression for each step.
- Iteration: You can iterate through the returned object to process each step individually.
💡 Why uCalc? (Comparative Analysis)
Without TraceTransform, debugging a multi-step transformation is a manual, imperative process:
- Manual Logging: You would have to insert logging statements or set breakpoints inside your application's logic to see how the string changes after each pass of a
whileloop that simulates a recursive transform. - Step-Through Debugging: While possible, it can be difficult to visualize the overall flow and see all intermediate states at once.
TraceTransform provides a declarative and integrated solution. It's a built-in feature of the engine that captures the entire history of a transformation automatically. This allows you to get a complete, high-level overview of the process in a single call, making it significantly easier to diagnose complex rule interactions, identify infinite loops, and verify that a transformation is behaving as expected.
Examples
Succinct: A simple cascading transformation (`A` -> `B` -> `C` -> `D`) shows the step-by-step output.
using uCalcSoftware;
var uc = new uCalc();
var t = new uCalc.Transformer();
// RewindOnChange is necessary for cascading rules to be re-evaluated.
t.FromTo("A", "B").RewindOnChange = true;
t.FromTo("B", "C").RewindOnChange = true;
t.FromTo("C", "D").RewindOnChange = true;
// Trace the transformation of "A"
uCalc.String trace = t.TraceTransform("A");
// Format the output list with ' -> ' for readability
trace.ListSeparator(" -> ");
Console.WriteLine(trace);
A -> B -> C -> D using uCalcSoftware; var uc = new uCalc(); var t = new uCalc.Transformer(); // RewindOnChange is necessary for cascading rules to be re-evaluated. t.FromTo("A", "B").RewindOnChange = true; t.FromTo("B", "C").RewindOnChange = true; t.FromTo("C", "D").RewindOnChange = true; // Trace the transformation of "A" uCalc.String trace = t.TraceTransform("A"); // Format the output list with ' -> ' for readability trace.ListSeparator(" -> "); Console.WriteLine(trace);
#include
#include "uCalc.h"
using namespace std;
using namespace uCalcSoftware;
int main() {
uCalc uc;
uCalc::Transformer t;
// RewindOnChange is necessary for cascading rules to be re-evaluated.
t.FromTo("A", "B").RewindOnChange(true);
t.FromTo("B", "C").RewindOnChange(true);
t.FromTo("C", "D").RewindOnChange(true);
// Trace the transformation of "A"
uCalc::String trace = t.TraceTransform("A");
// Format the output list with ' -> ' for readability
trace.ListSeparator(" -> ");
cout << trace << endl;
}
A -> B -> C -> D #include <iostream> #include "uCalc.h" using namespace std; using namespace uCalcSoftware; int main() { uCalc uc; uCalc::Transformer t; // RewindOnChange is necessary for cascading rules to be re-evaluated. t.FromTo("A", "B").RewindOnChange(true); t.FromTo("B", "C").RewindOnChange(true); t.FromTo("C", "D").RewindOnChange(true); // Trace the transformation of "A" uCalc::String trace = t.TraceTransform("A"); // Format the output list with ' -> ' for readability trace.ListSeparator(" -> "); cout << trace << endl; }
Imports System
Imports uCalcSoftware
Public Module Program
Public Sub Main()
Dim uc As New uCalc()
Dim t As New uCalc.Transformer()
'// RewindOnChange is necessary for cascading rules to be re-evaluated.
t.FromTo("A", "B").RewindOnChange = true
t.FromTo("B", "C").RewindOnChange = true
t.FromTo("C", "D").RewindOnChange = true
'// Trace the transformation of "A"
Dim trace As uCalc.String = t.TraceTransform("A")
'// Format the output list with ' -> ' for readability
trace.ListSeparator(" -> ")
Console.WriteLine(trace)
End Sub
End Module
A -> B -> C -> D Imports System Imports uCalcSoftware Public Module Program Public Sub Main() Dim uc As New uCalc() Dim t As New uCalc.Transformer() '// RewindOnChange is necessary for cascading rules to be re-evaluated. t.FromTo("A", "B").RewindOnChange = true t.FromTo("B", "C").RewindOnChange = true t.FromTo("C", "D").RewindOnChange = true '// Trace the transformation of "A" Dim trace As uCalc.String = t.TraceTransform("A") '// Format the output list with ' -> ' for readability trace.ListSeparator(" -> ") Console.WriteLine(trace) End Sub End Module
Practical: Traces the recursive expansion of a custom `MySum` function, showing how it is broken down into a standard arithmetic expression.
using uCalcSoftware;
var uc = new uCalc();
var t = uc.ExpressionTransformer;
// Assume these rules are pre-defined to create a recursive sum
t.FromTo("MySum({x})", "{x}");
t.FromTo("MySum({x}, {y})", "({x} + MySum({y}))").RewindOnChange = true;
uCalc.String trace = t.TraceTransform("MySum(1,2,3,4)");
trace.ListSeparator("\n");
Console.WriteLine(trace);
MySum(1,2,3,4)
(1 + MySum(2,3,4))
(1 + (2 + MySum(3,4)))
(1 + (2 + (3 + MySum(4))))
(1 + (2 + (3 + 4))) using uCalcSoftware; var uc = new uCalc(); var t = uc.ExpressionTransformer; // Assume these rules are pre-defined to create a recursive sum t.FromTo("MySum({x})", "{x}"); t.FromTo("MySum({x}, {y})", "({x} + MySum({y}))").RewindOnChange = true; uCalc.String trace = t.TraceTransform("MySum(1,2,3,4)"); trace.ListSeparator("\n"); Console.WriteLine(trace);
#include
#include "uCalc.h"
using namespace std;
using namespace uCalcSoftware;
int main() {
uCalc uc;
auto t = uc.ExpressionTransformer();
// Assume these rules are pre-defined to create a recursive sum
t.FromTo("MySum({x})", "{x}");
t.FromTo("MySum({x}, {y})", "({x} + MySum({y}))").RewindOnChange(true);
uCalc::String trace = t.TraceTransform("MySum(1,2,3,4)");
trace.ListSeparator("\n");
cout << trace << endl;
}
MySum(1,2,3,4)
(1 + MySum(2,3,4))
(1 + (2 + MySum(3,4)))
(1 + (2 + (3 + MySum(4))))
(1 + (2 + (3 + 4))) #include <iostream> #include "uCalc.h" using namespace std; using namespace uCalcSoftware; int main() { uCalc uc; auto t = uc.ExpressionTransformer(); // Assume these rules are pre-defined to create a recursive sum t.FromTo("MySum({x})", "{x}"); t.FromTo("MySum({x}, {y})", "({x} + MySum({y}))").RewindOnChange(true); uCalc::String trace = t.TraceTransform("MySum(1,2,3,4)"); trace.ListSeparator("\n"); cout << trace << endl; }
Imports System
Imports uCalcSoftware
Public Module Program
Public Sub Main()
Dim uc As New uCalc()
Dim t = uc.ExpressionTransformer
'// Assume these rules are pre-defined to create a recursive sum
t.FromTo("MySum({x})", "{x}")
t.FromTo("MySum({x}, {y})", "({x} + MySum({y}))").RewindOnChange = true
Dim trace As uCalc.String = t.TraceTransform("MySum(1,2,3,4)")
trace.ListSeparator(vbCrLf)
Console.WriteLine(trace)
End Sub
End Module
MySum(1,2,3,4)
(1 + MySum(2,3,4))
(1 + (2 + MySum(3,4)))
(1 + (2 + (3 + MySum(4))))
(1 + (2 + (3 + 4))) Imports System Imports uCalcSoftware Public Module Program Public Sub Main() Dim uc As New uCalc() Dim t = uc.ExpressionTransformer '// Assume these rules are pre-defined to create a recursive sum t.FromTo("MySum({x})", "{x}") t.FromTo("MySum({x}, {y})", "({x} + MySum({y}))").RewindOnChange = true Dim trace As uCalc.String = t.TraceTransform("MySum(1,2,3,4)") trace.ListSeparator(vbCrLf) Console.WriteLine(trace) End Sub End Module
Internal Test: Verifies advanced formatting of the trace output using `ListFormat` to create a custom, detailed step-by-step log.
using uCalcSoftware;
var uc = new uCalc();
var t = new uCalc.Transformer();
t.FromTo("A", "B").RewindOnChange = true;
t.FromTo("B", "C").RewindOnChange = true;
t.FromTo("C", "D").RewindOnChange = true;
uCalc.String trace = t.TraceTransform("A");
// Apply a custom format to each step in the list
trace.ListFormat("!", "(", ")", "$'{txt}->{n+1}/{c}'", "txt", "n", "c");
Console.WriteLine(trace);
(A->1/4!B->2/4!C->3/4!D->4/4) using uCalcSoftware; var uc = new uCalc(); var t = new uCalc.Transformer(); t.FromTo("A", "B").RewindOnChange = true; t.FromTo("B", "C").RewindOnChange = true; t.FromTo("C", "D").RewindOnChange = true; uCalc.String trace = t.TraceTransform("A"); // Apply a custom format to each step in the list trace.ListFormat("!", "(", ")", "$'{txt}->{n+1}/{c}'", "txt", "n", "c"); Console.WriteLine(trace);
#include
#include "uCalc.h"
using namespace std;
using namespace uCalcSoftware;
int main() {
uCalc uc;
uCalc::Transformer t;
t.FromTo("A", "B").RewindOnChange(true);
t.FromTo("B", "C").RewindOnChange(true);
t.FromTo("C", "D").RewindOnChange(true);
uCalc::String trace = t.TraceTransform("A");
// Apply a custom format to each step in the list
trace.ListFormat("!", "(", ")", "$'{txt}->{n+1}/{c}'", "txt", "n", "c");
cout << trace << endl;
}
(A->1/4!B->2/4!C->3/4!D->4/4) #include <iostream> #include "uCalc.h" using namespace std; using namespace uCalcSoftware; int main() { uCalc uc; uCalc::Transformer t; t.FromTo("A", "B").RewindOnChange(true); t.FromTo("B", "C").RewindOnChange(true); t.FromTo("C", "D").RewindOnChange(true); uCalc::String trace = t.TraceTransform("A"); // Apply a custom format to each step in the list trace.ListFormat("!", "(", ")", "$'{txt}->{n+1}/{c}'", "txt", "n", "c"); cout << trace << endl; }
Imports System
Imports uCalcSoftware
Public Module Program
Public Sub Main()
Dim uc As New uCalc()
Dim t As New uCalc.Transformer()
t.FromTo("A", "B").RewindOnChange = true
t.FromTo("B", "C").RewindOnChange = true
t.FromTo("C", "D").RewindOnChange = true
Dim trace As uCalc.String = t.TraceTransform("A")
'// Apply a custom format to each step in the list
trace.ListFormat("!", "(", ")", "$'{txt}->{n+1}/{c}'", "txt", "n", "c")
Console.WriteLine(trace)
End Sub
End Module
(A->1/4!B->2/4!C->3/4!D->4/4) Imports System Imports uCalcSoftware Public Module Program Public Sub Main() Dim uc As New uCalc() Dim t As New uCalc.Transformer() t.FromTo("A", "B").RewindOnChange = true t.FromTo("B", "C").RewindOnChange = true t.FromTo("C", "D").RewindOnChange = true Dim trace As uCalc.String = t.TraceTransform("A") '// Apply a custom format to each step in the list trace.ListFormat("!", "(", ")", "$'{txt}->{n+1}/{c}'", "txt", "n", "c") Console.WriteLine(trace) End Sub End Module