From 7c5ea26ed924fa42d3e477ddb1ee109e0a2d54ae Mon Sep 17 00:00:00 2001
From: "Paolo G. Giarrusso"
Date: Tue, 28 Jan 2014 21:46:02 +0100
Subject: [PATCH] Complete exercises
TODO: verify Markdown formatting.
---
exercises/E08.md | 43 +++++++++++++++++++++++++++++++------------
1 file changed, 31 insertions(+), 12 deletions(-)
diff --git a/exercises/E08.md b/exercises/E08.md
index 3f3382d..b525747 100644
--- a/exercises/E08.md
+++ b/exercises/E08.md
@@ -1,35 +1,54 @@
-Because of the delay, partial solutions will be
+Because of the delay, partial solutions are more welcome than usual.
+Please try to solve at least two-three exercises, and focus on the theory part.
-
-- Consider a macro running on an expression with nested subexpressions:
+- Consider a macro named `aMacro` running on an expression with nested subexpressions:
val intermediateExpr = if (cond) { list map f } else { list map g }
aMacro(intermediateExpr map h)
We said that aMacro can't know statically the what intermediateExpr is going to contain.
+Sketch a scenario which exemplifies the problem.
+
+- Assume again that `aMacro` is a macro and consider the snippet below, divided in two fragments marked (1) and (2). Will `aMacro` receive different arguments in examples (1) and (2)?
+
+```scala
+ //(1)
+ aMacro(1)
+ //(2)
+ aMacro({
+ val v = 1
+ v
+ })
+```
+
+ If there is a difference between the arguments in those scenarios:
+ - can you describe scenarios where the difference is or is not interesting, and motivate why?
+ - For scenarios where the difference is not interesting, does the difference introduce potential for bugs?
- Choose an example of boilerplate in the course lecture notes and try
describing how macros could be used to automate the generation of such
boilerplate.
-- Macros can also be used:
+- Macros can also be used in the implementation of DSLs. For instance:
- for integrating external DSLs
- - for language virtualization
- - for
- Give an example of a possible usage scenario.
+ - for implementing alternative semantics of existing code (language virtualization)
+ - to perform static analyses, even on code which does not get executed.
+ Give an example of a possible usage scenario among those categories, and/or point out additional categories with appropriate examples.
-- Inside trace_impl, we have two different proposalsfor the body:
+- Inside trace_impl in the code from the lecture (`14-macros/macros/01macros.scala`), we have two different proposals for the body:
+```scala
def trace(x: Any): Unit = macro trace_impl
def trace_impl(c: Context)(x: c.Expr[Any]): c.Expr[Unit] = {
import c.universe._
//Base version (1):
//c.Expr(q"""println("The value of %s is %s" format (${show(x)}, $x))""")
-
+ //
//Question: what's wrong if we write instead (2):
//c.Expr(q"""println(${"The value of %s is %s" format (show(x), x)})""")
}
+```
Please analyze and describe the difference between the two pieces of code, in
terms of the different execution times we have discussed during the lecture.
@@ -46,7 +65,7 @@ Coding exercises:
try writing a macro
- fun(f: Term => Term): HOASFun
+ def fun(f: Term => Term): HOASFun = macro ...
-that, when invoked as fun(strangeName => body...), returns
-HOASFun(strangeName => body..., "strangeName") by capturing the argument to the macro.
+that, when invoked as `fun(strangeName => body...)`, expands to
+`HOASFun(strangeName => body..., "strangeName")` by capturing the name (`"strangeName"`) of the parameter (`strangeName`) of the argument (`strangeName => body`) for the macro invocation.