| sidebar_position | 8 |
|---|
HypnoScript offers modern, hypnotically-named operators for safe handling of null and undefined values. These operators are direct aliases to TypeScript/JavaScript concepts, embedded in hypnotic metaphors.
| Construct | Hypnotic Synonym | Standard Operator | Meaning |
|---|---|---|---|
| Nullish Coalescing | lucidFallback |
?? |
Fallback for null/undefined |
| Optional Chaining | dreamReach |
?. |
Safe object access |
| Optional Array | dreamReach[ |
?.[ |
Safe array index |
| Optional Call | dreamReach( |
?.( |
Safe function call |
The lucidFallback operator (alias for ??) returns the right operand if the left is null or undefined.
value lucidFallback fallback
value ?? fallback
Focus {
entrance {
induce maybeValue: number = null;
induce defaulted: number = maybeValue lucidFallback 100;
observe "Value: " + defaulted; // Output: Value: 100
induce realValue: number = 42;
induce result: number = realValue lucidFallback 100;
observe "Value: " + result; // Output: Value: 42
}
} Relax
Focus {
entrance {
// lucidFallback only checks for null/undefined
induce zero: number = 0;
induce empty: string = "";
induce falseBool: boolean = false;
observe zero lucidFallback 42; // 0 (not null!)
observe empty lucidFallback "empty"; // "" (not null!)
observe falseBool lucidFallback true; // false (not null!)
// || checks for "falsy" values
observe zero || 42; // 42 (0 is falsy)
observe empty || "empty"; // "empty" ("" is falsy)
observe falseBool || true; // true (false is falsy)
}
} Relax
Focus {
entrance {
induce primary: number = null;
induce secondary: number = null;
induce tertiary: number = 99;
induce result: number = primary lucidFallback secondary lucidFallback tertiary;
observe "Value: " + result; // Output: Value: 99
}
} Relax
The dreamReach operator (alias for ?.) enables safe access to nested properties without throwing errors on null/undefined.
object dreamReach property
object ?. property
Focus {
tranceify Guest {
name: string;
profile: Profile;
}
tranceify Profile {
alias: string;
level: number;
}
entrance {
induce guest = Guest {
name: "Luna",
profile: Profile {
alias: "Hypna",
level: 5
}
};
// Safe access
induce alias: string = guest dreamReach profile dreamReach alias;
observe "Alias: " + alias; // Output: Alias: Hypna
// Null-safe access
induce nullGuest: Guest = null;
induce safeAlias = nullGuest dreamReach profile dreamReach alias lucidFallback "Unknown";
observe "Alias: " + safeAlias; // Output: Alias: Unknown
}
} Relax
Focus {
entrance {
induce numbers: array = [1, 2, 3, 4, 5];
induce maybeArray: array = null;
// Normal array access would fail on null
induce value1 = numbers dreamReach[2];
observe "Value 1: " + value1; // Output: Value 1: 3
// Null-safe array access
induce value2 = maybeArray dreamReach[0] lucidFallback 0;
observe "Value 2: " + value2; // Output: Value 2: 0
}
} Relax
Focus {
suggestion greet(name: string): string {
awaken "Hello, " + name + "!";
}
entrance {
induce maybeFunc: suggestion = greet;
induce nullFunc: suggestion = null;
// Safe function call
induce greeting1 = maybeFunc dreamReach("Luna");
observe greeting1; // Output: Hello, Luna!
// Null-safe call
induce greeting2 = nullFunc dreamReach("Max") lucidFallback "No function";
observe greeting2; // Output: No function
}
} Relax
The true power shows when combining dreamReach and lucidFallback:
Focus {
tranceify UserData {
user: User;
}
tranceify User {
profile: UserProfile;
}
tranceify UserProfile {
settings: Settings;
}
tranceify Settings {
theme: string;
}
entrance {
induce data: UserData = null;
// Deep navigation with fallback
induce theme: string = data dreamReach user dreamReach profile dreamReach settings dreamReach theme lucidFallback "default";
observe "Theme: " + theme; // Output: Theme: default
}
} Relax
Focus {
tranceify ApiResponse {
data: ResponseData;
error: ErrorInfo;
}
tranceify ResponseData {
items: array;
meta: Metadata;
}
tranceify Metadata {
total: number;
page: number;
}
entrance {
// Simulate API response
induce response: ApiResponse = ApiResponse {
data: null,
error: null
};
// Safe extraction with defaults
induce items = response dreamReach data dreamReach items lucidFallback [];
induce total = response dreamReach data dreamReach meta dreamReach total lucidFallback 0;
induce page = response dreamReach data dreamReach meta dreamReach page lucidFallback 1;
observe "Items: " + items;
observe "Total: " + total;
observe "Page: " + page;
}
} Relax
Focus {
tranceify AppConfig {
database: DatabaseConfig;
server: ServerConfig;
}
tranceify DatabaseConfig {
host: string;
port: number;
name: string;
}
tranceify ServerConfig {
port: number;
timeout: number;
}
entrance {
induce config: AppConfig = null; // Simulate missing config
// Load config with sensible defaults
induce dbHost = config dreamReach database dreamReach host lucidFallback "localhost";
induce dbPort = config dreamReach database dreamReach port lucidFallback 5432;
induce dbName = config dreamReach database dreamReach name lucidFallback "hypnodb";
induce serverPort = config dreamReach server dreamReach port lucidFallback 8080;
induce serverTimeout = config dreamReach server dreamReach timeout lucidFallback 30000;
observe "DB: " + dbHost + ":" + dbPort + "/" + dbName;
observe "Server: Port " + serverPort + ", Timeout " + serverTimeout + "ms";
}
} Relax
Focus {
tranceify FormData {
email: string;
age: number;
newsletter: boolean;
}
entrance {
induce formData: FormData = null; // Simulate empty form
// Validate and set defaults
induce email = formData dreamReach email lucidFallback "";
induce age = formData dreamReach age lucidFallback 0;
induce newsletter = formData dreamReach newsletter lucidFallback false;
// Validation with hypnotic operators
induce isValid = (Length(email) lookAtTheWatch 0) underMyControl (age yourEyesAreGettingHeavy 18);
if (isValid) {
observe "Valid input: " + email;
} else {
observe "Invalid input!";
}
}
} Relax
// ✓ Use lucidFallback for null checks
induce value = maybeNull lucidFallback defaultValue;
// ✓ Use dreamReach for nested objects
induce deep = obj dreamReach prop1 dreamReach prop2;
// ✓ Combine both for safe data extraction
induce safe = obj dreamReach prop lucidFallback fallback;
// ✓ Prefer lucidFallback over || for null checks
induce number = maybeZero lucidFallback 42; // Keeps 0
// ✓ Chain dreamReach for deep navigation
induce result = a dreamReach b dreamReach c dreamReach d;
// ✗ Avoid manual null checks when possible
if (obj != null && obj.prop != null) { // Cumbersome
induce value = obj.prop;
}
// Better:
induce value = obj dreamReach prop lucidFallback defaultValue;
// ✗ Avoid || for null checks (false positives!)
induce count = 0;
induce result = count || 10; // Returns 10 instead of 0!
// Better:
induce result = count lucidFallback 10; // Returns 0
| Scenario | Traditional | Modern (Hypnotic) |
|---|---|---|
| Null fallback | x != null ? x : y |
x lucidFallback y |
| Nested access | obj && obj.prop && obj.prop.deep |
obj dreamReach prop dreamReach deep |
| Array access | arr && arr[0] |
arr dreamReach[0] |
| Function call | fn && fn(arg) |
fn dreamReach(arg) |
| Combined | (obj && obj.prop) || default |
obj dreamReach prop lucidFallback default |
- lucidFallback (
??) is more efficient than||for null checks - dreamReach (
?.) prevents unnecessary exceptions on null access - Both operators are short-circuit: Right operand is only evaluated when needed
- No runtime overhead: Compiles to efficient machine code
HypnoScript's modern dream semantics offer:
- ✅ Type-safe null handling with
lucidFallback(??) - ✅ Safe object navigation with
dreamReach(?.) - ✅ Elegant syntax with hypnotic aliases
- ✅ Full compatibility with standard operators (
??,?.) - ✅ Performance without overhead
These operators are essential for robust, error-free HypnoScript programs and should be preferred over manual null checks.
- Operators – Complete operator reference
- Pattern Matching – Advanced control structures
- Tranceify – Custom types
- Error Handling – Error handling
Ready for null-safe programming? Use lucidFallback and dreamReach for robust code! 💎