From Bernard.Pichon@obspm.fr  Fri May 31 17:55:02 1996
Received: from mesiob.obspm.fr (mesiob.obspm.fr [145.238.2.2]) by dkuug.dk (8.6.12/8.6.12) with ESMTP id RAA25637 for <sc22wg5@dkuug.dk>; Fri, 31 May 1996 17:54:56 +0200
Received: from MESIOB.OBSPM.FR by MESIOB.OBSPM.FR (PMDF V4.2-14 #2584) id
 <01I5D4TQVON40023AV@MESIOB.OBSPM.FR>; Fri, 31 May 1996 18:00:34 +2
Date: Fri, 31 May 1996 18:00:33 +0002
From: "Bernard PICHON <pichon@obspm.fr>, Fax:(33-1)45077971"
 <Bernard.Pichon@obspm.fr>
Subject: FRANCE (AFNOR) contribution for Fortran 2000 proposals (PART TWO)
To: Miles.Ellis@etrc.ox.ac.uk, jkr@letterbox.rl.ac.uk, sc22wg5@dkuug.dk,
        lignelet@vcnam.cnam.fr, Michel.Olagnon@ifremer.fr,
        Bourstin@saturne.afnor.fr, Hebert@ajax.serma.cea.fr
Message-id: <01I5D4TQWU2Q0023AV@MESIOB.OBSPM.FR>
X-VMS-To: @F90_ISO
X-VMS-Cc: @F90_FR,PICHON
MIME-version: 1.0
Content-type: TEXT/PLAIN; CHARSET=US-ASCII
Content-transfer-encoding: 7BIT


FORTRAN 2000 Requirements Submission by AFNOR (FRANCE) --- PART TWO ---

    E-Mail : Bourstin@saturne.afnor.fr 

Working Group with :
    Patrice LIGNELET       Lignelet@vcnam.cnam.fr
    Bernard PICHON         Pichon@obspm.fr
    Michel OLAGNON         MOlagnon@ifremer.fr


Status : FOR CONSIDERATION

Summary :
     Some new elemental intrinsic functions, see  A)
     A new keyword for the bit manipulation functions, see B)
     About reserved keywords in Fortran, see C)
     Some improvements for the I/O's, see D1), D2) and D3)
     Some improvements in array uses, see E1), E2) and E3)
     Miscellaneous, see F)

============================================================================
============================================================================

A) Four new elemental intrinsic functions : TRUNCATE, ROUND, IBCHNG, ICOUNT

Basic Functionalities :
   TRUNCATE (X,N) truncates X within N digits;
   ROUND (X,N) rounds X within N digits;
   IBCHNG (I,POS) reverses the bit at position POS in I ;
   ICOUNT(I) counts the number of bit with the value 1 present in I .

Rationale : These functions may be useful in various applications

Estimated impact : None (on existing programs, apart a name conflict with an 
                   another existing IBCHNG function in an user program).

Detailled Specifications :
    TRUNCATE(X,N) truncates X (integer or real numbers) within N digits.
                  The result is arithmeticaly true is X is integer.
                  If X is real, the result value (in base 10) is the
                  nearest number close to the true mathematicaly truncated
                  value (this result value is the same as the result 
                  obtained by an appropriate formatted output).
                  If N is negative, no action is done.
                  Examples : TRUNCATE(1254,2)  is 1200
                             TRUNCATE(1.2512,3) is 1.25

    ROUND(X,N) rounds X (integer or real numbers) within N digits.
               The result is arithmeticaly true is X is integer or
               HUGE(X), with the sign of X, if the result exceeds
               the range of the processor.
               If X is real, the result value (in base 10) is the
               nearest number close to the true mathematicaly rounded
               value (this result value is the same as the result
               obtained by an appropriate formatted output) or 
               HUGE(X), with the sign of X, if the result exceeds
               the range of the processor.
               If N is negative, no action is done.
               Examples : ROUND(1254,2)  is 1300
                          ROUND(1.24712,3) is 1.25

    IBCHNG(I,POS) reverses the bit at position POS in integer I .
                  Example : IBCHNG(12,2) is 8

    ICOUNT(I) counts the number of bit with the value 1 in I .
              Example : ICOUNT(12) is 2

=============================================================================
=============================================================================

B) A tentative new keyword PATTERN= in bit manipulation functions such as
        IBCLR, IBSET, IBCHNG .

Basic Functionality :
    Using this keyword, it will be possible to apply the functions
        IBCLR, IBSET, IBCHNG for a set of bit positions. 

