diff options
author | Ryan McConnell <rammcconnell@gmail.com> | 2023-07-19 09:04:14 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-07-19 15:04:14 +0200 |
commit | 0d3bde95f578576d2e84d422d5694ee0e0055cbc (patch) | |
tree | 66e3f57b755f48f0c01a80d8bc93d743d5860667 | |
parent | 7d9fe106ecd70bf99b9f3224430debfe10060ce1 (diff) | |
download | Nim-0d3bde95f578576d2e84d422d5694ee0e0055cbc.tar.gz |
Adding info to manual (#22252)
* Adjustments * Moving example * typo * adding code example back and fix terms * Condensing
-rw-r--r-- | doc/manual.md | 60 |
1 files changed, 57 insertions, 3 deletions
diff --git a/doc/manual.md b/doc/manual.md index 1c3e66879..e3a036f0c 100644 --- a/doc/manual.md +++ b/doc/manual.md @@ -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 ----------- |