this is a weird concept but i just tried it and it works.
type
MachineID* = uint64
ParameterID* = int
Machine* = ref object
MachineParameterWindow* = distinct Machine
func parameters*(self: Machine): MachineParameterWindow =
return cast[MachineParameterWindow](self)
func `[]=`*(self: MachineParameterWindow; parameter, voltage: int) =
## Assign a parameter which applies to the whole machine.
discard # TODO
func `[]=`*(self: MachineParameterWindow; channel, parameter, voltage: int) =
## Assign a parameter which applies to a particular note track of the machine.
discard # TODO
it allows you to write code like machine.parameters[7] = ... and i suspect there are some other fun forms of abuse for this. i don't know if i'm actually going to keep this because it seems weird but its amazing that you can get away with it.
Anything that helps productivity like this is a good thing. But you should really be doing
template parameters*(self: Machine): MachineParameterWindow =
MachineParameterWindow(self)
to better represent that it's only a syntactical mechanism. cast instead of a direct conversion here might not be elided by the compiler and might perform a runtime operation, so it's better to use direct conversion here.