Rationale :
    With the existig functions IBCLR and IBSET (and the new one that
    we propose : IBCHNG), it is not possible to apply these functions
    for a set of bit positions since if the actual existing argument POS
    is array valued, depending either X is scalar, the result is conformable
    with POS, or X is array valued and must be conformable with POS but
    the result is not obtained in applaying POS to each element of X.

Estimated impact : None (on existing programs)

Detailled Specifications : 
    With the array-valued keyword PATTERN=<array>, which is incompatible
    with the keyword POS=, allow to apply the functions IBSET, IBCLR and
    the (new one) IBCHNG to the I (either scalar or array valued) for
    each value of <array>, rank one array of default integers.
    If FONC is either IBSET, IBCLR or IBCHNG,  J = FONC(I,Pattern=A) is 
    equivalent as :  J = I
                     Do ind = LBOUND(A), UBOUND(A) 
                        J = FONC(I,POS=A(ind))
                     End Do
    
    Examples : IBSET( (/ 12,6 /) , Pattern=(/ 0,4 /) ) is (/ 29,23 /)  
      whereas  IBSET( (/ 12,6 /) , Pos=(/ 0,4 /) ) will be (/ 13,22 /)
               IBCLR( (/ 28,22,15 /) , Pattern=(/ 4,2 /) ) is (/ 8,2,11 /)  
      whereas  IBCLR( (/ 28,22,15 /) , Pos=(/ 4,2 /) ) is in error

=============================================================================
=============================================================================

C) About reserved words in Fortran 20xx

Basic Functionality : 
    Let us declare as obsolete the use of keywords and other (to be reserved)
    words  (for instance, the newer keywords) of Fortran as identifiers. 
    A such use will be flaged as warnings by the compilers (during a
    fixed time, to be determined).

Rationale : A such thing will be very useful for compiler writers but
            also for programmers BUT

Estimated Impact : VERY STRONG . It is the reason why, we propose to inform
                   the user by a warning during a few revisions of the
                   standard, say 10 years or more, BUT this will be done. 

Detailled Specifications : 
    For each occurence of a word of the language (statement, function or
    subroutine name, keywords ...) user as a (user defined) specifiers, 
    names, the compiler must flag (either with the use of a compiler option
    or by default) this use by a warning. 

=============================================================================
=============================================================================

D) Some improvements for the I/O's

D1) New keywords READ_EOR, READ_EOF, WRITE_EOR (?), WRITE_EOF (?) in 
     INQUIRE statements.

Basic Functionality : A way to obtain by the processor itself and for a 
                      given logical unit or for a given file, the various
                      IOSTATUS code returned by the processor for the
                      conditions End_Of_Record or End_Of_File associated
                      with READ or WRITE (?) actions. 

Rationale : In fact, the standard does not give the exact values of the
            status code returned by the processor for such conditions.
            Only their sign (-) is determined with the restriction that
            the value associated with EOR must be different with the one
            associated with EOF. Thus, these values are processor dependent.
            By this present requirement, we propose a way to obtain for a 
            given processor, its real values. Its seems that new keywords in
            the INQUIRE statement is the most natural choice in view of 
            Fortran use of this statement. 
   
Estimated Impact : None (on existing programs)
   
Detailled Specifications :
   For a given logical unit (use of INQUIRE by keyword UNIT= ) or for a 
   given (connected) file (use of INQUIRE by keyword FILE= ), the use
   of keyword READ_EOR = ios returns in the default integer variable ios
   the real value of IOSTAT as returned in a End_Of_Record condition that 
   may be occur in a READ action for this logical unit or for this file.
   In fact, this real value may depend on the kind of devices (e.g. keyboard,
   tape device, disk ....).
   The same applies for READ_EOF keyword, and, if necessary, for WRITE_EOR
   and WRITE_EOF for WRITE actions.

History : Already proposed by France for 1539-2 standard on Varying Length
          Character Strings. 

-----------------------------------------------------------------------------

D2) New keywords IS_EOR and IS_EOF in INQUIRE, READ and WRITE statements.

Basic Functionality : A way to obtain by the processor itself, for a given 
                      logical unit or a given file, the certainty that the
                      processor has really encountered an End_Of_Record 
                      condition or an End_Of_File condition during the 
                      associated READ or WRITE statements or by a separate
                      test with INQUIRE statement. 

Rationale : In the same spirit that the previous requirement, this one,
            without the knowledge of the the real IOSTAT code value, allows
            the user to be informed of the exact kind of End_Of_something
            condition that has occured. 

Estimated Impact : None (on existing programs)
   
