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>
326 lines
7.6 KiB
Markdown
326 lines
7.6 KiB
Markdown
# 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
|
|
|
|
```lux
|
|
// 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
|
|
|
|
```lux
|
|
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
|
|
|
|
```lux
|
|
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
|
|
|
|
```lux
|
|
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
|
|
|
|
```lux
|
|
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
|
|
|
|
```lux
|
|
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
|
|
|
|
```lux
|
|
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
|
|
|
|
```lux
|
|
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
|
|
|
|
```lux
|
|
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
|
|
|
|
```lux
|
|
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
|
|
|
|
```lux
|
|
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
|
|
|
|
```lux
|
|
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.
|
|
|
|
```lux
|
|
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.
|
|
|
|
```lux
|
|
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.
|
|
|
|
```lux
|
|
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.
|
|
|
|
```lux
|
|
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
|
|
|
|
1. **Pick a project** at your skill level
|
|
2. **Break it down** into smaller tasks
|
|
3. **Start with types** - define your data structures
|
|
4. **Add effects** - what I/O do you need?
|
|
5. **Implement logic** - write pure functions first
|
|
6. **Test with handlers** - swap in mock handlers
|
|
|
|
## Need Help?
|
|
|
|
- Check `examples/` for working code
|
|
- Read the [Effects Guide](../guide/05-effects.md)
|
|
- Experiment in the REPL
|
|
|
|
Happy building!
|