Itās not clear what exactly this question means. @.
is working as intended. Conceptually it is just adding .
s everywhere where they make sense. E.g. not in x[1]
julia> x = [ [[1,2,3],[9,8,7]] ]; x.[1]
ERROR: syntax: invalid syntax "x.[1]" around REPL[...]:1
but itās fine in getindex
julia> getindex.(x, 1)
1-element Vector{Vector{Int64}}:
[1, 2, 3]
though not in getindex.
julia> getindex..(x, 1)
ERROR: UndefVarError: `..` not defined in `Main`
Iām sure there exist counter-examples to this intuitive idea, so check the source code or Benny`s reply to see what the macro is formally doing.
If you want your #6 to return [[1, 9]]
you need something like
f1(x) = (a -> getindex.(a, 1)).(x)
i.e.
f2(x) = broadcast(a -> broadcast(b -> getindex(b, 1), a), x)
julia> x = [ [[1,2,3],[9,8,7]] ]; f1(x)
1-element Vector{Vector{Int64}}:
[1, 9]
julia> 1-element Vector{Vector{Int64}}:
[1, 9]
Is it possible to write a macro @dotdot
so that @dotdot getindex..(x, 1)
gets converted into one of these? Sure. But what for x = [[ [[1,2,3],[9,8,7]] ]]
? Youād need getindex...(x, 1)
, which presumably will start conflicting with the splat operator ...
. If you want to keep broadcasting
as deep as possible, note that you can broadcast over scalars (and e.g. x = 5; getindex(x, 1)
works fine), so how do you know when to stop? In my opinion this would quickly become a convoluted mess which would be difficult to interpret.
Iām already not too fond of the @.
macro itself, as to some extent it hides whatās really happening. E.g. that @. x[1] + y
resolves to x[1] .+ y
and not x.[1] .+ y
or getindex.(x, 1) .+ y
. Itās not a lot of effort to just manually add some dots yourself, and doing this manually forces you to check whether it makes sense. Also note that leaving out select broadcasts can improve performance.