Simple example / tutorial for setting up project with macros / quasiquotes?

1,411 views
Skip to first unread message

Travis Good

unread,
Feb 21, 2015, 5:39:19 PM2/21/15
to scal...@googlegroups.com
Hi All,
I am trying to go through a tutorial on quasi-quotes and can't get even the most simple example to work for me. Note that this is exclusively a ScalaJS project. Is there a tutorial on setting up a ScalaJS only project for use with macros? What I have produces the following errors:
1) If I include blackbox macros the compiler tells me that :
[error] /Users/Neo/Documents/masteryScala/masterywebscala/src/main/scala/macroTest/DebugMacros.scala:14: object blackbox is not a member of package scala.reflect.macros

 

[error] import scala.reflect.macros.blackbox

even though in Eclipse this produces no errors. 

2) If I include whitebox macros, the compiler tells me the same thing.

3) If I include import scala.reflect.macros

I get a deprecation warning in Eclipse and it still fails to build. 

4) If I attempt the q"def x = 5" statement I get told that value q is "Not a member of string context."

I've been through the source of uTest and a few other projects, and have no idea what voodoo you are using to get this stuff to compile. Any help is greatly appreciated. Thanks!

Travis 

package macroTest

import scala.annotation.StaticAnnotation
import scala.language.experimental.macros

import scala.reflect.ClassTag

import scala.util.{Failure, Success}

import scala.collection.SortedSet

import scala.concurrent.duration.{FiniteDuration, Duration}

//import scala.reflect.macros.blackbox.Context

import scala.language.higherKinds

import scala.language.experimental.macros


//import scala.reflect.macros.whitebox.Context


//import scala.reflect.macros.blackbox


//import scala.reflect.macros.Context

object DebugMacros {

 def tester(): Unit = {

   q"def x = 5"

 }

}



Travis Good

unread,
Feb 21, 2015, 5:54:59 PM2/21/15
to scal...@googlegroups.com
Tried adding :

"org.scala-lang" % "scala-reflect" % "2.11.5"

to SBT project, along with variations. None of them seem to work. 

Travis Good

unread,
Feb 21, 2015, 6:00:33 PM2/21/15
to scal...@googlegroups.com
This config file works but I'm still getting the String Context Error.

lazy val root = project.in(file(".")).

  enablePlugins(ScalaJSPlugin)


import com.lihaoyi.workbench.Plugin._


import com.typesafe.sbteclipse.core.EclipsePlugin.EclipseKeys


EclipseKeys.withSource := true


workbenchSettings


name := "masteryWebScala"


version := "1"


scalaVersion := "2.11.5"


resolvers += Resolver.url("scala-js-releases",

    url("http://dl.bintray.com/scala-js/scala-js-releases/"))(

    Resolver.ivyStylePatterns)


persistLauncher := true


persistLauncher in Test := false


scalacOptions ++= Seq("-deprecation", "-unchecked", "-feature")


libraryDependencies ++= Seq(

"be.doeraene" %%% "scalajs-jquery" % "0.7.0",

    "org.scala-js" %%% "scalajs-dom" % "0.7.0",

    "org.monifu" %%% "minitest" % "0.11" % "test",

    "com.lihaoyi" %% "upickle" % "0.2.6"

)    


libraryDependencies <+= (scalaVersion)("org.scala-lang" % "scala-reflect" % _)


testFrameworks += new TestFramework("minitest.runner.Framework")


jsDependencies +=

  "org.webjars" % "jquery" % "2.1.3" / "jquery.js"


jsDependencies += ProvidedJS / "sha3.js"


jsDependencies += ProvidedJS / "travisObject.js"


bootSnippet := "ScalaJS.modules.tmw_Masterywebscala().main();" 


Travis Good

unread,
Feb 21, 2015, 6:40:37 PM2/21/15
to scal...@googlegroups.com
Ok. Got the following code to not throw errors 

def impl(c: Context)(f: c.Expr[Any]) = { import c.universe._

    val q"(..$args) => $body" = f.tree

    println(s"args = $args, body = $body")

    c.Expr(q"()")

  }

..using the above config and setup. I'm now going to create a separate project of implementations that I can call and see if I can call it. 

Travis Good

unread,
Feb 22, 2015, 1:08:21 AM2/22/15
to scal...@googlegroups.com
Alright, got it to work myself.
Steps:
1) Created another project (used the skeleton app).
2) Gave it the config referencing macros.
3) Defined a dummy macro as follows:

def straightTestImpl(c: Context)(a: c.Expr[String]) = {


    import c.universe._


    val r = "Hello World"    


    c.Expr(q"val x = 4")


    c.Expr(q"()")


  }

.. in a package called tgMacros

4) Used the sbt command publish-local to publish my project with name and organization as follows:

name := "tgmacrosproj"

organization := "travisgood"

 to the local repo.
5) Added a reference to the other project's build.sbt

"travisgood" %%% "tgmacrosproj" % "0.1-SNAPSHOT"

 6) Referenced the macro in an object in my main project, like so:

object DebugMacros {

 def testV(a: String): Unit = macro straightTestImpl

7) Ran the macro in main:

DebugMacros.testV(myStr)


Compiles and works fine. 
Note Well: The skeleton app currently published on the main page references:
"org.scala-js" %%% "scalajs-dom" % "0.8.0",  
Which is incompatible with what I believe is actually the current version, .7. This broke my build in very confusing ways when including the external project. 

I will now use this setup to continue to build my understanding of macros.

Travis Good

unread,
Feb 28, 2015, 2:43:45 PM2/28/15
to scal...@googlegroups.com
Have gotten a lot more things working now. Was going to start creating a tutorial, but a nice video / code tutorial already exists here:


Hope this helps anyone working in this space. 

d.j.g...@gmail.com

unread,
Mar 1, 2015, 12:15:12 PM3/1/15
to scal...@googlegroups.com
Thanks for the mention, Travis. Glad Essential Macros was helpful! :)

Cheers,

Dave

Reply all
Reply to author
Forward
0 new messages