I'm very much enjoying thinking about this and considering what might be 
the most Julian approach

> I thought one problem with not having "proper" inheritance is that this 
doesn't really help? Even small variations across AbstractAtoms types 
require a full implementation?

Actually, I don't think there's any substantial difference with Julia's 
inheritance model. Because if the concrete types share field names, methods 
can still access those fields even when they only know they have an 
abstract type. And if the fields are different, then any inheritance model 
would require a new implementation. The only difference is that in the case 
of same-name fields, the declarations must be repeated for each concrete 
type, which a fairly mild tax given that a macro can do it easily.

> This was my initial thought as well. The problem with that is that the 
Atom and Calculator, NeighbourList and Preconditioner objects are "linked": 
when Atoms is updated, then a "message" is sent to Calculator, 
Preconditioner and NeighbourList so that they can update themselves also. 
The Calculator, NeighbourList and Preconditioner objects in fact store 
additional data that is dependent on the data stored in Atoms.

> Because the same issues arise for NeighbourLists, for Preconditioners and 
potentially other objects that will be linked to Atoms type objects.
 
If you don't even know which objects will be linked when get_forces is 
first called, then I don't think you have any choice but to dispatch twice. 
First on the type of atoms, and second on the type of the internal 
variables, just as you did in your Option 1 code. But I think you can avoid 
the clunkiness by being a bit more fastidious about defining an interface 
for AbstractCalculator, AbstractPreConditioner, etc... and use those 
interface methods instead of just forwarding everything to a more 
specialized version of get_forces. That is, you might have something like 
getparam1(::AbstractCalculator) and then get_forces can directly send it 
a.calc without worrying exactly what type it is. But if the other object 
implementations are so different that no interface is possible, then yeah, 
I think you just have to write a different method for each possible 
combination of types.

Reply via email to