I think we should include the type signature of main! in most cases (like on the examples repo). Type mismatches for beginners will be less confusing if they can see the type of main!. It does come at the cost of brevity but I think it's worth it.
Before:
app [main!] { cli: platform "https://github.com/roc-lang/basic-cli/releases/download/0.19.0/Hj-J_zxz7V9YurCSTFcFdu6cQJie4guzsPMUi5kBYUk.tar.br" }
import cli.Stdout
main! = |_args|
Stdout.line!("Hello, World!")
After:
app [main!] { cli: platform "https://github.com/roc-lang/basic-cli/releases/download/0.19.0/Hj-J_zxz7V9YurCSTFcFdu6cQJie4guzsPMUi5kBYUk.tar.br" }
import cli.Stdout
import pf.Arg exposing [Arg]
main! : List Arg => Result {} _
main! = |_args|
Stdout.line!("Hello, World!")
for absolute beginners, it's super important to me to teach types only after teaching how to build things
like how it's done in e.g. Python
I agree with that for lessons and the tutorial etc. but if they're trying stuff on their own, starting from hello world, they will hit a type mismatch fast once they start altering main!.
Examples likely should be what we consider solid, but beginner friendly code. I think that means a type for every top level function
I do agree for first learning, types should be 100% avoided.
that's fair, for examples outside tutorials
Last updated: Jun 16 2026 at 16:19 UTC