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 AbstractPoints 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 ![]()