Skip to content

Commit 7ec3a10

Browse files
committed
wip
1 parent babefd8 commit 7ec3a10

File tree

1 file changed

+36
-28
lines changed

1 file changed

+36
-28
lines changed

docs/docs/reference/metaprogramming/inline.md

Lines changed: 36 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ layout: doc-page
33
title: Inline
44
---
55

6-
## Inline (whitebox/blackbox)
6+
## Inline (blackbox/whitebox)
77

88
`inline` is a new [soft modifier](../soft-modifier.html) that guarantees that a
99
definition will be inlined at the point of use. Example:
@@ -33,9 +33,9 @@ object Logger {
3333
The `Config` object contains a definition of the **inline value** `logging`.
3434
This means that `logging` is treated as a _constant value_, equivalent to its
3535
right-hand side `false`. The right-hand side of such an `inline val` must itself
36-
be a [constant expression](#the-definition-of-constant-expression). Used in this
36+
be a [constant expression](https://scala-lang.org/files/archive/spec/2.12/06-expressions.html#constant-expressions). Used in this
3737
way, `inline` is equivalent to Java and Scala 2's `final`. `final` meaning
38-
"constant" is still supported in Dotty, but will be phased out.
38+
_inlined constant_ is still supported in Dotty, but will be phased out.
3939

4040
The `Logger` object contains a definition of the **inline method** `log`.
4141
This method will always be inlined at the point of call.
@@ -195,27 +195,27 @@ where vals are used for value parameter bindings and defs are used for by-name
195195
parameter bindings. If an argument `E_i` is a simple variable reference `y`, the
196196
corresponding binding is omitted and `y` is used instead of `x_i` in `B`.
197197

198-
If a inline modifier is given for parameters, corresponding arguments must be
198+
If a `inline` modifier is given for parameters, corresponding arguments must be
199199
pure expressions of constant type.
200200

201201
#### The definition of constant expression
202202

203203
Right-hand sides of inline values and of arguments for inline parameters must be
204204
constant expressions in the sense defined by the [SLS §
205205
6.24](https://www.scala-lang.org/files/archive/spec/2.12/06-expressions.html#constant-expressions),
206-
including "platform-specific" extensions such as constant folding of pure
206+
including _platform-specific_ extensions such as constant folding of pure
207207
numeric computations.
208208

209209
### Specializing Inline (Whitebox)
210210

211-
Inline methods support the `<: T` return syntax. This means that the return type
211+
Inline methods support the ` <: T` return type syntax. This means that the return type
212212
of the inline method is going to be specialized to a more precise type upon
213213
expansion.
214214

215215
Consider the example below where the inline method `choose` can return an object
216216
of any of the two dynamic types. The subtype relationship is `B <: A`. Since we
217-
use the specializing inline syntax, the static types of the vals are inferred
218-
accordingly. Consequently, calling `meth` on `obj2` is a compile-time error.
217+
use the specializing inline syntax, the static types of the `val`s are inferred
218+
accordingly. Consequently, calling `meth` on `obj2` is not a compile-time error as `obj2` will be of type `B`.
219219

220220
```scala
221221
class A
@@ -224,7 +224,7 @@ class B extends A {
224224
}
225225

226226
inline def choose(b: Boolean) <: A = {
227-
if(b) new A()
227+
if (b) new A()
228228
else new B()
229229
}
230230

@@ -255,8 +255,8 @@ inline def g(x: Any) <: Any = inline x match {
255255
case x: Double => x
256256
}
257257

258-
g(1.0d): 1.0d
259-
val t: (String, String) = g("test")
258+
g(1.0d) // Has type 1.0d which is a subtype of Double
259+
g("test") // Has type (String, String)
260260
```
261261

262262
The scrutinee `x` is examined statically and the inline match is reduced
@@ -276,14 +276,36 @@ inline def toInt(n: Nat) <: Int = inline n match {
276276
case Succ(n1) => toInt(n1) + 1
277277
}
278278

279-
final val two = toInt(Succ(Succ(Zero)))
280-
val two_ : 2 = two
279+
final val natTwo = toInt(Succ(Succ(Zero)))
280+
val intTwo: 2 = natTwo
281281
```
282282

283-
`two` is inferred to have the singleton type 2.
283+
`natTwo` is inferred to have the singleton type 2.
284284

285285
#### scala.compiletime._
286286

287+
This package contains helper definitions providing support for compile time
288+
operations over values.
289+
290+
##### Const Value & Const Value Opt
291+
292+
`constvalue` is a function that produces the constant value represented by a
293+
type.
294+
295+
```scala
296+
inline def toIntC[N] <: Int =
297+
inline scala.compiletime.constValue[N] match {
298+
case 0 => 0
299+
case _: scala.compiletime.S[n1] => 1 + toIntC[n1]
300+
}
301+
302+
final val ctwo = toIntC[2]
303+
```
304+
305+
`constValueOpt` is the same as `constValue`, however returning an `Option[T]`
306+
enabling us to handle situations where a value is not present.
307+
308+
287309
##### Erased Value
288310

289311
We have seen so far inline methods that take terms (tuples and integers) as
@@ -345,20 +367,6 @@ final val two = toInt[Succ[Succ[Zero]]]
345367
behavior. Since `toInt` performs static checks over the static type of `N` we
346368
can safely use it to scrutinize its return type (`S[S[Z]]` in this case).
347369

348-
##### Const Value & Const Value Opt
349-
350-
`constvalue` is a function that produces the constant value represented by a
351-
type.
352-
353-
```scala
354-
inline def toIntC[N] <: Int =
355-
inline scala.compiletime.constValue[N] match {
356-
case 0 => 0
357-
case _: scala.compiletime.S[n1] => 1 + toIntC[n1]
358-
}
359-
360-
final val ctwo = toIntC[2]
361-
```
362370

363371
#### Implicit Match
364372

0 commit comments

Comments
 (0)