User-defined commutative operator in Fortran

Hej everyone,

I have a small technical question regarding user-defined binary operators, essentially for derived types. Say you have implemented two differents types, type_a and type_b and overload the + operator for these. The addition rules for these two types are

  • A + A = A
  • B + B = B
  • A + B = B + A = A

such that it is commutative. What I would typically do is something along the following lines

interface operator(+)
    ! A + A = A
    module function add_aa(a1, a2) result(a3)
        type(type_a), intent(in) :: a1, a2
        type(type_a) :: a3
    end function

    ! B + B = B
    module function add_bb(b1, b2) result(b3)
        type(type_b), intent(in) :: b1, b2
        type(type_b) :: b3
    end function

    ! A + B = A
    module function add_ab(a, b) result(c)
        type(type_a), intent(in) :: a
        type(type_b), intent(in) :: b
        type(type_a) :: c
    end function

    ! B + A = A
    module function add_ba(b, a) result(c)
        type(type_b), intent(in) :: b
        type(type_a), intent(in) :: a
        type(type_a) :: c
    end function
end interface

I was wondering however if there is any way to inform the compiler that + needs to be a commutative operator such that if I define only add_ab it would automatically generate the code for add_ba? For only two types, defining all four combinations is not a big deal admittedly, but I’d like to do that for six or seven different types and I wouldn’t mind simplifying a bit the tedious coding process.

Given the current language capabilities, I believe the only practical option you have is fypp templating: you can generate all interfaces using a double loop on the conformal types.

Polymorphism would be another, but in your case, decisions must be made on what’s the operation’s return type, so besides being slower (runtime type evaluation), it would be also less flexible.

Yep, polymorphism ain’t the way to go here and I figured I could do it with fypp but I was simply curious if there was a native Fortran functionality for that. Apparently not, too bad :slight_smile:

1 Like

Actually, I think your case may probably fit some of the future generics features, because what you’re doing is similar to when you have floating point accuracy being “promoted” to the most accurate type

! the result of this expression is real(real64)
0.0_real32 + 1.0_real64

however, I don’t have enough knowledge to comment on whether/how that may become possible in the future.