uCalc API Version: 5.7.0-preview.1 Released: 7/30/2026

Warning

uCalc API Preview Release Notice:This preview documentation describes the intended behavior of the API. It is not fully accurate or complete.The current preview build contains incomplete features, unoptimized performance, and is subject to breaking changes.Use of the preview version in your production code is not recommended.

(Constructor)

Constructor

Product: 

Class: 

Creates a new uCalc instance, optionally cloning an existing one, or creating an empty placeholder.

Remarks

The uCalc constructor initializes a new evaluation engine. Depending on the overload used, the new instance may:

  • Clone the default engine
  • Clone a specific engine
  • Create an empty placeholder for later assignment

Each instance maintains its own isolated namespace of variables, functions, operators, tokens, transformers, and configuration settings.


Constructor Overloads

1. uCalc(bool setAsDefault = false, bool autoRelease = false)

Creates a new uCalc instance as a clone of the Default instance.

  • setAsDefault = true
    The new instance becomes the new Default instance.
    Equivalent to calling IsDefault(true) after construction.

  • autoRelease (C++ only)
    Marks the instance for automatic release when it goes out of scope.
    Equivalent to calling Owned().

Isolation:
The new instance is a deep clone. Changes to this instance do not affect the Default instance or any other instance.


2. uCalc(uCalc other) (C# only)

Creates a new instance as a clone of another uCalc instance.

  • Not supported in C++ (invokes the native copy constructor instead).
  • For cross‑language consistency, prefer Clone().

4. uCalc(uCalc::Empty)

Creates an empty placeholder instance.

  • Allocates only a minimal handle
  • No internal engine state
  • Can later be assigned a real instance (e.g., via Clone() or assignment)

Useful for deferred initialization.


Instance Lifetime & Scoping

uCalc instances behave differently depending on:

  • How they were created (constructor vs Clone())
  • Whether they are owned
  • Whether the language supports deterministic destruction

Below is the unified model.


Lifetime Rules (All Languages)

Instances created with Clone()

  • Always persist until explicitly released with Release()
  • Going out of scope does not release them
  • The variable holding the handle may be destroyed, but the engine remains alive

Therefore:
Always call Release() when you no longer need a cloned instance.


C# Lifetime Rules

Constructor-created instances

  • Are automatically released only when used with using
  • Without using, they behave like cloned instances and must be released manually

Clone() instances

  • Same rule: auto-release only when wrapped in using

Examples:

{     var u1 = new uCalc();     var u2 = uc.Clone();     // Neither u1 nor u2 auto-release  }{     using var u1 = new uCalc();     using var u2 = uc.Clone();     // Both auto-release  }

C++ Lifetime Rules

Constructor-created instances

  • Auto-release when the object goes out of scope

Clone() instances

  • Must be released manually unless wrapped in a stack‑allocated uCalc

Examples:

{     auto u1 = new uCalc();     auto u2 = uc.Clone();     // Must call Release() manually  }{     uCalc u1;     uCalc u2(uc.Clone());     uc1.Owned();   uc2.Owned();   // Auto-release on scope exit  }

MemoryIndex vs Handle

  • Handle
    Internal pointer-like value; unpredictable value; cannot be duplicated.

  • MemoryIndex
    Stable, predictable identifier for an instance.
    Useful for detecting whether an instance has been released.

Released instances are recycled.
If you create a new instance immediately after releasing another, it will typically reuse the same MemoryIndex.


Comparative Analysis — Why uCalc?

vs. Native C#/C++ Objects

  • uCalc instances encapsulate a full expression engine, not just data
  • Cloning produces isolated execution environments
  • Deterministic destruction is optional and configurable
  • MemoryIndex provides introspection not available in native objects

vs. Script Engines

  • uCalc instances are lightweight and fast to clone
  • Each instance maintains its own namespace
  • No global state unless explicitly shared

Examples

Quick Start

ID: 255

				
					using uCalcSoftware;

var uc = new uCalc();
// Create a new instance
using (var calc = new uCalc()) {
   
   // Evaluate an expression
   Console.WriteLine(calc.Eval("2 + 3"));
}
				
			
5
				
					#include <iostream>
#include "uCalc.h"

using namespace std;
using namespace uCalcSoftware;

int main() {
   uCalc uc;
   // Create a new instance
   {
      uCalc calc;
      calc.Owned(); // Causes calc to be released when it goes out of scope

      // Evaluate an expression
      cout << calc.Eval("2 + 3") << endl;
   }
}
				
			
5
				
					Imports System
Imports uCalcSoftware
Public Module Program
   Public Sub Main()
      Dim uc As New uCalc()
      '// Create a new instance
      Using calc As New uCalc()
         
         '// Evaluate an expression
         Console.WriteLine(calc.Eval("2 + 3"))
      End Using
   End Sub
End Module
				
			
5
Creating isolated evaluation contexts.

ID: 256

				
					using uCalcSoftware;

var uc = new uCalc();
var main = new uCalc();
main.DefineVariable("rate = 0.05");

var scenarioA = main.Clone();
var scenarioB = main.Clone();

scenarioA.DefineVariable("rate = 0.10");
scenarioB.DefineVariable("rate = 0.20");

Console.WriteLine($"A: {scenarioA.Eval("1000 * rate")}");
Console.WriteLine($"B: {scenarioB.Eval("1000 * rate")}");
Console.WriteLine($"Main: {main.Eval("1000 * rate")}");
main.Release();
scenarioA.Release();
scenarioB.Release();

				
			
A: 100
B: 200
Main: 50
				
					#include <iostream>
#include "uCalc.h"

using namespace std;
using namespace uCalcSoftware;

int main() {
   uCalc uc;
   uCalc main;
   main.DefineVariable("rate = 0.05");

   auto scenarioA = main.Clone();
   auto scenarioB = main.Clone();

   scenarioA.DefineVariable("rate = 0.10");
   scenarioB.DefineVariable("rate = 0.20");

   cout << "A: " << scenarioA.Eval("1000 * rate") << endl;
   cout << "B: " << scenarioB.Eval("1000 * rate") << endl;
   cout << "Main: " << main.Eval("1000 * rate") << endl;
   main.Release();
   scenarioA.Release();
   scenarioB.Release();

}
				
			
A: 100
B: 200
Main: 50
				
					Imports System
Imports uCalcSoftware
Public Module Program
   Public Sub Main()
      Dim uc As New uCalc()
      Dim main As New uCalc()
      main.DefineVariable("rate = 0.05")
      
      Dim scenarioA = main.Clone()
      Dim scenarioB = main.Clone()
      
      scenarioA.DefineVariable("rate = 0.10")
      scenarioB.DefineVariable("rate = 0.20")
      
      Console.WriteLine($"A: {scenarioA.Eval("1000 * rate")}")
      Console.WriteLine($"B: {scenarioB.Eval("1000 * rate")}")
      Console.WriteLine($"Main: {main.Eval("1000 * rate")}")
      main.Release()
      scenarioA.Release()
      scenarioB.Release()
      
   End Sub
End Module
				
			
A: 100
B: 200
Main: 50
Creating uCalc instances

ID: 78

				
					using uCalcSoftware;

var uc = new uCalc();
uc.DefineVariable("x = 123");

var uc1 = new uCalc(); // Creates a new instance
Console.WriteLine(uc1.EvalStr("x")); // uc1 does not have a variable named x
uc1.Release(); // Releases uc1 if it is no longer needed

var uc2 = uc.Clone(); // Creates new instance that is a clone of uc
Console.WriteLine(uc2.EvalStr("x")); // starts with the value of x obtained from uc
uc2.Eval("x = 456"); // Changes the value of x in uc1 but not uc
Console.WriteLine(uc2.EvalStr("x"));
Console.WriteLine(uc.EvalStr("x")); // The original x in uc remains unchanged
uc2.Release();

// Language specific - auto-releasing uCalc object

{ // Instances pointed to by neither uCalc1 nor uCalc2 will be released when they go out of scope
   var uCalc1 = new uCalc();
   var uCalc2 = uc.Clone();
   // Call uCalc1.Release() and uCalc2.Release() explicitly if want to release them
}

{ // The instances that both uCalc1 and uCalc2 point to will be released when uCalc1 and uCalc2 go out of scope
   using var uCalc1 = new uCalc();
   using var uCalc2 = uc.Clone();

   // No need for uCalc1.Release() or uCalc2.Release(), they will automatically be released
}

				
			
Undefined identifier
123
456
123
				
					#include <iostream>
#include "uCalc.h"

using namespace std;
using namespace uCalcSoftware;

int main() {
   uCalc uc;
   uc.DefineVariable("x = 123");

   uCalc uc1; // Creates a new instance
   cout << uc1.EvalStr("x") << endl; // uc1 does not have a variable named x
   uc1.Release(); // Releases uc1 if it is no longer needed

   auto uc2 = uc.Clone(); // Creates new instance that is a clone of uc
   cout << uc2.EvalStr("x") << endl; // starts with the value of x obtained from uc
   uc2.Eval("x = 456"); // Changes the value of x in uc1 but not uc
   cout << uc2.EvalStr("x") << endl;
   cout << uc.EvalStr("x") << endl; // The original x in uc remains unchanged
   uc2.Release();

   // Language specific - auto-releasing uCalc object

   { // Instances pointed to by neither uCalc1 nor uCalc2 will be released when they go out of scope
      auto uCalc1 = new uCalc();
      auto uCalc2 = uc.Clone();
      // Call uCalc1.Release() and uCalc2.Release() explicitly if want to release them
   }

   { // The instances that both uCalc1 and uCalc2 point to will be released when uCalc1 and uCalc2 go out of scope
      
      uCalc uCalc1;
      uCalc uCalc2(uc.Clone());
      // No need for uCalc1.Release() or uCalc2.Release(), they will automatically be released
   }

}
				
			
Undefined identifier
123
456
123
				
					Imports System
Imports uCalcSoftware
Public Module Program
   Public Sub Main()
      Dim uc As New uCalc()
      uc.DefineVariable("x = 123")
      
      Dim uc1 As New uCalc() '// Creates a new instance
      Console.WriteLine(uc1.EvalStr("x")) '// uc1 does not have a variable named x
      uc1.Release() '// Releases uc1 if it is no longer needed
      
      Dim uc2 = uc.Clone() '// Creates new instance that is a clone of uc
      Console.WriteLine(uc2.EvalStr("x")) '// starts with the value of x obtained from uc
      uc2.Eval("x = 456") '// Changes the value of x in uc1 but not uc
      Console.WriteLine(uc2.EvalStr("x"))
      Console.WriteLine(uc.EvalStr("x")) '// The original x in uc remains unchanged
      uc2.Release()
      
      '// Language specific - auto-releasing uCalc object
      #If False
         { '// Instances pointed to by neither uCalc1 nor uCalc2 will be released when they go out of scope
         Dim uCalc1 = new uCalc()
         Dim uCalc2 = uc.Clone()
         '// Call uCalc1.Release() and uCalc2.Release() explicitly if want to release them
         }
         
         { '// The instances that both uCalc1 and uCalc2 point to will be released when uCalc1 and uCalc2 go out of scope
         
         
         '// No need for uCalc1.Release() or uCalc2.Release(), they will automatically be released
         }
         #End If
      End Sub
   End Module
				
			
Undefined identifier
123
456
123
Evaluating expressions

ID: 21

				
					using uCalcSoftware;

var uc = new uCalc();
// See EvalStr for more examples.

Console.WriteLine(uc.Eval("1+1"));
Console.WriteLine(uc.Eval("5*(3+9)^2"));
Console.WriteLine(uc.Eval("Length('This is a test')"));
				
			
2
720
14
				
					#include <iostream>
#include "uCalc.h"

using namespace std;
using namespace uCalcSoftware;

int main() {
   uCalc uc;
   // See EvalStr for more examples.

   cout << uc.Eval("1+1") << endl;
   cout << uc.Eval("5*(3+9)^2") << endl;
   cout << uc.Eval("Length('This is a test')") << endl;
}
				
			
2
720
14
				
					Imports System
Imports uCalcSoftware
Public Module Program
   Public Sub Main()
      Dim uc As New uCalc()
      '// See EvalStr for more examples.
      
      Console.WriteLine(uc.Eval("1+1"))
      Console.WriteLine(uc.Eval("5*(3+9)^2"))
      Console.WriteLine(uc.Eval("Length('This is a test')"))
   End Sub
End Module
				
			
2
720
14
"using" (C#) and Owned (C++) for auto-releasing uCalc object

ID: 161

				
					using uCalcSoftware;

var uc = new uCalc();

// In C# and VB you should use "using".
// In C++ you can flag a uCalc object for
// auto-release with Owned(), or by setting
// the last parameter of the constructor to true.

uc.IsDefault = true; // Set uc as the default uCalc object
uCalc.DefaultInstance.DefineVariable("Value = 'Original uc object'");
Console.WriteLine(uCalc.DefaultInstance.EvalStr("Value")); // Outputs: Original uc object

// Use "using" so that the object is auto-released when it it goes out of scope
using (var uCalcTemp = new uCalc()) {
   uCalcTemp.IsDefault = true; // Set uCalcTemp as the default uCalc object
   uCalc.DefaultInstance.DefineVariable("Value = 'uCalcTemp object'");
   Console.WriteLine(uCalc.DefaultInstance.EvalStr("Value")); // uCalcTemp object
}
// uCalcTemp goes out of scope here, and the default uCalc object reverts back to uc

Console.WriteLine(uCalc.DefaultInstance.EvalStr("Value")); // Original uc object

{
   /*using*/ var uCalcSticky = new uCalc(); // remains the default even after going out of scope
   uCalcSticky.IsDefault = true; // Set uCalcSticky as the default uCalc object
   uCalc.DefaultInstance.DefineVariable("Value = 'uCalcSticky object'");
   Console.WriteLine(uCalc.DefaultInstance.EvalStr("Value")); // Outputs: uCalcSticky object
}    // The uCalcSticky object itself goes out of scope here, but internally it remains the default uCalc object

Console.WriteLine(uCalc.DefaultInstance.EvalStr("Value"));
				
			
Original uc object
uCalcTemp object
Original uc object
uCalcSticky object
uCalcSticky object
				
					#include <iostream>
#include "uCalc.h"

using namespace std;
using namespace uCalcSoftware;

int main() {
   uCalc uc;

   // In C# and VB you should use "using".
   // In C++ you can flag a uCalc object for
   // auto-release with Owned(), or by setting
   // the last parameter of the constructor to true.

   uc.IsDefault(true); // Set uc as the default uCalc object
   uCalc::DefaultInstance().DefineVariable("Value = 'Original uc object'");
   cout << uCalc::DefaultInstance().EvalStr("Value") << endl; // Outputs: Original uc object


   {
      uCalc uCalcTemp;
      uCalcTemp.Owned(); // Causes uCalcTemp to be released when it goes out of scope // Make uCalcTemp owned so it reverts back to uc when uCalcTemp goes out of scope
      uCalcTemp.IsDefault(true); // Set uCalcTemp as the default uCalc object
      uCalc::DefaultInstance().DefineVariable("Value = 'uCalcTemp object'");
      cout << uCalc::DefaultInstance().EvalStr("Value") << endl; // uCalcTemp object
   }
   // uCalcTemp goes out of scope here, and the default uCalc object reverts back to uc

   cout << uCalc::DefaultInstance().EvalStr("Value") << endl; // Original uc object

   {
      uCalc uCalcSticky; // remains the default even after going out of scope
      uCalcSticky.IsDefault(true); // Set uCalcSticky as the default uCalc object
      uCalc::DefaultInstance().DefineVariable("Value = 'uCalcSticky object'");
      cout << uCalc::DefaultInstance().EvalStr("Value") << endl; // Outputs: uCalcSticky object
   }    // The uCalcSticky object itself goes out of scope here, but internally it remains the default uCalc object

   cout << uCalc::DefaultInstance().EvalStr("Value") << endl;
}
				
			
Original uc object
uCalcTemp object
Original uc object
uCalcSticky object
uCalcSticky object
				
					Imports System
Imports uCalcSoftware
Public Module Program
   Public Sub Main()
      Dim uc As New uCalc()
      
      '// In C# and VB you should use "using".
      '// In C++ you can flag a uCalc object for
      '// auto-release with Owned(), or by setting
      '// the last parameter of the constructor to true.
      
      uc.IsDefault = true '// Set uc as the default uCalc object
      uCalc.DefaultInstance.DefineVariable("Value = 'Original uc object'")
      Console.WriteLine(uCalc.DefaultInstance.EvalStr("Value")) '// Outputs: Original uc object
      
      '// Use "using" so that the object is auto-released when it it goes out of scope
      Using uCalcTemp As New uCalc()
         uCalcTemp.IsDefault = true '// Set uCalcTemp as the default uCalc object
         uCalc.DefaultInstance.DefineVariable("Value = 'uCalcTemp object'")
         Console.WriteLine(uCalc.DefaultInstance.EvalStr("Value")) '// uCalcTemp object
      End Using
      '// uCalcTemp goes out of scope here, and the default uCalc object reverts back to uc
      
      Console.WriteLine(uCalc.DefaultInstance.EvalStr("Value")) '// Original uc object
      
      If True Then
         Dim uCalcSticky As New uCalc() '// remains the default even after going out of scope
         uCalcSticky.IsDefault = true '// Set uCalcSticky as the default uCalc object
         uCalc.DefaultInstance.DefineVariable("Value = 'uCalcSticky object'")
         Console.WriteLine(uCalc.DefaultInstance.EvalStr("Value")) '// Outputs: uCalcSticky object
      End If    '// The uCalcSticky object itself goes out of scope here, but internally it remains the default uCalc object
      
      Console.WriteLine(uCalc.DefaultInstance.EvalStr("Value"))
   End Sub
End Module
				
			
Original uc object
uCalcTemp object
Original uc object
uCalcSticky object
uCalcSticky object