So arguably, this is just me not knowing how to write good roc/pipeline enough, but one thing I find annoying in Roc is when I have to add an extra function and it requires a set of parenthesis.
A common example is when with integer size mismatches. Here is an over extreme example of what I mean:
out = Num.shiftRightBy x y
Oh wait, x is a U64, not a Nat:
out =Num.shiftRightBy (Num.toNat x) y
Oh wait, I actually want to shift y like an I64, not a U64:
out = Num.toU64 (Num.shiftRightBy (Num.toNat x) (Num.toI64 y))
Hmm... That line looks gross, let's split it up:
x = Num.toNat x
y = Num.toI64 y
out = Num.toU64 (Num.shiftRightBy x y)
Oh wait, I can't shadow x and y in roc:
x1 = Num.toNat x
y1 = Num.toI64 y
out = Num.toU64 (Num.shiftRightBy x1 y1)
This of course gets worse as lines get longer and the parenthesis start to really add up.
Also, it is kinda annoying to need to go x1 x2 x3 if I have to modify a value multiple times. I think it makes some code much harder to read. Maybe that is some form of mutation bias. This pushes me to want more on the same line, but that leads back to the tons of parenthesis problem
I think always using the same name is also really useful to ensure that you will always enable the roc compiler to optimize to not have copies. If I only ever have access to the newest version of a variable, I can't accidentally reference an old versions.
Anyway, I don't really have a direct solution or idea, I have seen differing solutions like $ in haskell or just shadowing in general like you would see in rust.
Overall wondering what peoples thoughts are/how this could be better. Might just need to change how I write code.
My hunch is that editor will solve your problems :)
Brendan Hansknecht said:
out = Num.toU64 (Num.shiftRightBy (Num.toNat x) (Num.toI64 y))
thoughts on this?
out =
Num.toNat x
|> Num.shiftRightBy (Num.toI64 y)
|> Num.toU64
(personally that's how I'd write it!)
if x had a longer name, I'd probably go one step further:
out =
x
|> Num.toNat
|> Num.shiftRightBy (Num.toI64 y)
|> Num.toU64
but I generally think it looks kinda weird when a super short variable name is alone at the beginning of a pipe :big_smile:
out =
something
|> Num.toNat
|> Num.shiftRightBy (Num.toI64 somethingElse)
|> Num.toU64
Ok. So a lot of pipelining. That will definitely take my brain to some getting used to. Definitely more readable.
Out of curiosity, what would you do with something like this?
t0 = someCalculation
t1 =
if t0 >= range then
t0 - range
else
t0
t2 =
if t1 >= range then
modWithNonzero t1 range
else
t1
# use t2
Can the repeated version naming be made better?
At least in other languages, I tend to just give sub-expressions their own names on separate lines
I feel pipelines are better suited to single-value transformations (rather than binary operations, which feel unbalanced to me when using pipelines)
I agree, but then you have to name the sub-expressions which is part of the problem I have.
In some functions there will be a lot of these.
sometimes it works out to decompose those into smaller functions, but not always
I go out of my way to give subexpressions names that are "whatever I would put in a comment", or some reason why I'm doing the operation. Sometimes that ends up being really low-level like limited or rounded or something but reasons why are better names. I think it's valuable for debuggability / readability.
I mean, obviously that's how to name things! The point is I still like to do that even for small things like this because it helps me think through it and understand my own code.
Brendan Hansknecht said:
Out of curiosity, what would you do with something like this?
t0 = someCalculation t1 = if t0 >= range then t0 - range else t0 t2 = if t1 >= range then modWithNonzero t1 range else t1 # use t2
for this one I might extract a helper function:
ensureBelow = \num, minimum, transform ->
if num >= minimum then
transform num minimum
else
num
someCalculation
|> ensureBelow range Num.sub
|> ensureBelow range modWithNonzero
I'd assume this would end up inlining to the original
Yeah, my brain definitely does not think this way. Very interesting. Thanks!
happy to help! It took me a lot of Elm usage to learn about patterns like these :big_smile:
Last updated: Jun 16 2026 at 16:19 UTC