manual: cleanup the type/typedesc confusions, typedesc is here to stay for good
This commit is contained in:
parent
33a370866c
commit
135f867870
1 changed files with 20 additions and 20 deletions
|
|
@ -2357,7 +2357,7 @@ argument's resolution:
|
||||||
rem unresolvedExpression(undeclaredIdentifier)
|
rem unresolvedExpression(undeclaredIdentifier)
|
||||||
|
|
||||||
``untyped`` and ``varargs[untyped]`` are the only metatype that are lazy in this sense, the other
|
``untyped`` and ``varargs[untyped]`` are the only metatype that are lazy in this sense, the other
|
||||||
metatypes ``typed`` and ``type`` are not lazy.
|
metatypes ``typed`` and ``typedesc`` are not lazy.
|
||||||
|
|
||||||
|
|
||||||
Varargs matching
|
Varargs matching
|
||||||
|
|
@ -4434,7 +4434,7 @@ templates:
|
||||||
| ``notin`` and ``isnot`` have the obvious meanings.
|
| ``notin`` and ``isnot`` have the obvious meanings.
|
||||||
|
|
||||||
The "types" of templates can be the symbols ``untyped``,
|
The "types" of templates can be the symbols ``untyped``,
|
||||||
``typed`` or ``type``. These are "meta types", they can only be used in certain
|
``typed`` or ``typedesc``. These are "meta types", they can only be used in certain
|
||||||
contexts. Regular types can be used too; this implies that ``typed`` expressions
|
contexts. Regular types can be used too; this implies that ``typed`` expressions
|
||||||
are expected.
|
are expected.
|
||||||
|
|
||||||
|
|
@ -4598,7 +4598,7 @@ In templates identifiers can be constructed with the backticks notation:
|
||||||
.. code-block:: nim
|
.. code-block:: nim
|
||||||
:test: "nim c $1"
|
:test: "nim c $1"
|
||||||
|
|
||||||
template typedef(name: untyped, typ: type) =
|
template typedef(name: untyped, typ: typedesc) =
|
||||||
type
|
type
|
||||||
`T name`* {.inject.} = typ
|
`T name`* {.inject.} = typ
|
||||||
`P name`* {.inject.} = ref `T name`
|
`P name`* {.inject.} = ref `T name`
|
||||||
|
|
@ -4660,7 +4660,7 @@ template cannot be accessed in the instantiation context:
|
||||||
.. code-block:: nim
|
.. code-block:: nim
|
||||||
:test: "nim c $1"
|
:test: "nim c $1"
|
||||||
|
|
||||||
template newException*(exceptn: type, message: string): untyped =
|
template newException*(exceptn: typedesc, message: string): untyped =
|
||||||
var
|
var
|
||||||
e: ref exceptn # e is implicitly gensym'ed here
|
e: ref exceptn # e is implicitly gensym'ed here
|
||||||
new(e)
|
new(e)
|
||||||
|
|
@ -5095,27 +5095,26 @@ expression by coercing it to a corresponding ``static`` type:
|
||||||
The complier will report any failure to evaluate the expression or a
|
The complier will report any failure to evaluate the expression or a
|
||||||
possible type mismatch error.
|
possible type mismatch error.
|
||||||
|
|
||||||
type[T]
|
typedesc[T]
|
||||||
-------
|
-----------
|
||||||
|
|
||||||
In many contexts, Nim allows you to treat the names of types as regular
|
In many contexts, Nim allows you to treat the names of types as regular
|
||||||
values. These values exists only during the compilation phase, but since
|
values. These values exists only during the compilation phase, but since
|
||||||
all values must have a type, ``type`` is considered their special type.
|
all values must have a type, ``typedesc`` is considered their special type.
|
||||||
|
|
||||||
``type`` acts like a generic type. For instance, the type of the symbol
|
``typedesc`` acts like a generic type. For instance, the type of the symbol
|
||||||
``int`` is ``type[int]``. Just like with regular generic types, when the
|
``int`` is ``typedesc[int]``. Just like with regular generic types, when the
|
||||||
generic param is ommited, ``type`` denotes the type class of all types.
|
generic param is ommited, ``typedesc`` denotes the type class of all types.
|
||||||
As a syntactic convenience, you can also use ``type`` as a modifier.
|
As a syntactic convenience, you can also use ``typedesc`` as a modifier.
|
||||||
``type int`` is considered the same as ``type[int]``.
|
|
||||||
|
|
||||||
Procs featuring ``type`` params are considered implicitly generic.
|
Procs featuring ``typedesc`` params are considered implicitly generic.
|
||||||
They will be instantiated for each unique combination of supplied types
|
They will be instantiated for each unique combination of supplied types
|
||||||
and within the body of the proc, the name of each param will refer to
|
and within the body of the proc, the name of each param will refer to
|
||||||
the bound concrete type:
|
the bound concrete type:
|
||||||
|
|
||||||
.. code-block:: nim
|
.. code-block:: nim
|
||||||
|
|
||||||
proc new(T: type): ref T =
|
proc new(T: typedesc): ref T =
|
||||||
echo "allocating ", T.name
|
echo "allocating ", T.name
|
||||||
new(result)
|
new(result)
|
||||||
|
|
||||||
|
|
@ -5126,14 +5125,14 @@ When multiple type params are present, they will bind freely to different
|
||||||
types. To force a bind-once behavior one can use an explicit generic param:
|
types. To force a bind-once behavior one can use an explicit generic param:
|
||||||
|
|
||||||
.. code-block:: nim
|
.. code-block:: nim
|
||||||
proc acceptOnlyTypePairs[T, U](A, B: type[T]; C, D: type[U])
|
proc acceptOnlyTypePairs[T, U](A, B: typedesc[T]; C, D: typedesc[U])
|
||||||
|
|
||||||
Once bound, type params can appear in the rest of the proc signature:
|
Once bound, type params can appear in the rest of the proc signature:
|
||||||
|
|
||||||
.. code-block:: nim
|
.. code-block:: nim
|
||||||
:test: "nim c $1"
|
:test: "nim c $1"
|
||||||
|
|
||||||
template declareVariableWithType(T: type, value: T) =
|
template declareVariableWithType(T: typedesc, value: T) =
|
||||||
var x: T = value
|
var x: T = value
|
||||||
|
|
||||||
declareVariableWithType int, 42
|
declareVariableWithType int, 42
|
||||||
|
|
@ -5145,8 +5144,8 @@ types that will match the type param:
|
||||||
.. code-block:: nim
|
.. code-block:: nim
|
||||||
:test: "nim c $1"
|
:test: "nim c $1"
|
||||||
|
|
||||||
template maxval(T: type int): int = high(int)
|
template maxval(T: typedesc[int]): int = high(int)
|
||||||
template maxval(T: type float): float = Inf
|
template maxval(T: typedesc[float]): float = Inf
|
||||||
|
|
||||||
var i = int.maxval
|
var i = int.maxval
|
||||||
var f = float.maxval
|
var f = float.maxval
|
||||||
|
|
@ -5159,7 +5158,8 @@ The constraint can be a concrete type or a type class.
|
||||||
typeof operator
|
typeof operator
|
||||||
---------------
|
---------------
|
||||||
|
|
||||||
**Note**: ``typeof(x)`` can also be written as ``type(x)``.
|
**Note**: ``typeof(x)`` can also be written as ``type(x)`` but ``type(x)``
|
||||||
|
is discouraged.
|
||||||
|
|
||||||
You can obtain the type of a given expression by constructing a ``typeof``
|
You can obtain the type of a given expression by constructing a ``typeof``
|
||||||
value from it (in many other languages this is known as the `typeof`:idx:
|
value from it (in many other languages this is known as the `typeof`:idx:
|
||||||
|
|
@ -6581,7 +6581,7 @@ Custom pragmas are defined using templates annotated with pragma ``pragma``:
|
||||||
.. code-block:: nim
|
.. code-block:: nim
|
||||||
template dbTable(name: string, table_space: string = "") {.pragma.}
|
template dbTable(name: string, table_space: string = "") {.pragma.}
|
||||||
template dbKey(name: string = "", primary_key: bool = false) {.pragma.}
|
template dbKey(name: string = "", primary_key: bool = false) {.pragma.}
|
||||||
template dbForeignKey(t: type) {.pragma.}
|
template dbForeignKey(t: typedesc) {.pragma.}
|
||||||
template dbIgnore {.pragma.}
|
template dbIgnore {.pragma.}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue