Documentation structure inspired by Rust Book, Elm Guide, and others: Guide (10 chapters): - Introduction and setup - Basic types (Int, String, Bool, List, Option, Result) - Functions (closures, higher-order, composition) - Data types (ADTs, pattern matching, records) - Effects (the core innovation) - Handlers (patterns and techniques) - Modules (imports, exports, organization) - Error handling (Fail, Option, Result) - Standard library reference - Advanced topics (traits, generics, optimization) Reference: - Complete syntax reference Tutorials: - Calculator (parsing, evaluation, REPL) - Dependency injection (testing with effects) - Project ideas (16 projects by difficulty) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
7.6 KiB
Project Ideas
Here are projects to build with Lux, organized by difficulty and purpose.
Beginner Projects
1. Temperature Converter
Convert between Celsius, Fahrenheit, and Kelvin.
Skills: Basic I/O, functions, conditionals
// Starter code
fn celsiusToFahrenheit(c: Float): Float = c * 9.0 / 5.0 + 32.0
fn fahrenheitToCelsius(f: Float): Float = (f - 32.0) * 5.0 / 9.0
fn main(): Unit with {Console} = {
Console.print("Temperature Converter")
Console.print("1. Celsius to Fahrenheit")
Console.print("2. Fahrenheit to Celsius")
// ... implement menu and conversion
}
2. Number Guessing Game
Computer picks a number, user guesses with hints.
Skills: Random effect, loops, conditionals
fn game(): Unit with {Console, Random} = {
let secret = Random.int(1, 100)
Console.print("I'm thinking of a number 1-100...")
guessLoop(secret, 1)
}
3. Word Counter
Count words, lines, and characters in a file.
Skills: File effect, string operations
fn countFile(path: String): Unit with {Console, File} = {
let content = File.read(path)
let lines = String.lines(content)
let words = countWords(content)
let chars = String.length(content)
// ... display results
}
4. Simple Quiz
Multiple choice questions with scoring.
Skills: ADTs, pattern matching, state
type Question = { text: String, options: List<String>, correct: Int }
fn askQuestion(q: Question): Bool with {Console} = {
Console.print(q.text)
// ... display options and check answer
}
Intermediate Projects
5. Contact Book
CRUD operations with file persistence.
Skills: File I/O, JSON, ADTs, effects
type Contact = { name: String, email: String, phone: String }
effect ContactStore {
fn add(contact: Contact): Int
fn find(name: String): Option<Contact>
fn list(): List<Contact>
fn delete(id: Int): Bool
}
// Implement handlers for file-based and in-memory storage
6. Markdown Parser
Parse basic Markdown to HTML.
Skills: Parsing, string manipulation, ADTs
type MarkdownNode =
| Heading(Int, String) // level, text
| Paragraph(String)
| Bold(String)
| Italic(String)
| Code(String)
| List(List<String>)
| Link(String, String) // text, url
fn parseMarkdown(input: String): List<MarkdownNode> = ...
fn toHtml(nodes: List<MarkdownNode>): String = ...
7. Simple HTTP API Client
Fetch and display data from a REST API.
Skills: HTTP effect, JSON parsing
fn fetchWeather(city: String): Unit with {Console, Http} = {
let response = Http.get("https://api.weather.com/city/" + city)
let data = Json.parse(response)
let temp = Json.getFloat(data, "temperature")
Console.print(city + ": " + toString(temp) + "°C")
}
8. File Backup Tool
Copy files with logging and error handling.
Skills: File effect, error handling, recursion
fn backup(source: String, dest: String): Unit with {File, Console, Fail} = {
if File.isDirectory(source) then
backupDirectory(source, dest)
else
backupFile(source, dest)
}
Advanced Projects
9. Effect-Based Test Framework
Use effects for test isolation and assertions.
Skills: Custom effects, handlers, composition
effect Assert {
fn equal<T>(actual: T, expected: T): Unit
fn true(condition: Bool): Unit
fn fail(message: String): Unit
}
effect Test {
fn describe(name: String, tests: fn(): Unit): Unit
fn it(name: String, test: fn(): Unit): Unit
}
// Handlers collect results, run tests, report
10. Configuration DSL
Type-safe configuration with validation.
Skills: Effects, validation, ADTs
effect Config {
fn required(key: String): String
fn optional(key: String, default: String): String
fn validate(key: String, validator: fn(String): Bool): String
}
fn loadAppConfig(): AppConfig with {Config, Fail} = {
AppConfig {
host: Config.required("HOST"),
port: Config.validate("PORT", isValidPort),
debug: Config.optional("DEBUG", "false") == "true"
}
}
11. Mini Language Interpreter
Build an interpreter for a simple language.
Skills: Parsing, ADTs, recursion, effects
type Expr = ...
type Stmt = ...
type Value = ...
effect Runtime {
fn getVar(name: String): Value
fn setVar(name: String, value: Value): Unit
fn print(value: Value): Unit
}
fn interpret(program: List<Stmt>): Unit with {Runtime} = ...
12. Task Scheduler
Schedule and run tasks with dependencies.
Skills: Graphs, effects, async simulation
type Task = { id: String, deps: List<String>, action: fn(): Unit }
effect Scheduler {
fn schedule(task: Task): Unit
fn run(): Unit
fn wait(taskId: String): Unit
}
Effect Showcase Projects
These projects specifically highlight Lux's effect system.
13. Transactional Operations
Rollback on failure using effects.
effect Transaction {
fn begin(): Unit
fn commit(): Unit
fn rollback(): Unit
}
fn transfer(from: Account, to: Account, amount: Int): Unit
with {Transaction, Database, Fail} = {
Transaction.begin()
Database.debit(from, amount)
Database.credit(to, amount) // If this fails, rollback
Transaction.commit()
}
14. Mock HTTP for Testing
Swap real HTTP with recorded responses.
handler recordedHttp(responses: Map<String, String>): Http {
fn get(url) = {
match Map.get(responses, url) {
Some(body) => resume(body),
None => Fail.fail("No recorded response for: " + url)
}
}
}
// Test with recorded responses
let testResponses = Map.from([
("https://api.example.com/users", "[{\"id\": 1}]")
])
run fetchUsers() with { Http = recordedHttp(testResponses) }
15. Capability-Based Security
Use effects as capabilities.
effect FileRead { fn read(path: String): String }
effect FileWrite { fn write(path: String, content: String): Unit }
effect Network { fn fetch(url: String): String }
// This function can ONLY read files - it cannot write or use network
fn processConfig(path: String): Config with {FileRead} = ...
// This function has network but no file access
fn fetchData(url: String): Data with {Network} = ...
16. Async Simulation
Model async operations with effects.
effect Async {
fn spawn(task: fn(): T): Future<T>
fn await(future: Future<T>): T
fn sleep(ms: Int): Unit
}
fn parallel(): List<Int> with {Async} = {
let f1 = Async.spawn(fn(): Int => compute1())
let f2 = Async.spawn(fn(): Int => compute2())
let f3 = Async.spawn(fn(): Int => compute3())
[Async.await(f1), Async.await(f2), Async.await(f3)]
}
Project Complexity Guide
| Project | Effects Used | Lines of Code | Time |
|---|---|---|---|
| Temperature Converter | Console | ~50 | 1 hour |
| Guessing Game | Console, Random | ~80 | 2 hours |
| Word Counter | Console, File | ~60 | 1 hour |
| Contact Book | Console, File, Custom | ~200 | 4 hours |
| Markdown Parser | Pure + Console | ~300 | 6 hours |
| Test Framework | Custom effects | ~400 | 8 hours |
| Mini Interpreter | Custom effects | ~600 | 16 hours |
Getting Started
- Pick a project at your skill level
- Break it down into smaller tasks
- Start with types - define your data structures
- Add effects - what I/O do you need?
- Implement logic - write pure functions first
- Test with handlers - swap in mock handlers
Need Help?
- Check
examples/for working code - Read the Effects Guide
- Experiment in the REPL
Happy building!