Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does julia express this expression in this complex way?

Tags:

julia

I followed the documentation of julia:

julia> :(a in (1,2,3))
:($(Expr(:in, :a, :((1,2,3)))))

Now that :(a in (1,2,3))==:($(Expr(:in, :a, :((1,2,3))))), why does julia express this expression in this way? And what does $ exactly means? It seems to me that $ just evaluates the next expression in a global scope. I found the documentation unclear about this.

like image 299
atbug Avatar asked Nov 03 '15 07:11

atbug


2 Answers

The reason :(a in (1,2,3)) is displayed awkwardly as :($(Expr(...))) is because the show function for Expr typed objects (show_unquoted in show.jl) does not understand the in infix operator and fallbacks into a generic printing format.

Essentially it is the same as :(1 + 1) except that show_unquoted recognizes + as an infix operator and formats it nicely.

In any case, :(...) and $(...) are inverse operators in some sense, so :($(..thing..)) is exactly like ..thing.., which in this case is Expr(:in,:a,:((1,2,3))).

One can see this weirdness in :(1+1) for example. The output is of Expr type, as typeof(:(1+1))==Expr confirms. It is actually Expr(:+,1,1), but typing Expr(:+,1,1) on the REPL will show :($(Expr(:+,1,1))) - the generic formatting style of Expr typed objects.

Fixing show.jl to handle in could be a nice change. But the issue is harmless and concerns display formatting.

like image 161
Dan Getz Avatar answered Nov 08 '22 07:11

Dan Getz


$ is the interpolation command, Julia use this notation to interpolate Strings as well as Expression:

julia> a=1;
julia> "test $a" # => "test 1"
julia> :(b+$a) # => :(b + 1)

When you type a command in Julia REPL, it tries to evaluates the command and if the code do not have ; char at the end it prints the result, so it's more related to printing functions, that what will be seen on REPL, when a command executes.
so if you want to see the real contents of a variable one possibility is to use dump function:

julia> dump(:(a+b))
Expr
  head: Symbol call
  args: Array(Any,(3,))
    1: Symbol +
    2: Symbol a
    3: Symbol b
  typ: Any

julia> dump(:(a in b))
Expr
  head: Symbol in
  args: Array(Any,(2,))
    1: Symbol a
    2: Symbol b
  typ: Any

It's clear from above tests, that both expressions use a common data structure of Expr with head, args and typ without any $ inside.
Now try to evaluate and print result:

julia> :(a in b)
:($(Expr(:in, :a, :b)))

julia> :(a+b)
:(a + b)

We already know that both command create a same structure but REPL can't show the result of :(a in b) better that an Expr of result of another Expr and it's why there in a $ inside. But when dealing with :(a+b), REPL do more intelligently and understands that this:

Expr
  head: Symbol call
  args: Array(Any,(3,))
    1: Symbol +
    2: Symbol a
    3: Symbol b
  typ: Any

is equal to :(a+b).

like image 42
Reza Afzalan Avatar answered Nov 08 '22 09:11

Reza Afzalan