summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--doc/manual/generics.txt31
-rw-r--r--lib/system.nim11
2 files changed, 36 insertions, 6 deletions
diff --git a/doc/manual/generics.txt b/doc/manual/generics.txt
index d0a60b62a..bb5d0ab2c 100644
--- a/doc/manual/generics.txt
+++ b/doc/manual/generics.txt
@@ -116,7 +116,8 @@ type class           matches
 ``array``            any array type
 ``set``              any set type
 ``seq``              any seq type
-``any``              any type
+``auto``             any type
+``any``              distinct auto (see below)
 ==================   ===================================================
 
 Furthermore, every generic type automatically creates a type class of the same
@@ -196,6 +197,9 @@ supply all type parameters of the generic type, because any missing ones will
 be inferred to have the equivalent of the `any` type class and thus they will
 match anything without discrimination.
 
+To help you write more concise implicitly generic procs, the Nim's system
+module includes the named types `T1` through `T9` which are bind once aliases
+of the `auto` type.
 
 Concepts
 --------
@@ -273,7 +277,7 @@ value that will be matched only as a type.
 Please note that the ``is`` operator allows one to easily verify the precise
 type signatures of the required operations, but since type inference and
 default parameters are still applied in the concept body, it's also possible
-to encode usage protocols that do not reveal implementation details.
+to describe usage protocols that do not reveal implementation details.
 
 Much like generics, concepts are instantiated exactly once for each tested type
 and any static code included within the body is executed only once.
@@ -378,8 +382,8 @@ operator and also when types dependent on them are being matched:
 
 .. code-block:: nim
   type
-    MyConcept[M, N: static[int]; T] = concept x
-      x.foo(SquareMatrix[N, T]) is array[M, int]
+    MatrixReducer[M, N: static[int]; T] = concept x
+      x.reduce(SquareMatrix[N, T]) is array[M, int]
 
 The Nim compiler includes a simple linear equation solver, allowing it to
 infer static params in some situations where integer arithmetic is involved.
@@ -410,7 +414,7 @@ to match several procs accepting the same wide class of types:
 
 On the other hand, using ``bind once`` types allows you to test for equivalent
 types used in multiple signatures, without actually requiring any concrete
-types, thus allowing you to encode implementation detail types:
+types, thus allowing you to encode implementation-defined types:
 
 .. code-block:: nim
   type
@@ -425,10 +429,25 @@ types, thus allowing you to encode implementation detail types:
                   # and it must be a numeric sequence
 
 As seen in the previous examples, you can refer to generic concepts such as
-Enumerable[T] just by their short name. Much like the regular generic types,
+`Enumerable[T]` just by their short name. Much like the regular generic types,
 the concept will be automatically instantiated with the bind once auto type
 in the place of each missing generic param.
 
+Please note that generic concepts such as `Enumerable[T]` can be matched
+against concrete types such as `string`. Nim doesn't require the concept
+type to have the same number of parameters as the type being matched.
+In order to express such a requirement, you'll need to rely on a type
+mapping operator such a `genericHead` or `stripGenericParams` within the
+concept body:
+
+.. code-block:: nim
+  import future, typetraits
+
+  type
+    Functor[A] = concept f
+      f.value is A
+      map(f, A -> T1) is genericHead(f.type)[T1]
+
 
 Concept derived values
 ----------------------
diff --git a/lib/system.nim b/lib/system.nim
index 94e10d7df..0e777b707 100644
--- a/lib/system.nim
+++ b/lib/system.nim
@@ -98,6 +98,17 @@ type
   SomeNumber* = SomeInteger|SomeReal
     ## type class matching all number types
 
+  T1* = auto
+  T2* = auto
+  T3* = auto
+  T4* = auto
+  T5* = auto
+  T6* = auto
+  T7* = auto
+  T8* = auto
+  T9* = auto
+    ## Helper types for writing implicitly generic procs
+
 proc defined*(x: untyped): bool {.magic: "Defined", noSideEffect, compileTime.}
   ## Special compile-time procedure that checks whether `x` is
   ## defined.