nulls - CPULL/Dflat GitHub Wiki
Dflat handles null safety explicitly through type modifiers, default behaviors, and dedicated language constructs.
-
Basic Value Types vs. Other Native Types: Basic value types (integers, reals,
dec,bool,char, enums) are strictly non-nullable by default unless explicitly marked with a question mark (type?). Other native types (string,date,time,clock,lapse,addr), pointers, and all objects (classes, collections) are nullable by default; adding?to them (e.g.,date?,string?) is a compile error. -
Strings: Strings are nullable by default, and a null string is treated interchangeably with an empty string (
"").
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: Nullable by default; can be assignednulldirectly (date d = null), which sets it to the minimum possible value of ani64. -
time: Nullable by default; a nulltimeis represented by-1. -
clock: Nullable by default; can be assignednulldirectly (clock c = null), where it evaluates to0(sinceClock()never returns0). -
lapse: Nullable by default; null evaluates to code000(raw value 0). -
addr: Nullable by default; can be assignednulldirectly (addr a = null), representing an unmapped or invalid memory location evaluating to0.
date d = null; // Valid: sets to minimum i64 value
time t = null; // Valid: sets to -1
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 force-unwrap operator (note that!is reserved for copying, e.g.,x!).
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");
}