@@ -356,11 +356,11 @@ again together with a program that calls `assert`.
356356``` scala 
357357object  Macros  {
358358
359-   inline  def  assert (expr :  =>  Boolean ):  Unit  = 
359+   inline  def  assert (inline   expr : Boolean ):  Unit  = 
360360    $ { assertImpl(' expr ) }
361361
362362  def  assertImpl (expr : Expr [Boolean ]) = 
363-     ' { if  ! ($expr) then  throw  new  AssertionError (s " failed assertion:  ${$ expr} " ) }
363+     ' { if  ! ($expr) then  throw  new  AssertionError (" failed assertion: "   +   $ { expr.show} ) }
364364}
365365
366366object  App  {
@@ -414,33 +414,28 @@ assume that both definitions are local.
414414
415415The ` inline `  modifier is used to declare a ` val `  that is
416416either a constant or is a parameter that will be a constant when instantiated. This
417- aspect is also important for macro expansion.  To illustrate this,
418- consider an implementation of the ` power `  function that makes use of a
419- statically known exponent:
417+ aspect is also important for macro expansion.
418+ 
419+ To get values out of expressions containing constants ` Expr `  provides the method
420+ ` getValue `  (or ` value ` ). This will convert the ` Expr[T] `  into a ` Some[T] `  (or ` T ` ) when the
421+ expression contains value. Otherwise it will retrun ` None `  (or emit an error).
422+ To avoid having incidental val bindings generated by the inlining of the ` def ` 
423+ it is recommended to use an inline parameter. To illustrate this, consider an
424+ implementation of the ` power `  function that makes use of a statically known exponent:
420425``` scala 
421- inline  def  power (inline  n : Int , x : Double ) =  $ { powerCode(n, ' x ) }
426+ inline  def  power (x : Double , inline  n : Int ) =  $ { powerCode(' x , ' n ) }
427+ 
428+ private  def  powerCode (x : Expr [Double ], n : Expr [Int ])(given  QuoteContext ):  Expr [Double ] = 
429+   n.getValue match 
430+     case  Some (m) =>  powerCode(x, m)
431+     case  None  =>  ' { Math .pow($x, $y) }
422432
423- private  def  powerCode (n :  Int ,  x : Expr [Double ]):  Expr [Double ] = 
433+ private  def  powerCode (x : Expr [Double ],  n :  Int )( given   QuoteContext ):  Expr [Double ] = 
424434  if  (n ==  0 ) ' { 1.0  }
425435  else  if  (n ==  1 ) x
426-   else  if  (n %  2  ==  0 ) ' { val  y  =  $x *  $x; $ { powerCode(n /  2 , ' y ) } }
427-   else  ' { $x *  $ { powerCode(n -  1 , x) } }
428- ``` 
429- The reference to ` n `  as an argument in ` ${ powerCode(n, 'x) } `  is not
430- phase-consistent, since ` n `  appears in a splice without an enclosing
431- quote. Normally that would be a problem because it means that we need
432- the _ value_  of ` n `  at compile time, which is not available for general
433- parameters. But since ` n `  is an inline parameter of a macro, we know
434- that at the macro’s expansion point ` n `  will be instantiated to a
435- constant, so the value of ` n `  will in fact be known at this
436- point. To reflect this, we loosen the phase consistency requirements
437- as follows:
438- 
439-  -  If ` x `  is a inline value (or a inline parameter of an inline
440-    function) of type Boolean, Byte, Short, Int, Long, Float, Double,
441-    Char or String, it can be accessed in all contexts where the number
442-    of splices minus the number of quotes between use and definition
443-    is either 0 or 1.
436+   else  if  (n %  2  ==  0 ) ' { val  y  =  $x *  $x; $ { powerCode(' y , n /  2 ) } }
437+   else  ' { $x *  $ { powerCode(x, n -  1 ) } }
438+ ``` 
444439
445440### Scope Extrusion  
446441
@@ -472,7 +467,7 @@ that invokation of `run` in splices. Consider the following expression:
472467' { (x : Int ) =>  $ { run(' x ); 1  } }
473468``` 
474469This is again phase correct, but will lead us into trouble. Indeed, evaluating
475- the splice will reduce the expression ` ('x).run  `  to ` x ` . But then the result
470+ the splice will reduce the expression ` run ('x)`  to ` x ` . But then the result
476471
477472``` scala 
478473' { (x : Int ) =>  $ { x; 1  } }
@@ -590,12 +585,12 @@ inline method that can calculate either a value of type `Int` or a value of type
590585` String ` .
591586
592587``` scala 
593- inline  def  defaultOf (inline  str : String ) <:  Any  =  $ { defaultOfImpl(str) }
588+ inline  def  defaultOf (inline  str : String ) <:  Any  =  $ { defaultOfImpl(' str ) }
594589
595- def  defaultOfImpl (str :  String ) :  Expr [Any ] =  str  match  { 
596-   case   " int "   =>   ' { 1 } 
597-   case  " string " =>  ' {" a " 
598- }
590+ def  defaultOfImpl (strExpr :  Expr [ String ])( given   QuoteContext ) :  Expr [Any ] = 
591+   strExpr.value  match 
592+      case  " int " =>  ' {1 }
593+      case   " string "   =>   ' { " a " 
599594
600595//  in a separate file
601596val  a :  Int  =  defaultOf(" int" 
@@ -624,8 +619,10 @@ It is possible to deconstruct or extract values out of `Expr` using pattern matc
624619In ` scala.quoted.matching `  contains object that can help extract values from ` Expr ` .
625620
626621*  ` scala.quoted.matching.Const ` : matches an expression a literal value and returns the value.
622+ *  ` scala.quoted.matching.Value ` : matches an expression a value and returns the value.
627623*  ` scala.quoted.matching.ExprSeq ` : matches an explicit sequence of expresions and returns them. These sequences are useful to get individual ` Expr[T] `  out of a varargs expression of type ` Expr[Seq[T]] ` .
628624*  ` scala.quoted.matching.ConstSeq ` :  matches an explicit sequence of literal values and returns them.
625+ *  ` scala.quoted.matching.ValueSeq ` :  matches an explicit sequence of values and returns them.
629626
630627These could be used in the following way to optimize any call to ` sum `  that has statically known values.
631628``` scala 
@@ -661,7 +658,7 @@ optimize {
661658``` 
662659
663660``` scala 
664- def  sum (args : => Int * ):  Int  =  args.sum
661+ def  sum (args : Int * ):  Int  =  args.sum
665662inline  def  optimize (arg : Int ):  Int  =  $ { optimizeExpr(' arg ) }
666663private  def  optimizeExpr (body : Expr [Int ])(given  QuoteContext ):  Expr [Int ] =  body match  {
667664  //  Match a call to sum without any arguments
@@ -695,7 +692,7 @@ private def sumExpr(args1: Seq[Expr[Int]])(given QuoteContext): Expr[Int] = {
695692Sometimes it is necessary to get a more precise type for an expression. This can be achived using the following pattern match.
696693
697694``` scala 
698- def  f (exp : Expr [Any ]) = 
695+ def  f (exp : Expr [Any ])( given   QuoteContext )  = 
699696  expr match 
700697    case  ' { $x : $t } => 
701698      //  If the pattern match succeeds, then there is some type `T` such that
0 commit comments