liufengyun / gestalt

gestalt : portable and solid macros for Scala
https://github.com/scalacenter/macros
31 stars 3 forks source link

Implementation of the Optional macro #77

Closed liufengyun closed 7 years ago

liufengyun commented 7 years ago

Implementation of the Optional macro:

https://github.com/scalamacros/macrology201/blob/part1/macros/src/main/scala/Macros.scala

liufengyun commented 7 years ago

Implementation of this macro shows that writing macros in gestalt is much easier than scala.reflect, as programmers don't have to deal with owners. Due to the separation of typed and untyped trees, this implementation is also much solid.

xeno-by commented 7 years ago

@liufengyun The new macro system is indeed significantly more robust that the old one.

What I find extremely satisfying is that all these robustness guarantees are achieved by simply separating typed and untyped trees in API signatures, without any additional APIs like currentOwner, changeOwner, newSymbol, etc.

liufengyun commented 7 years ago

I don't think we can avoid newSymbol, it's required to write mindless like macros to create dummy ident to be subst later.

xeno-by commented 7 years ago

Not trying to make any argument whether monadless should or shouldn't be supported - that'll be a different discussion. Just noted that this discussion is orthogonal to the already non-trivial benefits provided by the new macro system.

liufengyun commented 7 years ago

Typed to typed transform is essential. Le 15 mai 2017 19:22, "Eugene Burmako" notifications@github.com a écrit :

@xeno-by commented on this pull request.

In macros/src/main/scala/gestalt/macros/Optional.scala https://github.com/liufengyun/gestalt/pull/77#discussion_r116550580:

+

  • val temp = toolbox.fresh("_temp")
  • val tempIdent = Ident(temp)
  • q"""
  • val $temp = $prefix
  • if ($tempIdent.isEmpty) $alt else $tempIdent.value
  • """
  • }
  • def map[B >: Null](f: A => B)(implicit m: toolbox.WeakTypeTag[A] @uncheckVar): Optional[B] = meta {
  • import toolbox._
  • val Function(param :: Nil, body) = f
  • val tempValDef = ValDef(toolbox.fresh("_temp"), prefix)
  • val tempIdent = Ident(tempValDef.symbol)

Is the tpd => tpd transform essential to this macro, or we can be just fine with untpd => untpd?

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/liufengyun/gestalt/pull/77#discussion_r116550580, or mute the thread https://github.com/notifications/unsubscribe-auth/AAuDyaqZTuRT9o7b8G1e93bAVoUN2M1Qks5r6InsgaJpZM4NbaQY .

liufengyun commented 7 years ago

Yes, I agree it's fine to delay the support for monadless, and it's also good to delay the support for problematic extractors. Showing Optional is also a big progress.

But generally, I see there's no escape from hiding the concept type and symbol from meta-programmers. Any efforts in the direction is problematic, in my opinion.

liufengyun commented 7 years ago

Another observation: macro writers (including me) tend to use extractors directly in patmat a lot:

https://github.com/arosenberger/nalloc/blob/master/macros/src/main/scala/org/nalloc/bitb/kcits/macros/Inliner.scala#L50

My guess is that in patmat, extractors give us more certainty -- there's always some obscurity about what's happening behind quasiqutoes.