Questions about traits

While I was reading the document “Traits, Generics and Modern-Day OOP
for Fortran” (version from june 2025), a number of questions and
remarks arose. In no particular order, unless it is in increasing
ignorance :blush:, here they are:

  • In section 5.1.2 you can find an explanation of the union of types. It
    was only at the end of that section that it became clear to me that
    the union refers only to the common features. In the INumeric example
    all the subroutines, functions and operators that are defined for
    integer and real(real64) intrinsic types. Is that correct?

    So, if I were to define an abstract interface of two (derived) types
    that have nothing in common, then the trait would be empty.

    Also, if I add complex to the INumeric trait, I would lose the
    comparison operators, but it would still have a lot of functionality,
    like the basic arithmetic operators and functions like ABS().

  • If I have a trait INumeric with a type set, can I somehow, without
    touching the original implementation (which might not even be
    available), extend the type set? Does that make sense at all?
    After all, if my first observation is correct, then such an extension
    might limit the features covered by the trait.

  • In section 5.6 the := assignment operator is introduced for type
    inference. But what happens if in this case:

    do i := 1,10
    write(,) i**10
    enddo

    The default integer that can accommodate the numbers 1 to 10, will
    fail miserably when it tries to accommodate 10**10,

    So, how useful is this feature, or how error-prone is it? (This
    example is also rather contrived, but still.) I would say that forcing
    the programmer to explicitly declare the type forces them to think
    about what type and kind should be.

  • There can be ambiguity about what traits a type supports, because the
    proposed syntax makes the type and the traits it supports independent.

    Consider:

  ! MyType without any trait
  module basic
      type :: MyType
          ...
      end type MyType
  end module basic

  ! MyType with IPrintable trait
  module with_trait
      use basic
      use mytraits, only: IPrintable

      implements IPrintable :: MyType
          procedure, pass :: output
      end implements MyType
  end module with_trait

  program ambiguous
      use basic
      use with_trait

      ! Which MyType do I have now?
      type(MyType) :: myvar

      call myvar%output    ! Would that be valid?
  end program ambiguous

I can think of several variations on this theme, like
defining two traits with the same name but different features and
attaching them both to the type via a similar route as above.

  • Personally, I do not like to see a “+” sign used for combining
    trait names. Why not “|” as with type sets? The reason is that the
    symbol for the addition operator now gets a new meaning, one which has
    nothing to do with addition. C++ and Java do this with string
    concatenation. Ugh.

Below is just a quick answer to your last question. I’ll answer your other questions in detail tomorrow, as I had a pretty long day.

I am not too fond of it either. The only choice that would have been both logical and sufficiently concise (and moreover consistent with the use of | for the complementary operation), is the & sign (as it is employed for this purpose in Swift). But as you know this is already in use for line continuation in Fortran, so we had to exclude it.

The only other alternative that I see is to use Fortran’s .and., as e.g. in IPrintable .and. ICalculable. This would require you to type five characters instead of one, and to my eyes, at least, it is not nearly as easy to read, since it looks like code that escaped from the 1970ies.

Because it would be the wrong symbol. You want the operation that is complementary to |.

I’ll explain it in more detail tomorrow, but | when applied to interface sets (also known as “types”) means the intersection set, \cap, of all the interfaces supported by the types. Whereas & in Swift, and + in our case, mean the unified set, \cup, of all the interfaces of the types.