Files
lux/docs/tutorials/project-ideas.md
Brandon Lucas 44f88afcf8 docs: add comprehensive language documentation
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>
2026-02-13 17:43:41 -05:00

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

  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
  • Experiment in the REPL

Happy building!