I order const and let according to the distinctive use case. When something does change, let and for things who persist all the same, const.
I think it is a good idea, to check (optionally?) if each let interacts in that way, or if let could also be changed into a const.
I think that way, it is easy to see what does what. Someone new to the code can rely on the keyword, to know if it is potentially changing at runtime.
If that is a stupid idea, just tell me, I am new to programming.
if you want to roll your own,
import macros
type MaybeStatic[T] = static[T] | T
template constLet[T](id:untyped, v:MaybeStatic[T]) =
when v is static:
const id = v
else:
let id = v
proc f(x:MaybeStatic[int]) =
constLet(y,x)
expandMacros:
echo y
f(3)
var x = 2
f(x)
Alternatively to nimpretty or nimsuggest, there could be a diagnostic message letting code authors just change var to let or let to const as they think most helps clarity and their plans for code evolution.
E.g., var-ness unused or run-time-ness unused. I suspect this is the sort of thing being asked for.
Maybe better messages would be "var could be let" or "let could be const" (or I guess the more rare "var could be const"...). Maybe such exists already..I didn't look.
When something does potentially change, I use let
I don't understand. A let binding cannot change; that's what distinguishes it from var. The difference between let and const is that the latter is evaluated at compile time.
I think you mean that the value could be different each time the let is evaluated? In which case we're saying the same thing — it's evaluated at runtime, not compile time.
(When something like let x = .... appears in a proc, there isn't a single variable x whose value changes. Instead, each call to that proc creates a new local variable x with a single immutable value, and x disappears when the proc exits. It's called "lexical scoping". This may not seem like a big distinction, but it is. Some early languages like LISP 1.x did things the way you describe, but it turns out to cause a lot of problems with recursive functions, closures, etc.)
It may partially be the language barrier, but your comments are incoherent. You could replace every const with let and it wouldn't affect program behavior unless the variable is used in a when or {.compiletime.} context. And you could replace every let with const as long as the initializer can be computed at compile time. That's the difference ... neither let nor const values can ever change.
I mean that let can, as an example, read input.
This is a true fact, but it doesn't help to explain what you mean. And const can also read input, at compile time, via staticRead.
The value itself stays the same, but its usage changes.
This does not help explain anything ... it's not at all clear what you mean by "usage".
Const will always be used in the same, predictable way, let can be used in unpredictable ways.
This too does not help to explain anything ... the predictability of how something is used is determined by control flow, not by whether the value was determined at compile time or at runtime.
Yeah, its the language barrier, although all the people involved in this thread already got the idea right, also cblake.
I understand that there are details to the implementation who change the meaning of those things, while I try to keep it simple and understand those things on a practical side.
To me, const was always meant to be used for things who represent something like a physical constant, while let is more supposed to change its meaning interactivity, and since that, evaluated at runtime.
I did try to make sense of his ideas in those diagnostic ways
Yeah, sorry, I seem to have missed your comment earlier.
To me, const was always meant to be used for things who represent something like a physical constant
That's just one usage. In a language like Nim, which takes compile-time dynamism to the max, you need a broader view. People write macros that generate consts that are computed, possibly from external files.