docs: add website and JS/WASM backend plans
Website Plan (docs/WEBSITE_PLAN.md): - Research from Elm, Gleam, Rust, Go, Elixir, Zig websites - Messaging strategy: "Effects you can see, tests you can trust" - Section structure: Hero, Problem, Solution (3 pillars), Examples - Self-hosting goal: Build lux-lang.org in Lux itself JS/WASM Backend Plan (docs/JS_WASM_BACKEND_PLAN.md): - Type mappings: Lux types → JavaScript equivalents - Code generation examples for functions, closures, ADTs, effects - 6-phase implementation: Core → StdLib → Effects → DOM → CLI → WASM - New Dom effect for browser manipulation - Timeline: 11-15 weeks for full support Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
483
docs/JS_WASM_BACKEND_PLAN.md
Normal file
483
docs/JS_WASM_BACKEND_PLAN.md
Normal file
@@ -0,0 +1,483 @@
|
||||
# Lux JavaScript/WASM Backend Plan
|
||||
|
||||
## Goal
|
||||
|
||||
Enable Lux to compile to JavaScript and WebAssembly, allowing:
|
||||
1. **Browser execution** - Run Lux in web browsers
|
||||
2. **Self-hosted website** - Build lux-lang.org in Lux itself (like Elm)
|
||||
3. **Universal deployment** - Same code runs on server (native) and client (JS/WASM)
|
||||
|
||||
## Research Summary
|
||||
|
||||
### How Gleam Does It
|
||||
|
||||
[Gleam compiles to JavaScript](https://gleam.run/news/v0.16-gleam-compiles-to-javascript/) with these characteristics:
|
||||
- **No runtime overhead** - Generated JS looks like human-written code
|
||||
- **Promise-based concurrency** - Uses native JS promises, not Erlang actors
|
||||
- **Good interop** - Gleam functions callable from JS/TS directly
|
||||
- [30% performance improvement](https://gleam.run/news/gleam-javascript-gets-30-percent-faster/) in v1.11.0 through optimization
|
||||
|
||||
### How Elm Does It
|
||||
|
||||
[Elm compiles to JavaScript](https://guide.elm-lang.org/interop/) with:
|
||||
- **Virtual DOM** - Efficient updates via diffing
|
||||
- **Ports** - Explicit interop boundary with JavaScript
|
||||
- **Small runtime** - Scheduler and virtual DOM
|
||||
- **Dead code elimination** - Only includes used code
|
||||
- **Name mangling** - Prefixes with underscore to avoid collisions
|
||||
|
||||
---
|
||||
|
||||
## Implementation Strategy
|
||||
|
||||
### Approach: Parallel to C Backend
|
||||
|
||||
Create `src/codegen/js_backend.rs` mirroring `c_backend.rs` structure:
|
||||
|
||||
```
|
||||
src/codegen/
|
||||
├── c_backend.rs # Existing: Lux → C → Native
|
||||
├── js_backend.rs # New: Lux → JavaScript
|
||||
└── wasm_backend.rs # Future: Lux → WASM (via C or direct)
|
||||
```
|
||||
|
||||
### Type Mappings
|
||||
|
||||
| Lux Type | JavaScript Type |
|
||||
|----------|-----------------|
|
||||
| `Int` | `number` (BigInt for large values) |
|
||||
| `Float` | `number` |
|
||||
| `Bool` | `boolean` |
|
||||
| `String` | `string` |
|
||||
| `Unit` | `undefined` |
|
||||
| `List<T>` | `Array` |
|
||||
| `Option<T>` | `{tag: "Some", value: T} \| {tag: "None"}` |
|
||||
| `Result<T, E>` | `{tag: "Ok", value: T} \| {tag: "Err", error: E}` |
|
||||
| `Closure` | `function` (closure environment captured naturally) |
|
||||
| `ADT` | `{tag: "VariantName", field0: ..., field1: ...}` |
|
||||
|
||||
### Code Generation Examples
|
||||
|
||||
#### Functions
|
||||
|
||||
```lux
|
||||
fn add(a: Int, b: Int): Int = a + b
|
||||
```
|
||||
|
||||
Generates:
|
||||
```javascript
|
||||
function add_lux(a, b) {
|
||||
return a + b;
|
||||
}
|
||||
```
|
||||
|
||||
#### Closures
|
||||
|
||||
```lux
|
||||
fn makeAdder(x: Int): (Int) -> Int = {
|
||||
fn(y: Int): Int => x + y
|
||||
}
|
||||
```
|
||||
|
||||
Generates:
|
||||
```javascript
|
||||
function makeAdder_lux(x) {
|
||||
return function(y) {
|
||||
return x + y;
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
#### Pattern Matching
|
||||
|
||||
```lux
|
||||
fn describe(opt: Option<Int>): String = {
|
||||
match opt {
|
||||
Some(n) => "Got " + toString(n),
|
||||
None => "Nothing"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Generates:
|
||||
```javascript
|
||||
function describe_lux(opt) {
|
||||
if (opt.tag === "Some") {
|
||||
const n = opt.value;
|
||||
return "Got " + String(n);
|
||||
} else {
|
||||
return "Nothing";
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### ADTs
|
||||
|
||||
```lux
|
||||
type Tree =
|
||||
| Leaf
|
||||
| Node(Int, Tree, Tree)
|
||||
```
|
||||
|
||||
Generates:
|
||||
```javascript
|
||||
// Constructor functions
|
||||
function Leaf_lux() {
|
||||
return { tag: "Leaf" };
|
||||
}
|
||||
|
||||
function Node_lux(value, left, right) {
|
||||
return { tag: "Node", field0: value, field1: left, field2: right };
|
||||
}
|
||||
```
|
||||
|
||||
#### Effects
|
||||
|
||||
Effects compile to async/await:
|
||||
|
||||
```lux
|
||||
fn fetchData(): String with Http = {
|
||||
Http.get("https://api.example.com/data")
|
||||
}
|
||||
```
|
||||
|
||||
Generates:
|
||||
```javascript
|
||||
async function fetchData_lux(handlers) {
|
||||
return await handlers.Http.get("https://api.example.com/data");
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Implementation Phases
|
||||
|
||||
### Phase 1: Core Language (2-3 weeks)
|
||||
|
||||
| Feature | Effort | Notes |
|
||||
|---------|--------|-------|
|
||||
| Basic types (Int, Float, Bool, String) | 2 days | Direct mapping |
|
||||
| Arithmetic and comparison operators | 1 day | |
|
||||
| Functions and calls | 2 days | |
|
||||
| Let bindings | 1 day | |
|
||||
| If expressions | 1 day | Ternary or if/else |
|
||||
| Pattern matching (basic) | 3 days | Tag checks, destructuring |
|
||||
| ADT definitions and constructors | 2 days | Object literals |
|
||||
| Closures | 2 days | Native JS closures |
|
||||
| Lists | 2 days | Map to Array |
|
||||
|
||||
**Milestone:** Can compile `fib.lux` to JS and run in Node.js
|
||||
|
||||
### Phase 2: Standard Library (1-2 weeks)
|
||||
|
||||
| Module | Effort | JS Implementation |
|
||||
|--------|--------|-------------------|
|
||||
| Console | 1 day | `console.log` |
|
||||
| String | 2 days | Native string methods |
|
||||
| List | 2 days | Array methods |
|
||||
| Math | 1 day | `Math.*` |
|
||||
| Option/Result | 1 day | Pattern matching |
|
||||
| JSON | 2 days | `JSON.parse/stringify` |
|
||||
|
||||
**Milestone:** Standard library examples work in browser
|
||||
|
||||
### Phase 3: Effects in JS (2 weeks)
|
||||
|
||||
| Effect | Effort | JS Implementation |
|
||||
|--------|--------|-------------------|
|
||||
| Console | 1 day | `console.log`, `prompt()` |
|
||||
| Http | 3 days | `fetch()` API |
|
||||
| File | 2 days | Not available in browser (Node.js only) |
|
||||
| Time | 1 day | `Date.now()`, `setTimeout` |
|
||||
| Random | 1 day | `Math.random()` |
|
||||
| DOM (new) | 5 days | New effect for browser manipulation |
|
||||
|
||||
**Milestone:** HTTP requests work in browser
|
||||
|
||||
### Phase 4: Browser/DOM Support (2-3 weeks)
|
||||
|
||||
New `Dom` effect for browser manipulation:
|
||||
|
||||
```lux
|
||||
effect Dom {
|
||||
fn querySelector(selector: String): Option<Element>
|
||||
fn createElement(tag: String): Element
|
||||
fn appendChild(parent: Element, child: Element): Unit
|
||||
fn addEventListener(el: Element, event: String, handler: () -> Unit): Unit
|
||||
fn setTextContent(el: Element, text: String): Unit
|
||||
fn setAttribute(el: Element, name: String, value: String): Unit
|
||||
fn getInputValue(el: Element): String
|
||||
}
|
||||
```
|
||||
|
||||
| Feature | Effort | Notes |
|
||||
|---------|--------|-------|
|
||||
| Basic DOM queries | 2 days | querySelector, getElementById |
|
||||
| Element creation | 2 days | createElement, appendChild |
|
||||
| Event handling | 3 days | addEventListener with closures |
|
||||
| Attribute manipulation | 2 days | setAttribute, classList |
|
||||
| Form handling | 2 days | Input values, form submission |
|
||||
| Virtual DOM (optional) | 5 days | Efficient updates |
|
||||
|
||||
**Milestone:** Can build interactive web page in Lux
|
||||
|
||||
### Phase 5: CLI Integration (1 week)
|
||||
|
||||
```bash
|
||||
# Compile to JavaScript
|
||||
lux compile app.lux --target js -o app.js
|
||||
|
||||
# Compile to JavaScript module (ES modules)
|
||||
lux compile app.lux --target js --module -o app.mjs
|
||||
|
||||
# Compile with bundled runtime
|
||||
lux compile app.lux --target js --bundle -o app.bundle.js
|
||||
|
||||
# Run in Node.js
|
||||
lux run app.lux --target js
|
||||
```
|
||||
|
||||
### Phase 6: WASM Backend (3-4 weeks)
|
||||
|
||||
Options:
|
||||
1. **Lux → C → Emscripten → WASM** (easiest, reuse C backend)
|
||||
2. **Lux → WASM directly** (more control, harder)
|
||||
3. **Lux → AssemblyScript → WASM** (middle ground)
|
||||
|
||||
Recommended: Start with Emscripten approach, direct WASM later.
|
||||
|
||||
---
|
||||
|
||||
## Architecture
|
||||
|
||||
### JS Backend Module Structure
|
||||
|
||||
```rust
|
||||
// src/codegen/js_backend.rs
|
||||
|
||||
pub struct JsBackend {
|
||||
output: String,
|
||||
indent: usize,
|
||||
functions: HashSet<String>,
|
||||
name_counter: usize,
|
||||
}
|
||||
|
||||
impl JsBackend {
|
||||
pub fn new() -> Self { ... }
|
||||
|
||||
pub fn compile(program: &[Decl]) -> Result<String, JsGenError> { ... }
|
||||
|
||||
fn emit_decl(&mut self, decl: &Decl) -> Result<(), JsGenError> { ... }
|
||||
fn emit_function(&mut self, func: &Function) -> Result<(), JsGenError> { ... }
|
||||
fn emit_expr(&mut self, expr: &Expr) -> Result<String, JsGenError> { ... }
|
||||
fn emit_pattern(&mut self, pattern: &Pattern, value: &str) -> Result<String, JsGenError> { ... }
|
||||
fn emit_adt(&mut self, adt: &TypeDecl) -> Result<(), JsGenError> { ... }
|
||||
|
||||
// JS-specific
|
||||
fn emit_runtime(&mut self) { ... } // Minimal runtime helpers
|
||||
fn emit_effect_handlers(&mut self, effects: &[Effect]) { ... }
|
||||
}
|
||||
```
|
||||
|
||||
### Runtime (Minimal)
|
||||
|
||||
```javascript
|
||||
// Lux JS Runtime (embedded in generated code)
|
||||
const Lux = {
|
||||
// Option helpers
|
||||
Some: (value) => ({ tag: "Some", value }),
|
||||
None: () => ({ tag: "None" }),
|
||||
|
||||
// Result helpers
|
||||
Ok: (value) => ({ tag: "Ok", value }),
|
||||
Err: (error) => ({ tag: "Err", error }),
|
||||
|
||||
// List helpers
|
||||
Cons: (head, tail) => [head, ...tail],
|
||||
Nil: () => [],
|
||||
|
||||
// Effect handler invoker
|
||||
handle: async (computation, handlers) => {
|
||||
return await computation(handlers);
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Browser Integration
|
||||
|
||||
### Entry Point
|
||||
|
||||
```lux
|
||||
// app.lux
|
||||
fn main(): Unit with Dom = {
|
||||
let button = Dom.createElement("button")
|
||||
Dom.setTextContent(button, "Click me!")
|
||||
Dom.addEventListener(button, "click", fn(): Unit => {
|
||||
Dom.setTextContent(button, "Clicked!")
|
||||
})
|
||||
let body = Dom.querySelector("body")
|
||||
match body {
|
||||
Some(el) => Dom.appendChild(el, button),
|
||||
None => ()
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Compiles to:
|
||||
```javascript
|
||||
async function main_lux(handlers) {
|
||||
const button = handlers.Dom.createElement("button");
|
||||
handlers.Dom.setTextContent(button, "Click me!");
|
||||
handlers.Dom.addEventListener(button, "click", function() {
|
||||
handlers.Dom.setTextContent(button, "Clicked!");
|
||||
});
|
||||
const body = handlers.Dom.querySelector("body");
|
||||
if (body.tag === "Some") {
|
||||
handlers.Dom.appendChild(body.value, button);
|
||||
}
|
||||
}
|
||||
|
||||
// Browser handler
|
||||
const BrowserDom = {
|
||||
createElement: (tag) => document.createElement(tag),
|
||||
setTextContent: (el, text) => { el.textContent = text; },
|
||||
addEventListener: (el, event, handler) => el.addEventListener(event, handler),
|
||||
querySelector: (sel) => {
|
||||
const el = document.querySelector(sel);
|
||||
return el ? Lux.Some(el) : Lux.None();
|
||||
},
|
||||
appendChild: (parent, child) => parent.appendChild(child)
|
||||
};
|
||||
|
||||
// Initialize
|
||||
main_lux({ Dom: BrowserDom });
|
||||
```
|
||||
|
||||
### HTML Integration
|
||||
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Lux App</title>
|
||||
</head>
|
||||
<body>
|
||||
<script src="app.js"></script>
|
||||
<script>
|
||||
// Generated initialization code
|
||||
Lux.main({ Dom: BrowserDom });
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Self-Hosting the Website
|
||||
|
||||
Once the JS backend is complete, the lux-lang.org website can be built in Lux:
|
||||
|
||||
```lux
|
||||
// website/src/Main.lux
|
||||
|
||||
import Html.{div, h1, p, button, text}
|
||||
import App.{Model, Msg, init, update, view}
|
||||
|
||||
fn main(): Unit with Dom = {
|
||||
let model = init()
|
||||
let root = Dom.querySelector("#app")
|
||||
match root {
|
||||
Some(el) => render(el, model),
|
||||
None => Console.print("No #app element found")
|
||||
}
|
||||
}
|
||||
|
||||
fn render(root: Element, model: Model): Unit with Dom = {
|
||||
let html = view(model)
|
||||
Dom.setInnerHtml(root, html)
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Testing Strategy
|
||||
|
||||
### Unit Tests
|
||||
|
||||
```rust
|
||||
#[test]
|
||||
fn test_js_function_generation() {
|
||||
let input = "fn add(a: Int, b: Int): Int = a + b";
|
||||
let js = JsBackend::compile(input).unwrap();
|
||||
assert!(js.contains("function add_lux(a, b)"));
|
||||
assert!(js.contains("return a + b"));
|
||||
}
|
||||
```
|
||||
|
||||
### Integration Tests
|
||||
|
||||
Run generated JS in Node.js and compare output:
|
||||
|
||||
```rust
|
||||
#[test]
|
||||
fn test_fibonacci_js() {
|
||||
let lux_code = include_str!("../../examples/fibonacci.lux");
|
||||
let js_code = JsBackend::compile(lux_code).unwrap();
|
||||
|
||||
let output = Command::new("node")
|
||||
.arg("-e")
|
||||
.arg(&js_code)
|
||||
.output()
|
||||
.unwrap();
|
||||
|
||||
assert!(String::from_utf8_lossy(&output.stdout).contains("fib(10) = 55"));
|
||||
}
|
||||
```
|
||||
|
||||
### Browser Tests
|
||||
|
||||
Use Playwright/Puppeteer to test DOM manipulation:
|
||||
|
||||
```javascript
|
||||
test('button click works', async ({ page }) => {
|
||||
await page.goto('http://localhost:3000/test.html');
|
||||
await page.click('button');
|
||||
expect(await page.textContent('button')).toBe('Clicked!');
|
||||
});
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Timeline
|
||||
|
||||
| Phase | Duration | Milestone |
|
||||
|-------|----------|-----------|
|
||||
| Phase 1: Core Language | 2-3 weeks | Fibonacci runs in Node.js |
|
||||
| Phase 2: Standard Library | 1-2 weeks | Examples work in browser |
|
||||
| Phase 3: Effects | 2 weeks | HTTP works in browser |
|
||||
| Phase 4: DOM Support | 2-3 weeks | Interactive page in Lux |
|
||||
| Phase 5: CLI Integration | 1 week | `lux compile --target js` |
|
||||
| Phase 6: WASM | 3-4 weeks | WASM execution |
|
||||
|
||||
**Total: 11-15 weeks** for full JS/WASM support
|
||||
|
||||
---
|
||||
|
||||
## Success Criteria
|
||||
|
||||
1. **Correctness**: All existing tests pass when targeting JS
|
||||
2. **Performance**: Within 2x of hand-written JS for benchmarks
|
||||
3. **Size**: Generated JS is reasonable size (< 2x hand-written equivalent)
|
||||
4. **Interop**: Easy to call Lux from JS and JS from Lux
|
||||
5. **Self-hosting**: lux-lang.org runs entirely on Lux-compiled JS
|
||||
|
||||
---
|
||||
|
||||
## References
|
||||
|
||||
- [Gleam JS Compilation](https://gleam.run/news/v0.16-gleam-compiles-to-javascript/)
|
||||
- [Elm JavaScript Interop](https://guide.elm-lang.org/interop/)
|
||||
- [Koka JavaScript Backend](https://koka-lang.github.io/koka/doc/book.html)
|
||||
- [PureScript Code Generation](https://github.com/purescript/purescript/tree/master/src/Language/PureScript/CodeGen)
|
||||
323
docs/WEBSITE_PLAN.md
Normal file
323
docs/WEBSITE_PLAN.md
Normal file
@@ -0,0 +1,323 @@
|
||||
# Lux Language Website Plan
|
||||
|
||||
## Research Summary
|
||||
|
||||
Analyzed 6 beloved language websites: **Elm**, **Gleam**, **Rust**, **Elixir**, **Zig**, and **Go**.
|
||||
|
||||
### Key Patterns from Successful Language Websites
|
||||
|
||||
| Pattern | Examples | Why It Works |
|
||||
|---------|----------|--------------|
|
||||
| **Emotional benefits over features** | Elm: "deploy and go to sleep" | Developers buy peace of mind, not feature lists |
|
||||
| **Problem-first messaging** | Rust: addresses memory bugs, Zig: "no hidden control flow" | Validates pain points before offering solution |
|
||||
| **Runnable code immediately** | Go Playground, Gleam Tour | Reduces friction, proves language works |
|
||||
| **Social proof** | Go: PayPal, Google testimonials | Builds credibility for enterprise adoption |
|
||||
| **Use-case segmentation** | Rust: CLI, WASM, networking, embedded | Helps users self-identify relevance |
|
||||
| **Progressive disclosure** | All: simple → complex | Doesn't overwhelm newcomers |
|
||||
| **Built with itself** | Elm site is built in Elm | Meta demonstration of capabilities |
|
||||
| **Inclusive community** | Gleam: prominent Code of Conduct | Signals healthy ecosystem |
|
||||
|
||||
---
|
||||
|
||||
## Lux's Unique Value Proposition
|
||||
|
||||
### Core Differentiators
|
||||
|
||||
1. **Effects are better than monads** - More intuitive for learning FP
|
||||
2. **Compile-time effect tracking** - Know exactly what code does
|
||||
3. **Swap handlers for testing** - No mocks needed
|
||||
4. **Native performance** - Compiles to C, matches Rust/C speed
|
||||
5. **Functional but practical** - Not academic, production-ready
|
||||
|
||||
### Tagline Options
|
||||
|
||||
- "A functional language with first-class effects"
|
||||
- "Know what your code does. All of it."
|
||||
- "Effects you can see. Tests you can trust."
|
||||
- "Functional programming that makes sense"
|
||||
|
||||
### Target Audiences
|
||||
|
||||
1. **Haskell/FP developers** frustrated by monads
|
||||
2. **Backend developers** wanting type safety without Java verbosity
|
||||
3. **Educators** teaching functional programming
|
||||
4. **Teams** wanting testable, maintainable code
|
||||
|
||||
---
|
||||
|
||||
## Website Structure
|
||||
|
||||
### Navigation
|
||||
|
||||
```
|
||||
[Logo: Lux] Learn Docs Playground Community GitHub
|
||||
```
|
||||
|
||||
### Section 1: Hero
|
||||
|
||||
**Headline:** "Functional programming with first-class effects"
|
||||
|
||||
**Subheadline:** "See exactly what your code does. Test it without mocks. Deploy with confidence."
|
||||
|
||||
**CTA Buttons:**
|
||||
- [Try Lux] → Interactive playground
|
||||
- [Get Started] → Installation guide
|
||||
|
||||
**Visual:** Animated effect flow visualization or side-by-side code showing effect signatures
|
||||
|
||||
### Section 2: The Problem (Pain Points)
|
||||
|
||||
**"The problem with side effects"**
|
||||
|
||||
> "Most bugs come from code doing things you didn't expect—network calls, file writes, database queries hidden deep in the call stack."
|
||||
|
||||
Show side-by-side:
|
||||
- **Other languages:** Function signature doesn't reveal what it does
|
||||
- **Lux:** Effect signature makes all side effects explicit
|
||||
|
||||
```lux
|
||||
// In Lux, the type tells you everything
|
||||
fn fetchUser(id: Int): User with Http, Database = {
|
||||
// You KNOW this touches network and database
|
||||
}
|
||||
```
|
||||
|
||||
### Section 3: The Solution (3 Pillars)
|
||||
|
||||
#### Pillar 1: Effects You Can See
|
||||
- Every function declares its effects
|
||||
- No hidden surprises in production
|
||||
- Refactor with confidence
|
||||
|
||||
```lux
|
||||
fn processOrder(order: Order): Result<Receipt, Error> with Database, Email = {
|
||||
let saved = Database.save(order)
|
||||
Email.send(order.customer, "Order confirmed!")
|
||||
Ok(Receipt(saved.id))
|
||||
}
|
||||
```
|
||||
|
||||
#### Pillar 2: Testing Without Mocks
|
||||
- Swap effect handlers at runtime
|
||||
- Test database code without a database
|
||||
- Test HTTP code without network
|
||||
|
||||
```lux
|
||||
// Production
|
||||
handle processOrder(order) with {
|
||||
Database -> realDatabase,
|
||||
Email -> smtpServer
|
||||
}
|
||||
|
||||
// Test - same code, different handlers
|
||||
handle processOrder(order) with {
|
||||
Database -> inMemoryStore,
|
||||
Email -> collectMessages
|
||||
}
|
||||
```
|
||||
|
||||
#### Pillar 3: Native Performance
|
||||
- Compiles to C via gcc -O2
|
||||
- Matches Rust/C performance
|
||||
- Reference counting with FBIP optimization
|
||||
|
||||
| Benchmark | Lux | Rust | Go | Node.js |
|
||||
|-----------|-----|------|----|---------|
|
||||
| Fibonacci | 0.015s | 0.018s | 0.041s | 0.110s |
|
||||
| Ackermann | 0.020s | 0.029s | 0.107s | 0.207s |
|
||||
|
||||
### Section 4: Learn by Example
|
||||
|
||||
**Interactive code snippets** (using playground embeds):
|
||||
|
||||
1. **Hello World** - Basic syntax
|
||||
2. **Pattern Matching** - ADTs and matching
|
||||
3. **Effects** - Console, File, HTTP
|
||||
4. **Handlers** - Swapping implementations
|
||||
5. **Testing** - Effect-based testing
|
||||
|
||||
Each example: Code + "Run" button + explanation
|
||||
|
||||
### Section 5: Use Cases
|
||||
|
||||
#### Backend Services
|
||||
- Effect tracking documents all side effects
|
||||
- Swap database handlers for testing
|
||||
- JSON, HTTP, SQL built-in
|
||||
|
||||
#### Reliable Systems
|
||||
- `is pure`, `is total` behavioral types
|
||||
- Compile-time guarantees
|
||||
- Idempotency verification (coming soon)
|
||||
|
||||
#### Teaching FP
|
||||
- Effects more intuitive than monads
|
||||
- Clear progression: pure → effects → handlers
|
||||
- Excellent error messages
|
||||
|
||||
### Section 6: Social Proof
|
||||
|
||||
**"What developers are saying"**
|
||||
|
||||
(Placeholder for future testimonials)
|
||||
|
||||
**Companies using Lux** (logos when available)
|
||||
|
||||
**Benchmark results** - Comparison chart vs Rust, Go, Node, Python
|
||||
|
||||
### Section 7: Getting Started
|
||||
|
||||
```bash
|
||||
# Install
|
||||
curl -sSL https://lux-lang.org/install.sh | sh
|
||||
|
||||
# Create project
|
||||
lux new my-app
|
||||
cd my-app
|
||||
|
||||
# Run
|
||||
lux run
|
||||
```
|
||||
|
||||
**Next steps:**
|
||||
- [Language Tour] - Interactive tutorial
|
||||
- [Guide] - In-depth documentation
|
||||
- [Examples] - Real-world code
|
||||
- [API Reference] - Standard library
|
||||
|
||||
### Section 8: Community
|
||||
|
||||
- **GitHub** - Source code, issues, PRs
|
||||
- **Discord** - Chat with the community
|
||||
- **Forum** - Discussions
|
||||
- **Code of Conduct** - Inclusive community
|
||||
|
||||
---
|
||||
|
||||
## Design Principles
|
||||
|
||||
### Visual Identity
|
||||
|
||||
- **Primary color:** Deep purple/violet (#6B46C1) - unique, memorable
|
||||
- **Accent:** Teal (#0D9488) for CTAs
|
||||
- **Background:** Clean whites and light grays
|
||||
- **Typography:** System fonts for performance, monospace for code
|
||||
|
||||
### Code Highlighting
|
||||
|
||||
Syntax highlighting theme that emphasizes:
|
||||
- **Effects** - Different color to make them stand out
|
||||
- **Types** - Clear distinction from values
|
||||
- **Keywords** - Subtle but readable
|
||||
|
||||
### Interactive Elements
|
||||
|
||||
- **Playground embeds** - Run code in browser
|
||||
- **Animated effects flow** - Visualize how effects propagate
|
||||
- **Hover tooltips** - Type information on code examples
|
||||
|
||||
---
|
||||
|
||||
## Technical Implementation
|
||||
|
||||
### Self-Hosting Goal
|
||||
|
||||
The website should be **built in Lux** (like Elm's site), demonstrating:
|
||||
- Lux compiles to JavaScript/WASM
|
||||
- Full-stack Lux is possible
|
||||
- The language is production-ready
|
||||
|
||||
### Architecture
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────┐
|
||||
│ lux-lang.org │
|
||||
├─────────────────────────────────────────┤
|
||||
│ Frontend (Lux → WASM/JS) │
|
||||
│ - Interactive playground │
|
||||
│ - Animated examples │
|
||||
│ - Client-side routing │
|
||||
├─────────────────────────────────────────┤
|
||||
│ Backend (Lux → Native) │
|
||||
│ - Serve static content │
|
||||
│ - Playground compilation API │
|
||||
│ - Package registry (future) │
|
||||
└─────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### Required Language Features
|
||||
|
||||
To build the website in Lux, we need:
|
||||
|
||||
| Feature | Status | Priority |
|
||||
|---------|--------|----------|
|
||||
| JS backend | Missing | P0 |
|
||||
| WASM backend | Missing | P1 |
|
||||
| DOM manipulation effect | Missing | P1 |
|
||||
| HTML DSL | Missing | P2 |
|
||||
| CSS-in-Lux | Missing | P2 |
|
||||
| Virtual DOM/diffing | Missing | P2 |
|
||||
| Client routing | Missing | P2 |
|
||||
|
||||
---
|
||||
|
||||
## Content Priorities
|
||||
|
||||
### Phase 1: Essential Content
|
||||
|
||||
1. **Landing page** - Hero, 3 pillars, getting started
|
||||
2. **Installation guide** - All platforms
|
||||
3. **Language tour** - Interactive tutorial
|
||||
4. **Effect system guide** - Core concept explanation
|
||||
5. **Standard library reference** - API docs
|
||||
|
||||
### Phase 2: Expansion
|
||||
|
||||
6. **Cookbook** - Common patterns
|
||||
7. **Video tutorials** - YouTube/embedded
|
||||
8. **Comparison guides** - vs Haskell, vs Rust, vs TypeScript
|
||||
9. **Blog** - Updates, deep dives
|
||||
10. **Showcase** - Projects built with Lux
|
||||
|
||||
### Phase 3: Community
|
||||
|
||||
11. **Package registry** - Browse packages
|
||||
12. **Forum integration** - Discussions
|
||||
13. **Contribution guide** - How to contribute
|
||||
14. **Governance** - RFC process
|
||||
|
||||
---
|
||||
|
||||
## Success Metrics
|
||||
|
||||
| Metric | Target |
|
||||
|--------|--------|
|
||||
| Time to first code run | < 60 seconds |
|
||||
| Tutorial completion rate | > 50% |
|
||||
| GitHub stars after website launch | 1000 in 6 months |
|
||||
| Package registry submissions | 50 in first year |
|
||||
| "I finally understand effects" comments | Qualitative goal |
|
||||
|
||||
---
|
||||
|
||||
## Inspiration Summary
|
||||
|
||||
| From | Take |
|
||||
|------|------|
|
||||
| **Elm** | Emotional messaging, interactive demos, built-with-itself |
|
||||
| **Gleam** | Friendly tone, ecosystem emphasis, inclusive community |
|
||||
| **Rust** | Problem-first messaging, use-case segmentation |
|
||||
| **Go** | Pragmatic testimonials, playground, multiple learning paths |
|
||||
| **Elixir** | Case studies, real code examples, ecosystem confidence |
|
||||
| **Zig** | Transparency, C interop story, pragmatic positioning |
|
||||
|
||||
---
|
||||
|
||||
## Next Steps
|
||||
|
||||
1. **Build JS/WASM backend** - Required to self-host
|
||||
2. **Create playground** - Run Lux in browser
|
||||
3. **Write language tour** - Interactive tutorial
|
||||
4. **Design visual identity** - Logo, colors, typography
|
||||
5. **Build MVP landing page** - Even if not in Lux initially
|
||||
6. **Launch and iterate** - Get feedback early
|
||||
Reference in New Issue
Block a user