[comp.lang.fortran] another side effect question

t19@nikhefh.nikhef.nl (Geert J v Oldenborgh) (08/01/90)

While on the subject of side effect of functions, is there anything in the 
(77) standard which prohibits

      PRINT *,AAP(1.)
      END
      REAL FUNCTION AAP(X)
      PRINT *,'THIS IS AAP'
      AAP = X
      END


None of the Fortrans I use properly prints this.  Yet, I find it a useful 
construct to remind me which set of functions I am using (of course only 
printing on the first call).

Geert Jan van Oldenborgh
oldenborgh@nikhef.nl

seymour@milton.u.washington.edu (Richard Seymour) (08/02/90)

In article <968@nikhefh.nikhef.nl> t19@nikhefh.nikhef.nl (Geert J v Oldenborgh) writes:
>
>While on the subject of side effect of functions, is there anything in the 
>(77) standard which prohibits
>
>      PRINT *,AAP(1.)
>      END
>      REAL FUNCTION AAP(X)
>      PRINT *,'THIS IS AAP'
>      AAP = X
>      END
>
  --- yes, there is:  page 12-29, section 12.11 "Restrictions on
 Function References and List Items"
"A function must not be referenced within an expression appearing 
anywhere in an input/output statement if such a reference causes an
input/output statement to be executed."

another way to look at it is to consider the PRINT statement as a
subroutine call (sort of) -- so haveing a PRINT invoke a PRINT is
recursion, which we all know Fortran thinks is nasty (page 3-6).

>
>None of the Fortrans I use properly prints this.  Yet, I find it a useful 
>construct to remind me which set of functions I am using (of course only 
>printing on the first call).
 ... many things are useful, Fortran just doesn't let you do them
 (legally)

good luck
--dick

maine@elxsi.dfrf.nasa.gov (Richard Maine) (08/02/90)

On 1 Aug 90 16:42:00 GMT, t19@nikhefh.nikhef.nl (Geert J v Oldenborgh) said:


Geert> While on the subject of side effect of functions, is there
Geert> anything in the (77) standard which prohibits

Geert>       PRINT *,AAP(1.)
Geert>       END
Geert>       REAL FUNCTION AAP(X)
Geert>       PRINT *,'THIS IS AAP'
Geert>       AAP = X
Geert>       END


Geert> None of the Fortrans I use properly prints this.  Yet, I find
Geert> it a useful construct to remind me which set of functions I am
Geert> using (of course only printing on the first call).

Yes, it is prohibited by section 12.11, "Restrictions on Function references
and List Items", which reads:

  A function must not be referenced within an expression appearing anywhere
  in an input/output statement if such a reference causes an input/output
  statement to be executed.

I subtlety of this restriction that annoys me relates to internal i/o.
Internal i/o isn't "really" i/o.  It is just doing format conversion,
taking advantage of the Fortran runtime capabilities that happen to also
be used for "real" i/o.  Nonetheless, by the strict definitions of the
standard, internal i/o does fall under the above restriction.  Thus,
I cannot do the following

        double precision time
        external tfmt
        character*12 tfmt
        ...
        write (*,*) tfmt(time)
        ...

        function tfmt(time)
  c Format a time value for printout.
        double precision time
        character*12 tfmt

        integer itime(4)
        external hmsms
  c hmsms converts time from total seconds to an array of 4 integers
  c with hours, minutes, seconds, and milliseconds.
  c Omitted from this example.

        call hmsms(time,itime)
        write (tfmt,'(i2.2,1h:,i2.2,1h:,i2.2,1h.i3.3)') itime
        return
        end

I have a routine simillar to tfmt, but to make it standard, I have to do
the conversion without using the internal write.  Not really too hard
in this case, but its annoying that I have to.  Some machines will let you
get by with the internal write, but it is not standard and there do
exist machines where it fails.

I generally avoid calling all but the simplest functions in i/o
statements because a function called in some context isn't even
allowed to print out an error or debugging message (and most routines
of any substantial content have places where error or debugging messages
are appropriate).

--

Richard Maine
maine@elxsi.dfrf.nasa.gov [130.134.64.6]

