Consider the following code to create linked list-like structure: type A = ref AObj AObj = object id: int parent: A child: A proc `$`(a: A): string = $a.id proc takeAsVar(curr: var A, next: A) = if curr == nil: curr = next # var A is wanted here and nowhere else else: let const_curr = curr echo "takeAsVar: curr before: ", curr curr.parent.child = next # Try changing curr to const_curr for same result echo "takeAsVar: curr after: ", curr # curr changes even though there is no "curr = ..." line. proc takeAsConst(curr: A, next: A) = if curr == nil: #curr = next # can't do this discard else: echo "takeAsConst: curr before: ", curr curr.parent.child = next echo "takeAsConst: curr after: ", curr let a1 = A(id: 1, parent: nil, child: nil) let a2 = A(id: 2, parent: nil, child: nil) let a3 = A(id: 3, parent: nil, child: nil) a1.child = a2 a2.parent = a1 takeAsVar(a1.child, a3) let a4 = A(id: 4, parent: nil, child: nil) let a5 = A(id: 5, parent: nil, child: nil) let a6 = A(id: 6, parent: nil, child: nil) a4.child = a5 a5.parent = a4 takeAsConst(a4.child, a6) # Works as expected
which outputs takeAsVar: curr before: 2 takeAsVar: curr after: 3 takeAsConst: curr before: 5 takeAsConst: curr after: 5 Notice how the value of the variable curr changes in the first proc without an explicit curr = .... We have a very simple object with a parent pointer and a child pointer. My initial goal was to create a linked list-like structure and inserting into a nil list could be handled by taking the original list by var since it allows for curr = next. Most of the logic for non-nil list has been removed to get a minimum working example, but the problem is this: When I want to change the child field of the parent of curr, then the variable curr itself is changed when taken by var. In my mind taking a parameter by var would only change whether you can write curr = ... and change the original or not. Here it seems that it somehow infers that curr.parent.child is the same as curr and changes curr as well. Have I misunderstood how var parameters work? Is this desired behaviour? Using version 0.16.1 (git hash: 137b5f43022c3c5e22a7f28c8012f1d0ea6007c6)