Open certik opened 4 years ago
You probably don't want to use both real(wp)
and result(r)
on the same function
statement.
Let me suggest this revision:
function log10(x) result(r)
real(kind=*), intent(in) :: x ! <- note the "assumed kind" type parameter
integer, parameter :: wp = kind(x) ! no longer a forward reference to x
real(kind=wp) :: r
r = log(x) / log(10._wp)
end
@klausler that's better. Thanks!
@klausler wrote:
You probably don't want to use both
real(wp)
andresult(r)
on the samefunction
statement.Let me suggest this revision:
function log10(x) result(r) real(kind=*), intent(in) :: x ! <- note the "assumed kind" type parameter ..
Though I don't have ready references at the moment, indications are the Fortran standard committee has disfavored the "assumed kind" option, that they have insisted the kind type parameter to be either defaulted or be given by a constant expression. One can see evidence of this with parameterized derived type (PDT) facility starting Fortran 2003 that introduced assumed length parameter option with derived types but no assumed kind; and with assumed type ( TYPE(*) ) and assumed rank ( DIMENSION(..) ) options starting Fortran 2018. It's unclear whether such a position against assumed kind can change in the future.
Note the original post here is but one use case for proper GENERICS in Fortran. Toward generics, it appears the committee is open to the notion of certain UTILITIES e.g., TYPEOF/CLASSOF intrinsic inquiry functions that can employed in dummy argument declarations. In the same vein, I wonder if might be feasible to consider another utility, say ALL_OF, that can be allowed in constant expressions.
Considering the standard states in the context of standard intrinsic modules, "The processor shall provide the named constants, derived types, and procedures described in 16.10.2" and among the constants listed include the KINDs of intrinsinc types such as REAL_KINDS, INTEGER_KINDS, CHARACTER_KINDS, etc., a utility such as ALL_OF can make feasible the following which might make it easier for processors to do the needful, meaning put together all the necessary wiring toward the generic interface needed by a coder, as illustrated in the original post.
function log10(x) result(r)
use, intrinsic :: iso_fortran_env, only : REAL_KINDS
real(kind=ALL_OF(REAL_KINDS)), intent(in) :: x
integer, parameter :: wp = kind(x) ! no longer a forward reference to x
real(kind=wp) :: r
r = log(x) / log(10._wp)
end
The TYPE_OF facility plans for 202X would simplify this usage.
@wclodius2 wrote June 30, 2020 3;40 PM EDT:
The TYPE_OF facility plans for 202X would simplify this usage.
No, it won't - see my earlier reply.
A similar proposal to specify the kind
as an argument: https://github.com/j3-fortran/fortran_proposals/issues/91.
Use case: when one wants to write a function that operates on all kinds, the only way currently is:
One can generate these in various ways (see https://github.com/fortran-lang/stdlib/issues/35 where we discuss various approaches).
Instead, it would be nice if one could write the above as follows:
Where one defines the local variable
wp
with the "working precision" ofx
. This would be a generic function (templated on the "kind"), that is instantiated when used to the actual kind of the input argumentx
at the call site.This would work for subroutines also, e.g.:
The way compilers would implement that is not by "templates" and "instantiation" but by simply immediately generating different versions of the
log10
function for all the precisions that the compiler supports, typically three for reals (sp
,dp
andqp
). So it should be about as fast to compile as the hand written first version above which does this explicitly. And once it is compiled, user code should be as fast to compile as today.