Skip to content

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 — evaluate expr for its side effect and discard the result. This is how you sequence Unit-returning calls in a pure language.
  • The last expression in a block is the block's value. printfn "Done." returns Unit, which becomes the value of main().
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