# 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, 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 fn list(): List 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) | Link(String, String) // text, url fn parseMarkdown(input: String): List = ... fn toHtml(nodes: List): 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(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): Unit with {Runtime} = ... ``` ### 12. Task Scheduler Schedule and run tasks with dependencies. **Skills**: Graphs, effects, async simulation ```lux type Task = { id: String, deps: List, 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): 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 fn await(future: Future): T fn sleep(ms: Int): Unit } fn parallel(): List 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!