I think it's pretty easy to make a mistake like:
let myTable = initTable[int, string]()
and not realize your mistake when you try to add something to the table. The compiler error messages don't give you enough hints:
myTable[33] = "cat"
opcode.nim(64, 12) Error: type mismatch: got (Table[system.int, system.string], int, string)
but expected one of:
system.[]=(a: var array[Idx, T], x: Slice[[]=.Idx], b: openarray[T])
system.[]=(s: var string, x: Slice[system.int], b: string)
system.[]=(a: var array[Idx, T], x: Slice[system.int], b: openarray[T])
system.[]=(s: var seq[T], x: Slice[system.int], b: openarray[T])
tables.[]=(t: var CountTable[[]=.A], key: A, val: int)
tables.[]=(t: CountTableRef[[]=.A], key: A, val: int)
tables.[]=(t: var OrderedTable[[]=.A, []=.B], key: A, val: B)
tables.[]=(t: var Table[[]=.A, []=.B], key: A, val: B)
tables.[]=(t: TableRef[[]=.A, []=.B], key: A, val: B)
tables.[]=(t: OrderedTableRef[[]=.A, []=.B], key: A, val: B)
I guess a trained Nim user will see the var and quickly know what they've done. But it's not intuitive at all, especially for new users.
It would be nice if the compiler attempted to give hints on how to fix errors. In this case the compiler could output at the end: "Are one of your parameters not mutable?" or something similar.
Another nice thing might be getting the compiler to find the closest match and tell the user the differences.
I recently ran into the same problem and as a newbie couldn't see how the output was relevant to my issue. Changing the actual variable definition to "var" solved my issue.
With the above example the current (nim 0.14.2) error message is just "Error: could not resolve myTable[33]" - and that only when assigning to myTable - when reading that's OK.
I really like nim as a language and can see its potential, but as a newbie it can get a hell complicated to get it to compile correctly (and I speak with a background of a long-term C and C++ programmer).