Those who program using Fortran will be served greatly if, in a future
revision of the standard, some facility is introduced that allows them
to write code that deals with literal constants more expressively and
easily which also improves readability and brings expressions closer
to the principle and ethos of For(mula) Tran(slation).
With literal constants treated as having defaults of the corresponding
intrinsic types and with the default real being required to only have
a decimal precision of 6 and an exponent range of 37, many coders run
to errors or make mistakes with their use of literal constants or end
up with verbose expressions that deviate considerably from
“black-board abstractions†. As readers will know well, examples
include:
integer(kind=IP) :: n
n = 8589934592 ! Can be an error depending on the processor even
if the constant is within the range
! handled by integer(kind=IP)
..
real(WP) :: r
complex(WP) :: c
..
r = 1.0/3.0 ! Can have different precision than
expected by a coder
c = ( 0.55, 0.45 ) ! ditto
..
character(kind=c_char) :: s
s = "Hello World!" ! Missing c_char_ prefix
Given this, can the language introduce a new statement, say
LITERALS_KINDS, which can be applied to a given scoping unit that
specifies the kinds of literal constants in constant expressions used
in that scope? The syntax and rules of LITERALS_KINDS statement can
be similar to that of USE statement but with restrictions similar to
ONLY specifier of needing to include a list and which covers only the
intrinsic types in the language.
So for example, if a coder can do:
module m
..
USE ..
LITERAL_KINDS :: integer => integer(kind=xx), real => real(yy)
..
IMPLICIT ..
..
real(..), parameter :: PI = 4.0*atan(1.0) ! 4.0 and 1.0 literals
treated as if 4.0_yy and 1.0_yy
integer(kind=..) :: i
real(kind=..) :: x
..
i = 2147483648 ! literal treated as 2147483648_xx
x = exp(3.0) ! literal treated as 3.0_yy
..
contains
..
subroutine foo( .. )
..
real(..) :: y
..
y = 2.0*PI ! literal treated as 2.0_yy
..
end subroutine foo
subroutine bar( .. )
..
LITERAL_KINDS :: integer => integer(kind=zz)
..
integer(..) :: n
..
n = 1000000 + n ! literal treated as 1000000_zz
..
end subroutine bar
end module m
and the rules of LITERAL_KINDS statement can be same/similar to those
of USE association in terms of how they apply to a given scoping unit
whether it be a BLOCK construct or a module/submodule procedure, and
so forth.
In the interest of brevity, I am trying not to delve into all the
details but provide only the broad sketch of an idea that is hopefully
clear from the above description. Of course, a lot more effort will
be required to develop a proposal for consideration toward a standard
revision.
But is it possible to obtain informed feedback by the readers on this
list on the technical aspects that can possibly come in the way of
inclusion of such a facility in the standard, at least from a
high-level perspective, the so-called helicopter view? Are any
similar options presently under consideration or on the stack for the
near future, or is it something that has been discussed previously?
Please note I am not concerned as much about the syntax aspects and
its correctness/completeness with respect to some semantic rulesets,
but about the broader idea of having better control of the kinds of
literal constants in code and not be constrained by language defaults
or current stipulations that can lead to considerable verbosity .
Thanks,
Vipul Parekh
|