Skip to content

[doc] wording, parameter inline modifier #7337

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 9 commits into from
Sep 30, 2019
43 changes: 24 additions & 19 deletions docs/docs/reference/metaprogramming/inline.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@ object Logger {
The `Config` object contains a definition of the **inline value** `logging`.
This means that `logging` is treated as a _constant value_, equivalent to its
right-hand side `false`. The right-hand side of such an `inline val` must itself
be a [constant expression](https://scala-lang.org/files/archive/spec/2.12/06-expressions.html#constant-expressions). Used in this
way, `inline` is equivalent to Java and Scala 2's `final`. Note that `final`, meaning
be a [constant expression](https://scala-lang.org/files/archive/spec/2.12/06-expressions.html#constant-expressions).
Used in this way, `inline` is equivalent to Java and Scala 2's `final`. Note that `final`, meaning
_inlined constant_, is still supported in Dotty, but will be phased out.

The `Logger` object contains a definition of the **inline method** `log`. This
Expand All @@ -58,7 +58,7 @@ def factorial(n: BigInt): BigInt = {
}
```

If `Config.logging == false`, this will be rewritten (simplified) to
If `Config.logging == false`, this will be rewritten (simplified) to:

```scala
def factorial(n: BigInt): BigInt = {
Expand Down Expand Up @@ -120,7 +120,7 @@ inline def power(x: Double, n: Int): Double = {
}
```

Parameters of inline methods can be marked `inline`. This means
Parameters of inline methods can have an `inline` modifier as well. This means
that actual arguments to these parameters must be constant expressions.
For example:

Expand Down Expand Up @@ -216,14 +216,14 @@ type `1`.
```scala
inline def zero() <: Int = 0

final val one: 1 = zero() + 1
val one: 1 = zero() + 1
```

## Inline Conditionals

If the condition of an if-then-else expressions is a constant, the expression simplifies to
the selected branch. Prefixing an if-then-else expression with `inline` forces
the condition to be a constant, and thus guarantees that the conditional will always
If the condition of an if-then-else expressions is a constant expression then it simplifies to
the selected branch. Prefixing an if-then-else expression with `inline` enforces that
the condition has to be a constant expression, and thus guarantees that the conditional will always
simplify.

Example:
Expand Down Expand Up @@ -272,8 +272,8 @@ The scrutinee `x` is examined statically and the inline match is reduced
accordingly returning the corresponding value (with the type specialized due to
the `<:` in the return type). This example performs a simple type test over the
scrutinee. The type can have a richer structure like the simple ADT below.
`toInt` matches the structure of a number in Church-encoding and _computes_ the
corresponding integer.
`toInt` matches the structure of a number in [Church-encoding](https://en.wikipedia.org/wiki/Church_encoding)
and _computes_ the corresponding integer.

```scala
trait Nat
Expand Down Expand Up @@ -319,11 +319,11 @@ the singleton type `2`.

#### `erasedValue`

We have seen so far inline methods that take terms (tuples and integers) as
So far we have seen inline methods that take terms (tuples and integers) as
parameters. What if we want to base case distinctions on types instead? For
instance, one would like to be able to write a function `defaultValue`, that,
given a type `T` returns optionally the default value of `T`, if it exists. In
fact, we can already express this using rewrite match expressions and a simple
given a type `T`, returns optionally the default value of `T`, if it exists.
We can already express this using rewrite match expressions and a simple
helper function, `scala.compiletime.erasedValue`, which is defined as follows:

```scala
Expand All @@ -333,11 +333,13 @@ erased def erasedValue[T]: T = ???
The `erasedValue` function _pretends_ to return a value of its type argument
`T`. In fact, it would always raise a `NotImplementedError` exception when
called. But the function can in fact never be called, since it is declared
`erased`, so can be only used at compile-time during type checking.
`erased`, so can only be used at compile-time during type checking.

Using `erasedValue`, we can then define `defaultValue` as follows:

```scala
import scala.compiletime.erasedValue

inline def defaultValue[T] = inline erasedValue[T] match {
case _: Byte => Some(0: Byte)
case _: Char => Some(0: Char)
Expand All @@ -360,10 +362,11 @@ Then:
val dAny: None.type = defaultValue[Any]
```

As another example, consider the type-level version of `toNat` above the we call
`toIntT`: given a _type_ representing a Peano number, return the integer _value_
corresponding to it. Consider the definitions of numbers as in the _Inline
Match_ section aboce. Here's how `toIntT` can be defined:
As another example, consider the type-level version of `toInt` below:
given a _type_ representing a Peano number,
return the integer _value_ corresponding to it.
Consider the definitions of numbers as in the _Inline
Match_ section above. Here is how `toIntT` can be defined:

```scala
inline def toIntT[N <: Nat] <: Int = inline scala.compiletime.erasedValue[N] match {
Expand Down Expand Up @@ -391,6 +394,8 @@ If an inline expansion results in a call `error(msgStr)` the compiler
produces an error message containing the given `msgStr`.

```scala
import scala.compiletime.{error, code}

inline def fail() = {
error("failed for a reason")
}
Expand All @@ -403,7 +408,7 @@ or
inline def fail(p1: => Any) = {
error(code"failed on: $p1")
}
fail(indentity("foo")) // error: failed on: indentity("foo")
fail(identity("foo")) // error: failed on: identity("foo")
```

## Summoning Implicits Selectively
Expand Down