Skip to content
JeffBezanson edited this page Sep 5, 2011 · 38 revisions
## Expressions and Eval

Julia code is represented as a syntax tree built out of Julia data structures of type Expr. This makes it easy to construct and manipulate Julia code from within Julia, without generating or parsing source text. Here is the definition of Expr:

type Expr
    head::Symbol
    args::Array{Any,1}
    typ
end

The head is a symbol identifying the kind of expression, and args is an array of subexpressions. typ is used by type inference to store type annotations (it can generally be ignored).

There is special syntax for "quoting" code (analogous to quoting strings) that makes it easy to create expression objects without explicitly constructing Exprs. There is a long form, for blocks of code, using quote ... end, and a short form using prefix :.

julia> e = :(a+b)
+(a,b)

julia> e.head
call

julia> e.args
{+,a,b}

Values of expressions may be interpolated into quote expressions with $ as in strings:

julia> a=1
1

julia> e = :($a+b)
+(1,b)

When the argument to : is just a symbol, a Symbol object results instead of an Expr.

An expression object can be evaluated (executed) at the top level scope (equivalent to loading from a file or typing at the prompt) using the eval function. This can be used in a manner similar to the C preprocessor to generate definitions that would be difficult to write manually. For example, the following code defines a series of operators on three arguments in terms of their 2-argument forms:

for op = (:+, :*, :&, :|, :$)
    eval(quote
        ($op)(a,b,c) = ($op)(($op)(a,b),c)
    end)
end

For uses like this the pattern eval(quote ... end) occurs repeatedly, so there is a nicer equivalent macro @eval:

for op = (:+, :*, :&, :|, :$)
    @eval begin
        ($op)(a,b,c) = ($op)(($op)(a,b),c)
    end
end
## Macros

Macros provide a convenient hook for rewriting syntax trees in a program. They are invoked with the following syntax:

@name arg1 arg2 ...

Before the program runs, this statement will be replaced with the result of calling an expander function for name on the expression objects of the arguments. Expanders are defined with the macro keyword:

macro name(arg1, arg2, ...)
    ...
end

Here is an example using a macro to define an assertion statement for debugging:

macro assert(ex)
    :($ex ? true : error("Assertion failed: ", $string(ex)))
end

@assert condition will expand to a ? expression that tests the condition, and if it is false throws an error containing a string representation of the condition expression. Notice that it would not be possible to write this as a function, since only the value of the condition and not the expression that computed it would be available.


Previous: Parallel ComputingNext: Calling C Code

Clone this wiki locally