Skip to content

Commit 97ce6c6

Browse files
committed
Complete unused user docmentation
1 parent ade5780 commit 97ce6c6

File tree

1 file changed

+52
-12
lines changed

1 file changed

+52
-12
lines changed

docs/docs/reference/unused-terms.md

Lines changed: 52 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,42 @@ title: "Unused Parameters"
55

66
Why unused parameters?
77
----------------------
8-
TODO
8+
The following examples shows an implementation of a simple state machine which can be in a state `On` or `Off`.
9+
The machine can change state from `Off` to `On` with `turnedOn` only if it is currently `Off`. This last constraint is
10+
captured with the `IsOff[S]` implicit evidence which only exists for `IsOff[Off]`.
11+
For example, not allowing calling `turnedOn` on in an `On` state as we would require an evidence of type `IsOff[On]` that will not be found.
12+
13+
```scala
14+
sealed trait State
15+
final class On extends State
16+
final class Off extends State
17+
18+
@implicitNotFound("State is must be Off")
19+
class IsOff[S <: State]
20+
object IsOff {
21+
implicit def isOff: IsOff[Off] = new IsOff[Off]
22+
}
923

24+
class Machine[S <: State] {
25+
def turnedOn(implicit ev: IsOff[S]): Machine[On] = new Machine[On]
26+
}
27+
28+
val m = new Machine[Off]
29+
m.turnedOn
30+
m.turnedOn.turnedOn // ERROR
31+
// ^
32+
// State is must be Off
33+
```
1034

11-
What are unused parameter?
12-
--------------------------
13-
Unused parameter are values that are know not to be used. Parameters of methods and functions
14-
can be declared as unused. Those parameters wont be usable for computations, thought they can
15-
be used as arguments to other unused parameters.
35+
These constraint that only depend on the types at the call site are completly resolved at compile time and never used at runtime.
36+
As these parameters are never used at runtime there is not real need to have them around, but they still need to be
37+
present at runtime to be able to do separate compilation and retain binary compatiblity. Unused parameters are contractually
38+
obligated to not be used at runtime, enforcing the essence of evidences on types and allows them to always be optimized away.
39+
40+
41+
How to define unused parameter?
42+
-------------------------------
43+
Parameters of methods and functions can be declared as unused, placing `unused` at the start of the parameter list (like `implicit`).
1644

1745
```scala
1846
def methodWithUnusedEv(unused ev: Ev): Int = 42
@@ -21,8 +49,17 @@ val lambdaWithUnusedEv: unused Ev => Int =
2149
unused (ev: Ev) => 42
2250
```
2351

24-
Not only parameters can be marked as unused, `val` and `def` can also be marked with `unused`.
25-
The will also only be usable as arguments to `unused` parameters.
52+
Those parameters will not be usable for computations, thought they can be used as arguments to other `unused` parameters.
53+
54+
```scala
55+
def methodWithUnusedInt1(unused i: Int): Int =
56+
i + 42 // ERROR: can not use i
57+
58+
def methodWithUnusedInt2(unused i: Int): Int =
59+
methodWithUnusedInt1(i) // OK
60+
```
61+
62+
Not only parameters can be marked as unused, `val` and `def` can also be marked with `unused`. These will also only be usable as arguments to `unused` parameters.
2663

2764
```scala
2865
unused val unusedEvidence: Ev = ...
@@ -49,9 +86,9 @@ methodWithUnusedEv(evidence1)
4986
methodWithUnusedEv(unusedEvidence2)
5087
```
5188

52-
State machine example
53-
---------------------
54-
The following examples shows an implementation of a simple state machine which can be in a state `On` or `Off`.
89+
State machine with unused evidence example
90+
------------------------------------------
91+
The following examples is an extended implementation of a simple state machine which can be in a state `On` or `Off`.
5592
The machine can change state from `Off` to `On` with `turnedOn` only if it is currently `Off`,
5693
conversely from `On` to `Off` with `turnedOff` only if it is currently `On`. These last constraint are
5794
captured with the `IsOff[S]` and `IsOn[S]` implicit evidence only exist for `IsOff[Off]` and `InOn[On]`.
@@ -74,16 +111,19 @@ final class Off extends State
74111
@implicitNotFound("State is must be Off")
75112
class IsOff[S <: State]
76113
object IsOff {
114+
// def isOff will not exist at runtime
77115
unused implicit def isOff: IsOff[Off] = new IsOff[Off]
78116
}
79117

80118
@implicitNotFound("State is must be On")
81119
class IsOn[S <: State]
82120
object IsOn {
83-
unused implicit def isOn: IsOn[On] = new IsOn[On]
121+
// val isOn will not exist at runtime
122+
unused implicit val isOn: IsOn[On] = new IsOn[On]
84123
}
85124

86125
class Machine[S <: State] private {
126+
// ev will disapear from both functions
87127
def turnedOn(implicit unused ev: IsOff[S]): Machine[On] = new Machine[On]
88128
def turnedOff(implicit unused ev: IsOn[S]): Machine[Off] = new Machine[Off]
89129
}

0 commit comments

Comments
 (0)