So I was wondering, if there is any way to implement a behavior that would be similar to Rust traits or Java interfaces. As we know, Fortran OOP is single-inheritance only, which is good, since any kind of inheritance seems to be considered an anti-pattern recently. Interfaces/traits, however, do not permit any data to be added to the type – only methods. This allows for flexible polymorphism without all the constructor/destructor hell.For instance, consider the following pseudocode:
trait StrConvertible
procedure(asstr_proto) :: asStr()
end trait
abstract interface
function :: asstr_proto(self) result(strrepr)
import StrConvertible
class(StrConvertible) :: self
character(len=:), allocatable :: strrepr
end subroutine
end interface
type, extends(Shape), facilitates(StrConvertible) :: Circle
contains
generic :: asStr => circle_asstr
end type
Then one could use it the following way:
subroutine print_anything(s)
class(StrConvertible) :: s
print *, s % asStr()
end subroutine
! ...
type(Circle) :: c
call print_anything(c)
Of course, this is only dream matter. But is it possible to currently perform such pattern, using Fortran 2023 revision? In other words, simulate multiple inheritance, assuming that we only inherit methods but not any actual class-data. The requirement is that it must be dynamically extensible (so when I make a new type that implements method toStr
, it must work with the old code without changing it – a requirement that procedure interfaces in Fortran do not meet, as far as I understand). Perhaps some procedure pointers can be used, but I can’t fully wrap my head around how to do it, since function pointer is a data anyway.
Alternatively, do you guys have any idea how to circumvent these crazy restrictions and write an extensible and flexible code in Fotran? Perhaps some other patterns could be developed to achieve that. I am very curious about your narrow and broad input on the topic.
Have a nice day!
Dominik