Skip to content

Commit 7299639

Browse files
committed
Improve code examples in inline.md
1 parent 70229a5 commit 7299639

File tree

1 file changed

+42
-33
lines changed

1 file changed

+42
-33
lines changed

docs/docs/reference/metaprogramming/inline.md

Lines changed: 42 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -144,22 +144,23 @@ Inline methods can override other non-inline methods. The rules are as follows:
144144

145145
```scala
146146
abstract class A:
147-
def f(): Int
148-
def g(): Int = f()
147+
def f: Int
148+
def g: Int = f
149149

150150
class B extends A:
151-
inline def f() = 22
152-
override inline def g() = f() + 11
151+
inline def f = 22
152+
override inline def g = f + 11
153153

154-
val b = B()
154+
val b = new B
155155
val a: A = b
156156
// inlined invocatons
157-
assert(b.f() == 22)
158-
assert(b.g() == 33)
157+
assert(b.f == 22)
158+
assert(b.g == 33)
159159
// dynamic invocations
160-
assert(a.f() == 22)
161-
assert(a.g() == 33)
160+
assert(a.f == 22)
161+
assert(a.g == 33)
162162
```
163+
163164
The inlined invocations and the dynamically dispatched invocations give the same results.
164165

165166
2. Inline methods are effectively final.
@@ -168,14 +169,14 @@ Inline methods can override other non-inline methods. The rules are as follows:
168169

169170
```scala
170171
abstract class A:
171-
inline def f(): Int
172+
inline def f: Int
172173

173174
object B extends A:
174-
inline def f(): Int = 22
175+
inline def f: Int = 22
175176

176-
B.f() // OK
177+
B.f // OK
177178
val a: A = B
178-
a.f() // error: cannot inline f() in A.
179+
a.f // error: cannot inline f() in A.
179180
```
180181

181182
### Relationship to `@inline`
@@ -224,6 +225,7 @@ including _platform-specific_ extensions such as constant folding of pure
224225
numeric computations.
225226
226227
An inline value must have a literal type such as `1` or `true`.
228+
227229
```scala
228230
inline val four = 4
229231
// equivalent to
@@ -249,17 +251,18 @@ specialized to a more precise type upon expansion. Example:
249251
```scala
250252
class A
251253
class B extends A:
252-
def m() = true
254+
def m = true
253255

254256
transparent inline def choose(b: Boolean): A =
255-
if b then new A() else new B()
257+
if b then new A else new B
256258

257259
val obj1 = choose(true) // static type is A
258260
val obj2 = choose(false) // static type is B
259261

260-
// obj1.m() // compile-time error: `m` is not defined on `A`
261-
obj2.m() // OK
262+
// obj1.m // compile-time error: `m` is not defined on `A`
263+
obj2.m // OK
262264
```
265+
263266
Here, the inline method `choose` returns an instance of either of the two types `A` or `B`.
264267
If `choose` had not been declared to be `transparent`, the result
265268
of its expansion would always be of type `A`, even though the computed value might be of the subtype `B`.
@@ -276,9 +279,9 @@ the singleton type `0` permitting the addition to be ascribed with the correct
276279
type `1`.
277280

278281
```scala
279-
transparent inline def zero(): Int = 0
282+
transparent inline def zero: Int = 0
280283

281-
val one: 1 = zero() + 1
284+
val one: 1 = zero + 1
282285
```
283286

284287
## Inline Conditionals
@@ -295,6 +298,7 @@ inline def update(delta: Int) =
295298
inline if delta >= 0 then increaseBy(delta)
296299
else decreaseBy(-delta)
297300
```
301+
298302
A call `update(22)` would rewrite to `increaseBy(22)`. But if `update` was called with
299303
a value that was not a compile-time constant, we would get a compile time error like the one
300304
below:
@@ -343,10 +347,10 @@ case class Succ[N <: Nat](n: N) extends Nat
343347

