I try use the `var` `let` and `mut` to test some scenario. First, we define the meaning of these terms(all for ref T type). 1\. `let` means fixed readonly variable binding, parameter without `var` means `let` binding proc p1() = let x = Node() x.left = nil # invalid change value x = Node() # invalid change variable binding proc p2(x: Node) = x.left = nil # invalid change value x = Node() # invalid change variable binding Run
> 2\. `var` means mutable variable binding, we can change the value, and we can > change the variable binding if it is local variable; we cannot change the > variable binding if it is parameter, so the compiler needn't pass pointer of > pointer to caller. proc p1() = var x = Node() x.left = nil # valid x = Node() # valid proc p2(x: var Node) = x.left = nil # valid x = Node() # invalid change variable binding Run > 3\. `mut` means the variable binding can be changed only, it can be used with > `let` and `var` in parameter. proc p1() = let mut x = Node() x.left = nil # invalid change value x = Node() # valid # it can be used to traverse the graph or list proc traverse(n: Node) = let mut x = n # valid while not x.isNil: x = x.right # valid proc p2(x: mut Node) = x.left = nil # invalid x = Node() # valid proc p3(x: var mut Node) = x.left = nil # valid x = Node() # valid Run To make rule simple and clear, readonly variable cannot be assigned to any `var` variable or field. proc p1(v1: Node) = let v2 = Node() var x = Node() x = v1 # invalid x.left = v2 # invalid Run Sometime we need assign a readonly variable to `var` variable, we introduce `{.mut.}` pragma, suppose the programmer know what he is doing(With ptr he can do anything). proc p1(v1: Node) = var cache {.mut.} : seq[Node] = @[] cache.add v1 # valid, with {.mut.}, it can hold readonly variable var x {.mut.} = v1 # valid Run Sometime we need to build immutable object with constructor or builder, we can introduce `{.cons.}` pragma, which means the proc `result` value can hold readonly object. proc createNode(ll, rr: Node): Node {.cons.} = result = Node() result.left = ll # valid result.right = rr # valid Run