Parameters are immutable in the procedure body. By default, their value cannot be changed because this allows the compiler to implement parameter passing in the most efficient way. If a mutable variable is needed inside the procedure, it has to be declared with var in the procedure body. Shadowing the parameter name is possible, and actually an idiom:
proc printSeq(s: seq, nprinted: int = -1) = var nprinted = if nprinted == -1: s.len else: min(nprinted, s.len) for i in 0 ..< nprinted: echo s[i]
I tested this example, but changed var to let. My code:
proc printSeq(s: seq, nprinted: int = -1) =
let nprinted = if nprinted == -1 : s.len else: min(nprinted, s.len)
for i in 0 ..< nprinted:
echo s[i]
printSeq(@['a', 'b', 'c', 'd', 'e', 'f'])
My code works fine:
(how to insert screenshot?)
So can I use let? Is document is correct there? Or it's a bit old?
Orlean.
Let creates a new variable that happens to share the name with the argument. But they are different memory locations.
This is what happens:
proc printSeq(s: seq, nprinted0: int = -1) =
let nprinted1 = if nprinted0 == -1 : s.len else: min(nprinted0, s.len)
for i in 0 ..< nprinted1:
echo s[i]
Well you quoted the correct section:
If a mutable variable is needed inside the procedure, it has to be declared with var in the procedure body.
In the example a let would also work but it would still be immutable and the tutorial tries to teach you how to get a mutable one.
This is an idiom and it can prevent bugs:
proc x(s: string) =
let s = s.toLowerAscii # cannot use the non-transformed 's' parameter by accident
use s
useAgain s