344348
transparent inline def toInt(n: Nat): Int =
345349
inline n match
346-
case Zero => 0
350+
case Zero => 0
347351
case Succ(n1) => toInt(n1) + 1
348352

349-
final val natTwo = toInt(Succ(Succ(Zero)))
353+
inline val natTwo = toInt(Succ(Succ(Zero)))
350354
val intTwo: 2 = natTwo
351355
```
352356

@@ -366,10 +370,10 @@ import scala.compiletime.{constValue, S}
366370

367371
transparent inline def toIntC[N]: Int =
368372
inline constValue[N] match
369-
case 0 => 0
373+
case 0 => 0
370374
case _: S[n1] => 1 + toIntC[n1]
371375

372-
final val ctwo = toIntC[2]
376+
inline val ctwo = toIntC[2]
373377
```
374378

375379
`constValueOpt` is the same as `constValue`, however returning an `Option[T]`
@@ -402,19 +406,20 @@ import scala.compiletime.erasedValue
402406

403407
inline def defaultValue[T] =
404408
inline erasedValue[T] match
405-
case _: Byte => Some(0: Byte)
406-
case _: Char => Some(0: Char)
407-
case _: Short => Some(0: Short)
408-
case _: Int => Some(0)
409-
case _: Long => Some(0L)
410-
case _: Float => Some(0.0f)
411-
case _: Double => Some(0.0d)
409+
case _: Byte => Some(0: Byte)
410+
case _: Char => Some(0: Char)
411+
case _: Short => Some(0: Short)
412+
case _: Int => Some(0)
413+
case _: Long => Some(0L)
414+
case _: Float => Some(0.0f)
415+
case _: Double => Some(0.0d)
412416
case _: Boolean => Some(false)
413-
case _: Unit => Some(())
414-
case _ => None
417+
case _: Unit => Some(())
418+
case _ => None
415419
```
416420

417421
Then:
422+
418423
```scala
419424
val dInt: Some[Int] = defaultValue[Int]
420425
val dDouble: Some[Double] = defaultValue[Double]
@@ -434,7 +439,7 @@ transparent inline def toIntT[N <: Nat]: Int =
434439
case _: Zero.type => 0
435440
case _: Succ[n] => toIntT[n] + 1
436441

437-
final val two = toIntT[Succ[Succ[Zero.type]]]
442+
inline val two = toIntT[Succ[Succ[Zero.type]]]
438443
```
439444

440445
`erasedValue` is an `erased` method so it cannot be used and has no runtime
@@ -555,6 +560,7 @@ keep the viral nature of implicit search programs based on logic programming.
555560
By contrast, the new `summonFrom` construct makes implicit search available
556561
in a functional context. To solve the problem of creating the right set, one
557562
would use it as follows:
563+
558564
```scala
559565
import scala.compiletime.summonFrom
560566

@@ -563,12 +569,14 @@ inline def setFor[T]: Set[T] = summonFrom {
563569
case _ => new HashSet[T]
564570
}
565571
```
572+
566573
A `summonFrom` call takes a pattern matching closure as argument. All patterns
567574
in the closure are type ascriptions of the form `identifier : Type`.
568575

569576
Patterns are tried in sequence. The first case with a pattern `x: T` such that an implicit value of type `T` can be summoned is chosen.
570577

571578
Alternatively, one can also use a pattern-bound given instance, which avoids the explicit using clause. For instance, `setFor` could also be formulated as follows:
579+
572580
```scala
573581
import scala.compiletime.summonFrom
574582

@@ -606,6 +614,7 @@ inline def f: Any = summonFrom {
606614
## `summonInline`
607615

608616
The shorthand `summonInline` provides a simple way to write a `summon` that is delayed until the call is inlined.
617+
609618
```scala
610619
transparent inline def summonInline[T]: T = summonFrom {
611620
case t: T => t

0 commit comments

Comments
 (0)