Skip to content

Latest commit

 

History

History
388 lines (297 loc) · 10.7 KB

File metadata and controls

388 lines (297 loc) · 10.7 KB
sidebar_position 8

Modern Dream Semantics – Nullish Operators

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.

Overview

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

Nullish Coalescing – lucidFallback (??)

The lucidFallback operator (alias for ??) returns the right operand if the left is null or undefined.

Syntax

value lucidFallback fallback
value ?? fallback

Basic Usage

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

Difference from || (OR)

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

Nested Fallbacks

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

Optional Chaining – dreamReach (?.)

The dreamReach operator (alias for ?.) enables safe access to nested properties without throwing errors on null/undefined.

Syntax

object dreamReach property
object ?. property

Object Access

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

Array Index with dreamReach[

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

Function Call with dreamReach(

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

Combining Both Operators

The true power shows when combining dreamReach and lucidFallback:

Safe Data Extraction

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

API Response Handling

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

Real-World Patterns

Config Loading with Defaults

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

User Input Validation

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

Best Practices

✅ Do's

// ✓ 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;

❌ Don'ts

// ✗ 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

Comparison Table: Operator Variants

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

Performance Notes

  • 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

Summary

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.

Next Steps


Ready for null-safe programming? Use lucidFallback and dreamReach for robust code! 💎