Is it just me or are there no constants yet in the Num module? At the moment I use Num.acos -1
for pi and Num.exp 1
for e. If not, I definitely think they should be exposed in the Num module. I am also partial to tau over pi so I wouldn't mind seeing that one in Num as well :big_smile: (rust and zig both already have it in their stdlibs as well)
definitely open to adding pi, tau, and e!
there is a bit of a design question though
for example, if the type of pi
is Frac *
(which seems like a reasonable choice to me) then what specific number do we use?
it sounds nice to store as many digits as will fit in whatever size you end up with (e.g. if you're using F32
, you get as many digits of pi as will fit in an F32
, but also if you're using F64
, you get as many digits as will fit in that) - but that means we can't implement it as a normal roc number literal
for that we'd need to get a bit fancier under the hood
which is doable, but maybe worth discussing if it's the design we want :big_smile:
Couldn't you just define it in roc? Like so:
pi : Frac *
pi = 3.1415...
Or would that not work for some reason?
I think the default Frac *
is F64
and roc will automatically convert it if used in an F32
context. So I don't see why it wouldn't work. I might be completely wrong however
I'm pretty sure you wouldnt be able to use it in multiple contexts. So you couldn't use it as an F32 in one library and as an F64 in another.
Would need to unify to one specific type
Kilian Vounckx said:
Or would that not work for some reason?
sure, it works, but if you replace the ...
with actual digits the problem becomes clearer :big_smile:
F64
, then it will overflow F32
.F32
, then it's a shorter number of digits than it could have been for F64
it's also entirely possible that nobody would miss the extra digits of precision and a number literal is fine :stuck_out_tongue:
Actually, that isn't the case. apparently this works and we just cut it shorter: 3.141592653589793238462643383279502884197169399375105820974944592f32
is that good? :sweat_smile:
that feels like a bug, although in this very specific case it's helpful haha
:thinking: I could see an argument for auto-truncating if the type is generic, e.g. Frac *
, but with f32
on the end it definitely seems like it should give an error
Idk if it is good. Just pointing it out
Either way, it doesn't solve the issue that without extra compiler magic, pi : Frac *
can't resolve to more than one type. So if a library you depend on uses pi
as F32
and you use it as F64
, it wouldn't type check. Or do we do something special with numbers? I know this is a problem with List a
.
Oh, nvm, this seems to just work with numbers.
I guess they are special already.
In programs I've written I could use numbers in different contexts differently. E.g. in a small ray tracer I could use a width variable defined as width = 400
(without type annotation) as both a Nat
and as an F64
It felt a bit like zig's comptime_int
Richard Feldman said:
that feels like a bug, although in this very specific case it's helpful haha
But you say it should be a bug? I think it is a nice feature!
Kilian Vounckx said:
Richard Feldman said:
that feels like a bug, although in this very specific case it's helpful haha
But you say it should be a bug? I think it is a nice feature!
specifically because of thef32
at the end - 3.141592653589793238462643383279502884197169399375105820974944592f32
like this is explicitly saying both "this is a number literal for an F32
" and also "this is a number literal that is too big to fit in an F32
", and in that situation I'd want the compiler to tell me "hey this number literal is too big for F32
; here's the truncated version—put that in your source code so you can actually see what you're getting at runtime"
I get what you mean
I don't know if it matters to me though. Whatever literal you put there, it will be in decimal. So it will always be rounded to fit in binary. Rounding to F32 will just cut of more. I don't think this should be an error for fractional literals
yeah it seems reasonable to auto-truncate if you don't specify a concrete type
Is something else needed than adding the literal in roc (and the symbols in rust)? If not, I would like to tackle this
Also, do we want other numbers as well? A lot of languages expose sqrt2
and others for example
I think that is all that is needed
I see this message has been there for a few days:
10 workflows awaiting approval
This workflow requires approval from a maintainer. Learn more. 8 expected checks
Is there something else that needs to be done on my side?
I approved the workflows and reviewed the PR :)
Github does not support notifications for these "workflows awaiting approval" so we need to remember to manually check.
We should make a zulip bot for that, I'll make an issue.
Oh I see. I'm glad I checked then
Thank you!
well, failing already :sweat_smile:
will check later today
I think the fix will be very similar to this one: https://github.com/roc-lang/roc/pull/5534/commits/47a78a8f249aa21b6352ddf1bf93df07f1c92b02
It was indeed a similar error. To be honest, I only ran the mono tests. If I had ran them all, I could have found the error. My bad
Thanks for the help
I updated the pr
Great, tests are running :)
What was the snap file you removed?
I saw it being added after running the tests
Is it some file that should be in gitignore?
Yeah, I put it in gitignore, it's some temporary artifact created by the snapshot tests.
Last updated: Jul 06 2025 at 12:14 UTC