templates.txt 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499
  1. Templates
  2. =========
  3. A template is a simple form of a macro: It is a simple substitution
  4. mechanism that operates on Nim's abstract syntax trees. It is processed in
  5. the semantic pass of the compiler.
  6. The syntax to *invoke* a template is the same as calling a procedure.
  7. Example:
  8. .. code-block:: nim
  9. template `!=` (a, b: untyped): untyped =
  10. # this definition exists in the System module
  11. not (a == b)
  12. assert(5 != 6) # the compiler rewrites that to: assert(not (5 == 6))
  13. The ``!=``, ``>``, ``>=``, ``in``, ``notin``, ``isnot`` operators are in fact
  14. templates:
  15. | ``a > b`` is transformed into ``b < a``.
  16. | ``a in b`` is transformed into ``contains(b, a)``.
  17. | ``notin`` and ``isnot`` have the obvious meanings.
  18. The "types" of templates can be the symbols ``untyped``,
  19. ``typed`` or ``typedesc`` (stands for *type
  20. description*). These are "meta types", they can only be used in certain
  21. contexts. Real types can be used too; this implies that ``typed`` expressions
  22. are expected.
  23. Typed vs untyped parameters
  24. ---------------------------
  25. An ``untyped`` parameter means that symbol lookups and type resolution is not
  26. performed before the expression is passed to the template. This means that for
  27. example *undeclared* identifiers can be passed to the template:
  28. .. code-block:: nim
  29. template declareInt(x: untyped) =
  30. var x: int
  31. declareInt(x) # valid
  32. x = 3
  33. .. code-block:: nim
  34. template declareInt(x: typed) =
  35. var x: int
  36. declareInt(x) # invalid, because x has not been declared and so has no type
  37. A template where every parameter is ``untyped`` is called an `immediate`:idx:
  38. template. For historical reasons templates can be explicitly annotated with
  39. an ``immediate`` pragma and then these templates do not take part in
  40. overloading resolution and the parameters' types are *ignored* by the
  41. compiler. Explicit immediate templates are now deprecated.
  42. **Note**: For historical reasons ``stmt`` is an alias for ``typed`` and
  43. ``expr`` an alias for ``untyped``, but new code should use the newer,
  44. clearer names.
  45. Passing a code block to a template
  46. ----------------------------------
  47. You can pass a block of statements as a last parameter to a template via a
  48. special ``:`` syntax:
  49. .. code-block:: nim
  50. template withFile(f, fn, mode, actions: untyped): untyped =
  51. var f: File
  52. if open(f, fn, mode):
  53. try:
  54. actions
  55. finally:
  56. close(f)
  57. else:
  58. quit("cannot open: " & fn)
  59. withFile(txt, "ttempl3.txt", fmWrite):
  60. txt.writeLine("line 1")
  61. txt.writeLine("line 2")
  62. In the example the two ``writeLine`` statements are bound to the ``actions``
  63. parameter.
  64. Usually to pass a block of code to a template the parameter that accepts
  65. the block needs to be of type ``untyped``. Because symbol lookups are then
  66. delayed until template instantiation time:
  67. .. code-block:: nim
  68. template t(body: typed) =
  69. block:
  70. body
  71. t:
  72. var i = 1
  73. echo i
  74. t:
  75. var i = 2 # fails with 'attempt to redeclare i'
  76. echo i
  77. The above code fails with the mysterious error message that ``i`` has already
  78. been declared. The reason for this is that the ``var i = ...`` bodies need to
  79. be type-checked before they are passed to the ``body`` parameter and type
  80. checking in Nim implies symbol lookups. For the symbol lookups to succeed
  81. ``i`` needs to be added to the current (i.e. outer) scope. After type checking
  82. these additions to the symbol table are not rolled back (for better or worse).
  83. The same code works with ``untyped`` as the passed body is not required to be
  84. type-checked:
  85. .. code-block:: nim
  86. template t(body: untyped) =
  87. block:
  88. body
  89. t:
  90. var i = 1
  91. echo i
  92. t:
  93. var i = 2 # compiles
  94. echo i
  95. Varargs of untyped
  96. ------------------
  97. In addition to the ``untyped`` meta-type that prevents type checking there is
  98. also ``varargs[untyped]`` so that not even the number of parameters is fixed:
  99. .. code-block:: nim
  100. template hideIdentifiers(x: varargs[untyped]) = discard
  101. hideIdentifiers(undeclared1, undeclared2)
  102. However, since a template cannot iterate over varargs, this feature is
  103. generally much more useful for macros.
  104. **Note**: For historical reasons ``varargs[expr]`` is not equivalent
  105. to ``varargs[untyped]``.
  106. Symbol binding in templates
  107. ---------------------------
  108. A template is a `hygienic`:idx: macro and so opens a new scope. Most symbols are
  109. bound from the definition scope of the template:
  110. .. code-block:: nim
  111. # Module A
  112. var
  113. lastId = 0
  114. template genId*: untyped =
  115. inc(lastId)
  116. lastId
  117. .. code-block:: nim
  118. # Module B
  119. import A
  120. echo genId() # Works as 'lastId' has been bound in 'genId's defining scope
  121. As in generics symbol binding can be influenced via ``mixin`` or ``bind``
  122. statements.
  123. Identifier construction
  124. -----------------------
  125. In templates identifiers can be constructed with the backticks notation:
  126. .. code-block:: nim
  127. template typedef(name: untyped, typ: typedesc) =
  128. type
  129. `T name`* {.inject.} = typ
  130. `P name`* {.inject.} = ref `T name`
  131. typedef(myint, int)
  132. var x: PMyInt
  133. In the example ``name`` is instantiated with ``myint``, so \`T name\` becomes
  134. ``Tmyint``.
  135. Lookup rules for template parameters
  136. ------------------------------------
  137. A parameter ``p`` in a template is even substituted in the expression ``x.p``.
  138. Thus template arguments can be used as field names and a global symbol can be
  139. shadowed by the same argument name even when fully qualified:
  140. .. code-block:: nim
  141. # module 'm'
  142. type
  143. Lev = enum
  144. levA, levB
  145. var abclev = levB
  146. template tstLev(abclev: Lev) =
  147. echo abclev, " ", m.abclev
  148. tstLev(levA)
  149. # produces: 'levA levA'
  150. But the global symbol can properly be captured by a ``bind`` statement:
  151. .. code-block:: nim
  152. # module 'm'
  153. type
  154. Lev = enum
  155. levA, levB
  156. var abclev = levB
  157. template tstLev(abclev: Lev) =
  158. bind m.abclev
  159. echo abclev, " ", m.abclev
  160. tstLev(levA)
  161. # produces: 'levA levB'
  162. Hygiene in templates
  163. --------------------
  164. Per default templates are `hygienic`:idx:\: Local identifiers declared in a
  165. template cannot be accessed in the instantiation context:
  166. .. code-block:: nim
  167. template newException*(exceptn: typedesc, message: string): untyped =
  168. var
  169. e: ref exceptn # e is implicitly gensym'ed here
  170. new(e)
  171. e.msg = message
  172. e
  173. # so this works:
  174. let e = "message"
  175. raise newException(EIO, e)
  176. Whether a symbol that is declared in a template is exposed to the instantiation
  177. scope is controlled by the `inject`:idx: and `gensym`:idx: pragmas: gensym'ed
  178. symbols are not exposed but inject'ed are.
  179. The default for symbols of entity ``type``, ``var``, ``let`` and ``const``
  180. is ``gensym`` and for ``proc``, ``iterator``, ``converter``, ``template``,
  181. ``macro`` is ``inject``. However, if the name of the entity is passed as a
  182. template parameter, it is an inject'ed symbol:
  183. .. code-block:: nim
  184. template withFile(f, fn, mode: untyped, actions: untyped): untyped =
  185. block:
  186. var f: File # since 'f' is a template param, it's injected implicitly
  187. ...
  188. withFile(txt, "ttempl3.txt", fmWrite):
  189. txt.writeLine("line 1")
  190. txt.writeLine("line 2")
  191. The ``inject`` and ``gensym`` pragmas are second class annotations; they have
  192. no semantics outside of a template definition and cannot be abstracted over:
  193. .. code-block:: nim
  194. {.pragma myInject: inject.}
  195. template t() =
  196. var x {.myInject.}: int # does NOT work
  197. To get rid of hygiene in templates, one can use the `dirty`:idx: pragma for
  198. a template. ``inject`` and ``gensym`` have no effect in ``dirty`` templates.
  199. Limitations of the method call syntax
  200. -------------------------------------
  201. The expression ``x`` in ``x.f`` needs to be semantically checked (that means
  202. symbol lookup and type checking) before it can be decided that it needs to be
  203. rewritten to ``f(x)``. Therefore the dot syntax has some limiations when it
  204. is used to invoke templates/macros:
  205. .. code-block:: nim
  206. template declareVar(name: untyped) =
  207. const name {.inject.} = 45
  208. # Doesn't compile:
  209. unknownIdentifier.declareVar
  210. Another common example is this:
  211. .. code-block:: nim
  212. from sequtils import toSeq
  213. iterator something: string =
  214. yield "Hello"
  215. yield "World"
  216. var info = toSeq(something())
  217. The problem here is that the compiler already decided that ``something()`` as
  218. an iterator is not callable in this context before ``toSeq`` gets its
  219. chance to convert it into a sequence.
  220. Macros
  221. ======
  222. A macro is a special kind of low level template. Macros can be used
  223. to implement `domain specific languages`:idx:.
  224. While macros enable advanced compile-time code transformations, they
  225. cannot change Nim's syntax. However, this is no real restriction because
  226. Nim's syntax is flexible enough anyway.
  227. To write macros, one needs to know how the Nim concrete syntax is converted
  228. to an abstract syntax tree.
  229. There are two ways to invoke a macro:
  230. (1) invoking a macro like a procedure call (`expression macros`)
  231. (2) invoking a macro with the special ``macrostmt`` syntax (`statement macros`)
  232. Expression Macros
  233. -----------------
  234. The following example implements a powerful ``debug`` command that accepts a
  235. variable number of arguments:
  236. .. code-block:: nim
  237. # to work with Nim syntax trees, we need an API that is defined in the
  238. # ``macros`` module:
  239. import macros
  240. macro debug(n: varargs[untyped]): untyped =
  241. # `n` is a Nim AST that contains the whole macro invocation
  242. # this macro returns a list of statements:
  243. result = newNimNode(nnkStmtList, n)
  244. # iterate over any argument that is passed to this macro:
  245. for i in 0..n.len-1:
  246. # add a call to the statement list that writes the expression;
  247. # `toStrLit` converts an AST to its string representation:
  248. add(result, newCall("write", newIdentNode("stdout"), toStrLit(n[i])))
  249. # add a call to the statement list that writes ": "
  250. add(result, newCall("write", newIdentNode("stdout"), newStrLitNode(": ")))
  251. # add a call to the statement list that writes the expressions value:
  252. add(result, newCall("writeLine", newIdentNode("stdout"), n[i]))
  253. var
  254. a: array [0..10, int]
  255. x = "some string"
  256. a[0] = 42
  257. a[1] = 45
  258. debug(a[0], a[1], x)
  259. The macro call expands to:
  260. .. code-block:: nim
  261. write(stdout, "a[0]")
  262. write(stdout, ": ")
  263. writeLine(stdout, a[0])
  264. write(stdout, "a[1]")
  265. write(stdout, ": ")
  266. writeLine(stdout, a[1])
  267. write(stdout, "x")
  268. write(stdout, ": ")
  269. writeLine(stdout, x)
  270. Arguments that are passed to a ``varargs`` parameter are wrapped in an array
  271. constructor expression. This is why ``debug`` iterates over all of ``n``'s
  272. children.
  273. BindSym
  274. -------
  275. The above ``debug`` macro relies on the fact that ``write``, ``writeLine`` and
  276. ``stdout`` are declared in the system module and thus visible in the
  277. instantiating context. There is a way to use bound identifiers
  278. (aka `symbols`:idx:) instead of using unbound identifiers. The ``bindSym``
  279. builtin can be used for that:
  280. .. code-block:: nim
  281. import macros
  282. macro debug(n: varargs[typed]): untyped =
  283. result = newNimNode(nnkStmtList, n)
  284. for x in n:
  285. # we can bind symbols in scope via 'bindSym':
  286. add(result, newCall(bindSym"write", bindSym"stdout", toStrLit(x)))
  287. add(result, newCall(bindSym"write", bindSym"stdout", newStrLitNode(": ")))
  288. add(result, newCall(bindSym"writeLine", bindSym"stdout", x))
  289. var
  290. a: array [0..10, int]
  291. x = "some string"
  292. a[0] = 42
  293. a[1] = 45
  294. debug(a[0], a[1], x)
  295. The macro call expands to:
  296. .. code-block:: nim
  297. write(stdout, "a[0]")
  298. write(stdout, ": ")
  299. writeLine(stdout, a[0])
  300. write(stdout, "a[1]")
  301. write(stdout, ": ")
  302. writeLine(stdout, a[1])
  303. write(stdout, "x")
  304. write(stdout, ": ")
  305. writeLine(stdout, x)
  306. However, the symbols ``write``, ``writeLine`` and ``stdout`` are already bound
  307. and are not looked up again. As the example shows, ``bindSym`` does work with
  308. overloaded symbols implicitly.
  309. Statement Macros
  310. ----------------
  311. Statement macros are defined just as expression macros. However, they are
  312. invoked by an expression following a colon.
  313. The following example outlines a macro that generates a lexical analyzer from
  314. regular expressions:
  315. .. code-block:: nim
  316. import macros
  317. macro case_token(n: untyped): untyped =
  318. # creates a lexical analyzer from regular expressions
  319. # ... (implementation is an exercise for the reader :-)
  320. discard
  321. case_token: # this colon tells the parser it is a macro statement
  322. of r"[A-Za-z_]+[A-Za-z_0-9]*":
  323. return tkIdentifier
  324. of r"0-9+":
  325. return tkInteger
  326. of r"[\+\-\*\?]+":
  327. return tkOperator
  328. else:
  329. return tkUnknown
  330. **Style note**: For code readability, it is the best idea to use the least
  331. powerful programming construct that still suffices. So the "check list" is:
  332. (1) Use an ordinary proc/iterator, if possible.
  333. (2) Else: Use a generic proc/iterator, if possible.
  334. (3) Else: Use a template, if possible.
  335. (4) Else: Use a macro.
  336. Macros as pragmas
  337. -----------------
  338. Whole routines (procs, iterators etc.) can also be passed to a template or
  339. a macro via the pragma notation:
  340. .. code-block:: nim
  341. template m(s: untyped) = discard
  342. proc p() {.m.} = discard
  343. This is a simple syntactic transformation into:
  344. .. code-block:: nim
  345. template m(s: untyped) = discard
  346. m:
  347. proc p() = discard