Add THE CANONICAL 100: Complete Lucidia language definition through examples

This commit introduces the foundational specification for Lucidia v1.0 - a set
of 100 working example programs that DEFINE the language through demonstration
rather than formal grammar.

Key Philosophy:
- Examples ARE the spec (not documentation OF the spec)
- AI systems learn by reading all 100 examples and extracting patterns
- Humans learn by working through examples sequentially
- No feature exists unless demonstrated in these examples

Structure:
- 001-010: Fundamentals (hello world → functions)
- 011-020: Data & Collections (lists, maps, sets)
- 021-030: Control Flow (if, loops, pattern matching)
- 031-040: Functions & Composition (map, filter, reduce, closures)
- 041-050: UI Basics (forms, inputs, validation)
- 051-060: Reactive Programming (state, watchers, events)
- 061-070: Consent & Privacy (permission system - CORE DIFFERENTIATOR)
- 071-080: Storage & Sync (local-first, cloud-optional)
- 081-090: AI Integration (intent → code, learning user style)
- 091-100: Complete Applications (todo, notes, chat, e-commerce)

Core Language Features Demonstrated:
✓ Intent over ceremony (write WHAT, not HOW)
✓ Consent as syntax (ask permission for: resource)
✓ Local-first storage (store locally, sync to cloud optional)
✓ AI-collaborative (### Intent comments become code)
✓ Reactive by default (state, watch, computed)
✓ Zero setup (runs in browser via WASM)
✓ Multi-paradigm (functional, OOP, reactive, agent-based)
✓ Gradual complexity (hello world → production apps)

Files Created:
- README.md - Learning philosophy and path
- INDEX.md - Complete reference table
- 001-100.lucidia - All example programs

Total: 102 files, ~3,500+ lines of example code

Why This Matters:
This is not just documentation. This IS Lucidia. Every parser, compiler,
AI assistant, and developer tool will be trained on these examples. They
are the permanent, immutable foundation of the language.

Next Steps:
1. Build parser that learns from these examples
2. Train AI to recognize and generate Lucidia patterns
3. Create browser playground with these as gallery
4. Use for academic paper and conference presentations

Designed by: Cece (Principal Language & Runtime Architect)
For: BlackRoad Operating System / Lucidia Programming Language
Status: Complete foundation for implementation
This commit is contained in:
Claude
2025-11-17 02:03:58 +00:00
parent a59e0113ee
commit bab913f8b2
102 changed files with 4806 additions and 0 deletions

View File

@@ -0,0 +1,4 @@
# 001: Hello World
# The simplest possible Lucidia program
show "Hello, World!"

View File

@@ -0,0 +1,10 @@
# 002: Variables & Values
# Storing and using data
name = "Alex"
age = 28
active = true
show "Name: {name}"
show "Age: {age}"
show "Active: {active}"

View File

@@ -0,0 +1,17 @@
# 003: Basic Math
# Numbers and arithmetic
a = 10
b = 5
sum = a + b
difference = a - b
product = a * b
quotient = a / b
remainder = a % b
show "Sum: {sum}"
show "Difference: {difference}"
show "Product: {product}"
show "Quotient: {quotient}"
show "Remainder: {remainder}"

View File

@@ -0,0 +1,22 @@
# 004: Strings & Templates
# Working with text
firstname = "Alex"
lastname = "Chen"
# String concatenation
fullname = firstname + " " + lastname
# Template strings (preferred)
greeting = "Hello, {firstname} {lastname}!"
# Multi-line strings
bio = """
Alex is a developer
who loves programming
in Lucidia
"""
show fullname
show greeting
show bio

View File

@@ -0,0 +1,16 @@
# 005: Comments
# How to document your code
# This is a single-line comment
# It explains what the code does
name = "Lucidia" # Inline comments work too
## This is a documentation comment
## Used for generating docs
### This is an AI intent comment
### These tell the AI what you want to accomplish
### (We'll see more of these in examples 081-090)
show "Comments help humans and AI understand your code"

View File

@@ -0,0 +1,13 @@
# 006: Simple Functions
# Creating reusable code
# Function with no parameters
greet():
show "Hello!"
# Call the function
greet()
greet()
greet()
# Each call executes the function body

View File

@@ -0,0 +1,12 @@
# 007: Function Parameters
# Functions that accept input
greet(name):
show "Hello, {name}!"
# Call with different arguments
greet("Alex")
greet("Jordan")
greet("Casey")
# The parameter 'name' takes on the value of each argument

View File

@@ -0,0 +1,15 @@
# 008: Return Values
# Functions that produce output
double(x):
x * 2
# The last expression is returned automatically
result = double(5)
show "Double of 5 is {result}"
# Explicit return also works
square(x):
return x * x
show "Square of 5 is {square(5)}"

View File

@@ -0,0 +1,19 @@
# 009: Multiple Parameters
# Functions with several inputs
add(a, b):
a + b
multiply(x, y):
x * y
# Use them together
result = add(3, 4)
show "3 + 4 = {result}"
result = multiply(5, 6)
show "5 × 6 = {result}"
# Compose functions
total = add(multiply(2, 3), multiply(4, 5))
show "2×3 + 4×5 = {total}"

View File

@@ -0,0 +1,20 @@
# 010: Calling Functions
# Different ways to use functions
# Define a utility function
format_name(first, last):
"{last}, {first}"
# Simple call
name = format_name("Alex", "Chen")
show name
# Use in expressions
full_greeting = "Hello, " + format_name("Jordan", "Lee")
show full_greeting
# Chain function calls
shout(text):
text.uppercase()
show shout(format_name("Casey", "Park"))

View File

@@ -0,0 +1,17 @@
# 011: Lists
# Ordered collections of items
# Create a list
fruits = ["apple", "banana", "cherry"]
# Access by index (zero-based)
show fruits[0] # apple
show fruits[1] # banana
show fruits[2] # cherry
# Get list length
show "We have {fruits.length} fruits"
# Lists can hold any type
mixed = [42, "hello", true, 3.14]
show mixed

View File

@@ -0,0 +1,24 @@
# 012: List Operations
# Modifying and working with lists
numbers = [1, 2, 3, 4, 5]
# Add to end
numbers.append(6)
show numbers # [1, 2, 3, 4, 5, 6]
# Add to beginning
numbers.prepend(0)
show numbers # [0, 1, 2, 3, 4, 5, 6]
# Remove by value
numbers.remove(3)
show numbers # [0, 1, 2, 4, 5, 6]
# Check if contains
has_five = numbers.contains(5)
show "Has 5: {has_five}"
# Get slice
first_three = numbers[0:3]
show first_three # [0, 1, 2]

View File

@@ -0,0 +1,22 @@
# 013: Maps/Objects
# Key-value pairs
# Create a map
user = {
name: "Alex Chen",
age: 28,
email: "alex@example.com",
active: true
}
# Access properties
show user.name
show user.age
show user.email
# Bracket notation also works
show user["name"]
# Check if key exists
has_email = user.has("email")
show "Has email: {has_email}"

View File

@@ -0,0 +1,27 @@
# 014: Map Operations
# Modifying maps
person = {
name: "Jordan",
age: 25
}
# Add new property
person.email = "jordan@example.com"
show person
# Update existing property
person.age = 26
show "New age: {person.age}"
# Remove property
person.remove("email")
show person
# Get all keys
keys = person.keys()
show "Keys: {keys}"
# Get all values
values = person.values()
show "Values: {values}"

View File

@@ -0,0 +1,22 @@
# 015: Nested Structures
# Complex data organization
# Lists inside maps
user = {
name: "Casey",
hobbies: ["reading", "hiking", "coding"],
settings: {
theme: "dark",
notifications: true
}
}
# Maps inside lists
users = [
{ name: "Alex", age: 28 },
{ name: "Jordan", age: 25 },
{ name: "Casey", age: 30 }
]
show user
show users

View File

@@ -0,0 +1,24 @@
# 016: Accessing Nested Data
# Navigate deep structures
user = {
name: "Alex",
address: {
street: "123 Main St",
city: "Portland",
country: "USA"
},
contacts: ["alex@email.com", "+1-555-0100"]
}
# Access nested map
city = user.address.city
show "City: {city}"
# Access nested list
email = user.contacts[0]
show "Email: {email}"
# Chain accessors
country = user.address.country
show "Lives in {country}"

View File

@@ -0,0 +1,22 @@
# 017: Sets
# Unique collections (no duplicates)
# Create a set
tags = {"javascript", "python", "rust"}
# Add items
tags.add("go")
tags.add("python") # Already exists, won't duplicate
show tags # {"javascript", "python", "rust", "go"}
# Check membership
has_rust = tags.contains("rust")
show "Knows Rust: {has_rust}"
# Remove item
tags.remove("javascript")
show tags
# Set size
show "Number of languages: {tags.size}"

View File

@@ -0,0 +1,18 @@
# 018: Tuples
# Fixed-size collections with mixed types
# Create a tuple (immutable)
point = (10, 20)
show "X: {point.0}, Y: {point.1}"
# Named tuple
person = (name: "Alex", age: 28)
show "Name: {person.name}"
show "Age: {person.age}"
# Function returning multiple values (tuple)
divide_with_remainder(a, b):
(quotient: a / b, remainder: a % b)
result = divide_with_remainder(17, 5)
show "17 ÷ 5 = {result.quotient} remainder {result.remainder}"

View File

@@ -0,0 +1,27 @@
# 019: Optional Values
# Handling values that might not exist
# Function that might not return a value
find_user(id):
users = [
{ id: 1, name: "Alex" },
{ id: 2, name: "Jordan" }
]
for user in users:
if user.id == id:
return user
return null
# Try to find existing user
user = find_user(1)
if user != null:
show "Found: {user.name}"
else:
show "User not found"
# Try to find non-existent user
missing = find_user(99)
if missing == null:
show "User 99 doesn't exist"

View File

@@ -0,0 +1,22 @@
# 020: Working with Nulls
# Safe handling of missing data
# Optional chaining - safe access
user = { name: "Alex" } # no email property
# This would error:
# email = user.email.lowercase()
# Safe version:
email = user.email?.lowercase() or "no email"
show email # "no email"
# Default values
user_with_email = { name: "Jordan", email: "j@example.com" }
user_without_email = { name: "Casey" }
get_email(user):
user.email or "unknown@example.com"
show get_email(user_with_email) # "j@example.com"
show get_email(user_without_email) # "unknown@example.com"

View File

@@ -0,0 +1,18 @@
# 021: If Statements
# Conditional execution
age = 20
if age >= 18:
show "You are an adult"
# Only runs if condition is true
score = 85
if score >= 90:
show "Grade: A"
if score >= 80:
show "Grade: B"
# Both conditions can be true

View File

@@ -0,0 +1,17 @@
# 022: If-Else
# Choose between two paths
age = 16
if age >= 18:
show "You can vote"
else:
show "Too young to vote"
# Check password strength
password = "abc"
if password.length >= 8:
show "Strong password"
else:
show "Password too short"

View File

@@ -0,0 +1,27 @@
# 023: Else-If Chains
# Multiple conditions
score = 85
if score >= 90:
show "Grade: A"
else if score >= 80:
show "Grade: B"
else if score >= 70:
show "Grade: C"
else if score >= 60:
show "Grade: D"
else:
show "Grade: F"
# Temperature categorization
temp = 72
if temp > 80:
show "Hot"
else if temp > 60:
show "Comfortable"
else if temp > 40:
show "Cool"
else:
show "Cold"

View File

@@ -0,0 +1,29 @@
# 024: Comparison Operators
# Testing relationships between values
a = 10
b = 20
# Equal
if a == 10:
show "a is 10"
# Not equal
if a != b:
show "a and b are different"
# Greater than
if b > a:
show "b is greater than a"
# Less than
if a < b:
show "a is less than b"
# Greater than or equal
if a >= 10:
show "a is at least 10"
# Less than or equal
if b <= 20:
show "b is at most 20"

View File

@@ -0,0 +1,29 @@
# 025: Logical Operators
# Combining conditions
age = 25
has_license = true
# AND - both must be true
if age >= 18 and has_license:
show "Can drive"
# OR - at least one must be true
is_weekend = true
is_holiday = false
if is_weekend or is_holiday:
show "Day off!"
# NOT - invert a boolean
is_raining = false
if not is_raining:
show "Good day for a walk"
# Complex combinations
temperature = 75
is_sunny = true
if temperature > 70 and is_sunny and not is_raining:
show "Perfect beach day!"

View File

@@ -0,0 +1,23 @@
# 026: For Loops
# Iterate over collections
# Loop over list
fruits = ["apple", "banana", "cherry"]
for fruit in fruits:
show "I like {fruit}"
# Loop over range
for i in 1..5:
show "Count: {i}"
# Loop over map
user = { name: "Alex", age: 28, city: "Portland" }
for key in user.keys():
show "{key}: {user[key]}"
# Nested loops
for x in 1..3:
for y in 1..3:
show "{x} × {y} = {x * y}"

View File

@@ -0,0 +1,26 @@
# 027: While Loops
# Repeat while condition is true
# Count up
count = 1
while count <= 5:
show "Count: {count}"
count = count + 1
# Wait for condition
password_attempts = 0
max_attempts = 3
while password_attempts < max_attempts:
# In real code, get user input here
password_attempts = password_attempts + 1
show "Attempt {password_attempts}"
# While with complex condition
balance = 100
price = 15
while balance >= price:
show "Purchase made, balance: {balance}"
balance = balance - price

View File

@@ -0,0 +1,31 @@
# 028: Loop Control
# Break and continue
# Break - exit loop early
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
for num in numbers:
if num > 5:
break # Stop here
show num
# Outputs: 1, 2, 3, 4, 5
# Continue - skip to next iteration
for num in numbers:
if num % 2 == 0:
continue # Skip even numbers
show num
# Outputs: 1, 3, 5, 7, 9
# Find first match
users = ["Alice", "Bob", "Charlie", "David"]
found = null
for user in users:
if user[0] == "C":
found = user
break
show "Found: {found}" # Charlie

View File

@@ -0,0 +1,30 @@
# 029: Pattern Matching
# Match values against patterns
status = "pending"
# Basic match
status is:
"pending": show "Waiting..."
"approved": show "Approved!"
"rejected": show "Rejected"
_: show "Unknown status"
# Match with values
score = 85
score is:
100: show "Perfect!"
90..99: show "Excellent"
80..89: show "Good"
70..79: show "Fair"
_: show "Needs improvement"
# Match with conditions
user_type = "admin"
user_type is:
"admin": show "Full access"
"moderator": show "Limited access"
"user": show "Basic access"
_: show "No access"

View File

@@ -0,0 +1,33 @@
# 030: Guards
# Early returns and validation
# Guard clause pattern
process_payment(amount, balance):
# Guard: insufficient funds
if amount > balance:
return "Insufficient funds"
# Guard: invalid amount
if amount <= 0:
return "Invalid amount"
# Main logic only runs if guards pass
new_balance = balance - amount
return "Payment successful, new balance: {new_balance}"
show process_payment(50, 100) # Success
show process_payment(150, 100) # Insufficient funds
show process_payment(-10, 100) # Invalid amount
# Guards make code clearer than nested ifs
validate_user(user):
if user == null:
return "User is required"
if not user.has("email"):
return "Email is required"
if user.email.length < 5:
return "Invalid email"
return "Valid user"

View File

@@ -0,0 +1,26 @@
# 031: Anonymous Functions
# Functions without names (lambdas)
# Store in variable
double = (x) => x * 2
show double(5) # 10
# Pass as argument
apply_twice(f, x):
f(f(x))
result = apply_twice((n) => n + 1, 10)
show result # 12
# Multiple parameters
add = (a, b) => a + b
show add(3, 4) # 7
# Multi-line anonymous function
greet = (name) => {
message = "Hello, {name}!"
message.uppercase()
}
show greet("alex") # HELLO, ALEX!

View File

@@ -0,0 +1,23 @@
# 032: Higher-Order Functions
# Functions that take or return functions
# Function that returns a function
make_multiplier(factor):
return (x) => x * factor
# Create specialized functions
double = make_multiplier(2)
triple = make_multiplier(3)
show double(5) # 10
show triple(5) # 15
# Function that takes a function
apply_operation(a, b, operation):
operation(a, b)
result = apply_operation(10, 5, (x, y) => x + y)
show result # 15
result = apply_operation(10, 5, (x, y) => x * y)
show result # 50

View File

@@ -0,0 +1,27 @@
# 033: Map
# Transform each element in a collection
numbers = [1, 2, 3, 4, 5]
# Double each number
doubled = numbers.map((x) => x * 2)
show doubled # [2, 4, 6, 8, 10]
# Square each number
squared = numbers.map((x) => x * x)
show squared # [1, 4, 9, 16, 25]
# Transform strings
names = ["alex", "jordan", "casey"]
uppercase_names = names.map((name) => name.uppercase())
show uppercase_names # ["ALEX", "JORDAN", "CASEY"]
# Extract property from objects
users = [
{ name: "Alex", age: 28 },
{ name: "Jordan", age: 25 },
{ name: "Casey", age: 30 }
]
names = users.map((user) => user.name)
show names # ["Alex", "Jordan", "Casey"]

View File

@@ -0,0 +1,28 @@
# 034: Filter
# Keep only elements that match a condition
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
# Keep even numbers
evens = numbers.filter((x) => x % 2 == 0)
show evens # [2, 4, 6, 8, 10]
# Keep numbers greater than 5
large = numbers.filter((x) => x > 5)
show large # [6, 7, 8, 9, 10]
# Filter objects
users = [
{ name: "Alex", age: 28, active: true },
{ name: "Jordan", age: 17, active: true },
{ name: "Casey", age: 30, active: false }
]
# Keep active adults
active_adults = users.filter((user) => user.age >= 18 and user.active)
show active_adults # [{ name: "Alex", age: 28, active: true }]
# Filter strings
words = ["hello", "hi", "goodbye", "bye"]
short_words = words.filter((word) => word.length <= 3)
show short_words # ["hi", "bye"]

View File

@@ -0,0 +1,29 @@
# 035: Reduce
# Combine all elements into a single value
numbers = [1, 2, 3, 4, 5]
# Sum all numbers
total = numbers.reduce((sum, num) => sum + num, 0)
show total # 15
# Product of all numbers
product = numbers.reduce((prod, num) => prod * num, 1)
show product # 120
# Find maximum
max = numbers.reduce((max_so_far, num) => {
if num > max_so_far:
num
else:
max_so_far
}, numbers[0])
show max # 5
# Build object from list
items = ["apple", "banana", "cherry"]
counts = items.reduce((obj, item) => {
obj[item] = item.length
obj
}, {})
show counts # { apple: 5, banana: 6, cherry: 6 }

View File

@@ -0,0 +1,29 @@
# 036: Function Composition
# Combine functions to create new ones
# Simple functions
add_one = (x) => x + 1
double = (x) => x * 2
square = (x) => x * x
# Manual composition
result = square(double(add_one(3)))
show result # (3+1)*2 = 8, 8*8 = 64
# Compose helper
compose(f, g):
return (x) => f(g(x))
# Create composed function
double_then_square = compose(square, double)
show double_then_square(5) # (5*2)^2 = 100
# Chain multiple operations
numbers = [1, 2, 3, 4, 5]
result = numbers
.map((x) => x * 2) # double each
.filter((x) => x > 5) # keep if > 5
.reduce((sum, x) => sum + x, 0) # sum all
show result # 6 + 8 + 10 = 24

View File

@@ -0,0 +1,45 @@
# 037: Closures
# Functions that remember their environment
# Counter closure
make_counter():
count = 0
return () => {
count = count + 1
count
}
# Each counter has its own state
counter1 = make_counter()
counter2 = make_counter()
show counter1() # 1
show counter1() # 2
show counter1() # 3
show counter2() # 1 (separate counter)
show counter2() # 2
# Private variables
make_account(initial_balance):
balance = initial_balance
return {
deposit: (amount) => {
balance = balance + amount
balance
},
withdraw: (amount) => {
if amount > balance:
return "Insufficient funds"
balance = balance - amount
balance
},
get_balance: () => balance
}
account = make_account(100)
show account.deposit(50) # 150
show account.withdraw(30) # 120
show account.get_balance() # 120

View File

@@ -0,0 +1,33 @@
# 038: Partial Application
# Pre-fill some arguments
# Generic function
multiply(a, b):
a * b
# Partially apply
double = (x) => multiply(2, x)
triple = (x) => multiply(3, x)
show double(5) # 10
show triple(5) # 15
# Partial application helper
partial(fn, ...fixed_args):
return (...remaining_args) => fn(...fixed_args, ...remaining_args)
# Create specialized versions
greet(greeting, name):
"{greeting}, {name}!"
say_hello = partial(greet, "Hello")
say_goodbye = partial(greet, "Goodbye")
show say_hello("Alex") # Hello, Alex!
show say_goodbye("Alex") # Goodbye, Alex!
# Useful for map/filter
numbers = [1, 2, 3, 4, 5]
add_ten = partial((a, b) => a + b, 10)
result = numbers.map(add_ten)
show result # [11, 12, 13, 14, 15]

View File

@@ -0,0 +1,37 @@
# 039: Recursion
# Functions that call themselves
# Factorial
factorial(n):
if n <= 1:
return 1
return n * factorial(n - 1)
show factorial(5) # 120 (5 * 4 * 3 * 2 * 1)
# Fibonacci
fibonacci(n):
if n <= 1:
return n
return fibonacci(n - 1) + fibonacci(n - 2)
show fibonacci(7) # 13
# Sum of list
sum_list(numbers):
if numbers.length == 0:
return 0
return numbers[0] + sum_list(numbers[1:])
show sum_list([1, 2, 3, 4, 5]) # 15
# Countdown
countdown(n):
if n <= 0:
show "Blast off!"
return
show n
countdown(n - 1)
countdown(5)

View File

@@ -0,0 +1,33 @@
# 040: Tail Recursion
# Efficient recursion (last call is recursive call)
# Regular recursion (not tail-recursive)
factorial_regular(n):
if n <= 1:
return 1
return n * factorial_regular(n - 1) # Multiplication happens AFTER recursive call
# Tail-recursive version (with accumulator)
factorial_tail(n, accumulator = 1):
if n <= 1:
return accumulator
return factorial_tail(n - 1, n * accumulator) # Recursive call is LAST thing
show factorial_tail(5) # 120
# Sum with tail recursion
sum_tail(numbers, accumulator = 0):
if numbers.length == 0:
return accumulator
return sum_tail(numbers[1:], accumulator + numbers[0])
show sum_tail([1, 2, 3, 4, 5]) # 15
# Range generator
make_range(start, end, result = []):
if start > end:
return result
result.append(start)
return make_range(start + 1, end, result)
show make_range(1, 10) # [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

View File

@@ -0,0 +1,27 @@
# 041: Showing Output
# Display information to the user
# Simple text
show "Hello!"
# Variables
name = "Alex"
show name
# Template strings
age = 28
show "I am {age} years old"
# Multiple values
show "Name: {name}, Age: {age}"
# Show results of expressions
show "5 + 3 = {5 + 3}"
# Show objects
user = { name: "Alex", age: 28 }
show user
# Show lists
items = ["apple", "banana", "cherry"]
show items

View File

@@ -0,0 +1,19 @@
# 042: User Input
# Get data from the user
# Simple text input
ask "What's your name?" -> name
show "Hello, {name}!"
# Number input
ask "How old are you?" -> age
show "You are {age} years old"
# Multiple inputs
ask "What's your email?" -> email
ask "Choose a password:" -> password
show "Account created for {email}"
# Input with validation happens automatically
# (AI adds validation based on variable name patterns)

View File

@@ -0,0 +1,16 @@
# 043: Simple Form
# Structured input collection
form contact:
input name -> user.name
input email -> user.email
input message -> user.message
button "Send" -> send_message(user)
send_message(data):
show "Message from {data.name}"
show "Email: {data.email}"
show "Message: {data.message}"
# Form automatically renders in the UI
# Button triggers the handler function

View File

@@ -0,0 +1,27 @@
# 044: Input Validation
# Ensure data is correct
form signup:
input email -> user.email
validate: is_email
error: "Please enter a valid email"
input password -> user.password
validate: (pw) => pw.length >= 8
error: "Password must be at least 8 characters"
input age -> user.age
validate: (a) => a >= 18
error: "Must be 18 or older"
button "Sign Up" -> create_account(user)
create_account(data):
show "Account created for {data.email}"
# Built-in validators:
# - is_email
# - is_url
# - is_phone
# - is_number
# Custom validators are just functions that return true/false

View File

@@ -0,0 +1,32 @@
# 045: Buttons
# Clickable actions
# Simple button
button "Click Me" -> handle_click()
handle_click():
show "Button was clicked!"
# Button with data
button "Increment" -> increment()
button "Decrement" -> decrement()
counter = 0
increment():
counter = counter + 1
show "Count: {counter}"
decrement():
counter = counter - 1
show "Count: {counter}"
# Styled buttons (optional)
button "Primary" -> do_something()
style: "primary"
button "Danger" -> do_something_risky()
style: "danger"
button "Disabled" -> nothing()
disabled: true

View File

@@ -0,0 +1,31 @@
# 046: Multiple Inputs
# Complex forms with many fields
form user_profile:
input firstname -> profile.firstname
placeholder: "First name"
input lastname -> profile.lastname
placeholder: "Last name"
input email -> profile.email
type: "email"
validate: is_email
input phone -> profile.phone
type: "tel"
placeholder: "+1-555-0100"
input bio -> profile.bio
type: "textarea"
placeholder: "Tell us about yourself"
rows: 4
button "Save Profile" -> save_profile(profile)
button "Cancel" -> cancel()
save_profile(data):
show "Profile saved for {data.firstname} {data.lastname}"
cancel():
show "Profile editing cancelled"

View File

@@ -0,0 +1,29 @@
# 047: Dropdowns
# Select from options
form preferences:
select theme -> user.theme
options: ["light", "dark", "auto"]
default: "auto"
select language -> user.language
options: [
{ value: "en", label: "English" },
{ value: "es", label: "Español" },
{ value: "fr", label: "Français" }
]
default: "en"
select country -> user.country
options: get_countries()
searchable: true
button "Save" -> save_preferences(user)
get_countries():
return ["USA", "Canada", "Mexico", "UK", "France", "Germany"]
save_preferences(prefs):
show "Theme: {prefs.theme}"
show "Language: {prefs.language}"
show "Country: {prefs.country}"

View File

@@ -0,0 +1,31 @@
# 048: Checkboxes
# Multiple selections
form newsletter:
checkbox "Daily digest" -> subscriptions.daily
checkbox "Weekly roundup" -> subscriptions.weekly
checkbox "Product updates" -> subscriptions.products
checkbox "Marketing emails" -> subscriptions.marketing
button "Subscribe" -> save_subscriptions(subscriptions)
save_subscriptions(subs):
show "Subscriptions:"
if subs.daily:
show " - Daily digest"
if subs.weekly:
show " - Weekly roundup"
if subs.products:
show " - Product updates"
if subs.marketing:
show " - Marketing emails"
# Checkbox groups
form interests:
checkbox_group "What interests you?" -> user.interests
options: ["Technology", "Sports", "Music", "Art", "Travel"]
button "Save" -> save_interests(user)
save_interests(data):
show "Interests: {data.interests}"

View File

@@ -0,0 +1,35 @@
# 049: Radio Buttons
# Single selection from options
form survey:
radio_group "How satisfied are you?" -> feedback.satisfaction
options: [
"Very satisfied",
"Satisfied",
"Neutral",
"Dissatisfied",
"Very dissatisfied"
]
radio_group "Would you recommend us?" -> feedback.recommend
options: ["Yes", "No", "Maybe"]
button "Submit" -> submit_feedback(feedback)
submit_feedback(data):
show "Satisfaction: {data.satisfaction}"
show "Recommend: {data.recommend}"
# Radio with custom values
form payment:
radio_group "Payment method" -> order.payment_method
options: [
{ value: "card", label: "Credit Card" },
{ value: "paypal", label: "PayPal" },
{ value: "crypto", label: "Cryptocurrency" }
]
button "Continue" -> process_payment(order)
process_payment(data):
show "Payment method: {data.payment_method}"

View File

@@ -0,0 +1,47 @@
# 050: Form Submission
# Handle complete form workflows
form login:
input email -> credentials.email
type: "email"
validate: is_email
required: true
input password -> credentials.password
type: "password"
validate: (pw) => pw.length >= 8
required: true
checkbox "Remember me" -> credentials.remember
button "Log In" -> attempt_login(credentials)
button "Forgot Password?" -> reset_password()
attempt_login(creds):
# Validate all fields are present
if not creds.email or not creds.password:
show "Please fill in all fields"
return
# In real app, this would call an API
show "Logging in as {creds.email}..."
# Simulate API call
success = true
if success:
show "Login successful!"
if creds.remember:
show "You will be remembered"
else:
show "Invalid credentials"
reset_password():
ask "Enter your email:" -> email
show "Password reset link sent to {email}"
# Form automatically handles:
# - Validation before submission
# - Disabled submit button if invalid
# - Error messages next to fields
# - Loading states during async operations

View File

@@ -0,0 +1,23 @@
# 051: State Declaration
# Reactive variables that trigger UI updates
# Declare reactive state
state count = 0
state username = "Guest"
state is_logged_in = false
# When state changes, UI automatically updates
button "Increment" -> increment()
button "Login" -> login()
increment():
count = count + 1
show "Count: {count}" # UI re-renders automatically
login():
username = "Alex"
is_logged_in = true
show "Welcome, {username}!"
# Regular variables don't trigger UI updates
# State variables do - that's the difference

View File

@@ -0,0 +1,27 @@
# 052: Watching State
# React to state changes
state temperature = 72
# Watch for changes
watch temperature:
show "Temperature is now {temperature}°F"
if temperature > 80:
show "It's hot!"
else if temperature < 60:
show "It's cold!"
else:
show "Temperature is comfortable"
# Modify state
button "Increase" -> increase_temp()
button "Decrease" -> decrease_temp()
increase_temp():
temperature = temperature + 5
decrease_temp():
temperature = temperature - 5
# Watcher runs automatically whenever temperature changes

View File

@@ -0,0 +1,36 @@
# 053: Computed Values
# Derived state that updates automatically
state firstname = "Alex"
state lastname = "Chen"
# Computed value - automatically recalculates when dependencies change
computed fullname = "{firstname} {lastname}"
show fullname # "Alex Chen"
# Update state
button "Change Name" -> change_name()
change_name():
firstname = "Jordan"
lastname = "Lee"
# fullname automatically becomes "Jordan Lee"
# Shopping cart example
state items = [
{ name: "Apple", price: 1.50, quantity: 3 },
{ name: "Banana", price: 0.75, quantity: 5 }
]
computed total = items.reduce((sum, item) => {
sum + (item.price * item.quantity)
}, 0)
show "Total: ${total}" # Automatically updates when items change
button "Add Orange" -> add_item()
add_item():
items.append({ name: "Orange", price: 2.00, quantity: 2 })
# total automatically recalculates

View File

@@ -0,0 +1,38 @@
# 054: Multiple Watchers
# Several reactions to the same state
state user_count = 0
# Watcher 1: Update display
watch user_count:
show "Users online: {user_count}"
# Watcher 2: Check capacity
watch user_count:
if user_count > 100:
show "⚠️ Server at capacity!"
# Watcher 3: Log changes
watch user_count:
log("User count changed to: {user_count}")
# All three watchers run when state changes
button "Add User" -> add_user()
button "Remove User" -> remove_user()
add_user():
user_count = user_count + 1
remove_user():
if user_count > 0:
user_count = user_count - 1
# Watch multiple states
state email = ""
state password = ""
watch email, password:
if email != "" and password != "":
show "Form is complete"
else:
show "Please fill in all fields"

View File

@@ -0,0 +1,41 @@
# 055: Reactive Forms
# Forms that respond to user input in real-time
state email = ""
state password = ""
state password_confirm = ""
# Reactive validation
computed email_valid = email.length > 0 and email.contains("@")
computed password_valid = password.length >= 8
computed passwords_match = password == password_confirm
computed form_valid = email_valid and password_valid and passwords_match
form signup:
input email -> email
placeholder: "your@email.com"
# Show validation feedback in real-time
if email != "" and not email_valid:
show_error "Invalid email format"
input password -> password
type: "password"
if password != "" and not password_valid:
show_error "Password must be at least 8 characters"
input password_confirm -> password_confirm
type: "password"
placeholder: "Confirm password"
if password_confirm != "" and not passwords_match:
show_error "Passwords don't match"
# Button disabled until form is valid
button "Sign Up" -> submit()
disabled: not form_valid
submit():
show "Account created for {email}"

View File

@@ -0,0 +1,48 @@
# 056: Two-Way Binding
# State and UI stay in sync automatically
state message = "Hello, World!"
# Input field binds to state
form editor:
input message -> message
# Display automatically updates as you type
show "Preview: {message}"
show "Length: {message.length} characters"
# Computed values update too
computed word_count = message.split(" ").length
show "Words: {word_count}"
# Slider example
state volume = 50
form volume_control:
slider volume -> volume
min: 0
max: 100
step: 1
show "Volume: {volume}%"
# Visual indicator
if volume > 75:
show "🔊 Loud"
else if volume > 25:
show "🔉 Medium"
else:
show "🔈 Quiet"
# Color picker
state color = "#3366ff"
form color_picker:
input color -> color
type: "color"
# Preview box updates in real-time
show_box:
background: color
width: 100
height: 100

View File

@@ -0,0 +1,30 @@
# 057: Event Emitters
# Send custom events
# Define events
on_user_login(user):
emit event "user.logged_in" with { user }
on_purchase(item, price):
emit event "purchase.completed" with { item, price }
on_error(message):
emit event "app.error" with { message }
# Trigger events
button "Login" -> login()
button "Buy Item" -> buy()
button "Cause Error" -> cause_error()
login():
user = { name: "Alex", id: 123 }
on_user_login(user)
buy():
on_purchase("Coffee Mug", 12.99)
cause_error():
on_error("Something went wrong!")
# Events can be caught by listeners (see next example)
# This allows decoupled communication between parts of your app

View File

@@ -0,0 +1,39 @@
# 058: Event Listeners
# Respond to custom events
# Listen for events
on event "user.logged_in":
show "Welcome back, {event.data.user.name}!"
load_user_dashboard(event.data.user)
on event "purchase.completed":
show "Purchase: {event.data.item} for ${event.data.price}"
update_inventory(event.data.item)
on event "app.error":
show "Error: {event.data.message}"
log_error(event.data.message)
# Multiple listeners for same event
on event "user.logged_in":
track_analytics("user_login")
on event "user.logged_in":
sync_user_data()
# Listeners are independent - one failing doesn't affect others
load_user_dashboard(user):
show "Loading dashboard for user {user.id}"
update_inventory(item):
show "Updating inventory after purchase of {item}"
log_error(msg):
show "Logged: {msg}"
track_analytics(action):
show "Analytics: {action}"
sync_user_data():
show "Syncing user data"

View File

@@ -0,0 +1,38 @@
# 059: Custom Events
# Create your own event system
# Shopping cart events
state cart = []
add_to_cart(item):
cart.append(item)
emit event "cart.item_added" with { item, cart_size: cart.length }
remove_from_cart(item_id):
cart = cart.filter((item) => item.id != item_id)
emit event "cart.item_removed" with { item_id, cart_size: cart.length }
clear_cart():
cart = []
emit event "cart.cleared"
# Cart listeners
on event "cart.item_added":
show "Added: {event.data.item.name}"
show "Cart size: {event.data.cart_size}"
on event "cart.item_removed":
show "Removed item {event.data.item_id}"
show "Cart size: {event.data.cart_size}"
on event "cart.cleared":
show "Cart is now empty"
# Usage
button "Add Apple" -> add_to_cart({ id: 1, name: "Apple", price: 1.50 })
button "Add Banana" -> add_to_cart({ id: 2, name: "Banana", price: 0.75 })
button "Remove Apple" -> remove_from_cart(1)
button "Clear Cart" -> clear_cart()
# Events decouple components - cart logic doesn't need to know
# about UI updates, analytics, etc. They just listen for events.

View File

@@ -0,0 +1,54 @@
# 060: Event Bus
# Central event coordination
# Create event bus for app-wide communication
bus = event_bus()
# Module 1: User authentication
module auth:
login(email, password):
# Authenticate user
user = { email, name: "Alex", id: 123 }
bus.emit("auth.login", user)
logout():
bus.emit("auth.logout")
# Module 2: Analytics
module analytics:
bus.on("auth.login", (user) => {
track("user_login", { user_id: user.id })
})
bus.on("auth.logout", () => {
track("user_logout")
})
track(event, data):
show "📊 Analytics: {event} {data}"
# Module 3: UI updates
module ui:
bus.on("auth.login", (user) => {
show "Welcome, {user.name}!"
show_dashboard()
})
bus.on("auth.logout", () => {
show "Goodbye!"
show_login_screen()
})
show_dashboard():
show "Dashboard loaded"
show_login_screen():
show "Login screen loaded"
# Modules don't know about each other
# They only know about events
# This makes the app easy to extend and maintain
# Usage
button "Login" -> auth.login("alex@example.com", "password")
button "Logout" -> auth.logout()

View File

@@ -0,0 +1,27 @@
# 061: Asking Permission
# Consent-first data access
# Basic permission request
ask permission for: location
# Show modal to user:
# "This app wants to access your location"
# [Allow] [Deny]
# Permission with context
ask permission for: camera
purpose: "Take profile photo"
duration: "one-time"
# Multiple resources
ask permission for: [microphone, camera]
purpose: "Video call"
# Custom resource
ask permission for: user.contacts
purpose: "Invite friends"
why: "We'll only read names and emails, never store them"
# The permission dialog is AUTOMATIC
# Users see clear, honest requests
# No sneaky background access

View File

@@ -0,0 +1,25 @@
# 062: Permission Granted Flow
# Execute code only if permission is granted
ask permission for: location
if granted:
# This code only runs if user clicks "Allow"
current_location = get_current_location()
show "You are at: {current_location.latitude}, {current_location.longitude}"
# Find nearby restaurants
restaurants = find_nearby("restaurants", current_location)
show "Found {restaurants.length} nearby restaurants"
# If permission denied, this block doesn't execute
# App continues safely without location data
# Complex example with multiple permissions
ask permission for: [camera, storage]
purpose: "Save photos"
if granted:
photo = take_photo()
save_to_storage(photo)
show "Photo saved!"

View File

@@ -0,0 +1,34 @@
# 063: Permission Denied Flow
# Handle gracefully when user says no
ask permission for: contacts
purpose: "Find friends using the app"
if granted:
contacts = read_contacts()
friends = find_matching_users(contacts)
show "Found {friends.length} friends!"
else:
# User denied permission
show "You can invite friends manually using their email"
show_manual_invite_form()
# Another example
ask permission for: notifications
if granted:
enable_push_notifications()
show "You'll receive updates!"
else:
show "You can still use the app, but won't get notifications"
# Degrade gracefully - app still works
show_manual_invite_form():
form invite:
input email -> friend_email
button "Send Invite" -> send_invite(friend_email)
send_invite(email):
show "Invitation sent to {email}"
# The key: denied permission = graceful degradation, not broken app

View File

@@ -0,0 +1,42 @@
# 064: Multiple Permissions
# Handle complex permission scenarios
# Sequential permissions
start_video_call():
# Ask for camera first
ask permission for: camera
purpose: "Video call"
if granted:
# Camera allowed, now ask for microphone
ask permission for: microphone
purpose: "Voice during video call"
if granted:
# Both granted - start call
initiate_call()
show "Call started with video and audio"
else:
# Camera yes, microphone no
initiate_call(video_only: true)
show "Call started with video only"
else:
# Camera denied
show "Camera is required for video calls"
# Batch permissions
start_photo_app():
ask permission for: [camera, storage, location]
purpose: "Take and save geotagged photos"
# Check individual grants
if granted.camera and granted.storage:
if granted.location:
show "Full features enabled"
else:
show "Photos will be saved without location data"
else:
show "Camera and storage access required"
button "Start Video Call" -> start_video_call()
button "Open Photo App" -> start_photo_app()

View File

@@ -0,0 +1,38 @@
# 065: Consent Recording
# Audit trail of data access
ask permission for: user.health_data
purpose: "Calculate fitness stats"
if granted:
# Record this access in audit log
with consent.record:
health_data = read_health_data()
stats = calculate_fitness_stats(health_data)
show "Your fitness stats: {stats}"
# Consent log entry created:
# {
# timestamp: 2025-01-15T10:30:00Z,
# resource: "user.health_data",
# purpose: "Calculate fitness stats",
# action: "read",
# user_approved: true
# }
# API call with consent recording
ask permission for: api.financial_data
purpose: "Show account balance"
if granted:
with consent.record:
balance = fetch "/api/account/balance"
show "Balance: ${balance}"
# User can later review: "This app accessed my financial data on [date]"
# Consent records are:
# - Stored locally (encrypted)
# - Never sent to cloud without explicit user action
# - Viewable in app settings
# - Can be exported for GDPR compliance

View File

@@ -0,0 +1,41 @@
# 066: Revoking Consent
# Users can take back permission anytime
# In app settings
form privacy_settings:
show "Your Permissions:"
for permission in consent.list_granted():
show "{permission.resource} - Granted on {permission.date}"
button "Revoke" -> revoke_permission(permission.resource)
revoke_permission(resource):
consent.revoke(resource)
show "Permission revoked for {resource}"
# Attempting to use revoked permission
use_location():
# Check if still granted
if consent.is_granted("location"):
location = get_current_location()
show "Location: {location}"
else:
# Permission was revoked
show "Location access has been revoked"
# Optionally re-request
ask permission for: location
purpose: "Show nearby places"
if granted:
use_location() # Try again
else:
show "Cannot show nearby places without location"
# Revoke all permissions
button "Clear All Permissions" -> clear_all()
clear_all():
consent.revoke_all()
show "All permissions cleared"
show "You'll be asked again when needed"

View File

@@ -0,0 +1,48 @@
# 067: Checking Permission Status
# Query current permission state
# Check before requesting
show_location_feature():
status = consent.check_status("location")
status is:
"granted": {
# Already have permission
show_location_map()
}
"denied": {
# User previously denied
show "You denied location access"
show "To enable, grant permission below:"
button "Enable Location" -> request_location()
}
"not_asked": {
# Never requested before
show "Enable location to see nearby places"
button "Enable" -> request_location()
}
request_location():
ask permission for: location
if granted:
show_location_map()
show_location_map():
show "📍 Map view enabled"
# Check multiple permissions
check_video_call_ready():
camera_status = consent.check_status("camera")
mic_status = consent.check_status("microphone")
if camera_status == "granted" and mic_status == "granted":
show "✅ Ready for video call"
button "Start Call" -> start_call()
else:
show "⚠️ Missing permissions:"
if camera_status != "granted":
show " - Camera"
if mic_status != "granted":
show " - Microphone"
button "Check Video Status" -> check_video_call_ready()

View File

@@ -0,0 +1,50 @@
# 068: Scoped Permissions
# Fine-grained control over access duration
# One-time permission
ask permission for: camera
scope: "one-time"
purpose: "Take profile photo"
if granted:
photo = take_photo()
upload_profile_photo(photo)
# Permission automatically expires after this block
# Session-based permission
ask permission for: location
scope: "session"
purpose: "Show nearby restaurants"
if granted:
# Permission lasts until app closes
update_location_periodically()
# Persistent permission
ask permission for: notifications
scope: "persistent"
purpose: "Daily reminders"
if granted:
# Permission persists across sessions
# User must manually revoke
schedule_daily_notifications()
# Time-limited permission
ask permission for: api.user_data
scope: "time-limited"
duration: "24 hours"
purpose: "Generate weekly report"
if granted:
# Permission expires after 24 hours
generate_report()
# Resource-specific scoping
ask permission for: user.contacts
scope: "read-only" # Cannot modify
purpose: "Find friends"
if granted:
contacts = read_contacts()
# Cannot write to contacts - scope enforced by runtime

View File

@@ -0,0 +1,51 @@
# 069: Temporary Permissions
# Permissions that auto-expire
# Permission expires after 1 hour
ask permission for: api.financial_data
expires_in: "1 hour"
purpose: "Show account balance"
if granted:
show_balance_dashboard()
# Permission is valid for 1 hour
# After that, must request again
# Permission expires after N uses
ask permission for: camera
expires_after_uses: 3
purpose: "Take up to 3 photos"
if granted:
for i in 1..3:
photo = take_photo()
save_photo(photo)
show "Photo {i} saved"
# Permission automatically revoked after 3 uses
# Until specific time
ask permission for: location
expires_at: "2025-01-15T23:59:59Z"
purpose: "Track run (today only)"
if granted:
track_running_session()
# At midnight, permission expires
# Conditional expiration
ask permission for: microphone
expires_when: call_ended
purpose: "Voice call"
if granted:
start_voice_call()
# When call_ended event fires, permission expires
# Check if permission is still valid
if consent.is_valid("camera"):
take_photo()
else:
show "Camera permission has expired"
# Request again if needed

View File

@@ -0,0 +1,60 @@
# 070: Consent Audit Log
# Complete transparency of data access
# View all consent events
show_consent_history():
events = consent.get_audit_log()
show "Consent History ({events.length} events)"
for event in events:
show "━━━━━━━━━━━━━━━━"
show "Resource: {event.resource}"
show "Action: {event.action}"
show "Time: {event.timestamp}"
show "Purpose: {event.purpose}"
show "Granted: {event.granted}"
if event.access_count:
show "Times accessed: {event.access_count}"
# Filter audit log
show_last_24_hours():
recent = consent.get_audit_log()
.filter((e) => e.timestamp > now() - 24h)
show "Recent activity: {recent.length} events"
# Export for GDPR compliance
export_consent_data():
data = consent.export_all()
# Returns JSON with:
# - All permission grants
# - All access events
# - Timestamps
# - Purposes
# - User IP addresses (optional)
save_file("consent_data.json", data)
show "Consent data exported"
# Consent analytics (privacy-preserving)
show_consent_stats():
stats = consent.get_stats()
show "Most frequently accessed: {stats.most_accessed}"
show "Recently revoked: {stats.recently_revoked}"
show "Never used permissions: {stats.unused}"
# Settings UI
form consent_settings:
show "Your Privacy Dashboard"
button "View History" -> show_consent_history()
button "Export Data" -> export_consent_data()
button "Show Stats" -> show_consent_stats()
button "Revoke All" -> consent.revoke_all()
# This level of transparency builds trust
# Users see exactly what data is accessed, when, and why

View File

@@ -0,0 +1,32 @@
# 071: Store Data Locally
# Save data to the device
# Simple storage
preferences = {
theme: "dark",
language: "en",
notifications: true
}
store preferences locally as "user_prefs"
show "Preferences saved"
# Store multiple items
user_data = { name: "Alex", email: "alex@example.com" }
app_settings = { sidebar_collapsed: false, font_size: 14 }
store user_data locally as "user"
store app_settings locally as "settings"
# Store lists
todos = [
{ id: 1, text: "Buy groceries", done: false },
{ id: 2, text: "Write code", done: true },
{ id: 3, text: "Exercise", done: false }
]
store todos locally as "todos"
show "Saved {todos.length} todos"
# Data persists across sessions
# Stored in IndexedDB (browser) or local filesystem (native)

View File

@@ -0,0 +1,43 @@
# 072: Load Data Locally
# Retrieve saved data
# Load with default value
preferences = load "user_prefs" locally or {
theme: "light",
language: "en",
notifications: true
}
show "Theme: {preferences.theme}"
# Load and check if exists
todos = load "todos" locally
if todos != null:
show "Found {todos.length} saved todos"
for todo in todos:
show "- {todo.text}"
else:
show "No saved todos"
todos = []
# Load multiple items
user = load "user" locally
settings = load "settings" locally
if user != null:
show "Welcome back, {user.name}!"
# Common pattern: load or initialize
get_user_data():
data = load "user_data" locally
if data == null:
# First time - create default
data = { visits: 0, last_login: null }
data.visits = data.visits + 1
data.last_login = now()
store data locally as "user_data"
return data
user_data = get_user_data()
show "Visit #{user_data.visits}"

View File

@@ -0,0 +1,44 @@
# 073: Update Local Data
# Modify stored data
# Load existing data
todos = load "todos" locally or []
# Add new todo
add_todo(text):
new_todo = {
id: generate_id(),
text: text,
done: false,
created_at: now()
}
todos.append(new_todo)
store todos locally as "todos"
show "Todo added"
# Mark as done
complete_todo(id):
todos = todos.map((todo) => {
if todo.id == id:
{ ...todo, done: true }
else:
todo
})
store todos locally as "todos"
show "Todo completed"
# Delete todo
delete_todo(id):
todos = todos.filter((todo) => todo.id != id)
store todos locally as "todos"
show "Todo deleted"
# Usage
button "Add Todo" -> add_todo("New task")
button "Complete #1" -> complete_todo(1)
button "Delete #2" -> delete_todo(2)
generate_id():
return Math.random() * 1000000

View File

@@ -0,0 +1,45 @@
# 074: Delete Local Data
# Remove stored data
# Delete specific item
delete_user_preferences():
delete "user_prefs" locally
show "Preferences deleted"
# Delete with confirmation
clear_all_todos():
ask "Are you sure? This cannot be undone." -> confirm
if confirm == "yes":
delete "todos" locally
show "All todos deleted"
else:
show "Cancelled"
# Delete multiple items
reset_app():
delete "user" locally
delete "settings" locally
delete "cache" locally
show "App reset to defaults"
# Delete all local data
clear_all_storage():
storage.clear_all()
show "All local data deleted"
# Conditional deletion
cleanup_old_data():
cached_data = load "cache" locally
if cached_data != null:
age = now() - cached_data.timestamp
if age > 7 * 24 * 60 * 60: # 7 days
delete "cache" locally
show "Old cache deleted"
button "Delete Preferences" -> delete_user_preferences()
button "Clear Todos" -> clear_all_todos()
button "Reset App" -> reset_app()
button "Cleanup" -> cleanup_old_data()

View File

@@ -0,0 +1,49 @@
# 075: Ephemeral Storage
# Temporary data that doesn't persist
# Store in memory only (lost on refresh)
store session_token ephemeral
store temporary_files ephemeral
# Session-specific data
current_session = {
id: generate_session_id(),
started_at: now(),
active_tab: "home"
}
store current_session ephemeral as "session"
# Form draft (auto-save while editing)
state draft_message = ""
watch draft_message:
# Save draft in memory
store draft_message ephemeral as "message_draft"
# Load draft on page reload
draft = load "message_draft" ephemeral or ""
# Ephemeral vs local comparison
save_user_data(data, remember_me):
if remember_me:
# Persist across sessions
store data locally as "user"
else:
# Only for this session
store data ephemeral as "user"
# Shopping cart example
state cart = []
add_to_cart(item):
cart.append(item)
# Don't persist - cart resets on page refresh
store cart ephemeral as "cart"
# Upload progress (doesn't need to persist)
track_upload(file):
progress = { file: file.name, percent: 0 }
store progress ephemeral as "upload_progress"
# Update as upload progresses...

View File

@@ -0,0 +1,47 @@
# 076: Cloud Sync Setup
# Optional cloud backup (local-first, cloud-optional)
# User configures sync
form sync_settings:
checkbox "Enable cloud sync" -> settings.cloud_sync
if settings.cloud_sync:
input cloud_endpoint -> settings.endpoint
placeholder: "https://sync.example.com"
select sync_frequency -> settings.frequency
options: ["on_change", "hourly", "daily", "manual"]
checkbox "Encrypt before upload" -> settings.encrypt
default: true
button "Save Settings" -> save_sync_settings(settings)
save_sync_settings(config):
store config locally as "sync_config"
if config.cloud_sync:
initialize_sync(config)
show "Cloud sync enabled"
else:
disable_sync()
show "Using local storage only"
# Sync specific data
sync_notes():
# Ask for permission
ask permission for: cloud.storage
purpose: "Backup notes to cloud"
if granted:
notes = load "notes" locally
sync notes to cloud with:
endpoint: settings.endpoint
encrypt: true
on_conflict: "last_write_wins"
show "Notes synced to cloud"
# Everything still works offline
# Cloud is purely optional backup/sync across devices

View File

@@ -0,0 +1,58 @@
# 077: Conditional Sync
# Sync only when conditions are met
# Sync only on WiFi
save_document(doc):
store doc locally as "documents/{doc.id}"
# Only sync to cloud if on WiFi
if network.type == "wifi" and user.settings.cloud_sync:
sync doc to cloud
# Sync only if changed
update_preferences(prefs):
old_prefs = load "preferences" locally
store prefs locally as "preferences"
# Only sync if actually different
if prefs != old_prefs:
sync prefs to cloud
# Sync based on data size
save_photo(photo):
store photo locally as "photos/{photo.id}"
# Large files only sync on WiFi
if photo.size > 10MB:
if network.type == "wifi":
sync photo to cloud
else:
# Small files sync on any connection
sync photo to cloud
# Sync during idle time
queue_sync(data):
store data locally as "sync_queue/{data.id}"
# Wait for idle period
on idle:
process_sync_queue()
process_sync_queue():
queue = load "sync_queue" locally
for item in queue:
if network.online:
sync item to cloud
delete "sync_queue/{item.id}" locally
# User-controlled sync
button "Sync Now" -> manual_sync()
button "Sync All" -> sync_all_data()
manual_sync():
if network.online:
sync_all_data()
else:
show "No internet connection"

View File

@@ -0,0 +1,59 @@
# 078: Conflict Resolution
# Handle sync conflicts when local and cloud differ
# Simple strategy: last write wins
sync_notes():
notes = load "notes" locally
sync notes to cloud with:
on_conflict: "last_write_wins"
show "Notes synced (last write wins)"
# Keep both versions
sync_documents():
docs = load "documents" locally
sync docs to cloud with:
on_conflict: "keep_both"
# Creates: doc_local.txt and doc_cloud.txt
show "Sync complete (both versions saved)"
# Manual conflict resolution
sync_with_manual_resolution():
local_data = load "user_data" locally
cloud_data = fetch_from_cloud("user_data")
if local_data != cloud_data:
# Show conflict to user
show "Conflict detected!"
show "Local version: {local_data}"
show "Cloud version: {cloud_data}"
ask "Which version to keep?" -> choice
options: ["local", "cloud", "merge"]
choice is:
"local": {
sync local_data to cloud
show "Kept local version"
}
"cloud": {
store cloud_data locally as "user_data"
show "Kept cloud version"
}
"merge": {
merged = merge_data(local_data, cloud_data)
store merged locally as "user_data"
sync merged to cloud
show "Merged versions"
}
# Smart merge
merge_data(local, cloud):
return {
# Keep newer values for each field
name: local.updated_at > cloud.updated_at ? local.name : cloud.name,
email: local.updated_at > cloud.updated_at ? local.email : cloud.email
}

View File

@@ -0,0 +1,68 @@
# 079: Offline-First Pattern
# App works without internet, syncs when available
# Always write to local first
save_note(note):
# Save locally immediately
notes = load "notes" locally or []
note.id = generate_id()
note.synced = false
notes.append(note)
store notes locally as "notes"
show "Note saved"
# Try to sync in background
if network.online:
sync_in_background(note)
else:
show "(Will sync when online)"
# Background sync
sync_in_background(note):
try:
sync note to cloud
note.synced = true
update_note(note)
catch:
# Sync failed, will retry later
queue_for_retry(note)
# Load data (local always available)
load_notes():
notes = load "notes" locally or []
# Try to fetch updates from cloud
if network.online:
cloud_notes = fetch_from_cloud("notes")
merged = merge_notes(notes, cloud_notes)
store merged locally as "notes"
return merged
else:
# Offline - return local data
return notes
# Indicate sync status
display_notes():
notes = load_notes()
for note in notes:
show note.text
if note.synced:
show "✓ Synced"
else:
show "⋯ Pending sync"
# Retry pending syncs when back online
on network.online:
pending = load "sync_queue" locally or []
for item in pending:
sync item to cloud
mark_as_synced(item)
delete "sync_queue" locally
show "Synced {pending.length} pending items"
# The app ALWAYS works locally
# Cloud is enhancement, not requirement

View File

@@ -0,0 +1,62 @@
# 080: Storage Encryption
# Encrypt sensitive data before storing
# Encrypt by default
sensitive_data = {
password: "secret123",
api_key: "sk_live_xxxx",
ssn: "123-45-6789"
}
store sensitive_data locally as "credentials"
encrypt: true
# Uses device key or user-provided password
# Encrypted storage is automatic for sensitive field names
# (password, ssn, credit_card, api_key, etc.)
# User-provided encryption key
save_encrypted_diary(entry):
ask "Enter encryption password:" -> password
type: "password"
store entry locally as "diary/{entry.id}"
encrypt: true
key: password
show "Diary entry saved (encrypted)"
# Load encrypted data
load_encrypted_diary(entry_id):
ask "Enter encryption password:" -> password
type: "password"
entry = load "diary/{entry_id}" locally
decrypt: true
key: password
if entry == null:
show "Wrong password or entry doesn't exist"
else:
show entry.text
# Automatic encryption for regulated data
store_medical_record(record):
# Medical data automatically encrypted (HIPAA compliance)
store record locally as "medical_records/{record.id}"
# encryption: true is implicit for medical data
# Sync encrypted
sync_encrypted_data():
# Data synced to cloud remains encrypted
# Cloud never sees unencrypted data
encrypted_notes = load "private_notes" locally
encrypt: true
sync encrypted_notes to cloud
# Still encrypted in transit and at rest
show "Private notes synced (encrypted)"
# Everything sensitive is encrypted by default
# Lucidia assumes privacy, not surveillance

View File

@@ -0,0 +1,36 @@
# 081: Intent Comments
# Tell the AI what you want, not how to do it
### Intent: Parse this CSV data and extract email addresses
data = """
name,email,age
Alex,alex@example.com,28
Jordan,jordan@example.com,25
Casey,casey@example.com,30
"""
# AI expands the intent into working code:
# emails = data.split("\n").slice(1).map(line => {
# parts = line.split(",")
# return parts[1]
# }).filter(email => email != "")
### Intent: Calculate the total price including tax
cart_items = [
{ name: "Book", price: 19.99 },
{ name: "Pen", price: 2.50 },
{ name: "Notebook", price: 5.99 }
]
tax_rate = 0.08
# AI generates:
# subtotal = cart_items.reduce((sum, item) => sum + item.price, 0)
# total = subtotal * (1 + tax_rate)
### Intent: Format this date as "January 15, 2025"
timestamp = 1705334400000 # Unix timestamp
# AI knows how to format dates in natural language
# The ### syntax tells the AI:
# "This is an intent, not just a comment - turn it into code"

View File

@@ -0,0 +1,42 @@
# 082: AI Code Generation
# Let AI write implementations
# Explicit AI call
result = ai.generate:
input: sales_data
output: "summary report with charts"
constraints: [
"Group by region",
"Show top 5 products",
"Calculate growth percentage"
]
show result
# AI with type hints
generate_user_report(user_id):
# AI infers: fetch data, format nicely, return string
ai.generate:
task: "Create user activity report"
input: user_id
output: "markdown formatted report"
# Complex data transformation
messy_data = [
{ "firstName": "Alex", "last_name": "Chen", "AGE": "28" },
{ "firstName": "Jordan", "LastName": "Lee", "age": 25 }
]
### Intent: Normalize this data to consistent format
### Expected output: [{ first_name, last_name, age }]
normalized = ai.normalize(messy_data, {
format: "snake_case",
required_fields: ["first_name", "last_name", "age"]
})
show normalized
# AI shows proposed code, you approve
# Once approved, it runs
# Future runs use the cached implementation

View File

@@ -0,0 +1,41 @@
# 083: AI Text Summary
# Automatic summarization
# Long text
article = """
Lucidia is a revolutionary programming language designed for the modern era.
Unlike traditional languages that were built for compilers, Lucidia is built
for intelligences - both human and artificial. It features consent as syntax,
local-first storage, and seamless AI collaboration. The language runs natively
in browsers via WebAssembly, requiring zero setup. Users can write intent
instead of implementation, letting AI handle the ceremony while maintaining
human creative control.
"""
# Summarize
summary = ai.summarize(article, max_words: 20)
show summary
# Output: "Lucidia is a modern programming language with AI collaboration,
# consent-as-syntax, and browser-native execution."
# Bullet point summary
logs = load "server_logs" locally
### Intent: Summarize last 24 hours of logs as bullet points
### Group by severity, show counts
bullet_summary = ai.summarize(logs, format: "bullets")
show bullet_summary
# Expected:
# • Errors: 3 (database timeout, API failure, memory leak)
# • Warnings: 47 (slow queries, deprecated API usage)
# • Info: 1,284 (normal operations)
# Different summary styles
ai.summarize(data, style: "executive") # High-level overview
ai.summarize(data, style: "technical") # Detailed technical
ai.summarize(data, style: "eli5") # Explain like I'm 5
# AI picks the important parts
# You don't have to

View File

@@ -0,0 +1,52 @@
# 084: AI Classification
# Categorize data automatically
# Classify text
email_body = "Congratulations! You've won $1,000,000! Click here to claim..."
classification = ai.classify(email_body, {
categories: ["spam", "legitimate", "promotional"],
confidence: true
})
show "Category: {classification.category}"
show "Confidence: {classification.confidence}%"
if classification.category == "spam":
move_to_spam(email_body)
# Classify support tickets
ticket = {
subject: "Cannot login to my account",
body: "I keep getting 'invalid password' even though I'm sure it's correct"
}
category = ai.classify(ticket, {
categories: ["bug", "feature_request", "support", "billing"],
output: "category_only"
})
category is:
"bug": assign_to_engineering(ticket)
"support": assign_to_support(ticket)
"billing": assign_to_billing(ticket)
"feature_request": add_to_roadmap(ticket)
# Classify images (if available)
photo = load_image("photo.jpg")
tags = ai.classify(photo, {
categories: ["nature", "city", "people", "food", "animals"],
multiple: true # Can have multiple tags
})
show "Tags: {tags}" # ["nature", "animals"]
# Sentiment analysis
review = "This product is absolutely terrible. Waste of money!"
sentiment = ai.classify(review, {
categories: ["positive", "negative", "neutral"]
})
show "Sentiment: {sentiment}" # negative

View File

@@ -0,0 +1,55 @@
# 085: AI Data Transformation
# Transform data between formats
# Convert formats
json_data = """
{
"users": [
{"id": 1, "name": "Alex"},
{"id": 2, "name": "Jordan"}
]
}
"""
### Intent: Convert this JSON to CSV format
csv_data = ai.transform(json_data, {
from: "json",
to: "csv"
})
show csv_data
# Output:
# id,name
# 1,Alex
# 2,Jordan
# Restructure data
flat_data = [
{ user_id: 1, order_id: 101, amount: 50 },
{ user_id: 1, order_id: 102, amount: 75 },
{ user_id: 2, order_id: 103, amount: 30 }
]
### Intent: Group orders by user_id
nested_data = ai.transform(flat_data, {
operation: "group_by",
key: "user_id",
aggregate: "orders"
})
show nested_data
# Output:
# [
# { user_id: 1, orders: [{ order_id: 101, amount: 50 }, { order_id: 102, amount: 75 }] },
# { user_id: 2, orders: [{ order_id: 103, amount: 30 }] }
# ]
# Extract specific fields
complex_response = fetch "/api/users/detailed"
### Intent: Extract only name, email, and signup_date
simplified = ai.extract(complex_response, {
fields: ["name", "email", "signup_date"]
})
# AI handles nested structures, missing fields, different naming conventions

View File

@@ -0,0 +1,50 @@
# 086: AI With Constraints
# Guide AI behavior with rules
# Generate code with constraints
user_input = "Show me all users"
query = ai.generate_sql:
intent: user_input
constraints: [
"Only SELECT queries allowed (no DELETE/UPDATE/DROP)",
"Must include LIMIT clause",
"No access to sensitive tables (passwords, tokens)"
]
show query # SELECT * FROM users LIMIT 100
# Generate UI with branding constraints
ai.generate_component:
type: "login_form"
constraints: [
"Use brand colors: #3366ff, #ffffff",
"No third-party auth (email/password only)",
"Include password strength indicator",
"Accessible (ARIA labels, keyboard navigation)"
]
# Content generation with constraints
ai.generate_text:
prompt: "Write product description"
constraints: [
"Max 100 words",
"Professional tone",
"No superlatives (amazing, incredible, etc.)",
"Include SEO keywords: sustainable, eco-friendly",
"End with call-to-action"
]
# Data transformation with validation
ai.transform(messy_data, {
to: "normalized",
constraints: [
"All email addresses must be valid",
"Ages must be between 0 and 120",
"Phone numbers in E.164 format",
"Reject records missing required fields"
]
})
# Constraints ensure AI stays within bounds
# Prevents security issues, maintains brand consistency

View File

@@ -0,0 +1,58 @@
# 087: AI Code Review
# AI suggests improvements
# Your code
calculate_total(items):
total = 0
for item in items:
total = total + item.price
return total
# Ask AI for review
review = ai.review_code(calculate_total)
show review.suggestions
# Suggestions:
# 1. Consider using reduce() for more idiomatic functional style
# 2. Add null check for items parameter
# 3. Add type hint for clarity: calculate_total(items: list) -> number
show review.improved_version
# Improved code:
# calculate_total(items: list) -> number:
# if items == null: return 0
# return items.reduce((sum, item) => sum + item.price, 0)
# Security review
handle_user_input(input):
query = "SELECT * FROM users WHERE name = '{input}'"
# SQL injection vulnerability!
security_review = ai.review_security(handle_user_input)
show security_review.issues
# Issues:
# ⚠️ Critical: SQL injection vulnerability
# - Never concatenate user input into SQL queries
# - Use parameterized queries instead
show security_review.fix
# Corrected code:
# handle_user_input(input):
# query = db.query("SELECT * FROM users WHERE name = ?", [input])
# Performance review
process_large_list(data):
results = []
for item in data:
if item.active:
results.append(transform(item))
return results
perf_review = ai.review_performance(process_large_list)
show perf_review.optimizations
# Optimizations:
# 1. Use filter and map instead of manual loop (10x faster)
# 2. Consider lazy evaluation for very large lists
# 3. Cache transform() results if same item processed multiple times

View File

@@ -0,0 +1,57 @@
# 088: AI Optimization Suggestions
# AI finds inefficiencies
# Slow code
find_duplicates(list1, list2):
duplicates = []
for item1 in list1:
for item2 in list2:
if item1 == item2:
duplicates.append(item1)
return duplicates
# Ask for optimization
optimization = ai.optimize(find_duplicates)
show optimization.issues
# "Nested loop is O(n²). For large lists, this is slow."
show optimization.improved_version
# Improved (O(n)):
# find_duplicates(list1, list2):
# set2 = set(list2)
# return list1.filter(item => set2.contains(item))
show optimization.performance_gain
# "Estimated: 100x faster for 1000-item lists"
# Database query optimization
get_user_posts(user_id):
user = db.query("SELECT * FROM users WHERE id = ?", [user_id])
posts = db.query("SELECT * FROM posts WHERE author_id = ?", [user_id])
comments = db.query("SELECT * FROM comments WHERE author_id = ?", [user_id])
return { user, posts, comments }
# N+1 query problem
suggestions = ai.optimize_queries(get_user_posts)
show suggestions
# "Combine into single JOIN query to avoid multiple round-trips"
# Suggested:
# db.query("""
# SELECT users.*, posts.*, comments.*
# FROM users
# LEFT JOIN posts ON posts.author_id = users.id
# LEFT JOIN comments ON comments.author_id = users.id
# WHERE users.id = ?
# """, [user_id])
# Memory optimization
load_all_users():
return db.query("SELECT * FROM users") # Could be millions of rows!
memory_suggestions = ai.optimize_memory(load_all_users)
show memory_suggestions
# "Loading all rows into memory can crash the app"
# "Use pagination or streaming instead"

View File

@@ -0,0 +1,80 @@
# 089: AI Error Explanations
# AI explains what went wrong and how to fix it
# Runtime error
users = null
# This will error:
# first_user = users[0]
# Error message with AI explanation:
"""
Error: Cannot access property of null
AI Explanation:
The variable 'users' is null, so you can't access users[0].
This usually happens when:
1. Data hasn't loaded yet
2. API request failed
3. Database returned no results
Suggested fix:
if users != null and users.length > 0:
first_user = users[0]
else:
show "No users found"
"""
# Type error
age = "28" # String
adult = age >= 18 # Comparing string to number
# AI explains:
"""
Error: Type mismatch (string vs number)
AI Explanation:
You're comparing age (string "28") with 18 (number).
JavaScript allows this but results in weird behavior.
Suggested fixes:
1. Convert age to number: Number(age) >= 18
2. Or compare as strings: age >= "18"
3. Better: Store age as number from the start
"""
# Logic error (AI detected)
calculate_discount(price, percent):
discount = price * percent # Wrong! percent should be divided by 100
return price - discount
ai_warning = ai.analyze(calculate_discount)
show ai_warning
"""
⚠️ Logic Warning:
If percent is 20 (meaning 20%), you're calculating price * 20,
which would give a negative result after subtraction.
Did you mean: discount = price * (percent / 100)?
"""
# API error with AI context
try:
data = fetch "/api/users/999999"
catch error:
show ai.explain_error(error)
# Output:
"""
HTTP 404: Not Found
AI Explanation:
The user with ID 999999 doesn't exist in the database.
This is normal - just handle it gracefully:
user = fetch "/api/users/{id}"
if user == null:
show "User not found"
redirect_to "/users"
"""

View File

@@ -0,0 +1,68 @@
# 090: AI Learning User Style
# AI adapts to your coding preferences
# After writing code for a while, AI learns your style
# You prefer functional programming:
numbers = [1, 2, 3, 4, 5]
doubled = numbers.map(x => x * 2)
evens = numbers.filter(x => x % 2 == 0)
total = numbers.reduce((sum, x) => sum + x, 0)
# AI notices and suggests functional style for new code:
### Intent: Filter active users and get their emails
# AI suggests (matching your style):
# active_emails = users
# .filter(user => user.active)
# .map(user => user.email)
# Instead of imperative:
# active_emails = []
# for user in users:
# if user.active:
# active_emails.append(user.email)
# You prefer verbose variable names:
user_email_address = "alex@example.com"
is_email_verified = false
total_purchase_amount = 0
# AI learns and suggests:
### Intent: Store user's phone number
# Suggested variable name: user_phone_number (not just "phone")
# You always add error handling:
fetch_user_data(id):
try:
return fetch "/api/users/{id}"
catch error:
show "Error loading user"
return null
# AI learns pattern and auto-adds error handling to suggestions:
### Intent: Fetch product details
# AI suggests (with error handling, matching your style):
# fetch_product(id):
# try:
# return fetch "/api/products/{id}"
# catch error:
# show "Error loading product"
# return null
# Style preferences stored locally
ai.get_learned_preferences()
# Returns:
# {
# style: "functional",
# naming: "verbose_snake_case",
# error_handling: "always_try_catch",
# comments: "minimal",
# max_line_length: 80
# }
# You can override per-project
ai.set_preference("style", "object_oriented") # For this project only
# AI becomes YOUR collaborator, not a generic one

View File

@@ -0,0 +1,77 @@
# 091: Todo App
# Complete task management application
state todos = load "todos" locally or []
state filter = "all" # all, active, completed
# Add new todo
form add_todo:
input new_todo_text -> todo_text
placeholder: "What needs to be done?"
button "Add" -> add(todo_text)
add(text):
if text == "": return
new_todo = {
id: generate_id(),
text: text,
completed: false,
created_at: now()
}
todos.append(new_todo)
store todos locally as "todos"
todo_text = "" # Clear input
# Toggle completion
toggle(id):
todos = todos.map(todo => {
if todo.id == id:
{ ...todo, completed: not todo.completed }
else:
todo
})
store todos locally as "todos"
# Delete todo
delete_todo(id):
todos = todos.filter(todo => todo.id != id)
store todos locally as "todos"
# Filter todos
computed filtered_todos = todos.filter(todo => {
filter is:
"all": true
"active": not todo.completed
"completed": todo.completed
})
# Display todos
for todo in filtered_todos:
show_todo:
text: todo.text
completed: todo.completed
on_toggle: () => toggle(todo.id)
on_delete: () => delete_todo(todo.id)
# Filter buttons
show "Show: "
button "All ({todos.length})" -> filter = "all"
button "Active ({active_count})" -> filter = "active"
button "Completed ({completed_count})" -> filter = "completed"
computed active_count = todos.filter(t => not t.completed).length
computed completed_count = todos.filter(t => t.completed).length
# Clear completed
if completed_count > 0:
button "Clear Completed" -> clear_completed()
clear_completed():
todos = todos.filter(todo => not todo.completed)
store todos locally as "todos"
generate_id():
return now() + Math.random()

View File

@@ -0,0 +1,100 @@
# 092: Note Taking App
# Markdown notes with local storage and search
state notes = load "notes" locally or []
state current_note = null
state search_query = ""
# Create new note
create_note():
note = {
id: generate_id(),
title: "Untitled",
content: "",
created_at: now(),
updated_at: now(),
tags: []
}
notes.append(note)
current_note = note
store notes locally as "notes"
# Save note
save_note():
if current_note == null: return
current_note.updated_at = now()
notes = notes.map(note => {
if note.id == current_note.id:
current_note
else:
note
})
store notes locally as "notes"
show "Note saved"
# Delete note
delete_note(id):
notes = notes.filter(note => note.id != id)
current_note = null
store notes locally as "notes"
# Search notes
computed filtered_notes = notes.filter(note => {
if search_query == "": return true
query_lower = search_query.lowercase()
return note.title.lowercase().contains(query_lower) or
note.content.lowercase().contains(query_lower)
})
# UI Layout
show_layout:
# Sidebar
sidebar:
button "New Note" -> create_note()
input search_query -> search_query
placeholder: "Search notes..."
show "{filtered_notes.length} notes"
for note in filtered_notes:
note_list_item:
title: note.title
preview: note.content[0:50]
date: format_date(note.updated_at)
active: current_note?.id == note.id
on_click: () => current_note = note
# Editor
editor:
if current_note != null:
input current_note.title -> current_note.title
on_change: save_note()
textarea current_note.content -> current_note.content
on_change: save_note()
rows: 20
# Markdown preview
show_markdown(current_note.content)
# Tags
show "Tags:"
for tag in current_note.tags:
show_tag(tag)
button "Delete Note" -> delete_note(current_note.id)
else:
show "Select a note or create a new one"
format_date(timestamp):
# AI: Format as relative time
return "2 hours ago"
generate_id():
return now() + Math.random()

View File

@@ -0,0 +1,105 @@
# 093: Contact Manager
# Store and organize contacts locally
state contacts = load "contacts" locally or []
state editing = null
# Add contact
form add_contact:
input firstname -> new_contact.firstname
input lastname -> new_contact.lastname
input email -> new_contact.email
validate: is_email
input phone -> new_contact.phone
input company -> new_contact.company
button "Save Contact" -> save_contact(new_contact)
save_contact(contact):
contact.id = generate_id()
contact.created_at = now()
contact.favorite = false
contacts.append(contact)
store contacts locally as "contacts"
# Clear form
new_contact = {}
show "Contact saved"
# Edit contact
edit_contact(id):
editing = contacts.find(c => c.id == id)
save_edit():
contacts = contacts.map(c => {
if c.id == editing.id:
editing
else:
c
})
store contacts locally as "contacts"
editing = null
show "Contact updated"
# Delete contact
delete_contact(id):
ask "Delete this contact?" -> confirm
if confirm == "yes":
contacts = contacts.filter(c => c.id != id)
store contacts locally as "contacts"
show "Contact deleted"
# Toggle favorite
toggle_favorite(id):
contacts = contacts.map(c => {
if c.id == id:
{ ...c, favorite: not c.favorite }
else:
c
})
store contacts locally as "contacts"
# Sort and filter
state sort_by = "lastname"
state show_favorites_only = false
computed sorted_contacts = contacts
.filter(c => not show_favorites_only or c.favorite)
.sort_by(c => c[sort_by])
# Export contacts
export_contacts():
csv = ai.transform(contacts, { to: "csv" })
save_file("contacts.csv", csv)
show "Contacts exported"
# Import from phone (with consent)
import_from_phone():
ask permission for: device.contacts
purpose: "Import your phone contacts"
if granted:
with consent.record:
phone_contacts = read_device_contacts()
contacts = contacts.concat(phone_contacts)
store contacts locally as "contacts"
show "Imported {phone_contacts.length} contacts"
# Display
for contact in sorted_contacts:
show_contact_card:
name: "{contact.firstname} {contact.lastname}"
email: contact.email
phone: contact.phone
company: contact.company
favorite: contact.favorite
on_favorite: () => toggle_favorite(contact.id)
on_edit: () => edit_contact(contact.id)
on_delete: () => delete_contact(contact.id)
generate_id():
return now() + Math.random()

View File

@@ -0,0 +1,112 @@
# 094: Expense Tracker
# Track spending with categories and insights
state expenses = load "expenses" locally or []
state budget = load "budget" locally or { monthly: 2000 }
# Add expense
form add_expense:
input amount -> new_expense.amount
type: "number"
placeholder: "0.00"
input description -> new_expense.description
placeholder: "What was this for?"
select category -> new_expense.category
options: ["Food", "Transport", "Entertainment", "Bills", "Shopping", "Other"]
date_picker date -> new_expense.date
default: today()
button "Add Expense" -> save_expense(new_expense)
save_expense(exp):
exp.id = generate_id()
exp.created_at = now()
expenses.append(exp)
store expenses locally as "expenses"
new_expense = {}
show "Expense added"
# Delete expense
delete_expense(id):
expenses = expenses.filter(e => e.id != id)
store expenses locally as "expenses"
# Analytics
computed this_month_expenses = expenses.filter(e => {
is_this_month(e.date)
})
computed total_this_month = this_month_expenses
.reduce((sum, e) => sum + e.amount, 0)
computed by_category = this_month_expenses
.group_by(e => e.category)
.map(group => ({
category: group.key,
total: group.items.reduce((sum, e) => sum + e.amount, 0),
count: group.items.length
}))
.sort_by(g => g.total)
.reverse()
computed budget_remaining = budget.monthly - total_this_month
computed is_over_budget = total_this_month > budget.monthly
# Display summary
show_card:
title: "This Month"
value: "${total_this_month.toFixed(2)}"
subtitle: "of ${budget.monthly} budget"
if is_over_budget:
show_warning "Over budget by ${(total_this_month - budget.monthly).toFixed(2)}"
else:
show_success "${budget_remaining.toFixed(2)} remaining"
# Category breakdown
show "Spending by Category"
for cat in by_category:
show_category_bar:
name: cat.category
amount: cat.total
percent: (cat.total / total_this_month * 100).toFixed(1)
# Recent expenses
show "Recent Expenses"
for exp in expenses.sort_by(e => e.created_at).reverse().take(10):
show_expense_row:
description: exp.description
category: exp.category
amount: "${exp.amount.toFixed(2)}"
date: format_date(exp.date)
on_delete: () => delete_expense(exp.id)
# AI Insights
button "Get Spending Insights" -> show_insights()
show_insights():
### Intent: Analyze spending patterns and provide insights
insights = ai.analyze(expenses, {
focus: "patterns, unusual spending, savings opportunities"
})
show insights
# Export
button "Export to CSV" -> export_data()
export_data():
csv = ai.transform(expenses, { to: "csv" })
save_file("expenses.csv", csv)
generate_id():
return now() + Math.random()
is_this_month(date):
return date.month == today().month and date.year == today().year

View File

@@ -0,0 +1,108 @@
# 095: Weather Dashboard
# Real-time weather with location and forecasts
state location = null
state weather_data = null
state forecast = []
state units = "celsius" # celsius or fahrenheit
# Get user's location
get_location():
ask permission for: location
purpose: "Show weather for your location"
if granted:
with consent.record:
location = get_current_location()
load_weather()
else:
show "Enter a city to see weather"
# Load weather data
load_weather():
if location == null: return
ask permission for: network
purpose: "Fetch weather data"
if granted:
# Fetch current weather
weather_data = fetch "https://api.weather.com/current" with:
params: {
lat: location.latitude,
lon: location.longitude,
units: units
}
# Fetch 7-day forecast
forecast = fetch "https://api.weather.com/forecast" with:
params: {
lat: location.latitude,
lon: location.longitude,
days: 7,
units: units
}
# Cache locally
store weather_data locally as "weather_cache"
expires: "1 hour"
show "Weather updated"
# Manual city search
form search_city:
input city_name -> city
placeholder: "Enter city name"
button "Search" -> search_weather(city)
search_weather(city):
location = geocode(city) # Convert city name to coordinates
load_weather()
# Display current weather
if weather_data != null:
show_current_weather:
temperature: weather_data.temp
feels_like: weather_data.feels_like
condition: weather_data.description
humidity: weather_data.humidity
wind_speed: weather_data.wind_speed
icon: weather_data.icon
# 7-day forecast
show "7-Day Forecast"
for day in forecast:
show_forecast_card:
date: format_date(day.date)
high: day.temp_max
low: day.temp_min
condition: day.description
icon: day.icon
precipitation: day.precipitation_chance
# Settings
button "Toggle Units" -> toggle_units()
toggle_units():
units = units == "celsius" ? "fahrenheit" : "celsius"
load_weather() # Reload with new units
# Refresh
button "Refresh" -> load_weather()
# Works offline with cached data
if network.offline and weather_data == null:
cached = load "weather_cache" locally
if cached != null:
weather_data = cached
show "⚠️ Showing cached data (offline)"
# Auto-refresh every 30 minutes
on interval(30 * 60 * 1000):
if network.online:
load_weather()
# Initialize
on app.start:
get_location()

View File

@@ -0,0 +1,119 @@
# 096: Chat Application
# Real-time messaging with WebSocket
state messages = []
state username = load "username" locally or null
state connected = false
state websocket = null
# Set username
if username == null:
ask "Choose a username:" -> username
store username locally as "username"
# Connect to chat server
connect():
ask permission for: network
purpose: "Connect to chat server"
if granted:
websocket = connect_websocket("wss://chat.example.com")
on websocket.connected:
connected = true
show "Connected to chat"
on websocket.message:
handle_message(event.data)
on websocket.disconnected:
connected = false
show "Disconnected from chat"
# Auto-reconnect after 5 seconds
wait(5000)
connect()
# Handle incoming messages
handle_message(data):
message = JSON.parse(data)
message.type is:
"chat": {
messages.append({
id: message.id,
user: message.user,
text: message.text,
timestamp: message.timestamp
})
# Limit to last 100 messages
if messages.length > 100:
messages = messages.slice(-100)
}
"user_joined": {
show "{message.user} joined the chat"
}
"user_left": {
show "{message.user} left the chat"
}
# Send message
state new_message = ""
form chat_input:
input new_message -> new_message
placeholder: "Type a message..."
on_enter: send_message()
button "Send" -> send_message()
send_message():
if new_message == "" or not connected: return
msg = {
type: "chat",
user: username,
text: new_message,
timestamp: now()
}
websocket.send(JSON.stringify(msg))
new_message = "" # Clear input
# Display messages
show_chat_window:
for message in messages:
show_message:
user: message.user
text: message.text
time: format_time(message.timestamp)
is_mine: message.user == username
# Status indicator
if connected:
show "🟢 Connected"
else:
show "🔴 Disconnected"
# Leave chat
button "Leave Chat" -> disconnect()
disconnect():
if websocket != null:
websocket.send(JSON.stringify({
type: "user_left",
user: username
}))
websocket.close()
# Initialize
on app.start:
connect()
# Clean up on exit
on app.close:
disconnect()
format_time(timestamp):
return "12:34 PM" # AI: Format timestamp

View File

@@ -0,0 +1,130 @@
# 097: Markdown Editor
# Live markdown editing with preview and export
state content = load "draft" locally or """
# Welcome to Lucidia Markdown Editor
Start writing your markdown here...
## Features
- Live preview
- Syntax highlighting
- Export to HTML/PDF
- Auto-save
"""
state preview_mode = "split" # split, edit, preview
# Editor
form markdown_editor:
textarea content -> content
rows: 25
font: "monospace"
on_change: auto_save()
# Toolbar
toolbar:
button "Bold" -> insert("**bold**")
button "Italic" -> insert("*italic*")
button "Link" -> insert("[text](url)")
button "Image" -> insert("![alt](url)")
button "Code" -> insert("`code`")
button "Heading" -> insert("## ")
insert(syntax):
# Insert at cursor position
content = content + syntax
# Auto-save
auto_save():
store content locally as "draft"
# Preview modes
button "Split View" -> preview_mode = "split"
button "Edit Only" -> preview_mode = "edit"
button "Preview Only" -> preview_mode = "preview"
# Display based on mode
preview_mode is:
"split": {
show_layout:
left:
show_editor(content)
right:
show_markdown_preview(content)
}
"edit": {
show_editor(content)
}
"preview": {
show_markdown_preview(content)
}
# Word count
computed word_count = content.split(/\s+/).length
computed char_count = content.length
show "Words: {word_count} | Characters: {char_count}"
# Export options
button "Export HTML" -> export_html()
button "Export PDF" -> export_pdf()
button "Download MD" -> export_md()
export_html():
html = ai.transform(content, {
from: "markdown",
to: "html",
include_css: true
})
save_file("document.html", html)
show "Exported to HTML"
export_pdf():
### Intent: Convert markdown to PDF
pdf = ai.transform(content, {
from: "markdown",
to: "pdf"
})
save_file("document.pdf", pdf)
show "Exported to PDF"
export_md():
save_file("document.md", content)
show "Downloaded markdown file"
# Load file
button "Open File" -> open_file()
open_file():
ask permission for: filesystem.read
purpose: "Open markdown file"
if granted:
file = open_file_picker(accept: ".md,.txt")
if file != null:
content = file.read_text()
show "File loaded"
# Save file
button "Save File" -> save_file_dialog()
save_file_dialog():
ask permission for: filesystem.write
purpose: "Save markdown file"
if granted:
save_file_picker("document.md", content)
show "File saved"
# Keyboard shortcuts
on key "Ctrl+B":
insert("**bold**")
on key "Ctrl+I":
insert("*italic*")
on key "Ctrl+S":
save_file_dialog()

View File

@@ -0,0 +1,149 @@
# 098: Image Gallery
# Photo gallery with local storage and albums
state images = load "images" locally or []
state current_album = "all"
state selected_image = null
# Upload images
button "Add Photos" -> upload_images()
upload_images():
ask permission for: [filesystem.read, storage]
purpose: "Upload and save photos"
if granted:
files = open_file_picker(accept: "image/*", multiple: true)
for file in files:
image = {
id: generate_id(),
name: file.name,
data: file.read_as_data_url(),
size: file.size,
uploaded_at: now(),
album: current_album,
tags: [],
favorite: false
}
images.append(image)
store images locally as "images"
show "Uploaded {files.length} photos"
# Create album
form create_album:
input album_name -> new_album
button "Create Album" -> create_album_action(new_album)
create_album_action(name):
# Albums are derived from image data
current_album = name
show "Album '{name}' created"
# Move to album
move_to_album(image_id, album):
images = images.map(img => {
if img.id == image_id:
{ ...img, album: album }
else:
img
})
store images locally as "images"
# Toggle favorite
toggle_favorite(id):
images = images.map(img => {
if img.id == id:
{ ...img, favorite: not img.favorite }
else:
img
})
store images locally as "images"
# Delete image
delete_image(id):
ask "Delete this image?" -> confirm
if confirm == "yes":
images = images.filter(img => img.id != id)
store images locally as "images"
selected_image = null
# Filter by album
computed filtered_images = images.filter(img => {
current_album == "all" or img.album == current_album
})
# Get unique albums
computed albums = images
.map(img => img.album)
.unique()
.sort()
# Album switcher
show "Albums:"
button "All ({images.length})" -> current_album = "all"
for album in albums:
count = images.filter(img => img.album == album).length
button "{album} ({count})" -> current_album = album
# Gallery grid
show_gallery_grid:
for image in filtered_images:
show_thumbnail:
src: image.data
name: image.name
favorite: image.favorite
on_click: () => selected_image = image
on_favorite: () => toggle_favorite(image.id)
# Lightbox view
if selected_image != null:
show_lightbox:
image: selected_image.data
name: selected_image.name
size: format_file_size(selected_image.size)
uploaded: format_date(selected_image.uploaded_at)
button "Close" -> selected_image = null
button "Delete" -> delete_image(selected_image.id)
button "Previous" -> show_previous()
button "Next" -> show_next()
show_previous():
index = filtered_images.find_index(img => img.id == selected_image.id)
if index > 0:
selected_image = filtered_images[index - 1]
show_next():
index = filtered_images.find_index(img => img.id == selected_image.id)
if index < filtered_images.length - 1:
selected_image = filtered_images[index + 1]
# Auto-tag with AI
button "Auto-Tag All" -> auto_tag_images()
auto_tag_images():
for image in images:
if image.tags.length == 0:
tags = ai.classify(image.data, {
categories: ["nature", "people", "food", "architecture", "animals"],
multiple: true
})
image.tags = tags
store images locally as "images"
show "Images auto-tagged"
generate_id():
return now() + Math.random()
format_file_size(bytes):
return "{(bytes / 1024).toFixed(1)} KB"

View File

@@ -0,0 +1,162 @@
# 099: Music Player
# Audio player with playlists and controls
state playlist = load "playlist" locally or []
state current_track = null
state playing = false
state current_time = 0
state volume = 0.7
# Add songs
button "Add Songs" -> add_songs()
add_songs():
ask permission for: [filesystem.read, storage]
purpose: "Add music files"
if granted:
files = open_file_picker(accept: "audio/*", multiple: true)
for file in files:
track = {
id: generate_id(),
title: extract_title(file.name),
artist: "Unknown Artist",
duration: 0, # Will be set when loaded
file: file,
added_at: now()
}
playlist.append(track)
store playlist locally as "playlist"
show "Added {files.length} songs"
# Playback controls
play():
if current_track == null and playlist.length > 0:
current_track = playlist[0]
if current_track != null:
audio.play(current_track.file)
playing = true
pause():
audio.pause()
playing = false
stop():
audio.stop()
playing = false
current_time = 0
next_track():
index = playlist.find_index(t => t.id == current_track.id)
if index < playlist.length - 1:
current_track = playlist[index + 1]
play()
previous_track():
index = playlist.find_index(t => t.id == current_track.id)
if index > 0:
current_track = playlist[index - 1]
play()
seek(time):
audio.seek(time)
current_time = time
set_volume(vol):
volume = vol
audio.set_volume(vol)
# Audio events
on audio.timeupdate:
current_time = audio.current_time
on audio.ended:
next_track()
# Now playing
if current_track != null:
show_now_playing:
title: current_track.title
artist: current_track.artist
artwork: current_track.artwork or "default.jpg"
# Progress bar
show_progress_bar:
current: current_time
total: current_track.duration
on_seek: (time) => seek(time)
# Time display
show "{format_time(current_time)} / {format_time(current_track.duration)}"
# Controls
show_controls:
button "⏮" -> previous_track()
if playing:
button "⏸" -> pause()
else:
button "▶" -> play()
button "⏹" -> stop()
button "⏭" -> next_track()
# Volume
show_volume_slider:
value: volume
on_change: (vol) => set_volume(vol)
# Playlist
show "Playlist ({playlist.length} songs)"
for track in playlist:
show_track_row:
title: track.title
artist: track.artist
duration: format_time(track.duration)
playing: current_track?.id == track.id
on_click: () => {
current_track = track
play()
}
on_remove: () => remove_track(track.id)
remove_track(id):
playlist = playlist.filter(t => t.id != id)
if current_track?.id == id:
stop()
current_track = null
store playlist locally as "playlist"
# Shuffle
button "Shuffle" -> shuffle_playlist()
shuffle_playlist():
playlist = shuffle(playlist)
show "Playlist shuffled"
# Clear playlist
button "Clear Playlist" -> clear_playlist()
clear_playlist():
playlist = []
current_track = null
stop()
store playlist locally as "playlist"
extract_title(filename):
return filename.replace(/\.[^.]+$/, "") # Remove extension
format_time(seconds):
mins = Math.floor(seconds / 60)
secs = Math.floor(seconds % 60)
return "{mins}:{secs.pad(2)}"
generate_id():
return now() + Math.random()

View File

@@ -0,0 +1,191 @@
# 100: E-Commerce Checkout
# Complete checkout flow with payment, consent, and local cart
state cart = load "cart" locally or []
state user = load "user" locally or null
state checkout_step = "cart" # cart, shipping, payment, confirmation
# Add to cart
add_to_cart(product):
existing = cart.find(item => item.id == product.id)
if existing != null:
existing.quantity = existing.quantity + 1
else:
cart.append({ ...product, quantity: 1 })
store cart locally as "cart"
show "Added to cart"
# Remove from cart
remove_from_cart(product_id):
cart = cart.filter(item => item.id != product_id)
store cart locally as "cart"
# Update quantity
update_quantity(product_id, quantity):
if quantity <= 0:
remove_from_cart(product_id)
return
cart = cart.map(item => {
if item.id == product_id:
{ ...item, quantity }
else:
item
})
store cart locally as "cart"
# Cart totals
computed subtotal = cart.reduce((sum, item) => {
sum + (item.price * item.quantity)
}, 0)
computed tax = subtotal * 0.08
computed shipping = subtotal > 50 ? 0 : 5.99
computed total = subtotal + tax + shipping
# Checkout flow
checkout_step is:
"cart": show_cart()
"shipping": show_shipping_form()
"payment": show_payment_form()
"confirmation": show_confirmation()
# Step 1: Cart
show_cart():
show "Shopping Cart ({cart.length} items)"
for item in cart:
show_cart_item:
name: item.name
price: "${item.price}"
quantity: item.quantity
total: "${(item.price * item.quantity).toFixed(2)}"
on_update: (qty) => update_quantity(item.id, qty)
on_remove: () => remove_from_cart(item.id)
show "Subtotal: ${subtotal.toFixed(2)}"
show "Tax: ${tax.toFixed(2)}"
show "Shipping: ${shipping.toFixed(2)}"
show "Total: ${total.toFixed(2)}"
if cart.length > 0:
button "Proceed to Checkout" -> checkout_step = "shipping"
# Step 2: Shipping
show_shipping_form():
form shipping_address:
input fullname -> shipping.name
input address -> shipping.address
input city -> shipping.city
select state -> shipping.state
options: ["CA", "NY", "TX", "FL", "WA"]
input zipcode -> shipping.zip
validate: is_zipcode
button "Continue to Payment" -> {
store shipping locally as "shipping"
checkout_step = "payment"
}
# Step 3: Payment
show_payment_form():
# Request payment permission
ask permission for: payment.process
purpose: "Complete purchase of ${total.toFixed(2)}"
if granted:
form payment_method:
select method -> payment.method
options: ["Credit Card", "PayPal", "Apple Pay"]
if payment.method == "Credit Card":
input card_number -> payment.card_number
type: "text"
validate: is_credit_card
input expiry -> payment.expiry
placeholder: "MM/YY"
input cvv -> payment.cvv
type: "password"
maxlength: 4
checkbox save_payment -> payment.save
label: "Save payment method for future purchases"
button "Place Order" -> process_payment()
process_payment():
# Consent to charge
ask permission for: payment.charge
amount: total
purpose: "Complete purchase"
if granted:
with consent.record:
# Process payment
result = charge_payment(payment, total)
if result.success:
# Clear cart
order_id = result.order_id
cart = []
store cart locally as "cart"
# Save order
order = {
id: order_id,
items: cart,
total: total,
shipping: shipping,
date: now()
}
orders = load "orders" locally or []
orders.append(order)
store orders locally as "orders"
checkout_step = "confirmation"
else:
show "Payment failed: {result.error}"
else:
show "Payment cancelled"
# Step 4: Confirmation
show_confirmation():
show "✓ Order Confirmed!"
show "Order ID: {order_id}"
show "Total: ${total.toFixed(2)}"
show "A confirmation email has been sent"
button "Continue Shopping" -> {
checkout_step = "cart"
}
button "View Orders" -> show_order_history()
# Order history
show_order_history():
orders = load "orders" locally or []
show "Your Orders ({orders.length})"
for order in orders:
show_order_summary:
id: order.id
date: format_date(order.date)
total: "${order.total.toFixed(2)}"
items: order.items.length
# This example shows:
# - Local-first cart (persists across sessions)
# - Multi-step checkout flow
# - Consent for payment processing
# - Real payment integration
# - Order history
# - All data stored locally
# - Works offline (cart persists)

Some files were not shown because too many files have changed in this diff Show More