# foo.nim
type
Foo* = object
bar: int
proc `bar`*(f: var Foo): int {.inline.} =
f.bar
proc `bar=`*(f: var Foo, val: int) {.inline.} =
f.bar = val
# main.nim
import foo
var f: Foo
f.bar += 1
echo f.bar
Results in:
Error: type mismatch: got <int, int literal(1)>
but expected one of:
proc `+=`[T: SomeOrdinal | uint | uint64](x: var T; y: T)
for a 'var' type a variable needs to be passed, but 'bar(f)' is immutable
proc `+=`[T: float | float32 | float64](x: var T; y: T)
first type mismatch at position: 1
required type: var T: float or float32 or float64
but expression 'bar(f)' is of type: int
for a 'var' type a variable needs to be passed, but 'bar(f)' is immutable
expression: bar(f) += 1
You need to define a += proc
proc `+=`*(f: var Foo, val: int) {.inline.} =
f.bar += val
You can return var int to make it behave more like a normal field:
type
Foo* = object
bar: int
proc bar*(f: Foo): int {.inline.} =
f.bar
proc bar*(f: var Foo): var int {.inline.} =
f.bar
var f: Foo
f.bar = 1
f.bar += 2
echo f.bar
Thanks for the response, but I am still getting an error.
# foo.nim
type
Foo* = object
bar: int
proc `bar`*(f: Foo): int {.inline.} =
f.bar
proc `bar=`*(f: var Foo, val: int) {.inline.} =
f.bar = val
proc `+=`*(f: var Foo, val: int) {.inline.} =
f.bar += val
but I am still getting an error.
From the compiler error message "but expression 'bar(f)' is of type: int" we may learn that your problem is, that you have a field called bar and a proc called bar. Do you really need this combination? When you rename one, than I would assume that it works. But I can not tell you how to fix it when you really need the same name.
Basically foo.bar tries to call the proc which returns an immutable number, here is a reworked example that avoids name conflicts:
type
Foo* = object
internal_bar: int
proc `bar`*(f: Foo): int {.inline.} =
## Getter for immutable Foo
f.internal_bar
proc `bar`*(f: var Foo): var int {.inline.} =
## Getter for mutable Foo
f.internal_bar
proc `bar=`*(f: var Foo, val: int) {.inline.} =
## Setter
f.bar = val
proc `+=`*(f: var Foo, val: int) {.inline.} =
# Operand
f.bar += val
Note that getters and setters are very unidiomatic as @Stefan_Salewski said, just export the internal fields unless you have specific validation routines, pre/post-processing you need to do at each field accesses.
IMO, you don't need a separate += for Foo, if you have bar that retuns var int. It is enough to write:
type
Foo* = object
internal_bar: int
proc `bar`*(f: Foo): int {.inline.} =
## Getter for immutable Foo
f.internal_bar
proc `bar`*(f: var Foo): var int {.inline.} =
## Getter for mutable Foo
f.internal_bar
proc `bar=`*(f: var Foo, val: int) {.inline.} =
## Setter
f.internal_bar = val
var a: Foo
a.bar = 10
a.bar += 5
echo a.bar