gama.old
gama.old copied to clipboard
Implement traits aka mixins aka gaml skills (composition of independent behaviours)
Is your request related to a problem? Please describe. The single-inheritance model provided by GAMA 1.8 is good for extending behaviours, but does not provide an easy way to compose multiple independent behaviours into a single agent. Currently this can be done only by copy and paste, as far as I know. Skills, on the other hand, represent a very good example of behaviour composition, but can only be defined by extending GAMA with some Java classes.
Describe the solution you'd like
I would like GAMA to allow me to define traits and attach them to species. These traits could actually be called skills, and the current Java-based skills could become just a special case of them. So we would have normal skills defined in gaml and native skills which are implemented in Java (because they need to mess with the internals of GAMA or need to call native libraries or whatever).
Here is a quite simple example of how I imagine it would be used:
skill wanderer implies: [moving] {
point targetLocation;
float wanderDistance <- 1.0 min: 0.0;
reflex reachTarget when: targetLocation != nil and location distance_to targetLocation > wanderDistance {
do goto target: targetLocation;
}
reflex wanderAroundTarget when: targetLocation != nil and location distance_to targetLocation <= wanderDistance {
do wander;
}
}
skill talker {
float talkDistance <- 1.0 min: 0.0;
species<agent> genericTargetSpecies <- agent;
action talk(agent other) virtual: true;
reflex talkToOther {
loop other over: agents at_distance(talkDistance) of_generic_species genericTargetSpecies {
do talk(other);
}
}
}
species person {
// whatever
}
species pusher parent: person skills: [wanderer, talker] {
action talk(agent other) {
write "selling absolutely legal stuff to " + other;
}
}
Describe alternatives you've considered The logical alternative to traits is multiple inheritance. But we all know that multiple inheritance is evil and that we should prefer composition whenever possible.
Another alternative could be to implements traits as a separate concept from skills, but I don't see the point in doing this, as probably the only different between traits and skills would be the fact that skills are implemented in Java.
Additional context There are of course many details to smooth out. For example, what is exactly the behaviour of skills/traits compared to inheritance? I would say that while inheritance creates a chain of species and lookup is performed recursively, skills are behaved as if their code was copy-pasted in the current species.
Also, what happens if a child species re-includes a skill already included in the parent class? I would say that this should be a no-op, but someone might want to include the skill talker (from the example above) twice, with different distance limits and target species. This would be possible with named skills, which would behave as composition through instance variables, but with reflexes merged into the containing species. This feature would be complex and very advanced, and might not be worth to implement. It can be left aside and implemented at a later time, if and when it is deemed useful enough.
Enhancement already proposed in #362, then abandoned... It is of course a logical evolution of GAML.