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
Closed

Improve public AST creation facilities #5917

scabug opened this issue Jun 15, 2012 · 4 comments

Comments

@scabug
Copy link

scabug 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
Copy link
Author

scabug 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
Copy link
Author

scabug 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
Copy link
Author

scabug 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 as completed Jul 11, 2013
@scabug
Copy link
Author

scabug 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
Projects
None yet
Development

No branches or pull requests

2 participants