Scala macro to print code? - scala

I want to do something like this:
def assuming[A](condition: => Boolean)(f: => A): A = {
require(condition, /* print source-code of condition */)
f
}
Sample usage:
def fib(n: Int) = n match { // yes, yes, I know this is not efficient
case 0 => 0
case 1 => 1
case i => assuming(i > 0) { fib(i-1) + fib(i-2) }
}
Now, for example, if you call fib(-20), I want it to throw an exception with a message like Assertion failed: -20 > 0 or Assertation failed: i > 0

Dude, isn't an assert macro one of the basic use cases you implement to learn how to use macros?
Well, that's what I thought, too.
By "glean snippets" in my other answer I meant what specs2 does in its s2 macro.
Or, you can do an arbitrary representation, as in my variant rip-off of expecty.
I thought I'd type your example into REPL, in a couple of lines. After all, you're just trying to print the snippet from the source that corresponds to the tree representing your conditional.
What could be easier?
Of course, it's easier under -Yrangepos, but we can postulate positions.
I'm willing to share how far I got before I lost interest.
People (e.g., paulp, who is the vox paulpuli) want trees to have attachments representing "the source I typed on my keyboard", because, you know, maybe I want it for a message or to figure out what the user was trying to accomplish.
It looks like the predicate p doesn't have a range position. So the other idea is that we know the start of the macro application, which is the paren of the second param list, so working backward through the source, matching the closing paren of the first param list, is doable.
Note that showCode isn't helpful because for a conditional like 10 < 5 it shows false, neatly folded.
object X {
import reflect.macros.blackbox.Context
def impl[A: c.WeakTypeTag](c: Context)(p: c.Expr[Boolean])(body: c.Expr[A]) = {
import c.universe._
def treeLine(t: Tree): String = lineAt(t.pos)
def lineAt(pos: Position): String = if (pos.isRange) pos.lineContent.drop(pos.column - 1).take(pos.end - pos.start + 1) else "???"
val msg =
if (p.tree.pos.isRange) { // oh, joy
treeLine(p.tree)
} else {
/*
Console println s"content ${p.tree.pos.lineContent}"
Console println s"column ${p.tree.pos.column}" // alas, that's the column of the point of the top of the tree, e.g., < in "a < b".
val len = body.tree.pos.start - p.tree.pos.start
p.tree.pos.lineContent drop (p.tree.pos.column - 1) take len
*/
// OK, I get it: positions are a big mystery. Make woo-woo ghost noises.
// What we do know is the start of the apply, which must have a close paren or brace in front of it to match:
// apply(condition)(body)
showCode(p.tree)
}
q"require($p, $msg) ; $body"
}
def x[A](p: Boolean)(body: =>A): A = macro X.impl[A]
}
It just occurred to me to get the rangy position this way:
object X {
import reflect.macros.blackbox.Context
def impl(c: Context)(p: c.Expr[Boolean]) = {
import c.universe._
def lineAt(pos: Position): String = if (pos.isRange) pos.lineContent.drop(pos.column - 1).take(pos.end - pos.start + 1) else "???"
val msg = lineAt(c.macroApplication.pos) // oh, joy
q"require($p, $msg) ; new { def apply[A](body: =>A): A = body }"
}
def x(p: Boolean): { def apply[A](body: =>A): A } = macro X.impl
}
That's close on usage x(10 < 5)(println("hi")): requirement failed: (10 < 5)(p. Margin for error.

Have you consulted the docs at:
http://www.scala-lang.org/api/2.11.0/scala-reflect/#scala.reflect.api.Printers
scala> show(q"-1 < 0")
res6: String = -1.$less(0)
scala> showCode(q"-1 < 0")
res7: String = (-1).<(0)
Alternatively, folks have used source positions to glean snippets to print.

