# What's your favorite syntactical sugar in Julia

I like the `@view` macro (it’s super handy!) and the broadcasting with `.`

``````julia> A = rand(5, 5)
5×5 Matrix{Float64}:
0.707239  0.440889  0.958134  0.783449   0.913452
0.741968  0.276487  0.489972  0.0194192  0.453019
0.318276  0.318808  0.156329  0.268038   0.223835
0.915922  0.743359  0.564748  0.60688    0.94491
0.344369  0.136049  0.539166  0.962701   0.831359

julia> subA = @view A[2:4, 2:4]
3×3 view(::Matrix{Float64}, 2:4, 2:4) with eltype Float64:
0.276487  0.489972  0.0194192
0.318808  0.156329  0.268038
0.743359  0.564748  0.60688

julia> subA .= 0
3×3 view(::Matrix{Float64}, 2:4, 2:4) with eltype Float64:
0.0  0.0  0.0
0.0  0.0  0.0
0.0  0.0  0.0

julia>
``````
2 Likes

One of my biggest pain points in Julia is that `[...]` makes a copy.

Using the macro in nested expressions needs parentheses which makes it not as quick to type:

``````julia> .+(x[1:3], x[2:4])
3-element Vector{Float64}:
-0.7509311698949941
1.709855739076295
0.7021749402293793

julia> .+(@view x[1:3], @view x[2:4])
ERROR: LoadError: ArgumentError: Invalid use of @view macro: argument must be a reference expression A[...].
Stacktrace:
[1] var"@view"(__source__::LineNumberNode, __module__::Module, ex::Any)
@ Base ./views.jl:138
in expression starting at REPL[11]:1

julia> .+(@view(x[1:3]), @view(x[2:4]))
3-element Vector{Float64}:
-0.7509311698949941
1.709855739076295
0.7021749402293793

julia> .+(@view(x[1:3]), @view(x[2:4]))

``````

I wonder actually, why this does not work. The `@.` propagates fully into the whole call, `@view` does not:

``````julia> @view x[1:3] .+ x[1:4]
ERROR: LoadError: ArgumentError: Invalid use of @view macro: argument must be a reference expression A[...].
Stacktrace:
[1] var"@view"(__source__::LineNumberNode, __module__::Module, ex::Any)
@ Base ./views.jl:138
in expression starting at REPL[13]:1

``````

Try `@views` instead of `@view`. That should apply to the whole expression. You can even apply it to a block, such as an entire function.

3 Likes

Isn’t it the case for @views?

2 Likes

I’m writing this to synthesize what I learnt thanks to you guys (and the Julia source code & docs). My understanding is that:

`@view` expects an array-indexing expression => you must give it something like `x[1:3]` or `x[:]` (throws an error otherwise)

`@views` expects “any” expression and transform array-slicing operations into views => cf. below (have been playing with `@views`)

``````julia> @views 1+2+3; "This is noise"
"This is noise"

julia> @views 1+2+3; "This is noise"; A
3×3 Matrix{Float64}:
1.0  1.0  1.0
2.0  2.0  2.0
3.0  3.0  3.0

julia> @views 1+2+3; "This is noise"; A[:]
9-element Vector{Float64}:
1.0
2.0
3.0
1.0
2.0
3.0
1.0
2.0
3.0

julia> A
3×3 Matrix{Float64}:
1.0  1.0  1.0
2.0  2.0  2.0
3.0  3.0  3.0

``````

and finally (as @DNF and @rafael.guerra suggested), voilà

``````julia> @views .+(x[1:3], x[2:4])
3-element Vector{Float64}:
0.6605174669013307
0.8487232659913083
1.2442778601207747

``````

The `@views` stops at the ;. Add parentheses, or `begin`/`end` as mentioned earlier, if you want it to apply across the ;

``````julia> @macroexpand ( @views 1+2; a[1] )
quote
1 + 2
#= REPL[8]:1 =#
a[1]
end

julia> @macroexpand @views ( 1+2; a[1] )
quote
1 + 2
#= REPL[9]:1 =#
(Base.maybeview)(a, 1)
end

julia> @macroexpand @views begin 1+2; a[1]; end
quote
#= REPL[11]:1 =#
1 + 2
#= REPL[11]:1 =#
(Base.maybeview)(a, 1)
end
``````
3 Likes

thank you for the clarification