Concerning Werner Schulz's wish list for Fortran:
I've shortened Schulz's discussions.
I comment on only a few of his topics. About the rest, or when I only
comment on a part of Schulz's suggestion, I'm either neutral, or not
knowledgable, or there's work in progress. You should look at the
papers and comment on the direction _now_ if you want to have any
effect.
J3 papers are available at ftp://ftp.ncsa.uiuc.edu/x3j3/doc/...
WG5 papers are available at ftp://ftp.nag.co.uk/sc22wg5/...
Fortran 2000 status is at http://www.ionet.net/~jwagener/j3/ (including
links to current papers on work-item-related topics).
Several of Schulz's wish-list items were proposed in paper 97-114.
Exactly _one_ item got onto the "maybe we'll elevate it to a work item
if we have time" list.
Werner Schulz wrote:
> (o) enumerated Type:
> Ada, C/C++, etc have it. It is a very useful and concise way
> to set up a list of options etc.
> It is always better to refer to options/constants by name
> rather than by number as frequently done in old F77 codes
> In F90 one cannot easily collect these options/constants into
> one structure.
> Example:
> TYPE(Enum) :: Weekdays(0:6) = (/Sun,Mon,Tue,Wed,Thu,Fri,Sat/)
> Now one use either Weekdays or directly Sun, etc.
Roger Glover wrote:
!What is wrong with this F90 code?
! INTEGER, PARAMETER :: Sun=0, Mon=1, Tue=2, Wed=3, Thu=4, Fri=5, Sat=6
! INTEGER :: Weekdays(0:6) = (/Sun,Mon,Tue,Wed,Thu,Fri,Sat/)
This code will compile. But when you have hundreds of names, it
becomes tedious and error prone to modify them. Yes, you could write
MON=SUN+1, etc. Another use for enumerated variables is for "mode"
flags. If your procedure has N modes, these could be indicated by an
integer taking values in 1:N, but there's nothing to stop a user from
sending in something that's out-of-range (a decent subtype system is
another topic). That's harder with enumerated types. It's not
impossible: the user could send a variable that's uninitialized instead
of a constant; that could be avoided by allowing public objects of
private type (so the user can't create new values), which is presently
proposed and being considered.
Werner Schulz wrote:
> (o) OO Features:
> ...
> A good OO implementation should be implemented asap.
> There are some good and not so good OO languages out there
> (Eiffel, Beta, Python, etc) and one should learn from them
> what to do and what to avoid.
The present proposals for polymorphic data and procecures avoid the C++
"virtual" mistake by adopting something more like Ada-95 "type'class."
At present the data subcommittee is stuck on what procedure signature
is inherited if there is more than one argument of the type to which
the procedure "belongs," and the procedure is not overridden. Suppose
there is a type T1 to which a procedure P "belongs," and suppose that P
has two arguments of type T1, say X and Y. If T1 is extended giving
T2, but a new P belonging to T2 is _not_ defined, should an assumed P
belonging to T2 have one argument of type T2 (say X) and the other one
(say Y) remaining of type T1, or should both X and Y be considered to
be of type T2 in the signature for the "new" P belonging to T2, or
should there be a mechanism to specify which behavior happens? The
first is the C++/Java style; the second is the Ada-95 style. Kurt
Hirchert has examples in paper 97-265. Some have argued for the
"principle of minimal surprise" -- do it like C++. Others have argued
for the "principle of maximal surprise" -- it's actually good for
something. Others have argued for the traditional Fortran solution --
we can't make up our minds, so let's do everything.
What's your opinion? Which would be more useful to you?
Werner Schulz wrote:
> (o) Shortening of Fortran
> e.g. ALLOCATE( X(1:N)=Zero ) allocates an array X(1:N) and sets
> all elements to Zero.
Roger Glover wrote:
! How is this *subtantively* different than:
! ALLOCATE( X(1:N) ); X=ZERO
!
! The only way I can imagine your syntax being useful is that it
! might be a syntactic way of expressing the initialization of an
! ALLOCATABLE with the PARAMETER attribute.
I presume by this remark that you mean a "run time parameter," which is
known as a "constant" in other languages?
Werner Schulz wrote:
> (o) Extension of CASE:
> The current version of the CASE statement is a somewhat inconsistent
> with the rest of the language. It is a much needed improvement of
> the IF-block but has been defined, im my opinion, in the wrong way.
>
> A more useful form is:
> SELECT CASE( A )
> CASE( r1<=A<r2, r3<A<=r4, r5,r6,r7 ) ! r stands for range
> ...
> CASE( r2<=A<r3, r8,r9 )
> ...
> CASE DEFAULT
> END SELECT
> where A can be integer or real or character(ASCII).
Artur Swietanowski wrote:
| I agree that this form of CASE would be appropriate in many cases.
| I disagree with arguments that exact comparisons with real numbers
| should be avoided because they depend on floating point hardware
| (an often cited reason to disallow REALs as loop iterators).
Roger Glover wrote:
! As currently defined, each "case-value-range," such as "r1<=A<r2" or
! "r9" must be composed of initialization expressions. And the "A" in
! this example is allowed to be any scalar expression. Thus, I think
! this proposed syntax could lead to some real parsing and human-
! readability nightmares. For exmple, does the "A" in the range have
! to be the same as the "A" in the "SELECT CASE" expression?
In 97-114, I proposed SELECT CASE (<expr>) ... CASE (r1 <= * < r2) ...
where * is a place-holder that refers to the value of <expr>.
! In my opinion, the real beauty of the SELECT CASE construct is
! that, it is possible for the compiler to set up a hash table
! that would reduce the speed of search execution down to the time
! required to do an array lookup. This is a so-called O(0) ("order
! zero") search.
! REAL values are much harder to handle in this sort of mechanism.
There have been at least four objections to REAL ranges for CASE
constructs, of which the above is just one.
Semantically, CASE is no different from IF. The existence of an
efficient implementation for an important subset of the usages of a
construct should not be used as an argument against the utility of the
other usages -- it looks more like an excuse than a reason.
The compiler can, when appropriate, do what Glover suggests. Indexing
(aka computed GOTO) isn't efficient when the range of integers is large
compared to the number of them, and doesn't work at all for character
type when LEN is large. Hashing could be used when appropriate.
Internally converting CASE to a sequence of IF ... THEN ... ELSE IF
THEN ... ELSE ... could be used when appropriate. The important thing
is to hide it "under the covers" -- let the user express intent most
clearly, and depend on the compiler to "do the right thing."
Would you expect / hope for use of indexing if you wrote:
SELECT CASE(J) ; CASE(1) ; ... ; CASE(1000000) ; ... END CASE
if there were no other cases? Wouldn't hashing be too much clanking
machinery? I would expect and hope for an IF-tree under-the-covers.
If REAL ranges of CASE were allowed, there would be nothing to prevent
the compiler to do what Glover likes (when it's appropriate).
One recently raised objection is that a program might have different
meaning on different platforms, or might compile on some, but not on
others, because different precisions and rounding methods might cause
REAL ranges to have different boundaries, or to overlap. This is _no_
different from the situation with IF, except that with IF you don't get
any help from the compiler in the case when ranges overlap. If the
compilers work correctly, one should be able to prevent overlap and
non-portable behavior by writing
CASE (A <= * < B) ; ... ; CASE (B <= * < C) ; ...
or CASE (A <= * <= B) ; ... ; CASE (B+NEAREST(B,1.0) <= * <= C); ...
(I prefer the first), except in the case when the ranges degenerate to
emptyness (and then the compiler should produce a message).
(This is, by the way, related to the reason to prohibit REAL loop
inductors: the number of "trips" might vary from platform to platform.)
Other objections are described in paper 97-114. So far, I consider all
objections to allowing REAL range for CASE to be "excuses," not
"reasons."
Werner Schulz wrote:
> (o) EXITs:
> allow exits from any block structure not just DO loops
> this would make goto even rarer.
Roger Glover wrote:
! It is almost as if someone had already thought of that. What good
! are construct names for "IF"s and "SELECT CASE"s otherwise? I hope
! they do just that some day.
William Clodius wrote:
] Oft discussed, but not planned. The specific use of EXIT for this purpose
] would either be incompatible with existing code or would require very
] complex rules.
Allowing EXIT from any construct was proposed during development of
Fortran 90, at which time it was "laughed out of the room." If adopted
then, semantics _would_ have been identical for EXIT from IF or CASE and
EXIT from DO. The situation isn't so bleak as Clodius paints it,
however: Simply _require_ that EXIT refer to a construct name if it
applies to an IF or CASE construct.
It's also useful to have a construct that doesn't do anything other
than provide a construct label, e.g. L: BEGIN ... END. Several reasons
are given in paper 97-114, but the one germane to this discussion is
that it allows writing "do P if X is not in set S" without extra tests,
or a GOTO, or gratuitous procedure-ification.
Werner Schulz wrote:
> (o) Modules:
> ... There is the compilation cascade when the implementation
> of a module is changed but not its (public) interface.
> These matters leave room for improvements that have to be addressed
> soon.
William Clodius wrote:
] A quality of implementation issue.
It is exceedingly difficult to solve this problem as a "quality of
implementation" issue, without separating implementation from interface
at the source level. It requires the compiler to emit separate
interface and implementation files (many already do), then "diff" the
newly created interface file against the old one, and discard it if
it's no different (none do). This approach is subverted if
implementation files have time stamps for the corresponding interface
file in them (which is a good idea -- it allows a check for consistency
when the program is linked).
Artur Swietanowski wrote:
| Modules as they are designed do not support the separation of
| the interface and implementation. They are simply poorly designed.
| Or perhaps designed for a different purpose.
Separating implementation from interface at the _source_code_ level has
other uses, as outlined in paper 97-114. _All_ of the benefits and
costs of separating implementation from specification should be
considered. By the way, it _can_ be done in a way compatible to Fortran
90 -- see paper 97-114.
> (o) Libraries:
Artur Swietanowski wrote:
| Right. The problem is, libraries in form of modules may only be
| distributed easily in source form (no way to separate interface
| from implementation).
One of the reasons cited in paper 97-114 to separate module interface
from implementation at the source level.
Werner Schulz wrote:
> (o) Obsolete Features:
> - NULLIFY (With the NULL in F95 NULLIFY becomes redundant.)
Artur Swietanowski wrote:
| Too late. Any F90 code using pointers uses NULLIFY now. Besides, I
| don't see any problem with this redundancy.
and Schulz replied:
> It's a feature that the committee didn't think through obviously
> since we now have a redundant feature in the F95 language.
It's not like J3 wasn't warned. => NULL() instead of NULLIFY was
proposed several times during development of Fortran 90.
> - DOUBLE PRECISION (use Real(kind=...))
Artur Swietanowski wrote:
| There should be a KIND value defined in the standard that would always
| make REAL(k) the same as DOUBLE PRECISION. After all we have plenty of
| good old F77 code to interface to. And, yes, it used DOUBLE PRECISION
| quite often. In general, there should be predefined KINDS directly
| corresponding to the most often used F77 types.
I'm satisfied with KIND(1.0e0) and KIND(1.0d0).
Werner Schulz wrote:
> (o) PARAMETER Variant:
> I have wished many times to have a variable that can only be
> declared once at the beginning of a programme and remains constant
> throughout.
Roger Glover wrote:
! One can obtain this effect fairly handily through use of
! modules[3]. True, it is not very efficient for large scale
! work. On the other hand initial parameter setting and usage
! is very unlikely to be a significant part of runtime.
! [3] For example:
!
! MODULE ReadOnly
! REAL, PRIVATE :: ReadIt = 0.0
! LOGICAL, PRIVATE :: ReadItIsSet = .FALSE.
!
! CONTAINS
! SUBROUTINE SetReadIt( Value ); REAL Value
! IF( .NOT. ReadItIsSet ) THEN
! ReadIt = Value
! ReadItIsSet = .TRUE.
! END IF
! END SUBROUTINE SetReadIt
!
! REAL FUNCTION GetReadIt()
! GetReadIt = ReadIt
! END FUNCTION GetReadIt
! !END CONTAINS
!
! END MODULE ReadOnly
Lifetime software costs (development, maintenance, operations) are
roughly proportional to code volume. Write-once "variables" (also
known as "constants" in other languages, and variables that are
read-only outside of the "owning" module, are presently being studied
in the context of features necessary and useful to allow users to
create extensions to the language, e.g. interval arithmetic, extended
precision arithmetic, ....
Werner Schulz wrote:
> (o) bindings to other languages
> I hear they are woorking on C <--> Fortran
> I hope this will stimulate some discussion about the
> next Fortran version (if it's not too late) and
> hopefully will include some of my wishes.
>
> WS
I had the same hopes about paper 97-114.
Roger Glover wrote:
! Also needed would be a good template (Ada generic) implementation.
Yes.
! Good exception handling is another must,
J3 knows this, and repeatedly "chickens out"
! as is conditional compilation (that is in the draft, right?).
A separate "part" (3) of the 95 standard, recently completed as a
"technical report" -- WG5 paper N1283.
! It also would not hurt to have APIs for numerics, networking, GUI, etc.,
! built into the language.
I don't know about "built into the language" but community standards,
not necessarily carrying the weight of ANSI and/or ISO are useful. One
for OpenGL was recently prepared by William Mitchell at NIST.
-----------------------------------------------------------------------------
Best regards,
Van Snyder
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|