feat: rebuild website with full learning funnel

Website rebuilt from scratch based on analysis of 11 beloved language
websites (Elm, Zig, Gleam, Swift, Kotlin, Haskell, OCaml, Crystal, Roc,
Rust, Go).

New website structure:
- Homepage with hero, playground, three pillars, install guide
- Language Tour with interactive lessons (hello world, types, effects)
- Examples cookbook with categorized sidebar
- API documentation index
- Installation guide (Nix and source)
- Sleek/noble design (black/gold, serif typography)

Also includes:
- New stdlib/json.lux module for JSON serialization
- Enhanced stdlib/http.lux with middleware and routing
- New string functions (charAt, indexOf, lastIndexOf, repeat)
- LSP improvements (rename, signature help, formatting)
- Package manager transitive dependency resolution
- Updated documentation for effects and stdlib
- New showcase example (task_manager.lux)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-02-16 23:05:35 -05:00
parent 5a853702d1
commit 7e76acab18
44 changed files with 12468 additions and 3354 deletions

View File

@@ -1173,6 +1173,110 @@ impl TypeEnv {
},
);
// Add Concurrent effect for concurrent/parallel execution
// Task is represented as Int (task ID)
env.effects.insert(
"Concurrent".to_string(),
EffectDef {
name: "Concurrent".to_string(),
type_params: Vec::new(),
operations: vec![
// Spawn a new concurrent task that returns a value
// Returns a Task<A> (represented as Int task ID)
EffectOpDef {
name: "spawn".to_string(),
params: vec![("thunk".to_string(), Type::Function {
params: Vec::new(),
return_type: Box::new(Type::Var(0)),
effects: EffectSet::empty(),
properties: PropertySet::empty(),
})],
return_type: Type::Int, // Task ID
},
// Wait for a task to complete and get its result
EffectOpDef {
name: "await".to_string(),
params: vec![("task".to_string(), Type::Int)],
return_type: Type::Var(0),
},
// Yield control to allow other tasks to run
EffectOpDef {
name: "yield".to_string(),
params: Vec::new(),
return_type: Type::Unit,
},
// Sleep for milliseconds (non-blocking to other tasks)
EffectOpDef {
name: "sleep".to_string(),
params: vec![("ms".to_string(), Type::Int)],
return_type: Type::Unit,
},
// Cancel a running task
EffectOpDef {
name: "cancel".to_string(),
params: vec![("task".to_string(), Type::Int)],
return_type: Type::Bool,
},
// Check if a task is still running
EffectOpDef {
name: "isRunning".to_string(),
params: vec![("task".to_string(), Type::Int)],
return_type: Type::Bool,
},
// Get the number of active tasks
EffectOpDef {
name: "taskCount".to_string(),
params: Vec::new(),
return_type: Type::Int,
},
],
},
);
// Add Channel effect for concurrent communication
env.effects.insert(
"Channel".to_string(),
EffectDef {
name: "Channel".to_string(),
type_params: Vec::new(),
operations: vec![
// Create a new channel, returns channel ID
EffectOpDef {
name: "create".to_string(),
params: Vec::new(),
return_type: Type::Int, // Channel ID
},
// Send a value on a channel
EffectOpDef {
name: "send".to_string(),
params: vec![
("channel".to_string(), Type::Int),
("value".to_string(), Type::Var(0)),
],
return_type: Type::Unit,
},
// Receive a value from a channel (blocks until available)
EffectOpDef {
name: "receive".to_string(),
params: vec![("channel".to_string(), Type::Int)],
return_type: Type::Var(0),
},
// Try to receive (non-blocking, returns Option)
EffectOpDef {
name: "tryReceive".to_string(),
params: vec![("channel".to_string(), Type::Int)],
return_type: Type::Option(Box::new(Type::Var(0))),
},
// Close a channel
EffectOpDef {
name: "close".to_string(),
params: vec![("channel".to_string(), Type::Int)],
return_type: Type::Unit,
},
],
},
);
// Add Sql effect for database access
// Connection is represented as Int (connection ID)
let row_type = Type::Record(vec![]); // Dynamic record type