They allow rewriting a field access or field assignment call to the `Action` type to something else, there is more detail in the manual: [https://nim-lang.org/docs/manual_experimental.html#special-operators-dot-operators](https://nim-lang.org/docs/manual_experimental.html#special-operators-dot-operators).
In the example I'm using the template to instead access a properties json field and make those access/assignments feel seamless. There is a remaining issue that the type returned is a `JsonNode` so in practice you would need: a.new_name.getStr() # extract the string from the JsonNode a.algo.getInt() # extract the int from the JsonNode Run If you want truly seamless calls without the need of `getStr` you would need something like the following, note the doAssert on the return type to make sure we don't get JsonNodes, and we don't need the . experimental template either: import json type Action = ref object properties: JsonNode template addPseudoField(A: typedesc, field: untyped, T: typedesc) = # A is for the type namespace (Action) template getType(args: varargs[untyped]): untyped = # Alias the JsonNode getType function when T is string: getStr(args) elif T is int: getInt(args) elif T is bool: getBool(args) elif T is float: getFloat(args) else: # You can add your own type special marshaller/deserializer raise newException(ValueError, "Unsupported type: " & $T) proc `field`*(a: A): T = a.properties[astToStr(field)].getType() proc `field=`*(a: A, val: T) = a.properties[astToStr(field)] = %val Action.addPseudoField(layer, int) Action.addPseudoField(add, bool) Action.addPseudoField(vis, bool) Action.addPseudoField(new_name, string) Action.addPseudoField(algo, int) var a = Action( properties: %*{ "layer": 0, "add": true, "vis": false, "new_name": "fancy_name" } ) echo a.new_name # "fancy_name" a.algo = 10 echo a.algo # 10 doAssert a.algo is int doAssert a.new_name is string Run