On Wednesday, 4 February 2015 18:30:06 UTC, Josh Langsfeld wrote:
>
> 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.
>

If I read this correctly, then what you are saying is that I am allowed to 
assume that my concrete abstract subtypes will contain certain fields, and 
if they don't then too bad for them, they need to go and re-implement some 
of the structure that I provide for AbstractAtoms.


> 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.
>


How about this then; in this case a new AbstractAtoms sub-type or a new 
AbstractCalculator sub-type would not need to implement the "interface" 
get_forces(a), but only the get_forces(a, c).

type Atoms <: AbstractAtoms
   X
   calc
   neigs
   precon
end

get_forces(a::AbstractAtoms) = get_forces(a, a.calc)

or even, as Avik Sengupta suggests, if an AbstractCalculator  `c` has a 
field c.atoms, with   a.calc.atoms == a, then I could even call

get_forces(a::AbstractAtoms) = get_forces(a.calc)

function get_forces(a::AbstractAtoms, c::AbstractCalculator)
   ta = typeof(a); tc = typeof(c)
   error("get_forces(::$ta, ::$tc) has not been implemented")
end


Thanks, I really appreciate this discussion.
    Christoph


 

Reply via email to