If you are using Scala 2.11.x the best way to go is the showCode method. This method will correctly print an arbitrary Scala tree. For example:
scala> import reflect.runtime.universe._
import reflect.runtime.universe._
showCode(q"3.14 < 42")
res1: String = 3.14.<(42)
In the previous versions of Scala you would have to use the method show which does not guarantee correctness:
scala> show(q"3.14 < 42")
res2: String = 3.14.$less(42)
The method showCode was designed with correctness in mind so it will not necessarily print beautiful code. If beauty is of importance for you can either contribute to the Scala Printers or you can write your own printer. Another interesting printer for Scala trees is the PrettyPrinter from Scala Refactoring.

Related

Is it possible in Scala to make a function that disallows the use of closures?

Say I have some function like this:
def doSomeCode(code: => Unit): Unit = {
println("Doing some code!")
code
}
It takes in a function, prints out "Doing some code!" and then calls the passed function. If for example we called it like:
doSomeCode {
println("Some code done!")
}
It would print out "Doing some code!", followed by "Some code done!".
But I would like to disallow the use of outside variables inside that code block, for example:
def otherFunction(): Unit = {
val number = 10
doSomeCode{
println("The number is " + number)
}
}
This will print out "Doing some code!", followed by "The number is 10". But I would like it to instead throw an error because I do not want number to be in the scope of doSomeCode. Is this possible to achieve in Scala?
To be clear I am not asking if this is a good idea, I just want to know if it is possible.
Edit:
The reason I want this is because I am trying to make a syntax that is perfectly functional, I want a block with no side effects. Ideally the syntax would look like:
val a = 1
val b = 2
val c = 3
val d = 4
val sum = use(a, c, d){
val total = a + c + d
total
}
This way I as a programmer know that the only variables used are a, c, and d and that sum is the only output. Trying to use anything else, eg b, would result in an error. Currently it is not possible to know at a glance what variables a block is using. I can achieve this by just making and using a function like this:
def example(): Unit = {
val a = 1
val b = 2
val c = 3
val d = 4
val sum = sum(a, c, d)
}
def sum(a: Int, b: Int, c: Int): Int = {
val total = a + b + c
total
}
This behaves exactly like how I want it to, but I would like it to be inline with the other code, not outside as an external function.
scala> def mkClosure(i: Int) = { s: String => s"$i - $s" }
mkClosure: (i: Int)String => String
scala> mkClosure(5)
res0: String => String = <function1>
Since whether the function depends on values which aren't parameters isn't encoded in the type system, there's no compiler-enforceable difference in Scala between such a function and a pure one. It's unlikely to be possible with macros: a compiler plugin is probably your best bet, especially if you want to allow certain values (e.g. println) to be used inside a block.

Get syntax string from runtime in scala [duplicate]

