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.
(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 callingIsDefault(true)after construction.autoRelease (C++ only)
Marks the instance for automatic release when it goes out of scope.
Equivalent to callingOwned().
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
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 using uCalcSoftware; var uc = new uCalc(); // Create a new instance using (var calc = new uCalc()) { // Evaluate an expression Console.WriteLine(calc.Eval("2 + 3")); }
#include
#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 #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; } }
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 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
Creating isolated evaluation contexts.
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 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();
#include
#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 #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(); }
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 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
Creating uCalc instances
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 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 }
#include
#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 #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 } }
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 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
Evaluating expressions
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 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')"));
#include
#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 #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; }
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 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