mirror of
https://github.com/nim-lang/Nim.git
synced 2026-02-14 07:13:27 +00:00
Adding info to manual (#22252)
* Adjustments * Moving example * typo * adding code example back and fix terms * Condensing
This commit is contained in:
@@ -2642,9 +2642,15 @@ of the argument.
|
||||
6. Conversion match: `a` is convertible to `f`, possibly via a user
|
||||
defined `converter`.
|
||||
|
||||
These matching categories have a priority: An exact match is better than a
|
||||
literal match and that is better than a generic match etc. In the following,
|
||||
`count(p, m)` counts the number of matches of the matching category `m`
|
||||
|
||||
There are two major methods of selecting the best matching candidate, namely
|
||||
counting and disambiguation. Counting takes precedence to disambiguation. In counting,
|
||||
each parameter is given a category and the number of parameters in each category is counted.
|
||||
The categories are listed above and are in order of precedence. For example, if
|
||||
a candidate with one exact match is compared to a candidate with multiple generic matches
|
||||
and zero exact matches, the candidate with an exact match will win.
|
||||
|
||||
In the following, `count(p, m)` counts the number of matches of the matching category `m`
|
||||
for the routine `p`.
|
||||
|
||||
A routine `p` matches better than a routine `q` if the following
|
||||
@@ -2662,6 +2668,11 @@ algorithm returns true:
|
||||
return "ambiguous"
|
||||
```
|
||||
|
||||
When counting is ambiguous, disambiguation begins. Parameters are iterated
|
||||
by position and these parameter pairs are compared for their type relation. The general goal
|
||||
of this comparison is to determine which parameter is more specific. The types considered are
|
||||
not of the inputs from the callsite, but of the competing candidates' parameters.
|
||||
|
||||
|
||||
Some examples:
|
||||
|
||||
@@ -5470,6 +5481,49 @@ The following example shows how a generic binary tree can be modeled:
|
||||
The `T` is called a `generic type parameter`:idx: or
|
||||
a `type variable`:idx:.
|
||||
|
||||
|
||||
Generic Procs
|
||||
---------------
|
||||
|
||||
Let's consider the anatomy of a generic `proc` to agree on defined terminology.
|
||||
|
||||
```nim
|
||||
p[T: t](arg1: f): y
|
||||
```
|
||||
|
||||
- `p`: Callee symbol
|
||||
- `[...]`: Generic parameters
|
||||
- `T: t`: Generic constraint
|
||||
- `T`: Type variable
|
||||
- `[T: t](arg1: f): y`: Formal signature
|
||||
- `arg1: f`: Formal parameter
|
||||
- `f`: Formal parameter type
|
||||
- `y`: Formal return type
|
||||
|
||||
The use of the word "formal" here is to denote the symbols as they are defined by the programmer,
|
||||
not as they may be at compile time contextually. Since generics may be instantiated and
|
||||
types bound, we have more than one entity to think about when generics are involved.
|
||||
|
||||
The usage of a generic will resolve the formally defined expression into an instance of that
|
||||
expression bound to only concrete types. This process is called "instantiation".
|
||||
|
||||
Brackets at the site of a generic's formal definition specify the "constraints" as in:
|
||||
|
||||
```nim
|
||||
type Foo[T] = object
|
||||
proc p[H;T: Foo[H]](param: T): H
|
||||
```
|
||||
|
||||
A constraint definition may have more than one symbol defined by seperating each definition by
|
||||
a `;`. Notice how `T` is composed of `H` and the return type of `p` is defined as `H`. When this
|
||||
generic proc is instantiated `H` will be bound to a concrete type, thus making `T` concrete and
|
||||
the return type of `p` will be bound to the same concrete type used to define `H`.
|
||||
|
||||
Brackets at the site of usage can be used to supply concrete types to instantiate the generic in the same
|
||||
order that the symbols are defined in the constraint. Alternatively, type bindings may be inferred by the compiler
|
||||
in some situations, allowing for cleaner code.
|
||||
|
||||
|
||||
Is operator
|
||||
-----------
|
||||
|
||||
|
||||
Reference in New Issue
Block a user