uCalc API Version: 2.1.3-preview.2 Released: 6/17/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: 

Transformer Library

Class: 

Transformer

Captures each intermediate step of a cascading or recursive transformation, returning a list of strings for debugging and analysis.

Syntax

TraceTransform(string)

Parameters

expressionString
string
The expression string to transform and trace.

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 while loop 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
				
					#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;
}
				
			
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
				
			
A -> B -> C -> D
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)))
				
					#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;
}
				
			
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
				
			
MySum(1,2,3,4)
(1 + MySum(2,3,4))
(1 + (2 + MySum(3,4)))
(1 + (2 + (3 + MySum(4))))
(1 + (2 + (3 + 4)))
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)
				
					#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;
}
				
			
(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
				
			
(A->1/4!B->2/4!C->3/4!D->4/4)