Quoting operator & literals

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?

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).

1 Like

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?

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.

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: