So final version from my first post would now look like: (I took variantp from andrea's patty and added my version of match)
template match*(t: typed, handlers: openArray): untyped = var x = ord(t.kind) handlers[x](t) message.nim import patty variantp Message: msgHit(target: string, hp: int) msgDeath(died: string) msgDayNight(isDay: bool) # normally queue var messages*: Message proc getTextHit(m: Message): string = "You hit " & m.target & " for " & $m.hp & " HP." proc getTextDeath(m: Message): string = m.died & " just died." proc getTextDayNight(m: Message): string = if m.isDay: result = "The day has just begun." else: result = "Beware! Night is coming." proc getText*(m: Message): string = match(m, [getTextHit, getTextDeath, getTextDayNight]) main.nim from message import msgDayNight, messages, getText # game time system proc informAboutDay() = messages = msgDayNight(isDay = true) # player informer proc update() = echo( getText(messages) ) when isMainModule: informAboutDay() update() Sweet. Except two things. First andrea's version is complicated and I do not understand it, so if by accident it stops working with new version of nim i am doomed. Second, I do not understand how my simple _match_ version is working, even though I wrote it and it is working... BTW: Is it possible instead of playing with AST in macros to spit just code built from strings? Like in static block i could create few lines of code which would be then compiled as rest of normal code? I know, this is wrong approach and AST is proper but still...