Detailled Specifications :
   In READ, WRITE or INQUIRE statements, the keyword IS_EOR = log returns 
   in the default logical variable log the value .TRUE. if the error that
   has occured can be consider as a End_Of_Record condition, .FALSE. 
   otherwise. The same for keyword IS_EOF concerning the End_Of_File 
   conditions. 

-----------------------------------------------------------------------------

D3) New keywords DEFAULT_READ and DEFAULT_WRITE in INQUIRE statement

Basic Functionality : A way to obtain the logical unit number associated, 
                      for a given processor, with the default read unit or
                      the default write unit. After what, this number can
                      be used freely to (re)direct I/O to a given logical
                      unit (previously connected by an OPEN statement) or
                      to the default I/O device.

Rationale : In fact, the standard does not give any fixed values for the 
            default logical units used by the processor. Hence, it appears
            impossible to (re)direct some I/O to the default device in 
            using only I/O statements. This can be done only with tests
            and duplication of I/O code, first time for one (or more)
            logical unit(s) previously connected by an appropriate OPEN
            and callable by the logical unit number and the second time
            only for the case of default device. 
            Compare this very simple example (for demonstration only):
            !
            ! to write data in a file but from time to time also on display
            !     
            If (MOD(n_record,10)== 0) Then
                Write(Unit=my_file,FMT=my_format) my_data
                Write(*,FMT=my_format) my_data
            Else
                Write(Unit=my_file,FMT=my_format) my_data                                                                
            End If
            !
            with this one, which will become possible with this requirement :
            !
            INQUIRE ( DEFAULT_WRITE = display )
            ......
            Write(UNIT=my_file,FMT=my_format)  my_data
            If (MOD(n_record,10)==0) Write(Unit=display,FMT=my_format) my_data
            !
            Also, with this logical unit number, it becomes possible to
            modify the characteristics of the default devices, for example,
            for displaying 132 characters on an appropriate display .....
            by the correct OPEN statement, OR, more simply, to know the 
            default characteristics of these default devices by an INQUIRE
            statement.
            
Estimated Impact : None (on existing programs)
   
Detailled Specifications :
   In INQUIRE statement, the use of keyword DEFAULT_READ = nunit 
   returns in the default integer variable nunit the logical unit number 
   that corresponds to the default input unit for this processor. 
   The same with keyword DEFAULT_WRITE for the default output device. 
   After that, this number can be used freely to (re)direct I/O to the 
   default I/O device (see example in the Rationale section).
   Remark : On many computers, the value returned by DEFAULT_READ= may 
            be 0 or 5 and for DEFAULT_WRITE= 1 or 6 .....

   An supplementary syntax, using OPEN statement, would be :
        OPEN ( Unit=nunit , Default_Read , .... )   or
        OPEN ( Unit=nunit , Default_Write , .... )
   It allow an user-defined logical unit number nunit for the default input
        or output device.

=============================================================================
=============================================================================

E) Some improvements in array uses 

E1) The consideration of an array as a single whole object  
                        AND
    POINTER attribute for array valued functions


Basic Functionality : Possibility to consider an array as a single whole 
                      object

Rationale : It appears that the present standard does not allow expressions 
               as MAXLOC(X(:))(1) or RESHAPE(X,(/n,n/))(:,n)
            It would be very interesting and useful to enforce the 
               consideration of an array as a single whole object, by the 
               use, for exemple, of parenthesis as in usual mathematical 
               expression.
            It also avoid to copy the result of many functions in temporary 
               local arrays. 
            Hence, we could write : 
                index = (MAXLOC(X(:))(1) (but see also F95)   or
                Y = (RESHAPE(X ,(/n,n/)))(:,n)
            With the POINTER attribute affected to MAXLOC, it becomes 
                possible to write statement such as : 
                P => MAXLOC( X(:) ) ; index = P(1)

Estimated Impact : None (on existing programs)
   
Detailled Specification : To enforce this consideration of a given array 
                              (for instance, as a result of an array valued
                              function) use of parenthesis (as in usual
                              mathematical expressions). 
                          The POINTER attribute will be affected to the
                              intrinsic array-valued transformational
                              functions as defined by the standard. 

-----------------------------------------------------------------------------

E2) New transformational functions : POSITION and LOCATION

Basic Functionalities : These functions convert the location of an element
                        in an array, defined as the set of subscripts that
                        refers to this element into its position defined as
                        a single number equals to the ``position'' of this
                        element in the array according to the so-called
                        array-element order.

Rationale : This allows the user to manipulate array-addresses (position
            or location) in a safe way and in the spirit of Fortran 90.

Estimated Impact : None (on existing programs)
   
