I've talked before about specifying the Roc version in the main.roc file, so people know which version your code is guaranteed to work with. Given the amount of breaking changes we're making these days, it seems like the time has come for us to implement this. What do you think?
we could do it now yeah. I was thinking just a number after the module keyword, e.g.
app 0.1.0-RC1 { # ...
package 0.1.0 { # ...
platform 0.1.1 { # ...
I don't think echo! should require a version number because the whole point of that one is to give you an ultra minimal way to start learning the language...if you're sharing your echo! source files with people, something has probably gone wrong :sweat_smile:
Is it though? Thinking about e.g. the playground or the like where you might want to share something around. Or in case you want to explain something or the like. Atleast I think I‘d prefer uniformity. If you’re supposed to include the version to warn about potentially breaking stuff happening in the meantime, why not especially at something targeted for people coming new into the language?
I don't want the first line of hello world to be declaring what version of the Roc compiler you're using :smile:
the whole purpose of echo! being exposed unqualified in this use case is specifically so that beginners can have a super minimal hello world experience that they can play around with and expand from
sharing is not an important part of that experience; but eliminating everything that's not strictly necessary for them to understand yet is an important part!
I was thinking just a number after the module keyword, e.g.
That looks good, I was thinking nightly versions should be allowed as well?
seems reasonable! :+1:
After the module keyword for me makes the impression of describing the version of the package or app. Where do you specify a package version currently?
by design, version isn't specified in the source code, it's specified in the URL
I want to avoid having competing sources of truth for the version number that can get out of sync with each other :smile:
Norbert Hajagos said:
After the module keyword for me makes the impression of describing the version of the package or app.
We could add roc- before the version
Should we let roc fmt add the version number and fail fmt --check if it is not there?
My thinking was to introduce it gently instead of having roc check error if the version specifier is absent.
Additionally fmt --check could also fail if the roc version doing the formatting is newer than the specified version and fmt could upgrade it automatically.
Do we want a version number to be mandatory? Seems useful for scripts and stuff you share, but maybe noisy/chore for your own apps?
I'd like to try out making it mandatory. For most people it will only be in one file in their project.
maybe noisy/chore for your own apps?
It's not very noisy in comparison to the massive url, and chore-wise roc fmt can just take care of it.
Richard Feldman said:
we could do it now yeah. I was thinking just a number after the module keyword, e.g.
app 0.1.0-RC1 { # ...package 0.1.0 { # ...platform 0.1.1 { # ...
I do wonder if it would be nicer to have it between the {}, e.g.:
## Read native and UTF-8 environment variables.
app [main!] {
pf: platform "https://github.com/roc-lang/basic-cli/releases/download/0.21.0-rc4/FvCh4vdqm3nBY6DWEfZ8RuGCVfjuMY43HA8KSNk9qVDn.tar.zst",
roc: "0.1.0"
}
import pf.OsStr
import pf.Stdout
import pf.Env
main! : List(OsStr) => Try({}, _)
main! = |_args| {
editor = Env.var!("EDITOR")?
Stdout.line!("Your favorite editor is ${editor.display()}!")?
...
I'm not sure whether it saves any effort or makes anything more natural, but to just throw the idea in, could it make sense to have a roc init or roc new to setup a template? For instance roc init would by default create an application module with the pf commented out (for echo platform) and roc: <current-version>. You might also supply --platform <platform-url> etc.
Going further, perhaps if you specify the platform it could template out the required entrypoints.
But to bring back to the point under question, it might help remove the noise for a beginner (especially/particularly if the required details expand beyond just the roc version).
We've talked about roc init before
Is the idea that the roc compiler will ensure the version number information remains true?
Consider the following scenario:
main.roc I set to 1.0.01.2.0. I don't change the version number in main.roc, I'm still compatible with 1.0.01.2.0-introduced Roc feature. I don't know I'm doing this so don't think to change the version number in main.roc.When I try to compile my project with the 1.2.0 compiler after that third step, will it show me an error saying I need to bump the compiler version in main.roc?
we could do that :+1:
for major and minor versions although not patch
we can't really be like "you rely on this bug having been fixed" I don't think :smile:
Do we want to support ranges in that case, like Pythons requires-python property in pyproject.toml then? Or is that not relevant for Roc? E.g.
app [main!] {
pf: ...
roc: ">=1.1.0, <1.3.0"
I definitely never want to do upper version bounds on anything
minimum only
Anton said:
I've talked before about specifying the Roc version in the main.roc file, so people know which version your code is guaranteed to work with. Given the amount of breaking changes we're making these days, it seems like the time has come for us to implement this. What do you think?
Sorry to jump in late, but I really like this idea. It seems like there are myriad examples where modern file formats (parquet, vortex) are explicit about including version numbers from the start, which gives them the flexibility to make updates when new, good ideas come along.
The other thing that seems to be in vogue (and for good reason) are "editions". It seems like new projects are using editions to positive effect (vortex again, protobuf, Rust) to guarantee, as the Rust documentation states, "stability with stagnation". Perhaps that could be something that is also useful for Roc? (I hope that these comments are helpful -- I apologize if they aren't!)
Jonathan said:
I'm not sure whether it saves any effort or makes anything more natural, but to just throw the idea in, could it make sense to have a
roc initorroc newto setup a template? For instanceroc initwould by default create an application module with thepfcommented out (for echo platform) androc: <current-version>. You might also supply--platform <platform-url>etc.
I like the idea to have roc be able to help. It looks like go is doing something similar with their modernizers as part of go fix.
Anton said:
people know which version your code is guaranteed to work with. Given the amount of breaking changes we're making these days, it seems like the time has come for us to implement this. What do you think?
I am concerned this may not help us much.
When I experience breaking changes recently, the sequence is typically something like ... go to make an app and realise the platform is now broken, go to update the platform and realise dependency X is now broken, then go to update dependency X and realise dependency Y is broken etc down the rabbit hole. I can fix all of those things but it usually takes me 4-5 hours before I'm back at the original task I set out to do.
So my concern with this proposal is that we may be limited by updating to the latest version of our dependencies which may be quite a way behind -- or coordinating between multiple versions of dependencies etc.
I've mitigated against this somewhat by minimising the number of dependencies... but that kind of works against the cross-platform packages design we had.
I am concerned this may not help us much.
There is less value when the dependency tree is bigger but for lots of cases people just have the platform as dependency so there it's valuable. For exercism it is feasible to sync all dependencies to one version and I think that makes for a nice experience.
I am going to start on a first opt-in version of this idea.
Anton said:
I am going to start on a first opt-in version of this idea.
Merged in PR#10521
Last updated: Aug 12 2026 at 12:35 UTC