Refactor signatures for overloading
Closed this issue · 4 comments
This thread made me realize that some functions are not easy to overload e.g. in 5.17 there was
move_agent!(agent::A, pos::ValidPos, model::ABM{<:ContinuousSpace{D},A}) where {D, A<:AbstractAgent}
which I wasn't able to find a way to overload with invoke
.
In 6.0 it is instead
move_agent!(agent::AbstractAgent, pos::ValidPos, model::ABM{<:ContinuousSpace})
which I understood how to overload.
Maybe it is a problem of understanding, but it seemed impossible to overload that signature. So I think that changing the signatures for easier overloading can be useful.
cc. @Datseris
I am sorry, I didn't understand the problem... :D
What does "overload" mean? Does it mean to add a new signature to the function move_agent
? If so, why does it matter what are the previous signatures it has?
Why is the second call signature easier to overload? I understand that it is a simpler signature, but what makes it easier to be "overloaded" (what this means not clear to me yet)?
this means to have this kind of behaviour:
# works in dev version, not in 5.17
using Agents
abstract type AbstractTurtle <: AbstractAgent end
@agent Turtle ContinuousAgent{2} AbstractTurtle begin end
function Agents.move_agent!(turtle::Turtle, pos::Agents.ValidPos, model::ABM{S}) where {S <: ContinuousSpace}
start = turtle.pos
invoke(Agents.move_agent!, Tuple{AbstractAgent, Agents.ValidPos, ABM}, turtle, pos, model)
println("Turtle started at $start, ended at $(turtle.pos)")
end
model = AgentBasedModel(Turtle, ContinuousSpace((50, 50)))
agent = add_agent!(model, (1, 0))
move_agent!(agent, (1,1), model)
walk!(agent, (2.0, 2.0), model) # even if I didn't touch walk!, it calls the new move_agent!
so in this case you can change all the methods calling move_agent!
in one shot (clearly you must know what you are doing though: https://docs.julialang.org/en/v1/base/base/#Core.invoke). The user in that thread gave a good enough motivation for the usefulness of such a feature in my opinion.
When you ask why is the second signature is easier to overload I'm not entirely sure but it seems to me that the signature in 5.17 is at the same level of specificity of a user definable function as above which means that Julia can't understand which one you want to use when calling move_agent!
.
Okay, but isn't this issue solved in v6?