Workaround for traditional inheritance features in object-oriented languages

It’s hard to provide an example that’s complicated enough to show the issue without being incomprehensible. It seems I failed :slight_smile:

Let me try to clarify:

computeQpValue() is pure virtual. There’s nothing to call down the chain. The levels of inheritance are (for the most part) adding layers of data that are available to the leaf classes.

In Julia computeQpValue() would definitely be implemented as computeQpValue(x::TimeAverager) and multiple dispatch would admirably fulfill the roll of the virtual function (In fact: I personally believe that multiple dispatch does this job much better than virtual functions for many reasons I won’t go into here).

The problem is how to get the data that’s needed in computeQpValue() for the computation. There are a few options:

1: You “dig”. You do things like x.element_average_value.element_integral.element_uo.time_interface.time

2: You provide single layer “shim” functions like:

time(x::TimeInterface) = x.time
time(x::ElementUserObject) = time(x.time_interface)
time(x::ElementIntegral) = time(x.element_uo)
time(x::ElementAverageValue) = time(x.element_integral)
computeQpValue(x::TimeAverager) = time(x.element_average_value)

3: You use inheritance

(#1) is a bummer for all the reasons I listed earlier.

(#2) is what a lot of Julia codes end up doing now… but it is completely unworkable for large numbers of member variables and deep hierarchies. Check out the massive number of member variables and methods inherited by AuxKernel: http://mooseframework.org/docs/doxygen/moose/classAuxKernel.html to provide shims for each of those would be a major bummer. In addition every time you change one of the fundamental classes to provide a new piece of data you would have to create thousands of shim functions.

Just look at how many objects end up inheriting _t from TransientInterface: www.mooseframework.org: TransientInterface Class Reference

BTW: This is not academic. I’ve actually implemented a massively parallel, multiphysics, finite-element framework using Julia: https://github.com/friedmud/MOOSE.jl and I’m running up against this problem. For what I have done at this point there is nothing too egregious… but if I take it further I’m going to end up in a big mess without some sort of inheritance.

3 Likes