Tutorial 01: Hello, World¶
Your first ll-lang program — zero boilerplate.
Prerequisites¶
Install .NET 10, then build the compiler:
git clone https://github.com/Neftedollar/ll-lang.git
cd ll-lang
dotnet build
# lllc is now available via dotnet run --project src/LLLangTool
Write the program¶
Create hello.lll:
module Hello
main() = printfn "Hello, ll-lang!"
Three lines. That is the entire program. No imports, no entry-point annotation, no braces.
Line 1 — module declaration. Every .lll file must start with module Name. The name must match the file name.
Line 3 — the entry point. main() is the canonical zero-parameter entry point. The empty parens signal a zero-param function — the compiler emits [<EntryPoint>] for it. printfn is in the prelude; it takes a Str and prints it with a newline.
No fn, no return, no {}.
Run it¶
lllc run hello.lll
Hello, ll-lang!
lllc run compiles to a temporary F# project and executes it via dotnet run. You get an answer in one command.
Build it¶
lllc build hello.lll
This writes hello.fs next to your source file. Inspect it:
// Generated by lllc
module Hello
[<EntryPoint>]
let main (argv: string[]) =
printfn "Hello, ll-lang!"
0
The compiler emits idiomatic F# — a proper [<EntryPoint>] main, 0 exit code, standard printfn. Nothing exotic.
A slightly larger example¶
module Hello
greet(name Str) = printfn (strConcat "Hello, " name)
main() =
_ = greet "Alice"
_ = greet "Bob"
printfn "Done."
New things here:
greet(name Str)— a function. Each parameter is written(name Type)in its own parens. Return type is inferred (Unit).strConcat— stdlib string concatenation._ = expr— evaluateexprfor its side effect and discard the result. This is how you sequenceUnit-returning calls in a pure language.- The last expression in a block is the block's value.
printfn "Done."returnsUnit, which becomes the value ofmain().
lllc run hello.lll
Hello, Alice
Hello, Bob
Done.
Validate without running¶
lllc build hello.lll
Reports syntax/type errors and writes generated output. For project builds, use lllc build at the project root.
Next steps¶
- 02-types-and-patterns.md — ADTs and exhaustive pattern matching
- 03-building-a-parser.md — a real-world example