I am a complete novice in functional programming. Dabbled a little bit with Erlang about 10 years ago, but nothing serious.
The one thing that strikes me a strange is "variables" being part of a functional language. The name "variable" means (well, to me) that it can change or vary, the very thing functional languages avoid. Or can local ones change?
To me it would have made more sense to call "variables" for "named values" instead, or "value" or "val" for short.
I would be grateful if someone experienced could provide a rational explanation of this (to me) conundrum.
Hi Niclas,
Variables are strictly local in Roc, and they are clearly identified using the $ sign. The main goals are (1) to make it easier for programmers from imperative languages to transition to Roc, and (2) to make some things easier to code.
As someone with 40 years of imperative programming experience, I can confirm that I often struggle to find the right way to implement something the functional way. I sometimes write imperative code just to get something working, and later convert it to a functional style. I love it! I find that I need to do this less and less over time.
Importantly, since variables are local, it's still easy to reason about state, which is the main benefit of immutability.
Hope this answers your question.
So in Roc it is possible to re-assign a variable, a = a + 1 for instance?
Mathematicians go nuts over such a statement. :wink:
Yes, it is. However, the variable needs to be declared and named with a $ prefix:
var $a = 0
$a = $a + 1
Niclas Hedhman has marked this topic as resolved.
Niclas Hedhman said:
Mathematicians go nuts over such a statement. :wink:
Haha, yes they do! I guess you can look at the code as a short-hand for this:
![]()
Another Niclas, I can hardly believe it! Welcome, twin! :kissing_face:
Mathematicians go nuts over such a statement. :wink:
Computers don't always work like mathematics, and I like the fact that Roc tries to be close to how computers work. If you need a programming language for mathematics proofs, you would probably find Idris or Lean a better choice. Roc is mostly meant for writing actual apps, that users actually use in the real world. Have you seen an HTTP server in Idris? It's barely readable. On the other hand, Roc is very well suited for these kind of tasks.
A rule of thumb I'm following: only use one (or maximum two) variable. If you need more, refactor your code into a state machine or some other architecture. With one variable, a for loop is a more readable syntax for a fold or the *_loop suffixed functions. Two variables are rarely acceptable, only for exceptional cases like an $index that counts the number of iterations, or in the very rare case where something is not a function of the two values in the variables, only in one.
Also worth noting that it's not a mutable value. Variables can only be reassigned, but their contents is immutable, so it's not possible to change one field e.g. this is invalid: $user.role = "admin", but this is valid, because a new struct is assigned: $user = {..$user, role: "admin"}
LLMs tend to overuse and incorrectly use the for loop and variables, because the training datasets consist mostly of imperative languages, but these language features are not meant to be used that way.
Think of it as a readability syntax sugar, not a different way to express logic.
Last updated: Oct 15 2026 at 17:56 UTC