I'd like to be able to run something like:
roc annotate -u main.roc
And it would automatically add type annotations to all the top-level functions in main.roc. The -u stands for update. If you omit it, the command just prints the annotations:
roc annotate main.roc
square : I32, I32 -> U64
message : Str
parse : Str -> Result I64 [InvalidFormat]
My motivation right now is that I have over 30 exercises in Exercism, and very few of them are annotated. It's probably a good idea to annotate them, and I wish I could automate that.
That sounds wonderful. Though I do think it will have some minor inconveniences with generality.
As in the concrete type may be I64 but the inferred type is Num a type decision.
Maybe it could be a flag on the formatter instead of a new sub command?
Oh yes, these are great points.
Something like:
roc format --add-annotations --annotation-types=specific main.roc
Couldn't this also be a nice LSP action?
Kilian Vounckx said:
Couldn't this also be a nice LSP action?
I always assumed this would be how we'd do it
And then we just add an action at the top of the module that does it for a whole file
That's good too, and probably easier to implement since there's already annotation suggestions in the LSP! It would not be as easy to integrate into a script though (e.g., suppose you want to write a script to check or add annotations in a GitHub action, you would need to spin up a language server).
It would not be as easy to use in a scripting environment, correct, but it would be more effort to implement that, probably? I think both are useful.
Let's treat this as three features?
roc format that adds signatures to all top level defsSounds perfect!
For 3, is roc format really the right place for this (as opposed to a new roc annotate)?
You're right, this feels a little bit like formatter config. To avoid polluting the roc <subcommand> namespace, do you think that roc format annotate is sufficiently clear?
(no opinion, I'll defer to others)
It seems reasonable on the surface to make the formatter add type annotations to all _exported_ functions (in a library), at least
I do imagine it being nice to not add type annotations to everything tho, since it could be handy to not have to update so many annotations during a refactor or something...
I don't think so, unfortunately, for three reasons:
a, b, is a good bit worse than useful names.:thinking: Maybe tho, there could be a refactoring tool that would try to identify a set of top-level annotations that, if removed and re-inferred, would cause all the type errors to go away
What if someone put a type signature to have the compiler help them get the annotated function to that type?
But I definitely think if this is possible, it would pretty much just be a net positive to ensure all top-level defs are type-annotated
Anyway, I'm now convinced that if nothing else this is solidly in the Hard Problem category, so likely not something we want to try to have the formatter just do, without a lot of careful thought
What are type variables named? Just defaulting to
a,b, is a good bit worse than useful names.
Would be fun to ship a small (like, really small) language model for something like this :stuck_out_tongue:
Something vaguely along these lines: https://www.microsoft.com/en-us/research/publication/flame-a-small-language-model-for-spreadsheet-formulas/
I actually want to experiment with something like that for doing a better error-tolerant parser
(tangent alert!)
I actually want to experiment with something like that for doing a better error-tolerant parser
That is very interesting, I have argued for an approach like that for error messages before, but it also makes a lot of sense for error-tolerant parsing.
Generating training data would be easy; you can take correct programs and mess them up a little.
Although a big risk would be that the same code could be parsed into a different correct program when you release a next version of your language model.
Last updated: Jun 16 2026 at 16:19 UTC