Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

If a deferred-type is instantiated with an extensible type, and passed a polymorphic object, does the object stay polymorphic? #123

Open
aury6623 opened this issue May 14, 2024 · 1 comment

Comments

@aury6623
Copy link
Contributor

Example:

module m
contains
    function tmpl{T}(obj) result(r)
        type(T) :: obj, r
        r = obj
    end function
end module

use m
type :: mytype
    integer :: x
end type
type, extends(mytype) :: myext
    integer :: y
end type

instantiate tmpl{mytype}
class(mytype), allocatable :: a, b

allocate(myext :: a)
b = tmpl(a)
print *, same_type_as(a, b)

end

After the assignment to b, what is the dynamic type of b? In other words, does same_type_as(a, b) print T or F?

If this was without templates, and tmpl was just a traditional function that took a type(mytype) argument, then the answer would be b has dynamic type mytype and the program would print F. The function invocation would "cast" a, which has dynamic type myext, to the nonpolymorphic dummy argument of type mytype, losing the "polymorphicness" of the object. Then the mytype result would be assigned back to b.

However, for a template, I think it could be useful for the type to retain its polymorphism, and return T. Yes, the template could use a deferred class, however that prevents using intrinsic types with that template.

Lets say you wanted to make a container template. If you want the container to accept both intrinsic types and polymorphic objects (without losing their polymorphicness), you'd have to either make two container templates, one with deferred-type and one with deferred-class, or you'd have to pick one and use a derived type wrapper object to handle the other.

It seems like it should be possible for the compiler to say "this template was instantiated with a non-abstract extensible type, so I'll replace all these TYPE(T) declarations with CLASS(T), ALLOCATABLE to allow polymorphic objects to work". However I'm aware that could come with a performance cost.

Perhaps there could be a mechanism for saying that a deferred type is always non-poymorphic, or always polymorphic, OR "automatic" based on the type used at instantiation. For example, using the syntax from #120, it could be

TYPE, ABSTRACT, DEFERRED :: polymorphic       ! Can only be used with CLASS
TYPE, DEFERRED :: nonpolymorphic              ! Can only be used with TYPE
TYPE, AUTOMATIC, DEFERRED :: possibly_either  ! Can only be used with TYPE, but acts like CLASS if the instantiation type is extensible

I'm not really sure what the best wording for the keywords would be. AUTOMATIC doesn't seem great. But the idea is there!

@aury6623
Copy link
Contributor Author

During the meeting today we decided the answer is no and this is not something we have time to look into right now. Maybe later.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant