Readers may be want to take a look at this suggestion at the J3 Fortran proposals site to alleviate the problem currently with default real which, colloquially stating, is single-precision:
opened 04:12PM - 11 Nov 19 UTC
Clause 7
A proposal from UK national body from year 2013: https://wg5-fortran.org/N1951-N… 2000/N1975.txt
```
--------------------------------------------------------------------------
Number: UK-01
Title: Default KINDs for constants and intrinsics
Status: For Consideration
Basic Functionality:
Program-specified default KIND for constants etc.
Rationale:
(a) In the 64-bit world default integer generally being 32-bit is
increasingly leading to incorrect programs.
(b) In the floating-point world default real generally being 32-bit
not infrequently leads to incorrect programs.
(c) It is tedious and error-prone to have to attach kind_param's to
individual literal constants.
(d) It is tedious and error-prone to have to specify a KIND= argument as
required for each individual reference to an intrinsic function.
(e) Program specification of the default type parameters is possible for
derived types but not intrinsic types.
Specification (requirements):
1. Provide a mechanism for specifying the default kind parameter for the
intrinsic types REAL and INTEGER.
2. Decouple the concepts of "default kind" from those of "single precision"
and "basic integer"; "default kind" to be used for literal constants,
implicit typing, etc., while "single precision" et al to be used for the
old storage association contexts.
Discussion:
Specifications (detailed):
--------------------------
a. There will be a new statement, that can appear only between the USE
statements and IMPLICIT statements, to specify the default kind for a
particular intrinsic type.
b. The effect of this statement is to change the default kind for the
remainder of the scoping unit. To avoid circular dependencies, it does
not affect the default kind of literals appearing in or before the
statement itself, nor does it affect the type implied by a PARAMETER
statement that appears before the statement.
Rationale: circular dependencies bad, named constants good.
c. The default kind setting in a scoping unit is initially that of its
host scoping unit; note that as nested scoping units appear necessarily
after any IMPLICIT statements, this will inherit the user setting.
d. In the case of REAL, the default kind for COMPLEX is also affected.
It does not affect double precision kind, which remains as twice single
precision in storage.
e. Terminology:
"default kind" = user-specifiable default kind
"single precision kind" = old default real kind
"basic integer kind" = old default integer kind
f. OPTIONAL: There is a reasonable argument to be made that permitting the
user to specify the kind for "double precision" constants and variables
would also be valuable.
g. Table of places where "default kind" is used, and what that should
correspond to in the new scheme, follows.
Context Should be
---------------------------------------------------------
(1) integer literal with no <kind-param> default kind
(2) "kindly" intrinsics with absent KIND= default kind * Note T0
(3) intrinsics with no KIND argument default kind * Note T1
(4) <type-spec> with no KIND parameter, e.g. REAL default kind * Note T2
(5) arguments to generic intrinsics accept both * Note T3
(6) args/result for specific intrinsics, e.g. AMIN1 basic kind * Note T4
(7) constants in ISO_FORTRAN_ENV basic kind * Note T5
(8) having the size of one numeric storage unit basic kind
(9) EQUIVALENCE/COMMON real/integer matching basic kind
Note T0.
This includes LBOUND, LCOBOUND, SIZE, SHAPE ... i.e. all the ones that
have a KIND= argument and return a REAL/INTEGER/COMPLEX result of the
specified kind when present, and default kind when not.
Note T1.
Actually these don't really matter much, as the value always fits into
basic kind. However, it would be more convenient when passing as an
actual argument, and more consistent, for these to be the new
user-specifiable default kind too. Here is a representative list of
the intrinsics concerned: DIGITS, PRECISION, RANGE, EXPONENT,
MAX_EXPONENT, and THIS_IMAGE.
Note T2.
Wherever the <type-spec> is, viz a type declaration statement, component
definition statement, array constructor, etc.
Note T3.
The affected intrinsics:arguments are DATE_AND_TIME: VALUE,
EXECUTE_COMMAND_LINE:EXITSTAT,CMDSTAT, GET_COMMAND:LENGTH,STATUS, and
similar. Not a big deal (values always representable in the basic kind)
but why not relax the requirement to permit larger kinds always anyway?
Note T4.
Not actually important. These are wholly redundant anyway.
Note T5.
As if it were a user-defined module with those constants.
Syntax (illustrative):
----------------------
DEFAULT <intrinsic-type-name> ( [ KIND = ] <int-constant-expr> )
where <intrinsic-type-name> is INTEGER or REAL.
Cnnn (Ryyy) The kind number specified in a DEFAULT INTEGER statement
shall specify a kind whose storage size is at least as great as that
of basic integer kind.
{Reason: To stop the user shooting his foot off with a short integer
kind.}
OPTIONAL: If we permit specification of double precision kind, add this
additional syntax:
DEFAULT DOUBLE PRECISION ( [ KIND = ] <int-constant-expr> )
Cnnn The kind number specified in a DEFAULT DOUBLE PRECISION
statement shall not specify a kind whose storage size is less than
that of default real kind.
{Reason: There might not be a bigger real kind than the user-specified
default, but it would be counter-intuitive to permit
specification of a double precision kind that is actually
smaller than default real.}
Example:
--------
This is just to show how it works, it is too trivial to show much
advantage.
Program sum_tan_prefix
Default Integer (Kind=Selected_Int_Kind(18))
Default Real (Kind=Selected_Real_Kind(15))
Real,Allocatable :: x(:)
Print *,'Input vector length N'
Read *, n
If (n<2) Stop 'Don''t be silly.'
Allocate(x(n))
Print *,'Input vector with',Size(x),'values in degrees'
Read *,x
tmp = 0
Print *,'SUM_TAN_PREFIX results'
Do i=1,Size(x)
tmp = tmp + Tan(x(i)*3.1415926535897932384/180)
Print *,i,x
End Do
End Program
```
Take a look also at the other thread at this site on NAMESPACE
s.
opened 08:02PM - 15 Nov 19 UTC
Clause 14
@FortranFan wrote in https://github.com/j3-fortran/fortran_proposals/issues/86#i… ssuecomment-554205627:
I have long debated in my own mind whether Fortran should formally introduce the concept of NAMESPACEs or whether MODULEs can themselves be elevated to first-class namespaces. Looking at the proposal at #86 and with #1, I'm presently inclined toward the former.
Whilst I don't quite have a list of the requirements and specifications necessary toward an initial proposal, a sketch of the idea is to include either a new NAMESPACE scope and/or NAMESPACE attribute to MODULEs in addition to PUBLIC/PRIVATE visibility of MODULEs in a NAMESPACE. Then a given NAMESPACE can IMPORT other NAMESPACEs. Fortran can formally define a GLOBAL namespace and state all EXTERNAL MODULEs (a la external procedures) in a program are part of this namespace. The language can then have some rules for name qualification and aliasing. Code then might look like the following with illustrative syntax:
```fortran-modern
namespace my_lib
public module constants
real, parameter :: PI = 3.14
end module
private module utils !<-- can be USE'd only by modules in the same namespace
interface
module subroutine draw()
end subroutine
end interface
end module
end namespace
namespace my_lib !<-- A namespace can be extended with more modules
public module solver
use constants, only : PI !<-- It can USE modules from the same namespace
contains
function calcradius( a ) result( r )
real, intent(in) :: a
result :: r
r = sqrt(a/PI)
end function
end module
end namespace
namespace global !<- optional, for 'global' namespace will exist by default
import my_lib, only : constants, solver ! import 'public' modules only from another namespace
program p !<-- A program unit can only be part of GLOBAL namespace
use constants, only : PI !<-- does not 'clash' with my_lib::constants
real :: area
print *, "PI = ", PI !<-- PI from USE-associated 'constants' module
area = 100.0
associate ( PI => my_lib::constants%PI, calcrad => my_lib::solver%calcradius )
print *, "circumference = ", 2.0*PI*calcrad(area)
end associate
end program
end namespace
```
Note the above is based on the use cases in #1 and #86; once more use cases are brought to light, it might help refine the idea of a NAMESPACE.
Notice a comment I just added there with a thought I long had which is to employ @certik ’s NAMESPACE
concept further to give more control to the users to specify “package” wide (aka namespace wide) defaults for various things:
With respect to the original post here toward the proposal for a “proper” NAMESPACE
facility in Fortran and given also discussions on this forum (#78 ) and requests elsewhere regarding the default kind of constants (and perhaps) intrinsics, the thought also is the NAMESPACE
to be able to define such defaults and to have all the enclosing modules to “inherit” the defaults:
namespace n
default real ( kind=selected_real_kind( p=12 ) )
..
module m
..
end namespace
namespace(n) module m
! the default kind of real literal constants shall be the one defined in the enclosing module which has a precision of 12
..
end module
3 Likes