Documentation Index
Fetch the complete documentation index at: https://soul-lang.com/llms.txt
Use this file to discover all available pages before exploring further.
null
The null value in Soul represents the intentional absence of any value. It is a special literal that indicates that a variable has no value or that a function returns nothing meaningful.
Basic Null Usage
Assign and work with null values:
// Explicit null assignment
value = null
user = null
result = null
// Function returning null
soul findUser(id) {
// Search logic...
return null // User not found
}
Null Checking
Check if values are null:
data = getUserData()
if (data == null) {
println("No user data available")
} else {
println("User data loaded")
}
// Null check with negation
if (data != null) {
processData(data)
}
Null in Conditionals
Null is considered falsy in conditional statements:
value = null
if (value) {
println("This won't execute")
} else {
println("Value is null or falsy")
}
// Explicit null check is clearer
if (value == null) {
println("Value is explicitly null")
}
Null vs Other Falsy Values
Distinguish null from other falsy values:
// Different falsy values
nullValue = null
emptyString = ""
zero = 0
falseValue = false
// Check specifically for null
if (nullValue == null) {
println("This is null")
}
// Check for any falsy value
if (!nullValue) {
println("This is falsy (could be null, false, 0, or empty string)")
}
Null in Function Returns
Return null to indicate absence or failure:
soul divide(a, b) {
if (b == 0) {
return null // Cannot divide by zero
}
return a / b
}
result = divide(10, 0)
if (result == null) {
println("Division failed")
} else {
println("Result: " + result)
}
Null in Object Properties
Handle null object properties:
user = {
"name": "Alice",
"email": null, // Email not provided
"age": 30
}
// Check null property
if (user.email == null) {
println("Email not provided")
} else {
println("Email: " + user.email)
}
Null in Arrays
Handle null elements in arrays:
items = [1, null, 3, null, 5]
// Process array with null checks
for (item in items) {
if (item != null) {
println("Item: " + item)
} else {
println("Found null item")
}
}
Null Coalescing
Provide default values for null:
soul getWithDefault(value, defaultValue) {
if (value == null) {
return defaultValue
}
return value
}
// Usage
name = getWithDefault(user.name, "Unknown")
age = getWithDefault(user.age, 0)
Null Safety Patterns
Safe navigation and method calls:
soul safeAccess(object, property) {
if (object == null) {
return null
}
return object[property]
}
soul safeMethodCall(object, methodName, args) {
if (object == null) {
return null
}
if (typeof object[methodName] != "function") {
return null
}
return object[methodName](args)
}
// Usage
user = getUser()
name = safeAccess(user, "name")
info = safeMethodCall(user, "getInfo", [])
Null in Error Handling
Use null to indicate error states:
soul parseNumber(str) {
if (str == null || str == "") {
return null
}
try {
return Number(str)
} catch (error) {
return null // Parse failed
}
}
result = parseNumber("123")
if (result == null) {
println("Invalid number")
} else {
println("Number: " + result)
}
Null in Database Operations
Handle null values from database queries:
soul findUserById(id) {
if (id == null) {
return null
}
user = database.query("SELECT * FROM users WHERE id = ?", id)
if (user == null || user.length() == 0) {
return null // User not found
}
return user[0]
}
Null Validation
Validate and handle null inputs:
soul validateInput(input) {
if (input == null) {
return {
"valid": false,
"error": "Input cannot be null"
}
}
if (typeof input != "string") {
return {
"valid": false,
"error": "Input must be a string"
}
}
if (input.trim() == "") {
return {
"valid": false,
"error": "Input cannot be empty"
}
}
return {
"valid": true,
"value": input.trim()
}
}
Null in Collections
Filter and handle null values in collections:
// Filter out null values
soul filterNulls(array) {
result = []
for (item in array) {
if (item != null) {
result.push(item)
}
}
return result
}
// Count null values
soul countNulls(array) {
count = 0
for (item in array) {
if (item == null) {
count++
}
}
return count
}
// Usage
data = [1, null, 3, null, 5]
cleaned = filterNulls(data) // [1, 3, 5]
nullCount = countNulls(data) // 2
Null in API Responses
Handle null values in API responses:
soul processApiResponse(response) {
if (response == null) {
return {
"success": false,
"error": "No response received"
}
}
if (response.data == null) {
return {
"success": false,
"error": "No data in response"
}
}
return {
"success": true,
"data": response.data
}
}
Null Assignment Patterns
Common patterns for null assignment:
// Initialize with null
currentUser = null
selectedItem = null
lastError = null
// Conditional assignment
if (shouldReset) {
currentUser = null
}
// Null after cleanup
soul cleanup() {
connection.close()
connection = null
cache.clear()
cache = null
}
Null Debugging
Debug null-related issues:
soul debugNull(value, label) {
if (value == null) {
println("DEBUG: " + label + " is null")
} else {
println("DEBUG: " + label + " = " + value + " (type: " + typeof value + ")")
}
}
// Usage
user = getUser()
debugNull(user, "user")
debugNull(user.name, "user.name")
Null Best Practices
Guidelines for working with null:
// Good - explicit null checks
soul processUser(user) {
if (user == null) {
return { error: "User is null" }
}
if (user.name == null) {
return { error: "User name is null" }
}
return { success: true, name: user.name }
}
// Better - comprehensive null handling
soul processUser(user) {
// Validate input
if (user == null || typeof user != "object") {
return {
success: false,
error: "Invalid user object"
}
}
// Extract with defaults
name = user.name != null ? user.name : "Unknown"
email = user.email != null ? user.email : "No email"
age = user.age != null ? user.age : 0
return {
success: true,
user: {
name: name,
email: email,
age: age
}
}
}
Best Practices
- Always check for null: Validate variables before use
- Use explicit comparisons:
value == null is clearer than !value
- Provide defaults: Use default values when null is encountered
- Document null returns: Clearly indicate when functions can return null
- Handle null gracefully: Don’t let null values crash your program
// Good - safe null handling
soul safeStringOperation(str) {
if (str == null) {
return ""
}
return str.trim().toUpperCase()
}
// Better - with comprehensive validation
soul safeStringOperation(str) {
if (str == null) {
return { success: false, error: "String is null", result: "" }
}
if (typeof str != "string") {
return { success: false, error: "Value is not a string", result: "" }
}
try {
result = str.trim().toUpperCase()
return { success: true, result: result }
} catch (error) {
return { success: false, error: error.toString(), result: "" }
}
}
Null handling is crucial for writing robust Soul applications. Always anticipate null values and handle them appropriately to prevent runtime errors and unexpected behavior.