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>
240 lines
8.2 KiB
HTML
240 lines
8.2 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>HTTP Server - Lux by Example</title>
|
|
<meta name="description" content="Build an HTTP server in Lux.">
|
|
<link rel="icon" href="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'><text y='.9em' font-size='90'>✨</text></svg>">
|
|
<link rel="preconnect" href="https://fonts.googleapis.com">
|
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
|
<link href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;600&family=Playfair+Display:wght@400;600;700&family=Source+Serif+4:opsz,wght@8..60,400;8..60,500;8..60,600&display=swap" rel="stylesheet">
|
|
<link rel="stylesheet" href="../static/style.css">
|
|
<style>
|
|
.example-container {
|
|
max-width: 900px;
|
|
margin: 0 auto;
|
|
padding: var(--space-xl) var(--space-lg);
|
|
}
|
|
|
|
.example-header {
|
|
margin-bottom: var(--space-xl);
|
|
}
|
|
|
|
.example-header h1 {
|
|
margin-bottom: var(--space-sm);
|
|
}
|
|
|
|
.example-header p {
|
|
font-size: 1.1rem;
|
|
}
|
|
|
|
.code-block {
|
|
background: var(--code-bg);
|
|
border: 1px solid var(--code-border);
|
|
border-radius: 8px;
|
|
margin: var(--space-lg) 0;
|
|
overflow: hidden;
|
|
}
|
|
|
|
.code-header {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
padding: var(--space-sm) var(--space-md);
|
|
background: var(--bg-secondary);
|
|
border-bottom: 1px solid var(--code-border);
|
|
}
|
|
|
|
.code-filename {
|
|
color: var(--text-muted);
|
|
font-family: var(--font-code);
|
|
font-size: 0.85rem;
|
|
}
|
|
|
|
.code-content {
|
|
padding: var(--space-md);
|
|
overflow-x: auto;
|
|
}
|
|
|
|
.code-content pre {
|
|
font-family: var(--font-code);
|
|
font-size: 0.9rem;
|
|
line-height: 1.6;
|
|
margin: 0;
|
|
}
|
|
|
|
.explanation {
|
|
background: var(--bg-glass);
|
|
border: 1px solid var(--border-subtle);
|
|
border-radius: 8px;
|
|
padding: var(--space-lg);
|
|
margin: var(--space-lg) 0;
|
|
}
|
|
|
|
.explanation h2 {
|
|
font-size: 1.25rem;
|
|
margin-bottom: var(--space-md);
|
|
text-align: left;
|
|
}
|
|
|
|
.explanation ul {
|
|
padding-left: var(--space-lg);
|
|
}
|
|
|
|
.explanation li {
|
|
color: var(--text-secondary);
|
|
margin-bottom: var(--space-sm);
|
|
}
|
|
|
|
.explanation code {
|
|
background: var(--code-bg);
|
|
padding: 0.1em 0.3em;
|
|
border-radius: 3px;
|
|
font-size: 0.9em;
|
|
color: var(--gold);
|
|
}
|
|
|
|
.run-it {
|
|
background: var(--bg-tertiary);
|
|
border: 1px solid var(--border-subtle);
|
|
border-radius: 8px;
|
|
padding: var(--space-lg);
|
|
margin: var(--space-lg) 0;
|
|
}
|
|
|
|
.run-it h3 {
|
|
margin-bottom: var(--space-md);
|
|
}
|
|
|
|
.run-it pre {
|
|
background: var(--code-bg);
|
|
padding: var(--space-md);
|
|
border-radius: 6px;
|
|
font-family: var(--font-code);
|
|
font-size: 0.9rem;
|
|
}
|
|
|
|
.example-nav {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
margin-top: var(--space-xl);
|
|
padding-top: var(--space-lg);
|
|
border-top: 1px solid var(--border-subtle);
|
|
}
|
|
|
|
.example-nav a {
|
|
color: var(--text-secondary);
|
|
padding: var(--space-sm) var(--space-md);
|
|
border: 1px solid var(--border-subtle);
|
|
border-radius: 4px;
|
|
}
|
|
|
|
.example-nav a:hover {
|
|
color: var(--gold);
|
|
border-color: var(--border-gold);
|
|
}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<nav>
|
|
<a href="/" class="logo">Lux</a>
|
|
<ul class="nav-links" id="nav-links">
|
|
<li><a href="/install">Install</a></li>
|
|
<li><a href="/tour/">Tour</a></li>
|
|
<li><a href="/examples/">Examples</a></li>
|
|
<li><a href="/docs/">Docs</a></li>
|
|
<li><a href="/play">Play</a></li>
|
|
<li><a href="https://git.qrty.ink/blu/lux" class="nav-source">Source</a></li>
|
|
</ul>
|
|
</nav>
|
|
|
|
<main class="example-container">
|
|
<header class="example-header">
|
|
<h1>HTTP Server</h1>
|
|
<p>Build a simple HTTP server with effect-tracked I/O. The type signature tells you exactly what side effects this code performs.</p>
|
|
</header>
|
|
|
|
<div class="code-block">
|
|
<div class="code-header">
|
|
<span class="code-filename">server.lux</span>
|
|
</div>
|
|
<div class="code-content">
|
|
<pre><code><span class="cm">// A simple HTTP server in Lux</span>
|
|
<span class="cm">// Notice the effect signature: {HttpServer, Console}</span>
|
|
|
|
<span class="kw">fn</span> <span class="fn">handleRequest</span>(req: <span class="ty">Request</span>): <span class="ty">Response</span> = {
|
|
<span class="kw">match</span> req.path {
|
|
<span class="st">"/"</span> => Response {
|
|
status: <span class="num">200</span>,
|
|
body: <span class="st">"Welcome to Lux!"</span>
|
|
},
|
|
<span class="st">"/api/hello"</span> => Response {
|
|
status: <span class="num">200</span>,
|
|
body: Json.stringify({ message: <span class="st">"Hello, World!"</span> })
|
|
},
|
|
_ => Response {
|
|
status: <span class="num">404</span>,
|
|
body: <span class="st">"Not Found"</span>
|
|
}
|
|
}
|
|
}
|
|
|
|
<span class="kw">fn</span> <span class="fn">main</span>(): <span class="ty">Unit</span> <span class="kw">with</span> {<span class="ef">HttpServer</span>, <span class="ef">Console</span>} = {
|
|
<span class="ef">HttpServer</span>.listen(<span class="num">8080</span>)
|
|
<span class="ef">Console</span>.print(<span class="st">"Server listening on http://localhost:8080"</span>)
|
|
|
|
<span class="kw">loop</span> {
|
|
<span class="kw">let</span> req = <span class="ef">HttpServer</span>.accept()
|
|
<span class="ef">Console</span>.print(req.method + <span class="st">" "</span> + req.path)
|
|
|
|
<span class="kw">let</span> response = handleRequest(req)
|
|
<span class="ef">HttpServer</span>.respond(response.status, response.body)
|
|
}
|
|
}
|
|
|
|
<span class="kw">run</span> main() <span class="kw">with</span> {}</code></pre>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="explanation">
|
|
<h2>Key Concepts</h2>
|
|
<ul>
|
|
<li><code>with {HttpServer, Console}</code> - The function signature declares exactly which effects this code uses</li>
|
|
<li><code>HttpServer.listen(port)</code> - Start listening on a port</li>
|
|
<li><code>HttpServer.accept()</code> - Wait for and return the next request</li>
|
|
<li><code>HttpServer.respond(status, body)</code> - Send a response</li>
|
|
<li>Pattern matching on <code>req.path</code> for routing</li>
|
|
</ul>
|
|
</div>
|
|
|
|
<div class="explanation">
|
|
<h2>Why Effects Matter Here</h2>
|
|
<ul>
|
|
<li>The type signature <code>with {HttpServer, Console}</code> tells you this function does network I/O and console output</li>
|
|
<li>Pure functions like <code>handleRequest</code> have no effects - they're easy to test</li>
|
|
<li>For testing, you can swap the <code>HttpServer</code> handler to simulate requests without a real network</li>
|
|
</ul>
|
|
</div>
|
|
|
|
<div class="run-it">
|
|
<h3>Run It</h3>
|
|
<pre>$ lux run server.lux
|
|
Server listening on http://localhost:8080
|
|
|
|
# In another terminal:
|
|
$ curl http://localhost:8080/
|
|
Welcome to Lux!
|
|
|
|
$ curl http://localhost:8080/api/hello
|
|
{"message":"Hello, World!"}</pre>
|
|
</div>
|
|
|
|
<nav class="example-nav">
|
|
<a href="index.html">← All Examples</a>
|
|
<a href="rest-api.html">REST API →</a>
|
|
</nav>
|
|
</main>
|
|
</body>
|
|
</html>
|