Detailled Specifications : 

     POSITION ( [Array=] X , [Script=] IX )
     LOCATION ( [Array=] X , [Pos=] n )

     Arguments :  X is an array,  n is a default integer (the ``position'')
                      and  IX is a rank-one array of default integers (the
                      ``location'') 
     Constraint : The size of IX is equal to the rank of X and, conversely,
     Values : POSITION(X,IX) returns the ``position'' in the array-element
                   order, of the element X(IX(1),....,IX(k)), where k is the
                   rank of X and, thus, the size of IX ; It is a default
                   integer. 
              LOCATION(X,n) is a rank-one array and its size is equal to
                   the rank of the array X and gives the ``location'' of the
                   element of X whose ``position'' is n . It is an array of
                   default integers.
              LOCATION(X,n) is the inverse function of POSITION
                   i.e. whatever IX (with legal values)
                           LOCATION(X,POSITION(IX)) ===  IX
                   and whatever n (between 1 and Size(X))
                           POSITION(X,LOCATION(X,n)) === n
     Examples : If X is a rank one array,
                   LOCATION(X,n) === (/ n + LBOUND(X,Dim=1) - 1 /)
                   POSITION(X,(/n/))  === n - LBOUND(X,Dim=1) + 1
                If Y is a rank two array,
                   LOCATION(X,n) ===                                        &
                   (/ n-(n/Size(X,Dim=1))*Size(X,Dim=1)+Lbound(X,Dim=1)-1 , &
                                           n/Size(X,Dim=1)+Lbound(X,Dim=2) /)
   
-----------------------------------------------------------------------------  
  
E3) New functions to handle arrays : SCRIPT, SCALAR and VECTOR  

Basic Functionalities :  SCRIPT(X,IX) allows us to use the elements of IX
                            i.e. IX(1),...,IX(k) where k is the size of IX
                            (and thus also the rank of X) for referencing an
                            element of the rank-k array X namely
                            SCRIPT(X,IX) === X( IX(1) , . . . , IX(k) ).

                         SCALAR (X,n) references the n-th element of array X
                            according to the so-called array-element order.

                         VECTOR (X,IX) references the elements X(IX(i)) for
                            i ranging from 1 to SIZE(IX). These elements form
                            a rank one array.

Rationale : A very useful feature of the function SCRIPT is to allow to use
                the result of some location function (e.g. MAXLOC, MINLOC)
                directely in other array statement.
            For example, we cannot use directely the result of MAXLOC
                to reference an element (i.e. X(MAXLOC(X)) is illegal when
                the rank of X is different to 1). 
            Here, an example that it would be very like to work : 
                 Integer, Dimension(2), Parameter ::    &
                          DX = (/1,0/) , &     ! for derivation along x-axis
                          DY = (/0,1/)         ! for derivation along y-axis
                 Integer, Dimension(2) :: IF   ! no yet reserved keywords ..
                 Real, Dimension(nx,ny) :: F   ! to represent a function
                 ......
                 IF = MAXLOC(F)
                 max_f = SCRIPT(F,IF)                       ! i.e. MAXVAL(F)
                 max_f_on_x = MAX( SCRIPT(F,IF-DX) ,  &
                                   SCRIPT(F,IF+DX) )
                 max_f_on_y = MAX( SCRIPT(F,IF-DY) ,  &
                                   SCRIPT(F,IF+DY) )
                 grad_f_on_x = max_f - max_f_on_x           ! gradiant on x
                 grad_f_on_y = max_f - max_f_on_y           ! gradiant on y
                 .......

            The function SCALAR may be considered as redundant with the two
                other functions SCRIPT and LOCATION since SCALAR(X,n) is
                SCRIPT( X , LOCATION(X,n) ) but, for symmetry reasons, we
                consider that it must be included. Also we can note that
                SCRIPT(X,IX) is SCALAR( X , POSITION(X,IX) ) .

            The function VECTOR will be (very) useful for (vector)
                  optimization since the use of arrays of only rank one
                  (and not of higher rank) is favourable (see the use of
                  the BLAS in LINPACK, or now, LAPACK). If this statement
                  will be correct in Fortran (see one of our proposals),
                  VECTOR(X,IX) is ( RESHAPE( X , (/Size(X)/) ) ) (IX) . 

Estimated Impact : None (on existing programs)
   
