Quoting operator & literals

question

#1

I’m trying to write some meta-code and I found that : operator return type is inconsistent:

> typeof(:(x)), typeof(:(1))
(Symbol,Int64)

I would expect the result of : to be always Expr, but it doesn’t seem to be true for literal expressions.

Is this by design? How do I pass literal expressions to functions that expect Expr?


#2

In Julia, Expr is a specific type with a head and args for representing ASTs. But other types can be expressions per se or part of expressions: such as symbols, and other atoms. Your function should handle these too, so it should not dispatch on Expr only (unless that’s the intention).


#3

Tamas,

I understand what you are saying but this decision doesn’t make it a convenient to write meta code.

I have a data type:

immutable P
  f::Expr
end

Where f will be something that will be symbolically differentiatable. (I will use rdiff). How should I change f data type in this case? Does it also mean that everywhere else I have in parameters f::Expr I have to do something else as well? Should I detect literales manually and wrap them somehow into Expr before passing to rdiff?


#4

My advice: don’t try to force things into a uniform Expr form. It makes meta-programming code less suited to Julia’s strengths because you can clean up Julia meta-programming code by dispatching on types rather than writing big case statements.

You can see how you could use dispatch in https://github.com/johnmyleswhite/Calculus.jl/blob/master/src/symbolic.jl. That code could even be more aggressive by adding the head symbols to the types of individual Expr objects to distinguish them using types alone.


#5

Anything can be an expression (or part of an expression) in Julia. Eg

julia> immutable Foo x end
julia> dump(:(x + $(Foo(9))))
Expr
  head: Symbol call
  args: Array{Any}((3,))
    1: Symbol +
    2: Symbol x
    3: Foo
      x: Int64 9
  typ: Any

so Foo(9) is just sitting there as an argument until + is called, and it is not an Expr, which :(Foo(9)) would be. (See this comment on a question I asked recently for related concepts).

More related to your application: I imagine a symbol eg :x is also symbolically differentiable, and it is not an expression. So don’t restrict the types.

Finally, you may find this library useful: