Skip to content

correct valueOrError to valueOrAbort #2539

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 2 commits into from
Oct 6, 2022
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion _overviews/scala3-macros/faq.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ All quotes containing a value of a primitive type is optimised to an `Expr.apply
Choose one in your project and stick with a single notation to avoid confusion.

## How do I get a value out of an `Expr`?
If the expression represents a value, you can use `.value`, `.valueOrError` or `Expr.unapply`
If the expression represents a value, you can use `.value`, `.valueOrAbort` or `Expr.unapply`

## How can I get the precise type of an `Expr`?
We can get the precise type (`Type`) of an `Expr` using the following pattern match:
Expand Down
16 changes: 9 additions & 7 deletions _overviews/scala3-macros/tutorial/macros.md
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ def powerCode(
x: Expr[Double],
n: Expr[Int]
)(using Quotes): Expr[Double] =
val value: Double = pow(x.valueOrError, n.valueOrError)
val value: Double = pow(x.valueOrAbort, n.valueOrAbort)
Expr(value)
```
Here, the `pow` operation is a simple Scala function that computes the value of `xⁿ`.
Expand All @@ -131,28 +131,30 @@ Other types can also work if a `ToExpr` is implemented for it, we will [see this

### Extracting Values from Expressions

The second method we use in the implementation of `powerCode` is `Expr[T].valueOrError`, which has an effect opposite to `Expr.apply`.
The second method we use in the implementation of `powerCode` is `Expr[T].valueOrAbort`, which has an effect opposite to `Expr.apply`.
It attempts to extract a value of type `T` from an expression of type `Expr[T]`.
This can only succeed, if the expression directly contains the code of a value, otherwise, it will throw an exception that stops the macro expansion and reports that the expression did not correspond to a value.

Instead of `valueOrError`, we could also use the `value` operation, which will return an `Option`.
Instead of `valueOrAbort`, we could also use the `value` operation, which will return an `Option`.
This way we can report the error with a custom error message.

```scala
...
import quotes.reflect.*
(x.value, n.value) match
case (Some(base), Some(exponent)) =>
pow(base, exponent)
case (Some(_), _) =>
report.error("Expected a known value for the exponent, but was " + n.show, n)
report.errorAndAbort("Expected a known value for the exponent, but was " + n.show, n)
case _ =>
report.error("Expected a known value for the base, but was " + x.show, x)
report.errorAndAbort("Expected a known value for the base, but was " + x.show, x)
```

Alternatively, we can also use the `Expr.unapply` extractor

```scala
...
import quotes.reflect.*
(x, n) match
case (Expr(base), Expr(exponent)) =>
pow(base, exponent)
Expand Down Expand Up @@ -196,7 +198,7 @@ inline def sumNow(inline nums: Int*): Int =
def sumCode(nums: Expr[Seq[Int]])(using Quotes): Expr[Int] =
nums match
case Varargs(numberExprs) => // numberExprs: Seq[Expr[Int]]
val numbers: Seq[Int] = numberExprs.map(_.valueOrError)
val numbers: Seq[Int] = numberExprs.map(_.valueOrAbort)
Expr(numbers.sum)
case _ => report.error(
"Expected explicit argument" +
Expand Down Expand Up @@ -244,7 +246,7 @@ inline def test(inline ignore: Boolean, computation: => Unit): Boolean =
${ testCode('ignore, 'computation) }

def testCode(ignore: Expr[Boolean], computation: Expr[Unit])(using Quotes) =
if ignore.valueOrError then Expr(false)
if ignore.valueOrAbort then Expr(false)
else Expr.block(List(computation), Expr(true))
```

Expand Down
2 changes: 1 addition & 1 deletion _overviews/scala3-macros/tutorial/quotes.md
Original file line number Diff line number Diff line change
Expand Up @@ -367,7 +367,7 @@ As with expression quote patterns, type variables are represented using lower ca

## FromExpr

The `Expr.value`, `Expr.valueOrError`, and `Expr.unapply` methods uses intances of `FromExpr` to extract the value if possible.
The `Expr.value`, `Expr.valueOrAbort`, and `Expr.unapply` methods uses intances of `FromExpr` to extract the value if possible.
```scala
extension [T](expr: Expr[T]):
def value(using Quotes)(using fromExpr: FromExpr[T]): Option[T] =
Expand Down