Detailled Specifications :

    SCRIPT(X,IX) references the elements X( IX(1) , . . . , IX(k) ) of the
                 array X where k is the rank of X . 

        Arguments : X is an array and IX is an array of default integer.
        Constaint : IX is an rank-one array of default integers. its size (k)
                           must be equals to the rank of X
        Value : A scalar, equals to X( IX(1) , ... , IX(k) )
        Examples : If X is a rank one array :  SCRIPT(X,IX)) === X(IX(1))
                       is a scalar and, thus, is different to X(IX) which
                       is a array.


     SCALAR ( X [[,Pos=] , n ] )

         Arguments : X is an array  and  n is a default integer. When the
                        argument n is not present, its default value is 1
         Constraint : 1 <= n <= SIZE(X)
         Examples : When X is an array of size 1 (but eventually, of any
                        rank), SCALAR(X) is the value of the (only) element
                        of this array. For instance, we can write :
                           ix = SCALAR(MAXLOC(Y)) where Y is a rank one array.
                        Note that in F95 for this example, it will be better
                           to write : ix = MAXLOC(Y,Dim=1)
                     Let Y defined by :   Real, Dimension(10,10) :: Y
                           valid expressions are : x = SCALAR(Y,1)
                                                   z = SCALAR(Y,10)


     VECTOR ( X [,IX] )

          Arguments : X is an array  and  IX  is a rank one array of default
                          integers. When the argument IX is not present, its
                          default value is (/ (i,i=1,SIZE(X)) /)
          Constraint : Whatever i from 1 to SIZE(IX), we must have :
                          1 <= IX(i) <= SIZE(X)
          Examples : VECTOR(X) === RESHAPE(X,(/Size(X)/)) that represents the
                         a possible (?) use of this function.

=============================================================================
=============================================================================

F) Miscellaneous

F1) Handling of error messages

Basic Functionality : Use of a available system-function that returns,
                          for any error code available for the processor, the
                          error message (as generated by the system) in a
                          character string.

Estimated Impact : None (on existing programs)
   
Detailled Specification :

         Character(Len=*) ERROR_MESSAGE (ieor,operation) where
              ieor is an error code (as generated by the processor)
              operation is a character string that defines the operation
                  under consideration.
              The result is the corresponding error message.

         This can be implemented in a module with a standard defined name
            and available for each processor.

         Example : Write(*,*) ERROR_MESSAGE (ior,'READ')

-----------------------------------------------------------------------------

F2) New INTENT attribute : COPY_IN 

References:  F90 Standard, 5.1.2.3, 12.5.2.9

Basic Functionality:  Ensure that the entity associated with an argument,
                         otherwise with INTENT (IN) attribute, is passed to
                         the procedure through a mechanism that ensures that
                         modifications to the actual argument outside of the
                         scope of the procedure are not reflected.
                      The two following constructs would then be equivalent:
                         INTERFACE
                            SUBROUTINE SUB (A)
                               REAL, INTENT (IN) :: A
                            END
                         END INTERFACE
                         ......
                         CALL SUB ((A))

                      and
                         INTERFACE
                            SUBROUTINE SUB (A)
                               REAL, INTENT (COPY_IN) :: A
                            END
                         END INTERFACE
                         ......
                         CALL SUB (A)

Rationale:  When writing library subroutines, it is not always possible
               to encapsulate them, since one cannot assume that actual
               arguments are not going to be modified outside of the scope
               of the procedure. This is the case, for instance, when the
               procedure calls a user-procedure passed as one of its
               arguments, and that this user-procedure modifies via global
               access the actual value of another argument. This problem can
               presently only be avoided by a change in the calling sequence,
               so, in order to ease encapsulation, we suggest that the
               symetrical facility be provided for the receiving sequence.

Estimated Impact: Whether this will affect other language features and mean
                      that wide-ranging edits to the standard will be needed:
                      Very limited.
                  Whether it will be hard to implement in compilers: Easy,
                      since already implemented as CALL SUB ((A))
                  Whether it will slow compilation: Unlikely.
                  Whether it will slow program execution: Only if used
                      unnecessarily, and for some implementations.

Detailed Specification: The INTENT (COPY_IN) attribute specifies that
                            the dummy argument is a copy of the actual
                            argument of the invoking scoping unit, that
                            retains the value that it has at the time of
                            invocation. It must not be redefined or become
                            undefined during the execution of the procedure.

-----------------------------------------------------------------------------

F3) New keyword NOCOPY =  for function TRANSFERT and RESHAPE

Basic Functionality, Rationale : With this keyword and a value .TRUE.  i.e.
                                 NOCOPY = .TRUE.  in the functions TRANSFERT
                                 or RESHAPE, the action will be done without
                                 copy-in / copy-out of the argument. 

Estimated Impact : ????
  
=============================================================================
=============================================================================

