From: Dietmar Ebner on
I'm looking into ways to support Fortran 2003 features in Babel [1] -
a language interoperability framework for high-performance computing,
and encountered a couple of obstacles. Hopefully, someone on this list
can help me out. I'm fairly inexperienced with Fortran so please
excuse wrong terminology or misunderstandings.

Babel uses SIDL (Scientific Interface Definition Lanuage) in order to
declare the public interface of components. SIDL supports a
traditional Java-like object model with single inheritance and
multiple implementation of interfaces. There's two things in F03 I'm
particularly interested in, i.e., C interoperability and the new OO
features such as type-bound procedures and type extension. BIND(C)
seems to work mostly fine for us, but there are two issues in
supporting object oriented paradigms that came up:

a) There's at most one type an extended type can derive from. This
makes it somewhat unnatural to support interfaces. Our current
approach is to generate unrelated types that represent interfaces
along with cast procedures that implement both up- and down-casting
(as we do for Fortran 90). However, this feels somewhat unnatural to
users so we would be interested in alternative suggestions.

b) We would like to support type-bound procedures. However, I ran into
an issue with module interdependencies that seems to be a major
obstacle. There's nothing in SIDL that prevents the user from passing
objects and interfaces as arguments. This frequently leads to circular
references both in user code and in Babel's runtime library. Here's a
simple example:

module A_mod
type A
contains
procedure :: a => A_a
end type A
contains
subroutine A_a(self, my_b)
class(A), intent(in) :: self
class(B), intent(in) :: my_b
end subroutine A_a
end module A_mod

module B_mod
type B
contains
procedure :: b => B_b
end type B
contains
subroutine B_b(self, my_a)
class(B), intent(in) :: self
class(A), intent(in) :: my_a
end subroutine B_b
end module B_mod

Both A and B reference each other leading to circular build
dependencies. Related threads suggest submodules [2] as a way to
separate type declarations and method implementation (This is also
what we do for Fortran 90 bindings). I can see how this would work for
regular procedures calling each other. However, submodules seem to
require to spell out the interface explicitly in the type declaration.
If the circular references are caused by the argument types, this
would re-introduce use-dependencies among the type modules (unless I'm
missing something). Also, submodules don't seem to be widely supported
yet.

One solution I can think of is to create an abstract dummy type T' for
each type T replacing all references to T with T' in interface
declarations. This would break the dependencies but would require the
user to explicitly down-cast function results and out arguments, which
is something we don't really like. Hopefully, somebody out there can
suggest a better solution.

Thanks in advance and sorry for the lengthy posting,

Dietmar

[1] https://computation.llnl.gov/casc/components/index.html
[2] http://www.iso.org/iso/catalogue_detail.htm?csnumber=37995

--
Dietmar Ebner
Center for Applied Scientific Computing
Lawrence Livermore National Laboratory E: ebner(a)llnl.gov
Box 808, L-422 T: (+1 925) 422-0055
Livermore, CA 94551-0808 F: (+1 925) 423-5951