Beliavsky <beli...@aol.com> schrieb:
In section 10.7 of Metcalf/Reid/Cohen (2018), they write, "IfUnsurprisingly, the authors are right. And I quote:
an error or end-of-file condition occurs on input, the statement
terminates and all list items and any implied-do variables become undefined."
12.11.2 Error conditions and the ERR= specifier
[...]
If an error condition occurs during execution of an input/output
statement that contains either an ERR= specifier or an IOSTAT=
specifier then:
[...]
(2) if the statement is a data transfer statement or the error
condition occurs during a wait operation, all do-variables in the
statement that initiated the transfer become undefined;
[...]
(6) if the statement is a data transfer statement or the error
condition occurs during a wait operation, all do-variables in the
statement that initiated the transfer become undefined;
Although gfortran, g95, ifort, and flang all say that i is 42Correct. There is a fine difference between "works when tested" and "advertised as working in extension to the standard". Any compiler
and j is 8 at the end of the following code, I believe the Fortran
standard does not mandate this. Correct?
might have chosen to document this behavior (gfortran didn't), then
it would be possible to rely on it for that particular compiler,
but it would be non-portable. As is, the behavior might change
with a new version, a different optimization option, or (somewhat
unlikely) the phase of the moon.
In section 10.7 of Metcalf/Reid/Cohen (2018), they write, "If
an error or end-of-file condition occurs on input, the statement
terminates and all list items and any implied-do variables become
undefined."
Although gfortran, g95, ifort, and flang all say that i is 42
and j is 8 at the end of the following code, I believe the Fortran
standard does not mandate this. Correct?
Since all the compilers I have tested update the variables that can be read and preserve the old values of the variable that cannot be read, and since this
behavior may be what the user wants, would it make sense to add a PRESERVE specifier to the READ statement? With PRESERVE=.TRUE. the current behavior would be mandated.
Beliavsky <beli...@aol.com> schrieb:
Since all the compilers I have tested update the variables that can be read and preserve the old values of the variable that cannot be read, and since thisThe tradition of Fortran is to use strings for I/O, such as
behavior may be what the user wants, would it make sense to add a PRESERVE specifier to the READ statement? With PRESERVE=.TRUE. the current behavior would be mandated.
ADVANCE="NO". Of course, your proposal could be amended for that.
It would also be necessary to specify what happens for asynchronous
I/O.
If a compiler has a different way of doing I/O that makes this hard,
such a provision would force that compiler to a) change that method,
and b) to make it selectable at run-time - a user might specify
a string (or that would have to be disallowed.
If a user wants that effect, it is probably better to use
individual I/O statements. Stream I/O and non-advancing I/O
should offer enough possibilities to do this. Or, it is also
possible to specify something like
read (unit,fmt,iostat=ios) tmp
if (ios == 0) a = tmp
Beliavsky <beli...@aol.com> schrieb:
The tradition of Fortran is to use strings for I/O, such as
ADVANCE="NO". Of course, your proposal could be amended for that.
It would also be necessary to specify what happens for asynchronous
I/O.
If a compiler has a different way of doing I/O that makes this hard,
such a provision would force that compiler to a) change that method,
and b) to make it selectable at run-time - a user might specify
a string (or that would have to be disallowed.
If a user wants that effect, it is probably better to use
individual I/O statements. Stream I/O and non-advancing I/O
should offer enough possibilities to do this. Or, it is also
possible to specify something like
read (unit,fmt,iostat=ios) tmp
if (ios == 0) a = tmp
In section 10.7 of Metcalf/Reid/Cohen (2018), they write, "If an error or end-of-file condition occurs on input, the statement terminates and all list items and any implied-do variables become undefined.".
Although gfortran, g95, ifort, and flang all say that i is 42 and j is 8 at the end of the following code, I believe the Fortran standard does not mandate this. Correct?
program main
implicit none
character (len=100) :: text
integer :: i,j,ierr
text = "42 abc"
i = 7
j = 8
read (text,*,iostat=ierr) i,j
print*,"ierr, i, j =",ierr,i,j
end program main
Since all the compilers I have tested update the variables that can be read and preserve the old values of the variable that cannot be read, and since this
behavior may be what the user wants, would it make sense to add a PRESERVE specifier to the READ statement? With PRESERVE=.TRUE. the current behavior would be mandated.
On Saturday, March 26, 2022 at 9:42:25 AM UTC-4, Beliavsky wrote:.
Since all the compilers I have tested update the variables that can be read and preserve the old values of the variable that cannot be read, and since thisA further suggestion. When reading an array from a string, the returned IOSTAT
behavior may be what the user wants, would it make sense to add a PRESERVE specifier to the READ statement? With PRESERVE=.TRUE. the current behavior would be mandated.
tells you whether or not the entire array could be read, but it would be nice to know
how many of the array elements could be read. An NREAD specifier returning an integer could be used for this. Since a READ statement may have multiple scalar
and array items, the NREAD would correspond to the last item in the list. If it is a
scalar, NREAD would be 1 if the scalar were read, otherwise 0. As demonstrated at
https://github.com/Beliavsky/FortranTip/blob/main/iomsg.f90 , IOMSG from gfortran
currently gives an informative message saying which item in a list could not be read,
but the IOMSG from Intel Fortran does not provide this information.
Fortran 202x will have SPLIT intrinsics. One can split lines into strings and read
individual items from them.
If you want these facilities, use PL/I. which stores those values that
were read in, and leaves unchanged those variables for which
a value could not be read in on account of some error or whatever.
.
PL/I even provides a variable (COUNT) that tells you the
number of values that were successfully read and stored.
.
We have been using these PL/I facilities for 55 years.
We have been using these PL/I facilities for 55 years.
Robin,
I think programming languages sometimes become so unpopular and
unsupported that they are not viable, regardless of their intrinsic merits. Some say this about Fortran, but I hope they are wrong. I think it is true
of PL/1. You have been educating us about Pl/I for years (decades?. More
than one millennium?) Besides the Wikipedia article, what are the best
online resources in your opinion? Maybe reading them would give
Fortranners some ideas.
On Monday, March 28, 2022 at 6:50:52 AM UTC-7, Beliavsky wrote:
(snip)
We have been using these PL/I facilities for 55 years.
Possibly with a 55 year old compiler.
Robin,
I think programming languages sometimes become so unpopular and
unsupported that they are not viable, regardless of their intrinsic merits. >> Some say this about Fortran, but I hope they are wrong. I think it is true >> of PL/1. You have been educating us about Pl/I for years (decades?. More
than one millennium?) Besides the Wikipedia article, what are the best
online resources in your opinion? Maybe reading them would give
Fortranners some ideas.
I was doing both Fortran and PL/I programming in 9th grade.
My Algebra I book actually had a PL/I chapter, but we conveniently
skipped over it. That was Fortran IV days, and I found PL/I much
more fun to program in.
There are actual stories from those designing PL/I. Among others,
and I suspect unlike many programming languages, PL/I (or NPL)
was designed before the first compiler was started.
(For those interested, there is what Knuth calls Fortran 0, that is,
the language as it was thought up before the first compiler.)
In any case, when they were first working on PL/I, they thought about
making it more compatible with (the then current) Fortran, but decided
that in the time they had (less than a year) that was not possible.
One result of designing before implementation, is that come features
turned out harder to implement than they might have thought.
(And especially considering the smaller and slower computers
of the time.) Many original PL/I features have now made it into
Fortran, close to 60 years later. It is also interesting to see the
ones that haven't.
For one, PL/I had generic intrinsic functions from the beginning,
and still more generic than Fortran. You can, for example, call
SQRT with an integer (that is, fixed point) argument. Since PL/I
allows fixed point types with the radix point other than just to the
right of the LSD, that makes sense. (In many cases, values are
converted to double precision floating point, and that is used
for the actual function call.) And yet Fortran still doesn't do that.
(PL/I will even let you call SQRT with a CHAR argument, and do
the conversion for you, if the value looks like a number.)
Sometimes it looks to me that when features are added to Fortran,
they try to make it as hard as possible for users to use them.
Complicated rules are added, so that both compiler writers
and programmers have a hard time figuring them out.
It looks to me like PL/I tends to have simpler rules, though
sometimes harder for compiler writers.
But yes, there aren't enough PL/I users to get compilers writers
interested, and not enough compilers to get users interested.
Some of those "features" of PL/I do not encourage the most efficient
code. Fortran in some ways forces you to think in ways that encourage execution efficiency.
On Monday, March 28, 2022 at 6:50:52 AM UTC-7, Beliavsky wrote:
(snip)
Possibly with a 55 year old compiler.We have been using these PL/I facilities for 55 years.
I was doing both Fortran and PL/I programming in 9th grade.
My Algebra I book actually had a PL/I chapter, but we conveniently
skipped over it. That was Fortran IV days, and I found PL/I much
more fun to program in.
There are actual stories from those designing PL/I. Among others,
and I suspect unlike many programming languages, PL/I (or NPL)
was designed before the first compiler was started.
(For those interested, there is what Knuth calls Fortran 0, that is,
the language as it was thought up before the first compiler.)
In any case, when they were first working on PL/I, they thought about
making it more compatible with (the then current) Fortran, but decided
that in the time they had (less than a year) that was not possible.
One result of designing before implementation, is that come features
turned out harder to implement than they might have thought.
(And especially considering the smaller and slower computers
of the time.) Many original PL/I features have now made it into
Fortran, close to 60 years later. It is also interesting to see the
ones that haven't.
For one, PL/I had generic intrinsic functions from the beginning,
and still more generic than Fortran. You can, for example, call
SQRT with an integer (that is, fixed point) argument. Since PL/I
allows fixed point types with the radix point other than just to the
right of the LSD, that makes sense. (In many cases, values are
converted to double precision floating point, and that is used
for the actual function call.) And yet Fortran still doesn't do that.
(PL/I will even let you call SQRT with a CHAR argument, and do
the conversion for you, if the value looks like a number.)
Sometimes it looks to me that when features are added to Fortran,
they try to make it as hard as possible for users to use them.
Complicated rules are added, so that both compiler writers
and programmers have a hard time figuring them out.
It looks to me like PL/I tends to have simpler rules, though
sometimes harder for compiler writers.
But yes, there aren't enough PL/I users to get compilers writers
interested, and not enough compilers to get users interested.
Some of those "features" of PL/I do not encourage the most efficient
code. Fortran in some ways forces you to think in ways that encourage execution efficiency.
..
But yes, there aren't enough PL/I users to get compilers writers
interested, and not enough compilers to get users interested.
OK, why did Fortran remove allowing real variables in DO loops?
I don't think it is to encourage efficient code. (Note that PL/I
even allows complex and CHAR variables in DO loops.)
But yes, there aren't enough PL/I users to get compilers writers interested, and not enough compilers to get users interested.A PL/I compiler is currently under development, already implementing
most of PL/I.
And of course, IBM is still developing its PL/I compiler.
On Tuesday, March 29, 2022 at 4:26:33 AM UTC+2, Robin Vowels wrote:any more or not available on a new platform. The IBM one is neither cheap nor widely marketed, and the other one is closed source, developed by a rather small company. Also, there is an alternative complicated language with all the features one might
A PL/I compiler is currently under development, already implementing
But yes, there aren't enough PL/I users to get compilers writers
interested, and not enough compilers to get users interested.
most of PL/I.
And of course, IBM is still developing its PL/I compiler.
For Fortran, there are a number of both open and closed source compilers with large user bases and developer communities. That means, that one is almost certain not to have to rewrite anything in a new language just because the old one is not supported
gah4 <ga...@u.washington.edu> schrieb:
OK, why did Fortran remove allowing real variables in DO loops?
I don't think it is to encourage efficient code. (Note that PL/I
even allows complex and CHAR variables in DO loops.)
I don't have a first-hand account of why it happened, but there
is a strong suspect: Rounding errors leading to uncertainties
about the number of iterations.
While there is little doubt about the intended semantics of
DO R = 0.,10.,0.5
there is likely to be problems with
DO R = 0., 10, 0.1
(I'm not 100% convinced about that, since one might
as well write
DO R = 0., 10.05, 0.1
or
DO R=0., 9.95, 0.1
but I suspect that people got it wrong a lot).
On Monday, March 28, 2022 at 10:39:24 PM UTC-7, Thomas Koenig wrote:
gah4 <ga...@u.washington.edu> schrieb:
OK, why did Fortran remove allowing real variables in DO loops?
I don't think it is to encourage efficient code. (Note that PL/I
even allows complex and CHAR variables in DO loops.)
I don't have a first-hand account of why it happened, but there
is a strong suspect: Rounding errors leading to uncertainties
about the number of iterations.
While there is little doubt about the intended semantics of
DO R = 0.,10.,0.5
there is likely to be problems with
DO R = 0., 10, 0.1
(I'm not 100% convinced about that, since one might
as well write
DO R = 0., 10.05, 0.1
or
DO R=0., 9.95, 0.1
but I suspect that people got it wrong a lot).
Well, yes. But for me, it isn't up to the compiler to force me,
(and in only one specific case) to avoid rounding errors.
So, okay, the language can be designed to encourage efficient code,
but it shouldn't require it.
The actual reason this one bothers me, is that when I was younger
I would sometimes translate BASIC programs to Fortran, from
implementations that only have a floating point type.
On 3/29/22 1:16 PM, gah4 wrote:
The actual reason this one bothers me, is that when I was younger
I would sometimes translate BASIC programs to Fortran, from
implementations that only have a floating point type.
Yeah, BASIC should not be the model programming language for fortran.
Ok, here is the problem with floating point loops in fortran. I don't
know how BASIC designed their loops, but in fortran, the first thing
that happens is that the trip count is evaluated. That determines the
number of iterations of the loop (excepting early exits, etc.).
Then the loop index is initialized and its value is incremented each
pass through the loop. See the problem now? In floating point
arithmetic, roundoff errors can accumulate for the floating point index value, so during the final loop iteration, its value can be less than
the upper bound (surprising the programmer who thinks there should have
been additional passes through the loop body), or it can be greater than
the upper bound (surprising the programmer who thinks extra iterations
were performed by mistake.
Except for some exceptional situations where the loop ranges and indexes occur without rounding error, either one or the other of those two
surprising things happens. In other words, in the typical situation, the programmer is surprised. That is the sign that this was a poorly
designed feature to begin with. Another sign is that the rounding errors
can change depending on how the rounding mode is set at the time the
loop is executed, or it can change with compiler optimization level,
where the increment is done in different ways or using a different instruction sequence.
So no matter how you look at it, it was a poor language design choice.
And doing loops with integer counters, which does not suffer from this
kind of roundoff error, is not only easy, sometimes the code is even
simpler and easier to understand. And yes, as you point out, it may be
more efficient too.
And Fortran still allows you to make all kinds of other rounding
errors, including in IF statements, maybe even in loops!
On Thursday, March 31, 2022 at 12:19:47 AM UTC+11, gah4 wrote:
And Fortran still allows you to make all kinds of other roundingSilverfrost F95 warns when you compare REALs in an IF statement.
errors, including in IF statements, maybe even in loops!
On Wednesday, March 30, 2022 at 5:52:11 PM UTC-7, Robin Vowels wrote:.
On Thursday, March 31, 2022 at 12:19:47 AM UTC+11, gah4 wrote:
And Fortran still allows you to make all kinds of other rounding
errors, including in IF statements, maybe even in loops!
.Silverfrost F95 warns when you compare REALs in an IF statement.I wouldn't be against a warning for DO statements.
By the way:
DCL I FIXED BIN(31,0) COMPLEX;
DO I=1+1I BY 1+1I WHILE(ABS(I)<200);
PUT SKIP LIST(I, I**I,SQRT(I));
END;
DCL I FIXED BIN(31,0) COMPLEX;
DO I=1+1I BY 1+1I WHILE(ABS(I)<200);
PUT SKIP LIST(I, I**I,SQRT(I));
END;
This would never have run to completion using the PL/I-F compiler,
for floating-point overflow would have occurred at around the 50th
iteration.
It won't compile because the BY option cannot be COMPLEX.
On Thursday, March 31, 2022 at 9:17:26 PM UTC-7, Robin Vowels wrote:.
(snip, I wrote)
DCL I FIXED BIN(31,0) COMPLEX;This would never have run to completion using the PL/I-F compiler,
DO I=1+1I BY 1+1I WHILE(ABS(I)<200);
PUT SKIP LIST(I, I**I,SQRT(I));
END;
for floating-point overflow would have occurred at around the 50th iteration.
It won't compile because the BY option cannot be COMPLEX.
I actually didn't try that one, but one I did 45 years ago:
On Thursday, March 31, 2022 at 9:17:26 PM UTC-7, Robin Vowels wrote:.
(snip, I wrote)
I actually didn't try that one, but one I did 45 years ago:DCL I FIXED BIN(31,0) COMPLEX;This would never have run to completion using the PL/I-F compiler,
DO I=1+1I BY 1+1I WHILE(ABS(I)<200);
PUT SKIP LIST(I, I**I,SQRT(I));
END;
for floating-point overflow would have occurred at around the 50th iteration.
It won't compile because the BY option cannot be COMPLEX.
DCL (A, B, C, D) CHAR(20);
B='1';
C='. 100';
D='1';
DO A=B TO C BY D;
PUT SKIP LIST(A, SQRT(A));
END;
I actually didn't try that one, but one I did 45 years ago:
DCL (A, B, C, D) CHAR(20);
B='1';
C='. 100';
D='1';
DO A=B TO C BY D;
PUT SKIP LIST(A, SQRT(A));
END;
This one won't work.
Even if the error in the assignment to C were corrected,
it still won't work.
The reason?
Conversion from numeric to character (after the arithmetic)
introduces leading blanks, that causes inequality when
the control variable A is compared with C.
That results in an infinite loop.
For the code to work, the string constants assigned to both B and C must be written
as strings containing exactly 18 characters (right adjusted, of course).
Sysop: | Keyop |
---|---|
Location: | Huddersfield, West Yorkshire, UK |
Users: | 159 |
Nodes: | 16 (0 / 16) |
Uptime: | 99:48:36 |
Calls: | 3,209 |
Files: | 10,563 |
Messages: | 3,009,979 |