summary refs log tree commit diff stats
path: root/doc
diff options
context:
space:
mode:
authorAraq <rumpf_a@web.de>2012-08-22 22:46:02 +0200
committerAraq <rumpf_a@web.de>2012-08-22 22:46:02 +0200
commitf8931798899647b65ebb7d7dcf28d6976da599ce (patch)
tree0fdbd7f0b5516279458d21bf99a698cb2cb89e37 /doc
parenta95e958046447d0ef88d93337171d4b8339348a4 (diff)
downloadNim-f8931798899647b65ebb7d7dcf28d6976da599ce.tar.gz
documented hygienic templates; made tests green; fixed system.clamp
Diffstat (limited to 'doc')
-rwxr-xr-xdoc/manual.txt61
-rwxr-xr-xdoc/nimrodc.txt2
2 files changed, 59 insertions, 4 deletions
diff --git a/doc/manual.txt b/doc/manual.txt
index 813f1a5b4..07be0c492 100755
--- a/doc/manual.txt
+++ b/doc/manual.txt
@@ -2967,8 +2967,8 @@ In templates identifiers can be constructed with the backticks notation:
 

   template typedef(name: expr, typ: typeDesc) {.immediate.} = 

     type

-      `T name`* = typ

-      `P name`* = ref `T name`

+      `T name`* {.inject.} = typ

+      `P name`* {.inject.} = ref `T name`

       

   typedef(myint, int)

   var x: PMyInt

@@ -2982,7 +2982,7 @@ Lookup rules for template parameters
 
 A parameter ``p`` in a template is even substituted in the expression ``x.p``.
 Thus template arguments can be used as field names and a global symbol can be
-covered by the same argument name even when fully qualified:
+shadowed by the same argument name even when fully qualified:
 
 .. code-block:: nimrod
   # module 'm'
@@ -3017,6 +3017,61 @@ But the global symbol can properly be captured by a ``bind`` statement:
   tstLev(levA)
   # produces: 'levA levB'
 
+
+Hygiene in templates
+~~~~~~~~~~~~~~~~~~~~

+
+Per default templates are `hygienic`:idx:\: Local identifiers declared in a
+template cannot be accessed in the instantiation context:
+
+.. code-block:: nimrod
+  
+  template newException*(exceptn: typeDesc, message: string): expr =
+    var
+      e: ref exceptn  # e is implicitely gensym'ed here
+    new(e)
+    e.msg = message
+    e
+    
+  # so this works:
+  let e = "message"
+  raise newException(EIO, e)
+
+
+Whether a symbol that is declared in a template is exposed to the instantiation
+scope is controlled by the `inject`:idx: and `gensym`:idx: pragmas: gensym'ed
+symbols are not exposed but inject'ed are.
+
+The default for symbols of entity ``type``, ``var``, ``let`` and ``const``
+is ``gensym`` and for ``proc``, ``iterator``, ``converter``, ``template``,
+``macro`` is ``inject``. However, if the name of the entity is passed as a 
+template parameter, it is an inject'ed symbol:
+
+.. code-block:: nimrod
+  template withFile(f, fn, mode: expr, actions: stmt): stmt {.immediate.} =

+    block:

+      var f: TFile  # since 'f' is a template param, it's injected implicitely
+      ...
+      

+  withFile(txt, "ttempl3.txt", fmWrite):

+    txt.writeln("line 1")

+    txt.writeln("line 2")

+
+
+The ``inject`` and ``gensym`` pragmas are second class annotations; they have
+no semantics outside of a template definition and cannot be abstracted over:
+
+.. code-block:: nimrod
+  {.pragma myInject: inject.}
+  
+  template t() =
+    var x {.myInject.}: int # does NOT work
+
+
+To get rid of hygiene in templates, one can use the `dirty`:idx: pragma for
+a template. ``inject`` and ``gensym`` have no effect in ``dirty`` templates.
+
+
 

 Macros

 ------

diff --git a/doc/nimrodc.txt b/doc/nimrodc.txt
index 98e1b96d8..7b969c3bb 100755
--- a/doc/nimrodc.txt
+++ b/doc/nimrodc.txt
@@ -487,7 +487,7 @@ objects as `shallow`:idx:\:
 .. code-block:: Nimrod

   var s = "abc"

   shallow(s) # mark 's' as shallow string

-  var x = s  # now might does not copy the string!

+  var x = s  # now might not copy the string!

   

 Usage of ``shallow`` is always safe once you know the string won't be modified

 anymore, similar to Ruby's `freeze`:idx:.