All the time! Usually when calling a generic procedure. Here’s two random snippets from two very different projects:
select type(value)
class is (AbstractValue)
call this%insert(trim(name),value)
type is (integer)
call this%insert(trim(name),newValue(value))
type is ( logical )
call this%insert(trim(name),newValue(value))
type is ( real(KIND=DP))
call this%insert(trim(name),newValue(value))
type is (character(len=*))
call this%insert(trim(name),newValue(value))
class default
print*, "wrong attribute type insertAttribute0"
end select
...
select type (values)
type is (integer(int8))
status = nf90_get_var(ncid, varid, values)
type is (integer(int16))
status = nf90_get_var(ncid, varid, values)
type is (integer(int32))
status = nf90_get_var(ncid, varid, values)
type is (real(real32))
status = nf90_get_var(ncid, varid, values)
type is (real(real64))
status = nf90_get_var(ncid, varid, values)
type is (character(len=*))
status = nf90_get_var(ncid, varid, values)
class default
status = NF90_EBADTYPE
end select
Mixing unlimited polymorphic types and generic procedures is currently quite painful, and almost always involves a lot of copy-pasting.
Could it not be something along the lines of “when there are multiple types in the argument of type is, the subsequent block is expanded as if it had been written once for each type”. So that the compiler rewrites
select type(variable)
type is (type1[, type2, type3, ...])
<expression>
end select type
literally as
select type (variable)
type is (type1)
<expression>
type is (type2)
<expression>
type is (type3)
<expression>
...
end select type
This sort of rewriting is also being proposed in C++, in the proposed template for as part of the reflection proposal.
This syntactic sugar would probably also go a long way to enabling lots of generic programming without needing to add new syntax, although really one would want compile-time generic programming. A massive downside to the above is that type errors can only be caught at runtime.