j3-fortran / fortran_proposals

Proposals for the Fortran Standard Committee
178 stars 15 forks source link

US16 TYPEOF and CLASSOF #158

Open certik opened 4 years ago

certik commented 4 years ago

The Committee is discussing a proposal for TYPEOF and CLASSOF.

Proposals:

https://j3-fortran.org/doc/year/19/19-142r1.txt https://j3-fortran.org/doc/year/20/20-114.txt

beddalumia commented 2 years ago

Would this allow to define a function with polymorphic result?

As an example, let's take this (invalid) code:

pure function polymorphic_sum(A,B) result(C)
   class(some_class),intent(in) :: A
   class(some_class),intent(in) :: B
   type(some_class) :: C
   C = [some implementation of A + B]
end function       

Currently my understanding is that C cannot have a polymorphic type (class(some_class) would not be valid, of course, since C is not a dummy argument). A solution might appear to lie in a subroutine then:

pure subroutine polymorphic_sum(A,B,C)
   class(some_class),intent(in)  :: A
   class(some_class),intent(in)  :: B
   class(some_class),intent(out) :: C
   C = [some implementation of A + B]
end function       

But no, latest gfortran complains that C cannot be polymorphic in a pure subroutine, since it's a dummy argument with intent(out) attribute (and I can totally understand this too).

Finally, something like this:

pure function polymorphic_sum(A,B) result(C)
   class(some_class),intent(in) :: A
   type(typeof(A)),intent(in)   :: B
   type(typeof(A)) :: C
   C = [some implementation of A + B]
end function       

In my humble understanding might work, since the type of actual argument passed to dummy A would

I am not so well versed in pure functional programming intricacies, but I cannot see a reason for the purity to be compromised by this: I pass two arguments that must have same actual type, I get out a result of the same type.

Despite I cannot see the real pitfall I have the feeling that it would not really work, but then I cannot wrap my head around how one writes a pure overload for the + operator (or similar) that can be polymorphic via inheritance. Note that this is not multiple dispatch, even if it seems so, since actual arguments passed to A and B must have the same type, making it effectively a single-dispatch case. So I feel it should not be that difficult to achieve.