Quiz 1.11: Metaprogramming and macros


Q1: Metaprogramming theory

Which of the following statements are correct ?

RESOLUTION

Concerning the wrong answers: the characteristic of metaprogramming in Julia is that the code is changed after it is parsed in Expressions. For the same reasons we can't "go around" code that, without the macro, would create syntax errors (i.e. errors during parsing).

The correct answers are:

  • Macros in Julia allow to programmatically transform one or more code expressions in a different expression
  • Invoking a Julia macro implies making two different operations\: first "create" an expression, and then evaluating it
  • A symbol allows to refer to an identifier rather than to the object associated (binded) to it
  • Expressions are composed of symbols
  • To evaluate an expression all the symbols referred in the expressions must be accessible at the global scope of where the evaluation happens

Q2: Evaluation of an expression

Given the following code snippet:\n

x = 10
y = 3
myMult = Meta.parse("$x * y")
x = 2
y = 5
output = eval(myMult)

Which of the following sentences are correct?

RESOLUTION

The expression is made by the content of variable x (because we are using the dollar sign) that multiplies the variable y. The evaluation of what y contains, used to make the actual multiplication, is done at the time of evaluating the expression, so the multiplication that is done is 10 * 5

The correct answers are:

  • out is 50

Q3: Components of an expression

Given the following code snippet:

a         = [100,10,0]
expr      = Meta.parse("a[1]+1")
expr.XXXX = 2

To what XXXX should be replaced with, in order for the evaluation of expr to retun the value 11 ? (hint: you can dump the expression)


RESOLUTION

We want to change the index of the array that we want to sum to the fixed value 1, so to have the expression to evaluate to 10+1 instead of 100+1. The expression is made of several nested expressions. First, we have a call to the addition operator (+) (first argument), the a[1] element (second argument) and the value 1 (third element). So we first want args[2]. Then we have a reference expression where the first argument is the variable (symbol) a and, finally, the second argument is the index value, 1 - that here we want to change to 2 -, so we want to have expr.args[2].args[2] = 2

The correct answer is: args[2].args[2]


Q4: Macros

Given the following code snippet:

macro Foo(inExpr)
    return 2
end
@Foo a=3
a

Which of the following sentences are correct?

RESOLUTION

The script leads to an evaluation error (i.e., not a parsing one) as a results not defined. The original expression of the assignment of a to 3 is not part of the ASL, what it is is a single, constant value 2 that is what the invocation of the macro produces. However this is not binded to a, so a in the expanded code is not even present.

The correct answers are:

  • a is not defined