Butter layout Julia

Why does it work:

function test_func(a, b) a + b end test_func((1, 2)...) 

But is that not so?

 macro test_func(a, b) a + b end @test_func((1, 2)...) 

Is this a mistake in Julia?

+7
julia-lang
source share
1 answer

Macros work with surface syntax, so @test_func does not see splat result. Instead, he sees the splat operation himself! As always, a great way to verify this is to quote it and see what syntax the macro works in:

 julia> :(@test_func((1,2)...)) :(@test_func (1,2)...) julia> Meta.show_sexpr(ans) (:macrocall, symbol("@test_func"), (:..., (:tuple, 1, 2))) 

So, the macro receives only one argument (not two), and it is Expr(:..., Expr(:tuple, 1, 2)) . Note that the tuple (1,2) is passed to your macro, but it is just hidden inside the splat operation. Thus, you can delve into Expr and sort the implementation of splatting by yourself:

 julia> macro test_func(as...) if length(as) == 1 && isa(as[1], Expr) && as[1].head == :... && isa(as[1].args[1], Expr) && as[1].args[1].head == :tuple a, b = as[1].args[1].args elseif length(as) == 2 a, b = as else error("unsupported syntax $as") end return esc(:($a + $b)) end julia> @test_func((1,2)...) 3 

But this is the only kind of sorting that supports splatting. See what happens if you try to use a variable instead:

 julia> @test_func(xs...) ERROR: unsupported syntax (:(xs...),) 

Now there is no way for the macro to know that it should be put together!

+10
source share

All Articles