I want to do something like this:
def assuming[A](condition: => Boolean)(f: => A): A = {
require(condition, /* print source-code of condition */)
f
}
Sample usage:
def fib(n: Int) = n match { // yes, yes, I know this is not efficient
case 0 => 0
case 1 => 1
case i => assuming(i > 0) { fib(i-1) + fib(i-2) }
}
Now, for example, if you call fib(-20), I want it to throw an exception with a message like Assertion failed: -20 > 0 or Assertation failed: i > 0
Dude, isn't an assert macro one of the basic use cases you implement to learn how to use macros?
Well, that's what I thought, too.
By "glean snippets" in my other answer I meant what specs2 does in its s2 macro.
Or, you can do an arbitrary representation, as in my variant rip-off of expecty.
I thought I'd type your example into REPL, in a couple of lines. After all, you're just trying to print the snippet from the source that corresponds to the tree representing your conditional.
What could be easier?
Of course, it's easier under -Yrangepos, but we can postulate positions.
I'm willing to share how far I got before I lost interest.
People (e.g., paulp, who is the vox paulpuli) want trees to have attachments representing "the source I typed on my keyboard", because, you know, maybe I want it for a message or to figure out what the user was trying to accomplish.
It looks like the predicate p doesn't have a range position. So the other idea is that we know the start of the macro application, which is the paren of the second param list, so working backward through the source, matching the closing paren of the first param list, is doable.
Note that showCode isn't helpful because for a conditional like 10 < 5 it shows false, neatly folded.
object X {
import reflect.macros.blackbox.Context
def impl[A: c.WeakTypeTag](c: Context)(p: c.Expr[Boolean])(body: c.Expr[A]) = {
import c.universe._
def treeLine(t: Tree): String = lineAt(t.pos)
def lineAt(pos: Position): String = if (pos.isRange) pos.lineContent.drop(pos.column - 1).take(pos.end - pos.start + 1) else "???"
val msg =
if (p.tree.pos.isRange) { // oh, joy
treeLine(p.tree)
} else {
/*
Console println s"content ${p.tree.pos.lineContent}"
Console println s"column ${p.tree.pos.column}" // alas, that's the column of the point of the top of the tree, e.g., < in "a < b".
val len = body.tree.pos.start - p.tree.pos.start
p.tree.pos.lineContent drop (p.tree.pos.column - 1) take len
*/
// OK, I get it: positions are a big mystery. Make woo-woo ghost noises.
// What we do know is the start of the apply, which must have a close paren or brace in front of it to match:
// apply(condition)(body)
showCode(p.tree)
}
q"require($p, $msg) ; $body"
}
def x[A](p: Boolean)(body: =>A): A = macro X.impl[A]
}
It just occurred to me to get the rangy position this way:
object X {
import reflect.macros.blackbox.Context
def impl(c: Context)(p: c.Expr[Boolean]) = {
import c.universe._
def lineAt(pos: Position): String = if (pos.isRange) pos.lineContent.drop(pos.column - 1).take(pos.end - pos.start + 1) else "???"
val msg = lineAt(c.macroApplication.pos) // oh, joy
q"require($p, $msg) ; new { def apply[A](body: =>A): A = body }"
}
def x(p: Boolean): { def apply[A](body: =>A): A } = macro X.impl
}
That's close on usage x(10 < 5)(println("hi")): requirement failed: (10 < 5)(p. Margin for error.
Have you consulted the docs at:
http://www.scala-lang.org/api/2.11.0/scala-reflect/#scala.reflect.api.Printers
scala> show(q"-1 < 0")
res6: String = -1.$less(0)
scala> showCode(q"-1 < 0")
res7: String = (-1).<(0)
Alternatively, folks have used source positions to glean snippets to print.
If you are using Scala 2.11.x the best way to go is the showCode method. This method will correctly print an arbitrary Scala tree. For example:
scala> import reflect.runtime.universe._
import reflect.runtime.universe._
showCode(q"3.14 < 42")
res1: String = 3.14.<(42)
In the previous versions of Scala you would have to use the method show which does not guarantee correctness:
scala> show(q"3.14 < 42")
res2: String = 3.14.$less(42)
The method showCode was designed with correctness in mind so it will not necessarily print beautiful code. If beauty is of importance for you can either contribute to the Scala Printers or you can write your own printer. Another interesting printer for Scala trees is the PrettyPrinter from Scala Refactoring.

Access code file and line number from Scala macro?

