# @. and UndefVarError

I have here a simple snippet of an example function that works just fine, i.e it returns what I expect it to return when i call it with a 2D argument x and a 1D argument p.

@. function dummy(x,p)
3.0*x[:,2] +p[1] +x[:,1]*p[2]
end

If instead i say (for example because i want to use the result of this calculation in the same function for further calculations)

@. function dummy(x,p)
w= 3.0*x[:,2] +p[1] +x[:,1]*p[2]
return w
end

then I get an “UndefVarError: w not defined”. so far so good.

however, i have tried all sorts of ways that I can think of defining w (as a local array of appropriate shape, i.e. an array of the length of the first dimension of x) but the error message remains always the same. even if i try to define w as an obviously wrong type, the error message is “not defined” as opposed to some form of “nonsense defined”

how do i define a local w correctly in julia for use in a @. function?

thanks

You don’t need to apply `@.` to the entire function (and I wouldn’t recommend doing so, for exactly the reason you’ve run into here). The problem is that `@.` turns your `=` into `.=`, which in turn transforms `w = ...` into `w .= ...` which tries to broadcast the result into the (non-existent) array `w`.

``````function dummy(x, p)
w = @.(3.0*x[:,2] +p[1] +x[:,1]*p[2])
return w
end
``````

1 Like

Not sure why, but the parser seems to be sensitive to a particular space here:

``````julia> x = randn(10,10); p = randn(10);
julia> @. 3.0*x[:,2] + p[1] + x[:,1] * p[2]
10-element Array{Float64,1}:
-2.9666319136896138
2.7282891603028543
-4.853840108488322
0.6058019669739523
-1.2711187026514819
0.07949352735277701
1.151771108029404
3.6311609306720025
1.156418356474127
-2.5863095768830022

julia> @. 3.0*x[:,2] +p[1] + x[:,1] * p[2]
ERROR: LoadError: MethodError: no method matching @__dot__(::LineNumberNode, ::Module, ::Expr, ::Expr)
Closest candidates are:
in expression starting at REPL[24]:1
``````

It’s because macro argument parsing is a space sensitive parsing context, and the parser uses the space to disambiguate unary vs binary `+`. Compare:

``````julia> :(@a y +x).args[3:end]
2-element Array{Any,1}:
:y
:(+x)

julia> :(@a y + x).args[3:end]
1-element Array{Any,1}:
:(y + x)
``````

Some kind of space sensitive disambiguation is more obviously necessary when you consider unary `-`.

1 Like