@@ -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,26 @@ 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 methods
420+ ` value `  (or ` getValue ` ). This will convert the ` Expr[T] `  into a ` T `  (or ` Some[T] ` ) when the
421+ expression contains value. Otherwise it will emit an error (or retrun ` None ` ).
422+ To avoid having incidental val bindings generated by the inlining of the ` def ` 
423+ it is recomended 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 ]):  Expr [Double ] = 
429+   powerCode(x, n.value) //  Transform `n` into an Int or emit an error if it is not possible
422430
423- private  def  powerCode (n :  Int ,  x : Expr [Double ]):  Expr [Double ] = 
431+ private  def  powerCode (x : Expr [Double ],  n :  Int ):  Expr [Double ] = 
424432  if  (n ==  0 ) ' { 1.0  }
425433  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.
434+   else  if  (n %  2  ==  0 ) ' { val  y  =  $x *  $x; $ { powerCode(' y , n /  2 ) } }
435+   else  ' { $x *  $ { powerCode(x, n -  1 ) } }
436+ ``` 
444437
445438### Scope Extrusion  
446439
@@ -472,7 +465,7 @@ that invokation of `run` in splices. Consider the following expression:
472465' { (x : Int ) =>  $ { run(' x ); 1  } }
473466``` 
474467This 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
468+ the splice will reduce the expression ` run ('x)`  to ` x ` . But then the result
476469
477470``` scala 
478471' { (x : Int ) =>  $ { x; 1  } }
@@ -590,9 +583,9 @@ inline method that can calculate either a value of type `Int` or a value of type
590583` String ` .
591584
592585``` scala 
593- inline  def  defaultOf (inline  str : String ) <:  Any  =  $ { defaultOfImpl(str) }
586+ inline  def  defaultOf (inline  str : String ) <:  Any  =  $ { defaultOfImpl(' str ) }
594587
595- def  defaultOfImpl (str :  String ):  Expr [Any ] =  str  match  {
588+ def  defaultOfImpl (strExpr :  Expr [ String ] ):  Expr [Any ] =  strExpr.value  match  {
596589  case  " int" =>  ' {1 }
597590  case  " string" =>  ' {" a" 
598591}
@@ -624,8 +617,10 @@ It is possible to deconstruct or extract values out of `Expr` using pattern matc
624617In ` scala.quoted.matching `  contains object that can help extract values from ` Expr ` .
625618
626619*  ` scala.quoted.matching.Const ` : matches an expression a literal value and returns the value.
620+ *  ` scala.quoted.matching.Value ` : matches an expression a value and returns the value.
627621*  ` 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]] ` .
628622*  ` scala.quoted.matching.ConstSeq ` :  matches an explicit sequence of literal values and returns them.
623+ *  ` scala.quoted.matching.ValueSeq ` :  matches an explicit sequence of values and returns them.
629624
630625These could be used in the following way to optimize any call to ` sum `  that has statically known values.
631626``` scala 
@@ -661,7 +656,7 @@ optimize {
661656``` 
662657
663658``` scala 
664- def  sum (args : => Int * ):  Int  =  args.sum
659+ def  sum (args : Int * ):  Int  =  args.sum
665660inline  def  optimize (arg : Int ):  Int  =  $ { optimizeExpr(' arg ) }
666661private  def  optimizeExpr (body : Expr [Int ])(given  QuoteContext ):  Expr [Int ] =  body match  {
667662  //  Match a call to sum without any arguments
0 commit comments