Skip to content
CPU edited this page Oct 8, 2026 · 3 revisions

Nulls

Dflat handles null safety explicitly through type modifiers, default behaviors, and dedicated language constructs.

1. Nullability Rules

  • Value Types: Strictly non-nullable by default unless explicitly marked with a question mark (type?). Reference classes and strings are nullable by default.

  • Strings: Strings are nullable by default, and a null string is treated interchangeably with an empty string (""). Note that writing string? is a compile error since string is already nullable.

    i32 normalInt = 10; // Non-nullable value type i32? nullableInt = null; // Explicitly nullable value type string text = null; // Strings are nullable by default string emptyText = ""; // Treated interchangeably with a null string

2. Native Type Null Handling

  • date: Can be assigned null directly (date d = null), which sets it to the minimum possible value of an i64.

  • clock: Can be assigned null directly (clock c = null), where it evaluates to 0 (since GetClock() never returns 0).

  • addr: Can be assigned null directly (addr a = null), representing an unmapped or invalid memory location evaluating to 0.

    date d = null; // Valid: sets to minimum i64 value clock c = null; // Valid: evaluates to raw value 0 addr a = null; // Valid: evaluates to raw value 0

3. Propagation and Comparison

  • Arithmetic: Null values propagate automatically through arithmetic operations.

  • Equality & Sorting: Null values evaluate equal only to other nulls and sort first in ordering.

  • Reference Checks: Expressions like a == null may invoke overloaded equality operators, whereas a is null always performs a direct reference check.

    i32? result = 10 + null; // Evaluates to null (propagation) bool check = (nullableInt == null); // May invoke overloaded equality bool direct = nullableInt is null; // Direct reference check

4. Unwrapping and Safety Mechanisms

  • enforce Construct: The enforce a { } else { } construct serves as the dedicated unwrap mechanism for nullable types (type?) and weak references (note that strings cannot be enforced).
  • Null-Safe Operators: Fully supports ?., ??, and ??=.
  • Member Access: Attempting to access members or properties on a null object reference immediately raises a NullPointerException. There is no unsafe x! force-unwrap operator for general objects.

Null coalescing and assignment

i32 b = nullableInt ?? 0;    // Safely unwraps into non-nullable target
myClass ??= MyClassConstructor(); // Initialize the class if it was null

Null-safe navigation

string userName = user?.Profile?.Name ?? "John Doe";

user?.Profile?.Name evaluates safely if user/Profile is null and defaults to John Doe if any of the steps are null

Enforce unwrap mechanism (for nullable types / weak references)

Foo? bar = GetNullableObject(); // ... maybe initialized maybe not ...
enforce bar {
    // 'bar' is safely unwrapped and non-nullable in this block
    bar.Baz();
} else {
    // Handle the null or error case
    Print("There is no Foo[l]");
}

Clone this wiki locally