Nice work, this closure-as-an-object pattern is quite useful in JavaScript as
an alternative to its IMHO convoluted prototype-based OO.
That being said, a syntax which retains the meaning of `*` and is more compact
might be preferable, something more like Scala's classes perhaps:
# The ``*`` means what it always means in Nim: "visible outside of the
# defining module". The arguments of the default constructor are defined in
# the class declaration itself.
class Counter*(start {.private.}: int, step: var int) of SomeBaseClass:
# ``start`` is private, so it is just a constructor argument.
# ``step`` automatically also becomes a public value symbol (see below).
# The class definition body is the default constructor body.
# Public value symbols also become class properties: vars automatically
get
# getters and setters by default, lets only getters.
# var step*: int = step <-- automatically inserted for public ctor arg.
let firstVal = start
var value* {.ro.}: int = start # read-only, no setter generated.
private:
var someSecret = 0 # No getter or setter generated for this.
proc change(op: proc(x, y: int): int) = value = op(value, step)
# Public message API.
proc inc*() = change(`+`)
proc dec*() = change(`-`)
# An alternative constructor.
ctor() = ctor(0, 1)
# The resulting public API in "concept notation" with export markers,
# c is an instance:
#
# Conter*(int, int) is Counter
# Counter() is Counter
# c.step*() is int
# c.`step=`*(int)
# c.firstVal() is int
# c.value*() is int
# c.`value=`*(int)
# c.inc*()
# c.dec*()
Run
The public/private semantics follow Nim's public-by-default object field access
rule, but it could easily be inverted to private-by-default. Nim's parser can
process this, so it could be mapped to the functionality you already
implemented.