[net.lang] does Fortran 77 allow recursion?

ark@alice.UUCP (Andrew Koenig) (08/15/85)

>> ...
>>I find the biggest
>>weaknesses fortran has for scientific programming are:
>>	- no recursion - makes everything tough, especially multiple integration

> I was under the impression that Fortran-77 allows recursion in the sense that
> a routine may call itself either directly or through a chain of other routines-
> am I mistaken?

You are mistaken.  A particular implementor may choose to allow recursion,
but the Fortran 77 standard does not require it to be implemented.

johnl@ima.UUCP (08/22/85)

The Fortran 77 standard specifically disallows recursion.  Section 15.2
on "Referencing a Function" says:

    A subprogram must not reference itself, either directly
    or indirectly.

(Subprogram is previously defined to be a function or a subroutine.)

This is a historical artifact that the Fortran community is stuck with.
Existing Fortran compilers on IBM 370 machines use a calling discipline
where all of the register and return address save areas are allocated
statically.  (When they came up with the 360 calling sequence, they didn't
seem to think that recursion or stacks were important.)  PL/I later came
up with a modified semi-compatible version of that linkage which does use
a stack, does allow recursion, and is much slower.  Ergo, if you want your
Fortran programs to be portable and standard, don't recurse.

You might hope that some Fortran systems that disallow recursion would at
least detect it and barf, by having an "active" flag for each routine.
But no, not in any compiler I've ever seen.

John Levine, ima!johnl

mangoe@umcp-cs.UUCP (Charley Wingate) (08/23/85)

In article <103600003@ima.UUCP> johnl@ima.UUCP writes:

>The Fortran 77 standard specifically disallows recursion.  Section 15.2
>on "Referencing a Function" says:

>    A subprogram must not reference itself, either directly
>    or indirectly.

>(Subprogram is previously defined to be a function or a subroutine.)

>This is a historical artifact that the Fortran community is stuck with.
>Existing Fortran compilers on IBM 370 machines use a calling discipline
>where all of the register and return address save areas are allocated
>statically.  (When they came up with the 360 calling sequence, they didn't
>seem to think that recursion or stacks were important.)  PL/I later came
>up with a modified semi-compatible version of that linkage which does use
>a stack, does allow recursion, and is much slower.  Ergo, if you want your
>Fortran programs to be portable and standard, don't recurse.

Static allocation is also enforced by the common use of data statements to
initialize variables which are then changed during calls to the subroutine.
Every Fortran compiler I've ever seen allocates storage so that the
changed values persist (although some linkers manage to defeat this under
the right circumstances).  This feature is quite commonly used to have some
one-time initialization performed for the routine.  So it looks to me like
any Fortran compiler which wants to offer recursion, even as an extension,
must provide user control of whether allocation is static or not.

Charley Wingate  umcp-cs!mangoe

chris@umcp-cs.UUCP (Chris Torek) (08/23/85)

>From: johnl@ima.UUCP
>
>You might hope that some Fortran systems that disallow recursion would at
>least detect it and barf, by having an "active" flag for each routine.
>But no, not in any compiler I've ever seen.
>
>John Levine, ima!johnl

The F77 compiler I just tried my recursion example on (it's an
"almost 4.3" F77) said "Warning on line <n> of <file>: recursive
call".
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 4251)
UUCP:	seismo!umcp-cs!chris
CSNet:	chris@umcp-cs		ARPA:	chris@maryland

ark@alice.UucP (Andrew Koenig) (08/24/85)

Charley Wingate points out that there are many Fortran programs that
use DATA statements to initialize values that are later changed.

It may interest all of you to know that programs that do that
violate the Fortran 77 standard.  Page 8-11, section 8.9:

	The execution of a RETURN statement or an END
	statement within a subprogram causes all entities
	within the subprogram to become undefined except
	for the following:

	1. Entities specified by SAVE statements

	2. Entities in blank common

	3. Initially defined entities that have neither been
	   redefined nor become undefined

	4. Entities in a named common block that appears in
	   the subprogram and appears in at least one other
	   program unit that is referencing, either directly
	   or indirectly, that subprogram

Thus you can initialize a variable with a DATA statement in
a subprogram and have it retain its value AS LONG AS YOU NEVER
ASSIGN A VALUE TO IT ELSEWHERE.  If you do assign it elsewhere,
YOU MUST NAME IT IN A SAVE STATEMENT or it will become undefined
when you return.

ken@boring.UUCP (08/26/85)

In article <1349@umcp-cs.UUCP> mangoe@umcp-cs.UUCP (Charley Wingate) writes:
>Static allocation is also enforced by the common use of data statements to
>initialize variables which are then changed during calls to the subroutine.
>Every Fortran compiler I've ever seen allocates storage so that the
>changed values persist

Note that nowhere in the Fortran standard is such persistence
sanctioned unless the storage resides in COMMON, which must also be
present in some outine in the current calling chain. Think about
overlays (ick!) and you will see why this restriction exists.

	Ken
-- 
UUCP: ..!{seismo,okstate,garfield,decvax,philabs}!mcvax!ken Voice: Ken!
Mail: Centrum voor Wiskunde en Informatica, Kruislaan 413, 1098 SJ, Amsterdam.

ken@boring.UUCP (08/26/85)

Before people start telling me, the SAVE statement in F77 is intended
to allow such retention of previous values.

	Ken
-- 
UUCP: ..!{seismo,okstate,garfield,decvax,philabs}!mcvax!ken Voice: Ken!
Mail: Centrum voor Wiskunde en Informatica, Kruislaan 413, 1098 SJ, Amsterdam.

mangoe@umcp-cs.UUCP (Charley Wingate) (08/27/85)

In article <6600@boring.UUCP> ken@mcvax.UUCP (Amoeba #117) writes:

>>Static allocation is also enforced by the common use of data statements to
>>initialize variables which are then changed during calls to the subroutine.
>>Every Fortran compiler I've ever seen allocates storage so that the
>>changed values persist

>Note that nowhere in the Fortran standard is such persistence
>sanctioned unless the storage resides in COMMON, which must also be
>present in some outine in the current calling chain. Think about
>overlays (ick!) and you will see why this restriction exists.

This is certainly true, but it looks to me as if this sort of storage
management is going to persist.  There are too many programs which rely on
that sort of implementation.

Charley Wingate

herndon@umn-cs.UUCP (09/06/85)

  Persistence of local variables is sanctioned in the FORTRAN 77
language.  However, it is not guaranteed unless the appropriate
keyword (AUTOMATIC) is used in the variables' declarations.

					Robert Herndon

johnl@ima.UUCP (09/16/85)

As has been pointed out several times here, it is easy to detect at compile
time which routines in a program might be indirectly recursive.
Unfortunately, that is not very useful.  I have seen lots of programs
with routines which call each other back and forth, but are written so that
they are not in fact recursive -- routine A calls routine B which has code
that calls routine A, but not when passed the arguments which A passes to it.
You can't reliably figure this out at compile time since it is clearly
equivalent to the halting problem, which is undecidable.

What you could do, though, and what I have never seen, is to detect recursion
at run time.  Each routine has a flag which it sets when it is entered and
clears when it exits.  Should a routine's flag be set at entry time, it means
that a recursive call is being made and the program can print helpful
diagnostics.

John Levine, ima!johnl

PS:  I must admit, that I wrote a Fortran compiler called INfort which some
of you may have used, and I didn't put in such a check either.  Then again,
since I used the C compiler code generator, recursive routines worked just
fine.