rosenkra@convex1.convex.com (William Rosencranz) (08/02/90)

In article <968@nikhefh.nikhef.nl> t19@nikhefh.nikhef.nl (Geert J v Oldenborgh) writes:
>
>While on the subject of side effect of functions, is there anything in the 
>(77) standard which prohibits
>
>      PRINT *,AAP(1.)
>      END
>      REAL FUNCTION AAP(X)
>      PRINT *,'THIS IS AAP'
>      AAP = X
>      END
>
>
>None of the Fortrans I use properly prints this.  Yet, I find it a useful 
>construct to remind me which set of functions I am using (of course only 
>printing on the first call).
>
>Geert Jan van Oldenborgh
>oldenborgh@nikhef.nl

you can't do i/o during a print statement, i believe, since this is recursive
which fortran does not like too much.

note that you CAN do this in C:

	double app();

	main ()
	{
		printf ("%6.4f\n", app(1.));
	}

	double app(arg)
	double arg;
	{
		printf ("THIS IS AAP\n");
		return (arg);
	}

it would result in:

	THIS IS AAP
	1.0000

C has no problems at all with recursion, in general, another reason it
should not be dismissed...

-bill
rosenkra%c1yankee@convex.com

(my opinions, not my employer's...)

Bill Rosenkranz            |UUCP: {uunet,texsun}!convex!c1yankee!rosenkra
Convex Computer Corp.      |ARPA: rosenkra%c1yankee@convex.com

bam@bnlux0.bnl.gov (Bruce A. Martin) (08/18/90)

In article <MAINE.90Aug1113017@altair.dfrf.nasa.gov> maine@elxsi.dfrf.nasa.gov (Richard Maine) writes:
>...
>
>  A function must not be referenced within an expression appearing anywhere
>  in an input/output statement if such a reference causes an input/output
>  statement to be executed.
>
>... subtlety of this restriction that annoys me relates to internal i/o.
>Internal i/o isn't "really" i/o.  It is just doing format conversion,
>taking advantage of the Fortran runtime capabilities that happen to also
>be used for "real" i/o.  Nonetheless, by the strict definitions of the
>standard, internal i/o does fall under the above restriction.  Thus,
>I cannot do the following
>...
Ah, but formatting is usually implemented as a sort of co-routine process,
wherein one procedure tracks along the iolist (pushing or pulling values)
whilst another one keeps track of where it was in the format string. Both
procedures affect the contents of some sort of internal line buffer (as well
as file status, for non-internal I/O).  If you think this is unnecessary
overkill, remember that a format may contain such contex-sensitive nasties
as TL and P (unless you want to have different rules for internal I/O and
probably different routines for their formatting).

If the evaluation of an iolist item causes I/O -- even internal I/O -- then
the format cracker would be reentered.

OK, I know it could have been done with reentrant library routines, but that
was a more general a cost tradeoff that went the other way when Fortran 77 
was standardized.  Today, it probably wouldn't cost very much to make
everything reentrant, and I wouldn't be surprised to find that many 
Fortran processors already can handle it.

In any event, it's not so simple to allow it just for internal I/O.

>
>... a function called in some context isn't even
>allowed to print out an error or debugging message (and most routines
>of any substantial content have places where error or debugging messages
>are appropriate).

Yes, that irks me too.  But it's hard to allow the "good" cases and 
make only the bad ones illegal.  I guess what's really desireable is
general recursion and reentrancy of procedures, not rule relaxations
for seemingly harmless special cases.

>Richard Maine >maine@elxsi.dfrf.nasa.gov [130.134.64.6]

Bruce A. Martin (bam@bnlux0.bnl.gov)

peter@ficc.ferranti.com (Peter da Silva) (08/20/90)

In article <2068@bnlux0.bnl.gov> bam@bnlux0.bnl.gov (Bruce A. Martin) writes:
> In article <MAINE.90Aug1113017@altair.dfrf.nasa.gov> maine@elxsi.dfrf.nasa.gov (Richard Maine) writes:
> >... subtlety of this restriction that annoys me relates to internal i/o.
> >Internal i/o isn't "really" i/o....

Speaking of internal I/O, how come you can't do list-directed formatting
in an internal I/O statement (or, if you can, how long has this been
true so I can bitch to a vendor)?
-- 
Peter da Silva.   `-_-'
+1 713 274 5180.   'U`
peter@ferranti.com (currently not working)
peter@hackercorp.com

cunniff@hpfcso.HP.COM (Ross Cunniff) (08/21/90)

> Speaking of internal I/O, how come you can't do list-directed formatting
> in an internal I/O statement (or, if you can, how long has this been
> true so I can bitch to a vendor)?

Well, most venders do allow it; however, FORTRAN 77 disallows it because
FORTRAN 77 never made clear how list-directed I/O was to be done.
Specifically, it is impossible to know how many digits a vendor may
choose to print, how many spaces (or other separators) the vendor may
choose to use, etc., etc.  Why they didn't specify this is beyond
me (that old 'Prior Art' thing, probably.  They didn't want to break
all the existing implementations out there...)

The result of this unpredictability is that you can never know if
your list-directed output will fit in the string you give for
internal I/O.  This doesn't seem to bother those vendors and
users who have been doing it all this time.

> Peter da Silva

				Ross Cunniff
				Hewlett-Packard Colorado Language Lab
				cunniff@hpfcla.hp.com

hirchert@ux1.cso.uiuc.edu (Kurt Hirchert) (08/21/90)

In article <B0C5KA7@xds13.ferranti.com> peter@ficc.ferranti.com (Peter da Silva) writes:
>Speaking of internal I/O, how come you can't do list-directed formatting
>in an internal I/O statement (or, if you can, how long has this been
>true so I can bitch to a vendor)?

Consider the following:

1. The formats produced by list-directed output are processor-dependent; so are
   the criteria for moving to the next record.  This would make it nearly
   impossible to use list-directed output to an internal file in a portable
   fashion, since you would know neither how big to make the records of the
   internal file nor how many of them to provide.  Since the whole point of
   standards is portability (at some level), the argues against standardizing
   list-directed output to internal files.

2. On the other hand, the formats used for list-directed input are determined
   by the data itself.  This would make it quite easy to use list-directed
   input from internal files in a portable fashion.  This argues in favor of
   standardizing list-directed input from internal files.

3. People expect input and output to be symmetric and are likely to complain
   if a form of input is allowed without allowing the corresponding form of
   output.  This argues against standardizing list-directed input from
   internal files without standardizing list-directed output to internal files.

There is no way to satisfy all three of these arguments.  When FORTRAN 77 was
written, X3J3 chose points 1 and 3 and prohibited all list-directed
input/output to internal files.  When X3J3 was working on Fortran 90, it went
with points 2 and 3 instead, and list-directed input/output to internal files
is permitted.

(You will have to make up your own mind about whether you want to push your
vendor for Fortran 90 in order to get this feature.)
-- 
Kurt W. Hirchert     hirchert@ncsa.uiuc.edu
National Center for Supercomputing Applications

maine@elxsi.dfrf.nasa.gov (Richard Maine) (08/23/90)

On 20 Aug 90 16:31:58 GMT, peter@ficc.ferranti.com (Peter da Silva) said:

Peter> Speaking of internal I/O, how come you can't do list-directed formatting
Peter> in an internal I/O statement (or, if you can, how long has this been
Peter> true so I can bitch to a vendor)?

Somebody else (I think Karl Hurchert (sp?)) touched on the whys before.

As for the rest of your question, it isn't legal yet, but it is legal
in the proposed Fortran 90 standard.  Ask your favorite religious advisor
for guesses as to when Fortran 90 will be an "official" standard.
Current guesses seem to range from the end of 1990 (for an ISO standard;
no hope of ANSI ratification by then) to infinity.

So if you want to bitch at a vendor, you can bitch at them about whether
they have started work on a Fortran 90 compiler and how soon they
project release.  Several vendors do claim to be working on Fortran 90
compilers already (at least they say so when I bitch at them), so I'd
say you are justified in kicking yours if they aren't.  Squeek loudly
enough and maybe we'll get "greased" (choose any of several possible
interpretations :-)).
--

Richard Maine
maine@elxsi.dfrf.nasa.gov [130.134.64.6]