@@ -7,10 +7,9 @@ title: "Macros"
77
88## Macros: Quotes and Splices
99
10- Macros are built on two well-known fundamental operations: quotation and
11- splicing. Quotation is expressed as ` '{...} ` for expressions and as ` '[...] `
12- for types. Splicing is expressed as ` ${ ... } ` . Additionally, within a quote
13- or a splice we can quote or splice identifiers directly (i.e. ` 'e ` and ` $e ` ).
10+ Macros are built on two well-known fundamental operations: quotation and splicing.
11+ Quotation is expressed as ` '{...} ` for expressions and splicing is expressed as ` ${ ... } ` .
12+ Additionally, within a quote or a splice we can quote or splice identifiers directly (i.e. ` 'e ` and ` $e ` ).
1413Readers may notice the resemblance of the two aforementioned syntactic
1514schemes with the familiar string interpolation syntax.
1615
@@ -45,7 +44,7 @@ def showExpr(expr: Expr[Boolean])(using Quotes): Expr[String] =
4544```
4645
4746If ` e ` is an expression, then ` '{e} ` represents the typed
48- abstract syntax tree representing ` e ` . If ` T ` is a type, then ` ' [T]`
47+ abstract syntax tree representing ` e ` . If ` T ` is a type, then ` Type.of [T]`
4948represents the type structure representing ` T ` . The precise
5049definitions of "typed abstract syntax tree" or "type-structure" do not
5150matter for now, the terms are used only to give some
@@ -62,14 +61,12 @@ Quotes and splices can also be applied directly to identifiers. An identifier
6261splice ` ${x} ` . Analogously, an quoted identifier ` 'x ` that appears inside a splice
6362is treated as a quote ` '{x} ` . See the Syntax section below for details.
6463
65- Quotes and splices are duals of each other. For arbitrary
66- expressions ` e ` and types ` T ` we have:
64+ Quotes and splices are duals of each other.
65+ For arbitrary expressions ` e ` we have:
6766
6867``` scala
6968$ {' {e}} = e
7069' {$ {e}} = e
71- $ {' [T ]} = T
72- ' [$ {T }] = T
7370```
7471
7572## Types for Quotations
@@ -78,7 +75,7 @@ The type signatures of quotes and splices can be described using
7875two fundamental types:
7976
8077- ` Expr[T] ` : abstract syntax trees representing expressions of type ` T `
81- - ` Type[T] ` : type structures representing type ` T ` .
78+ - ` Type[T] ` : non erased representation of type ` T ` .
8279
8380Quoting takes expressions of type ` T ` to expressions of type ` Expr[T] `
8481and it takes types ` T ` to expressions of type ` Type[T] ` . Splicing
@@ -90,8 +87,8 @@ The two types can be defined in package [`scala.quoted`](https://dotty.epfl.ch/a
9087``` scala
9188package scala .quoted
9289
93- sealed abstract class Expr [+ T ]
94- sealed abstract class Type [T ]
90+ sealed trait Expr [+ T ]
91+ sealed trait Type [T ]
9592```
9693
9794Both ` Expr ` and ` Type ` are abstract and sealed, so all constructors for
@@ -375,7 +372,7 @@ where `T` is not defined in the current stage, we construct the type constructor
375372of ` List ` applied to the splice of the result of searching for a given instance for ` Type[T] ` :
376373
377374``` scala
378- ' [ List [ $ { summon[Type [T ]] } ] ]
375+ Type .of [ List [ summon[Type [T ]]. Underlying ] ]
379376```
380377
381378This is exactly the algorithm that Scala 2 uses to search for type tags.
@@ -493,7 +490,7 @@ var x: Expr[T] = ...
493490This code, if it was accepted, would _ extrude_ a reference to a quoted variable
494491` y ` from its scope. This would subsequently allow access to a variable outside the
495492scope where it is defined, which is likely problematic. The code is clearly
496- phase consistent, so we cannot use PCP to rule it out. Instead we postulate a
493+ phase consistent, so we cannot use PCP to rule it out. Instead, we postulate a
497494future effect system that can guarantee that splices are pure. In the absence of
498495such a system we simply demand that spliced expressions are pure by convention,
499496and allow for undefined compiler behavior if they are not. This is analogous to
@@ -502,7 +499,7 @@ verified, to be pure.
502499
503500[ Multi-Stage Programming] ( ./staging.md ) introduces one additional method where
504501you can expand code at runtime with a method ` run ` . There is also a problem with
505- that invokation of ` run ` in splices. Consider the following expression:
502+ that invocation of ` run ` in splices. Consider the following expression:
506503
507504``` scala
508505' { (x : Int ) => $ { run(' x ); 1 } }
@@ -573,7 +570,7 @@ val arr: Array[Int] = Array.apply(1, [2,3 : Int]:Int*)
573570
574571var sum = 0
575572val f = x => ' {sum += $x}
576- $ { _root_.Macros .map(' arr , ' f )(' [Int ])}
573+ $ { _root_.Macros .map(' arr , ' f )(Type .of [Int ])}
577574sum
578575```
579576
@@ -720,7 +717,7 @@ private def sumExpr(args1: Seq[Expr[Int]])(using Quotes): Expr[Int] =
720717
721718### Recovering precise types using patterns
722719
723- Sometimes it is necessary to get a more precise type for an expression. This can be achived using the following pattern match.
720+ Sometimes it is necessary to get a more precise type for an expression. This can be achieved using the following pattern match.
724721
725722``` scala
726723def f (expr : Expr [Any ])(using Quotes ) = expr match
0 commit comments