How can I access the name of the code file and line number in a Scala macro? I looked at SIP-19 and it says it can be easily implemented using macros...
EDIT:
To clarify, I want the code file and line number of the caller. I already have a debug macro and I want to modify it to print the line number and file name of whoever calls debug
You want c.macroApplication.pos, where c is for Context.
c.enclosingPosition finds the nearest macro on the stack that has a position. (See the other answer.) For instance, if your assert macro generates a tree for F"%p: $msg" but doesn't assign a position, the F macro would be positionless.
Example from a string interpolator macro, F"%p":
/* Convert enhanced conversions to something format likes.
* %Q for quotes, %p for position, %Pf for file, %Pn line number,
* %Pc column %Po offset.
*/
private def downConvert(parts: List[Tree]): List[Tree] = {
def fixup(t: Tree): Tree = {
val Literal(Constant(s: String)) = t
val r = "(?<!%)%(p|Q|Pf|Po|Pn|Pc)".r
def p = c.macroApplication.pos
def f(m: Match): String = m group 1 match {
case "p" => p.toString
case "Pf" => p.source.file.name
case "Po" => p.point.toString
case "Pn" => p.line.toString
case "Pc" => p.column.toString
case "Q" => "\""
}
val z = r.replaceAllIn(s, f _)
Literal(Constant(z)) //setPos t.pos
}
parts map fixup
}
If you mean file name and line number of the current position in the source code, for 2.10, my answer to that SO question is what your looking for:
def $currentPosition:String = macro _currentPosition
def _currentPosition(c:Context):c.Expr[String]={ import c.universe._
val pos = c.enclosingPosition
c.Expr(Literal(Constant(s"${pos.source.path}: line ${pos.line}, column ${pos.column}")))
}
That should work with 2.11 as well, although this way of creating the AST seems deprecated.
You can also have a look at that excerpt of my project Scart; it's how I use this technique to emit traces for debugging purposes.
The example in 'Writing Scala Compiler Plugins' shows how to access the line name and current number of the current position, as the others answers have mentioned.
http://www.scala-lang.org/old/node/140
In addition to the answers above, you can also get the position from the AST returned from a CompilationUnit.
For example:
def apply(unit: CompilationUnit) {
// Get the AST
val tree = unit.body
// Get the Position
// Scala.util.parsing.input.Position
val myPos = tree.pos
// Do something with the pos
unit.warning(pos, "Hello world")
}

Scala extending while loops to do-until expressions

