Null Safety
The Alia language provides null safety mechanisms to help developers avoid null value errors.
1. Null and Nullable Types
Null is a standalone type that cannot participate in any operations (arithmetic, comparison, logical, etc.); operating on a Null value or a variable whose value is Null raises an error immediately. typeOf null returns 'Null'.
Use the ? suffix to declare a nullable type, meaning the value can be either the target type or Null.
Basic Syntax
<Type?> ~ nullable type declaration
Example
~ nullable string
const name: String? = null
const greeting: String? = 'Hello'
~ nullable number
const age: Number? = null
const count: Number? = 42
~ nullable object
const user: Object? = null
~ Null is a standalone type
print typeOf null ~ outputs 'Null'
2. The Ok Built-in Alias
Ok is a built-in alias that checks whether a value is non-null, equivalent to typeOf val != 'Null', returning a Boolean. In contexts requiring explicit grouping, such as assert, write it as (Ok val).
Basic Syntax
Ok <Value val> ~ returns a Boolean
Example
const value1 = 'Hello'
const value2 = null
print Ok value1 ~ outputs true
print Ok value2 ~ outputs false
type User *[name: String]
const user: User? = *[name: 'Alice']
if Ok user {
print 'User exists: ' .. user.name
}
assert (Ok value1)
3. Nullable Parameters
In an alias declaration, <Type? argName> declares a nullable parameter, allowing null to be passed.
Basic Syntax
alias <Type? argName> -> { argName }
Example
~ nullable string parameter
alias greet <String? name> -> {
if Ok name {
print 'Hello, ' .. name
} else {
print 'Hello, stranger'
}
}
greet 'Alice' ~ outputs 'Hello, Alice'
greet null ~ outputs 'Hello, stranger'
~ multiple nullable parameters
alias createUser <String? name> and <Number? age> -> *[name: String, age: Number] {
const realName = name ?? 'Anonymous'
const realAge = age ?? 0
return *[ name: realName, age: realAge ]
}
const u1 = call createUser ['Bob', 25]
print u1.name ~ outputs 'Bob'
print u1.age ~ outputs 25
const u2 = call createUser [null, null]
print u2.name ~ outputs 'Anonymous'
print u2.age ~ outputs 0
~ mixing nullable and non-nullable parameters
alias divide <Number a> <Number? b> -> Number {
if Ok b {
if b == 0 { return 0 }
return a / b
} else {
return 0
}
}
print call divide [10, 2] ~ outputs 5
print call divide [10, null] ~ outputs 0
4. The Null Coalescing Operator
?? returns the right-hand value when the left-hand side is null, and the left-hand value otherwise.
Basic Syntax
<Value left> ?? <Value right>
Example
~ basic usage
const name = null
const displayName = name ?? 'Anonymous user'
print displayName ~ outputs 'Anonymous user'
const count = 42
const displayCount = count ?? 0
print displayCount ~ outputs 42
~ chained usage
const value = null ?? null ?? 'Default value'
print value ~ outputs 'Default value'
5. Comprehensive Example
~ comprehensive null safety example
~ 1. nullable type declarations
const username: String? = null
const age: Number? = 25
~ 2. checking with Ok
if Ok username {
print 'Username: ' .. username
} else {
print 'Username is empty'
}
~ 3. providing defaults with ??
const displayName = username ?? 'Anonymous user'
print 'Display name: ' .. displayName
~ 4. nested nullable objects
type User *[name: String, email: String?]
const bob: User? = *[name: 'Bob', email: 'bob@example.com']
const guest: User? = null
if Ok bob {
print 'Email: ' .. (bob.email ?? 'default@example.com')
} else {
print 'User is empty'
}
const fallback: User = guest ?? *[name: 'Guest', email: null]
print 'Display name: ' .. fallback.name
6. Best Practices
6.1 Prefer Nullable Types
~ recommended: declare nullable return types explicitly
alias findUser <Number id> -> Object? {
if id > 0 { return *[id: id] }
return null
}
const user: Object? = findUser 1
6.2 Use ?? to Provide Sensible Defaults
~ recommended: provide meaningful defaults
const config = *[timeout: null, retries: null]
const timeout = config.timeout ?? 3000
const retries = config.retries ?? 3
6.3 Use Ok for Existence Checks
~ recommended: check that a value exists before operating on it
const result = null
if Ok result {
print 'Operation succeeded: ' .. result
} else {
print 'Operation failed'
}