JuliaDynamics / Agents.jl

Agent-based modeling framework in Julia
https://juliadynamics.github.io/Agents.jl/stable/
MIT License
725 stars 117 forks source link

Design the new `@agent` macro #869

Closed Tortar closed 11 months ago

Tortar commented 1 year ago

I'm designing the new macro (I will dispatch on the same macro @agent, with the old syntax deprecated in favor of the new one, but both usable with @agent)

Currently we agreed to something like:

@agent GridAgent{2} struct NewAgent <: Foo
    x::Int
    const y::Int
end

but I don't like it since it is not intuitive so I propose something like

@agent struct NewAgent <: Foo
    GridAgent{2}
    x::Int
    const y::Int
end

which to me seems much better

Tortar commented 1 year ago

@Datseris I would really like to hear your opinion on this :-)

Tortar commented 1 year ago

I’m even inclined to export a utility function fieldsof to improve it further to

@agent struct NewAgent <: Foo
    fieldsof(GridAgent{2})
    x::Int
    const y::Int
end
Datseris commented 1 year ago

I still think

@agent GridAgent{2} struct NewAgent <: Foo
    x::Int
    const y::Int
end

is the way to go because it doesn't confuse a Type with the fields. I also think it is the most intuitive way to go.

Datseris commented 1 year ago

how does default values to fields work here? can you also do

@agent GridAgent{2} struct NewAgent <: Foo
    x::Int
    const y::Int
   z::Real = 0.5
end
Tortar commented 1 year ago

However for what regards the macro I still really like the alternative with the other syntax though, since it makes it clear that the base_type is used only to paste its field in the new struct, notice that even

grid_agent_fields = fieldsof(GridAgent{2})
@agent struct NewAgent <: Foo 
    grid_agent_fields 
    x::Int
    const y::Int
    z::Real = 0.5
end

works, which seems very clean and easy to grasp. In practice the only difference to a normal mutable struct is that the first field is special.

Tortar commented 1 year ago

Sorry for the back and forth, actually everything works in respect to default values

Tortar commented 12 months ago

mmh I'm considering that the agent from which we inherit fields can be also used to define a new abstract type from which the new created agent can be a subtype, maybe it is better to use your version, since in the end we will not use only the agent to inherit fields.

What I'm thinking we can do is:

This would allow us to dispatch on these abstract version internally, which can be good e.g. for allowing NoSpaceAgents along side SpaceAgents in an easy way.

Tortar commented 11 months ago

I revisioned #870 and merged it, hopefully it should be alright, maybe this topic still needs a small PR revising docs, but I ensured to write about the change everywhere it needs to :-)