I'm trying to do some experiment with Scala. I'd like to repeat this experiment (randomized) until the expected result comes out and get that result. If I do this with either while or do-while loop, then I need to write (suppose 'body' represents the experiment and 'cond' indicates if it's expected):
do {
val result = body
} while(!cond(result))
It does not work, however, since the last condition cannot refer to local variables from the loop body. We need to modify this control abstraction a little bit like this:
def repeat[A](body: => A)(cond: A => Boolean): A = {
val result = body
if (cond(result)) result else repeat(body)(cond)
}
It works somehow but is not perfect for me since I need to call this method by passing two parameters, e.g.:
val result = repeat(body)(a => ...)
I'm wondering whether there is a more efficient and natural way to do this so that it looks more like a built-in structure:
val result = do { body } until (a => ...)
One excellent solution for body without a return value is found in this post: How Does One Make Scala Control Abstraction in Repeat Until?, the last one-liner answer. Its body part in that answer does not return a value, so the until can be a method of the new AnyRef object, but that trick does not apply here, since we want to return A rather than AnyRef. Is there any way to achieve this? Thanks.
You're mixing programming styles and getting in trouble because of it.
Your loop is only good for heating up your processor unless you do some sort of side effect within it.
do {
val result = bodyThatPrintsOrSomething
} until (!cond(result))
So, if you're going with side-effecting code, just put the condition into a var:
var result: Whatever = _
do {
result = bodyThatPrintsOrSomething
} until (!cond(result))
or the equivalent:
var result = bodyThatPrintsOrSomething
while (!cond(result)) result = bodyThatPrintsOrSomething
Alternatively, if you take a functional approach, you're going to have to return the result of the computation anyway. Then use something like:
Iterator.continually{ bodyThatGivesAResult }.takeWhile(cond)
(there is a known annoyance of Iterator not doing a great job at taking all the good ones plus the first bad one in a list).
Or you can use your repeat method, which is tail-recursive. If you don't trust that it is, check the bytecode (with javap -c), add the #annotation.tailrec annotation so the compiler will throw an error if it is not tail-recursive, or write it as a while loop using the var method:
def repeat[A](body: => A)(cond: A => Boolean): A = {
var a = body
while (cond(a)) { a = body }
a
}
With a minor modification you can turn your current approach in a kind of mini fluent API, which results in a syntax that is close to what you want:
class run[A](body: => A) {
def until(cond: A => Boolean): A = {
val result = body
if (cond(result)) result else until(cond)
}
}
object run {
def apply[A](body: => A) = new run(body)
}
Since do is a reserved word, we have to go with run. The result would now look like this:
run {
// body with a result type A
} until (a => ...)
Edit:
I just realized that I almost reinvented what was already proposed in the linked question. One possibility to extend that approach to return a type A instead of Unit would be:
def repeat[A](body: => A) = new {
def until(condition: A => Boolean): A = {
var a = body
while (!condition(a)) { a = body }
a
}
}
Just to document a derivative of the suggestions made earlier, I went with a tail-recursive implementation of repeat { ... } until(...) that also included a limit to the number of iterations:
def repeat[A](body: => A) = new {
def until(condition: A => Boolean, attempts: Int = 10): Option[A] = {
if (attempts <= 0) None
else {
val a = body
if (condition(a)) Some(a)
else until(condition, attempts - 1)
}
}
}
This allows the loop to bail out after attempts executions of the body:
scala> import java.util.Random
import java.util.Random
scala> val r = new Random()
r: java.util.Random = java.util.Random#cb51256
scala> repeat { r.nextInt(100) } until(_ > 90, 4)
res0: Option[Int] = Some(98)
scala> repeat { r.nextInt(100) } until(_ > 90, 4)
res1: Option[Int] = Some(98)
scala> repeat { r.nextInt(100) } until(_ > 90, 4)
res2: Option[Int] = None
scala> repeat { r.nextInt(100) } until(_ > 90, 4)
res3: Option[Int] = None
scala> repeat { r.nextInt(100) } until(_ > 90, 4)
res4: Option[Int] = Some(94)

Repeating function call until we'll get non-empty Option result in Scala

A very newbie question in Scala - how do I do "repeat function until something is returned meets my criteria" in Scala?
Given that I have a function that I'd like to call until it returns the result, for example, defined like that:
def tryToGetResult: Option[MysteriousResult]
I've come up with this solution, but I really feel that it is ugly:
var res: Option[MysteriousResult] = None
do {
res = tryToGetResult
} while (res.isEmpty)
doSomethingWith(res.get)
or, equivalently ugly:
var res: Option[MysteriousResult] = None
while (res.isEmpty) {
res = tryToGetResult
}
doSomethingWith(res.get)
I really feel like there is a solution without var and without so much hassle around manual checking whether Option is empty or not.
For comparison, Java alternative that I see seems to be much cleaner here:
MysteriousResult tryToGetResult(); // returns null if no result yet
MysteriousResult res;
while ((res = tryToGetResult()) == null);
doSomethingWith(res);
To add insult to injury, if we don't need to doSomethingWith(res) and we just need to return it from this function, Scala vs Java looks like that:
Scala
def getResult: MysteriousResult = {
var res: Option[MysteriousResult] = None
do {
res = tryToGetResult
} while (res.isEmpty)
res.get
}
Java
MysteriousResult getResult() {
while (true) {
MysteriousResult res = tryToGetResult();
if (res != null) return res;
}
}
You can use Stream's continually method to do precisely this:
val res = Stream.continually(tryToGetResult).flatMap(_.toStream).head
Or (possibly more clearly):
val res = Stream.continually(tryToGetResult).dropWhile(!_.isDefined).head
One advantage of this approach over explicit recursion (besides the concision) is that it's much easier to tinker with. Say for example that we decided that we only wanted to try to get the result a thousand times. If a value turns up before then, we want it wrapped in a Some, and if not we want a None. We just add a few characters to our code above:
Stream.continually(tryToGetResult).take(1000).flatMap(_.toStream).headOption
And we have what we want. (Note that the Stream is lazy, so even though the take(1000) is there, if a value turns up after three calls to tryToGetResult, it will only be called three times.)
Performing side effects like this make me die a little inside, but how about this?
scala> import scala.annotation.tailrec
import scala.annotation.tailrec
scala> #tailrec
| def lookupUntilDefined[A](f: => Option[A]): A = f match {
| case Some(a) => a
| case None => lookupUntilDefined(f)
| }
lookupUntilDefined: [A](f: => Option[A])A
Then call it like this
scala> def tryToGetResult(): Option[Int] = Some(10)
tryToGetResult: ()Option[Int]
scala> lookupUntilDefined(tryToGetResult())
res0: Int = 10
You may want to give lookupUntilDefined an additional parameter so it can stop eventually in case f is never defined.