Reputation: 51039
For example, here:
ys = lift(frequency, phase) do fr, ph
@. 0.3 * sin(fr * xs - ph)
end
from here.
I am failing to interpret it as a macro definition or call.
Upvotes: 12
Views: 1836
Reputation: 69869
I think it is worth to add that it is easy to learn what @.
does by invoking help. Press ?
then write @.
and hit enter to get:
help?> @.
@. expr
Convert every function call or operator in expr into a "dot call" (e.g.
convert f(x) to f.(x)), and convert every assignment in expr to a "dot
assignment" (e.g. convert += to .+=).
If you want to avoid adding dots for selected function calls in expr, splice
those function calls in with $. For example, @. sqrt(abs($sort(x))) is
equivalent to sqrt.(abs.(sort(x))) (no dot for sort).
(@. is equivalent to a call to @__dot__.)
Examples
≡≡≡≡≡≡≡≡≡≡
julia> x = 1.0:3.0; y = similar(x);
julia> @. y = x + 3 * sin(x)
3-element Array{Float64,1}:
3.5244129544236893
4.727892280477045
3.4233600241796016
where you also learn that @.
is just a shorthand for @__dot__
.
And if you want to find its definition write e.g.:
julia> @which @. 1
@__dot__(__source__::LineNumberNode, __module__::Module, x) in Base.Broadcast at broadcast.jl:1241
to get the exact information on location of its implementation or write @edit @. 1
and it will get opened-up in your editor.
Above I have commented on how to learn what @.
does and how it is implemented. If you want to learn what is the effect of @.
(or any macro in general) you can use the @macroexpand
macro. Therefore if you write e.g.:
julia> @macroexpand @. coalesce(sin(@view x[:, 1]), 0.0)
:(coalesce.(sin.(true && (view)(x, :, 1)), 0.0))
you can see how @.
macro rewrites your original expression coalesce(sin(x), 0.0)
. Note that in this case the expressions are not evaluated - you only get an equivalent expression with all macros removed.
If you wanted to see only @.
macro expanded (assuming - as in an example above it is the outermost macro) then use:
julia> @macroexpand1 @. coalesce(sin(@view x[:, 1]), 0.0)
:(coalesce.(sin.(#= REPL[11]:1 =# @view(x[:, 1])), 0.0))
As you can see @macroexpand1
is not recursive and only expanded the outermost macro and left @view
macro untouched.
Upvotes: 9
Reputation: 6388
TLDR: @
invokes a macro. https://docs.julialang.org/en/v1/manual/metaprogramming/
One of julia's best features in my opinion are it's macros. They allow you to easily write functions that manipulate source code. @.
for example turns 0.3 * sin(fr * xs - ph)
into 0.3 .* sin(fr .* xs - ph)
. Another common example is @time
which roughly would translate the same expression to
t1=time()
0.3 * sin(fr * xs - ph)
println(time()-t1)
Note that neither of these are achievable by a function, since functions have their inputs evaluated before they run, while macros instead operate on the code itself.
Upvotes: 7