import strutils
let colors = ["red", "green"]
for id,color in colors:
echo color & $id # Works - Q. is it a string?
echo $id & color # Error - type mismatch: got (proc(x:varargs[expr]){.gcsafe,locks:0.},range 0..1(int))
echo "" & $id & color # Works - Q. is it a string?
As as a noob my assumption is that it's an issue with precedence (infix/prefix)?
Also I wanted to know the magic behind macros and strings. I have hard time finding what macros accept as parameters and what conversions happen to them? So as I understand nim does some magic to convert strings to NimNode (?). Can someone please tell me why the following does not work.
import strutils, macros
let colors = ["red", "green"]
macro someMacro(str: string): stmt =
result = parseStmt("proc $1() = echo \"$1\"" % $str)
someMacro("someColor") # Works fine
someMacro("some" & "Color") # Error - unhandled exception: false invalid node kind nnkInfix for macros.`$`
for id, color in colors:
someMacro(color) # Error - redefinition of color (does color literally converts into string?)
someMacro(color & "s") # Error - unhandled exception: false invalid node kind nnkInfix for macros.`$`
Sorry for my noobish questions and thank you for your time!
As as a noob my assumption is that it's an issue with precedence (infix/prefix)?
Yes, the $ causes a problem with echo and gets parsed as
`$`(echo, id) & color
So you have to use brackets:
echo($id & color)
Luckily you don't actually need $ with echo as it takes a variable number of arguments and automatically applies $ to all of them:
echo id, color
Macros can be a bit confusing as they do take Nim statements and expressions (aka NimNodes) as arguments. You can print the AST of some piece of code with dumpTree. Specifying the macro as macro someMacro(str: static[string]): stmt works for the first issue, but not the second, as the compiler doesn't know that it could unroll the for loop at compile time. You could instead move all your code inside the macro or a compile time proc:
import strutils, macros
const colors = ["red", "green"]
proc makeProc(str: string): NimNode {.compiletime.} =
parseStmt "proc $1 = echo \"$1\"" % str
macro someMacro: stmt =
result = newStmtList()
result.add makeProc("someColor")
result.add makeProc("some" & "Color2")
for id, color in colors:
result.add makeProc(color)
result.add makeProc(color & "s")
someMacro()