# Explanation of the @. syntax

I came across this piece of syntax that was not immediately obvious to me.

``````
sum(@. (data > 0.5) & (data < 0.75)) / length(samples)

``````

I worked out that this is “mapping” the dot operator over all the other operators. I.e. the same result is obtained by:

``````
sum( (data .> 0.5) .& (data .< 0.75)) / length(samples)

``````

I know this is related to meta programming, which I am not good at. Could someone explain the mechanism of this?

Thx

Basically `@.` goes through the expression and inserts dots on all the functions in the expression.

1 Like

It’s not really metaprogramming, other than that the person who implemented `@.` was metaprogramming. Crash course:

A macro (`@something`) takes an expression as input, returns another expression and evaluates it.

So when you write `@. x^2 - 2 * y + f(x)`, you give `@.` the argument `:(x^2 - 2 * y + f(x))`. The internal logic of `@.` looks at each operator and dots it, and thus returns `:(x.^2 .- 2 .* y .+ f.(x))`, which is now evaluated, so `@. x^2 - 2 * y + f(x)` is equivalent to `x.^2 .- 2 .* y .+ f.(x)`.

10 Likes

You can use `@macroexpand` to see the code generated by a macro.

``````julia> data = rand(4);

julia> @macroexpand sum(@. (data > 0.5) & (data < 0.75)) / length(data)
:(sum((&).((>).(data, 0.5), (<).(data, 0.75))) / length(data))
``````
10 Likes

Thank you! Oscar for confirming my interpretation, John for the useful advice re: @macroexpand. Your replies were very helpful. I will mark Gustaphe’s reply as solution - I hadn’t realized! Appreciate it.

And just in case you (or anyone else) hasn’t seen it, this blog post gives a really excellent explanation of why you’d want to dot every operator in an expression.

1 Like