Getter and setter functions
Recently I stumbled on some interesting behaviour when using a “getter”-like function in combination with broadcasting calls. For the sake of argument lets assume:
abstract type AbstractPoint{T} end
mutable struct Point{T} <: AbstractPoint{T}
position::Vector{T}
end
where the position
method returns the position
field, assuming that the interface for AbstractPoint
requires that every inheriting type has such a field:
position(p::AbstractPoint) = p.position
As far as I have observed it, a Julia-esque way to update the position
of an instance of Point
and other AbstractPoint
s would be:
position!(p::AbstractPoint, new_pos) = (p.position = new_pos)
Assigning to a getter function?
However, what also appears to work, is to write:
function position!(p::AbstractPoint, new_pos)
position(p) .= new_pos
return nothing
end
The above function only works when broadcasting .=
and, naturally, also for non-mutable versions of Point
. I am not certain why this works, but it enables the reuse of position!
by other subtypes of AbstractPoint
when changing the getter method for position(...)
, i.e., if those subtypes do not have a field position
but rather a composite type that does have a position
field.
This syntax does not work with non-Array types.
The question
Has anyone here ever used the above syntax for a setter function intentionally? In which ways can this cause unwanted effects? I’m still to new to Julia to be familiar enough with the broadcasting system to fully understand the workings of this code. The use cases for this are rather limited, since it only works for Arrays, but my benchmarking attempt has shown no allocations for either version of position!
. Feedback is highly welcome