Rewritten deleted impls section from notebook

This commit is contained in:
2022-10-25 17:38:09 +01:00
parent 778c87db77
commit d9c35c3591

View File

@@ -0,0 +1,61 @@
In Orchid, types and typeclasses aren't distinguished. Impls are the equivalent of typeclass
implementations. The syntax looks like this:
```orc
impl typeExpression [by name [over overriddenName, furtherOverriddenNames...]] via valueExpression
```
An impl can be considered a candidate for an auto if its typeExpression unifies with the auto's type
An impl candidate can be used to resolve an auto if
- typeExpression unifies with the auto's type
- it is not present in any other matching impl's override tree
- all other candidates are present in its override tree
In Rust impls can be placed in one of two modules; the trait owner, and the type owner. In orchid
that is not the case, so two additional possibilities arise that Rust's orphan rules prevent.
## Foster impls
If it doesn't make sense for either of the participants to acknowledge the others, foster impls
can be created which don't own any of the participant symbols.
```orc
import GenericModule::Typeclass
import SpecificModule::(Type, function)
impl Typeclass Type by fosterTypeclassType via function
```
Foster impls can be placed in foster packages whose sole purpose is to glue packages together, or
they can be embedded in usercode.
## Arbiter impls
If multiple foster impls exist for a given package, or if you use a foster package but one of the
parents involved has added an impl in the mean time, ambiguities arise. To resolve these, arbiter
impls can be used to decide which impl's value will win.
``` orc
import BadModule::badImpl
import GoodModule::goodImpl
import GenericModule::Typeclass
import SpecificModule::Type
impl Typeclass Type by arbiterGoodModuleTypeclassType over goodImpl, badImpl via goodImpl
```
Notice that goodImpl appears both as a value and an impl name. Named impls are always also
exported as value substitution rules, specifically to account for situations where you want to use
them despite auto resolution. They can be referenced in arbiter rules, exception rules for more
general impls, auto-parameter overrides, and directly used as values in code.
The more common and less hacky use case for arbiter rules is when a very general rule from a
general package needs to be overridden by a more specific rule from a deep ancestor.
---
In all cases, these problems represent a concern gap or overlap and should be eventually resolved
by the authors of the original packages. The purpose of foster and arbiter rules is to not stall
the ecosystem on a trivial conflict of concepts and to make adding dependencies less risky.
It should still take some effort to maintain a large dependency list, but the risk of complete
blockage becomes a more manageable constant effort.