ref is a traced pointer to "something" allocated on the heap. Usually this is an object but can be anything for real.
type A = ref int
let a = new A
echo a[] # 0, because not inited but "zeroed"
a[] = 2
echo a[] # 2
proc incA(x: A) = inc x[]
incA(a)
echo a[] # 3
You see that you need to dereference [] the ref to modify the value and the value itself is "created" with new on the heap. Normally that would be an object or tuple and not "just" an int.
See: http://nim-lang.org/docs/manual.html#types-reference-and-pointer-types
Using var for a parameter creates an invisible pointer and the data does not need to lay on the heap but still needs to be mutable.
See: http://nim-lang.org/docs/manual.html#procedures-var-parameters (and esp. the comment at the end of the section)
I hope I got that all right :)
vars with refs are a bit confusing, but with an example is easy to get:
proc exA(i: int) =
i = 0 # Doesn't compile
proc exB(i: var int) =
i = 0 # Compiles
proc exC(i: ref MyRefObject) =
i.myProp = 0 # Compiles
i = new MyRefObject() # Doesn't compile
proc exD(i: var ref MyRefObject) =
i.myProp = 0 # Compiles
i = new MyRefObject() # compiles