Skip to content
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

Improve public AST creation facilities #5917

Closed
scabug opened this issue Jun 15, 2012 · 4 comments

Comments

Projects
None yet
2 participants
@scabug
Copy link

commented Jun 15, 2012

Currently there does exist a simple way to create trees (reify), but its applicability is limited to static templates with holes having statically known types. However when writing macros, there's frequently a need in something more sophisticated.

This is an open research question, and there are several possible approaches to solving this problem:

  1. Classic quasiquotes that use string interpolation syntax: https://github.com/scalamacros/kepler/tree/topic/interpolation
  2. TreeHugger-like DSL: http://eed3si9n.com/treehugger/
  3. Improved reify that would work with partially typed trees
@scabug

This comment has been minimized.

Copy link
Author

commented Jun 15, 2012

Imported From: https://issues.scala-lang.org/browse/SI-5917?orig=1
Reporter: @xeno-by
Affected Versions: 2.10.0

@scabug

This comment has been minimized.

Copy link
Author

commented Jun 28, 2012

@xeno-by said:
There's also an interesting approach to pattern matching against trees: https://github.com/ochafik/Scalaxy/wiki/Scalaxy-Compilets.

@scabug

This comment has been minimized.

Copy link
Author

commented Jul 12, 2012

@xeno-by said (edited on Mar 3, 2014 10:58:41 AM UTC):
Nice example which illustrates once again why reify isn't always applicable:

 def pack[A](a: A): Array[Byte] = macro pack_impl[A]

   def pack_impl[A: c.TypeTag](c: Context)(a: c.Expr[A]): c.Expr[Array[Byte]] = {
     import c.universe._
     c.reify {
       val baos = new ByteArrayOutputStream
       packto_impl(c)(c.reify[OutputStream]{ baos }, a).splice
       // works: packto_impl(c)(c.Expr[OutputStream](Ident("baos")), a).splice
       // doesn't work: packto_impl(c)(c.reify[OutputStream]{ baos }, a).splice
       baos.toByteArray
     }
   }

   def packto[A](output: OutputStream, value: A): Unit = macro packto_impl[A]

   def packto_impl[A: c.TypeTag](c: Context)(output: c.Expr[OutputStream], value: c.Expr[A]): c.Expr[Unit] = { .... }

Compiling this code will signalize about cross-stage evaluation. This is justified, because the value of baos (as a free variable) will be captured by reification. But this value is only available at runtime, while splice in question needs to work at compile-time.

This is all reasonable and stuff from the staging point of view, but it doesn't really matter for the programmer who just wants to quasiquote.

@scabug scabug closed this Jul 11, 2013

@scabug

This comment has been minimized.

Copy link
Author

commented Jul 11, 2013

@xeno-by said:
Fixed in scala/scala#2714

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.