Many data structures in the standard library have immutable and mutable accessor procs and iterators. See the tables module for example:
proc `[]`[A, B](t: Table[A, B]; key: A): B
proc mget[A, B](t: var Table[A, B]; key: A): var B
iterator pairs[A, B](t: Table[A, B]): tuple[key: A, val: B]
iterator mpairs[A, B](t: var Table[A, B]): tuple[key: A, val: var B]
iterator values[A, B](t: Table[A, B]): B
iterator mvalues[A, B](t: var Table[A, B]): var B
It seems that people stumble upon this rather often, wondering why they can't manipulate the returned values when using foo[x].bar[y] = z or for x in someSeq: (items).
I suggest to replace the immutable versions with the mutable ones. An argument against this could be that you would not have to explicitly state the intent to manipulate the values anymore. If this won't be done, I think renaming the prefix m to var would at least make the intention of these procs and iterators cleaner.
Indeed, that would be great. In other languages (libraries) accessors return references, which is fairly reasonable.
E.g. http://www.cplusplus.com/reference/map/map/operator[]/
However, is there a way to achieve this in Nim at all? I just tried writing this piece of code:
type
Num = object
x: int
proc get(n: var Num): var int = n.x
proc get(n: Num): int = n.x
var n = Num(x: 7)
echo get(n)
Compiler output:
Error: ambiguous call; both my.get(n: var Num): var int and my.get(n: Num): int match for: (Num)
Hmmm. I'd expect the compiler to simply use the non-var version if possible, otherwise the other one. What's prohibiting the compiler from doing this kind of reasoning? I'd love to learn more about the issue.