E01073: 'null' does not exist in EK9 - use tri-state semantics (unset/set) with '?' operator
What went wrong
The 'null' literal does not exist in EK9.
Worked examples
Compilable examples demonstrating this error and the correct fix:
- ek9 -q 277 (Why does AI generate null checks instead of guards in EK9?)
- ek9 -q 146 (How do I structure functions without early return in EK9?)
- ek9 -q 128 (Why can't I extend List or Dict in EK9?)
Rationale
EK9 replaces null with tri-state semantics:
- Tony Hoare (inventor of null): Called it his "billion-dollar mistake"
- Java's NullPointerException is the runtime failure null produces
- EK9's tri-state model eliminates this entire class of bugs
[THREE STATES IN EK9]
- Absent - no memory allocated to hold a value (what other languages call null); EK9 is designed so that a program can never observe it - a missing Dict key gives the getOrDefault default, typically an unset object, not an absent one
- Unset - Object exists but has no meaningful value
- Set - Object exists with valid, usable value
How to fix it
Use String(), Integer(), etc. to create unset values. Use '?' operator to check if values are set. Use guards for safe access.
See also
- E01070: 'break' not supported (use stream pipelines with 'head')
- E01071: 'continue' not supported (use stream pipelines with 'filter')
- E01072: 'return' not supported (use return declarations)
- E01073: 'null' not supported (use tri-state semantics)
- E01074: semicolons not needed (indentation-based syntax)
https://ek9.io/basics.html#tri-state https://ek9.io/forAI.json#$.excludedFeatures.features[?(@.keyword=="null")]
Examples
Every example is compiled by the EK9 compiler: the first fails exactly as captioned, the others fix it.
Fails with E01073: 'null' does not exist in EK9 - use tri-state semantics (unset/set) with '?' operator
#!ek9 defines module error.e01073.bad defines function unknownName() <- name as String: String() name: null
Fixed: An unset value stands where null would; test it with ?
#!ek9 defines module error.e01073.good defines function unknownName() <- name as String: String() greeting() -> name as String <- message as String: "Hello, guest" if name? message: "Hello, " + name
Questions and answers
These Q&A entries show E01073 and its fix:
- Q128: Why can't I extend List or Dict in EK9?
- Q146: How do I structure functions without early return in EK9?
- Q277: Why does AI generate null checks instead of guards in EK9?
- Q898: What does the ? operator mean in EK9?
- Q971: How do guards work in EK9 if statements?
- Q973: How do I declare a variable inside an if condition in EK9?
- Q975: Can guards be used in switch and while, not just if?
- Q982: How do ? and guards work together in EK9?
- Q991: Trace the execution flow through these guards. What values get printed?
- Q993: The compiler reports E08030 on my discount lookup. What is wrong and how do I fix it?
- Q1004: In Rust I check if an Option has a value with is_some(). How do I do this in EK9?
- Q1009: In Go I return (value, error) and check if err != nil. What does EK9 use instead?
- Q1011: In Python I use 'with psycopg2.connect() as conn:' for database connections. How do I manage resources in EK9?
- Q1023: What is the difference between :=, :=? and the explicit re-point-and-check in EK9 control flow?
- Q1024: How do I re-point an existing variable and run a block only when the new value is set?
- Q1038: How do I try multiple configuration sources and use the first one that has a value?
- Q1059: Why is there no ?? null coalescing operator in EK9, and how do I default an unset value?
- Q1088: What does default ? report for a partially-initialised record?
- Q1091: Provide a fallback display name when the user name is unset.
- Q1093: Chain multiple fallback values to find the first one that is set.
- Q1107: Check the set and unset states of a component's fields.
- Q1150: Loop while a connection value remains set, processing each iteration.
- Q1152: Set a default port only if one has not already been provided.
- Q1157: Guard a try block so it only runs when the guard value is set.
- Q1201: Check if a project has a deadline set, and warn if it is in the past.
- Q1220: Set a default user name only if no name has been provided.
- Q1222: Set a fallback deadline only if no deadline was specified.
- Q1223: Apply a minimum price only if the product price hasn't been set.
- Q1224: Set a default tax rate only when the rate hasn't been configured.
- Q1225: Apply a default session timeout only if no timeout was set.
- Q1232: Apply a default Configuration record only if no configuration was provided.