Repository navigation
Nulls
Dflat handles null safety explicitly through type modifiers, default behaviors, and dedicated language constructs.
-
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 writingstring?is a compile error sincestringis 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
-
date: Can be assignednulldirectly (date d = null), which sets it to the minimum possible value of ani64. -
clock: Can be assignednulldirectly (clock c = null), where it evaluates to0(sinceGetClock()never returns0). -
addr: Can be assignednulldirectly (addr a = null), representing an unmapped or invalid memory location evaluating to0.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
-
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 == nullmay invoke overloaded equality operators, whereasa is nullalways 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
-
enforceConstruct: Theenforce 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 unsafex!force-unwrap operator for general objects.
i32 b = nullableInt ?? 0; // Safely unwraps into non-nullable target
myClass ??= MyClassConstructor(); // Initialize the class if it was null
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
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]");
}