From: Aris Tofanis on
m_b_metcalf <michaelmetcalf(a)compuserve.com> wrote:
> On Mar 25, 6:55=A0am, ajay <ajay.rawa...(a)gmail.com> wrote:
>> how can we implement this in fortran 77.
>> i know there is intrinsic recursive function in fortran 90/95.
>>
>> function func(x,y)
>> ...
>> ...
>> if ( y.lt.1.0d0 ) then
>>
>> func = ........
>>
>> elseif ( y.gt.1.0d0 ) then
>>
>> func = something/func(x,-y)
>>
>> end if
>>
>> end function
>>
>> waiting for the reply.....
>> thanking you.....
>
> Basically, you can't. But if you just add the recursive keyword and
> use a modern compiler, it will work.

I have never seen problems with g77 when creating a wrapper routine,
which only calls the routine you want to call recursively:

function wrapfunc(x,y)
wrapfunc = func(x,y)
end

and call wrapfunc inside func. But I also never felt quite comfortable
with this solution.
From: Richard Maine on
Aris Tofanis <aris.tofanis(a)6zbp6h.invalid> wrote:

> m_b_metcalf <michaelmetcalf(a)compuserve.com> wrote:
....
> > Basically, you can't. But if you just add the recursive keyword and
> > use a modern compiler, it will work.
>
> I have never seen problems with g77 when creating a wrapper routine,
> which only calls the routine you want to call recursively:
>
> function wrapfunc(x,y)
> wrapfunc = func(x,y)
> end
>
> and call wrapfunc inside func. But I also never felt quite comfortable
> with this solution.

Recursion is near the top of the list of things that I recommend *NOT*
doing just because you haven't happened to see problems. I would only do
it if it were affirmatively documented to be supported (as it is in f90+
with the recursive keyword). It is far too easy for it to appear to work
in simple cases, but fail just when you are really counting on it.

--
Richard Maine | Good judgment comes from experience;
email: last name at domain . net | experience comes from bad judgment.
domain: summertriangle | -- Mark Twain
From: Aris Tofanis on
nospam(a)see.signature (Richard Maine) wrote:
> Aris Tofanis <aris.tofanis(a)6zbp6h.invalid> wrote:
>
>> m_b_metcalf <michaelmetcalf(a)compuserve.com> wrote:
> ...
>>> Basically, you can't. But if you just add the recursive keyword and
>>> use a modern compiler, it will work.
>>
>> I have never seen problems with g77 when creating a wrapper routine,
>> which only calls the routine you want to call recursively:
>>
>> function wrapfunc(x,y)
>> wrapfunc = func(x,y)
>> end
>>
>> and call wrapfunc inside func. But I also never felt quite comfortable
>> with this solution.
>
> Recursion is near the top of the list of things that I recommend *NOT*
> doing just because you haven't happened to see problems. I would only do
> it if it were affirmatively documented to be supported (as it is in f90+
> with the recursive keyword). It is far too easy for it to appear to work
> in simple cases, but fail just when you are really counting on it.

I realize it is bad practice what I suggested, in case of a compiler
which strictly speaking does not support recursion. But what about an
f90+ compiler which does support recursion? And the example above is
very simple, but what if this kind of two-step recursion eventually
happens in a less transparent way? Can I trust it is going to work,
or should I avoid it?
From: Richard Maine on
Aris Tofanis <aris.tofanis(a)2ttqdw.invalid> wrote:

> I realize it is bad practice what I suggested, in case of a compiler
> which strictly speaking does not support recursion.

It is "bad practice" because it can fail to work, and the failure can
happen in subtle ways that can escape your testing.

> But what about an
> f90+ compiler which does support recursion?

As all f90+ compilers do.

> And the example above is
> very simple, but what if this kind of two-step recursion eventually
> happens in a less transparent way? Can I trust it is going to work,
> or should I avoid it?

I repeat my statement that I would only do it if it were affirmatively
documented to be supported. No you cannot just trust that it will work
if it is not documented to. That was my whole point. Just trusting that
it will work is the opposite of my recommendation.

If it is an f90+ compiler and you use the recursive keyword, then it is
documented to work. That documentation is the f90 standard, in
conjunction with the compiler's claim to be an f90 compiler.

Do note the condition about using the recursive keyword. That keyword
was added to the language for a reason - not just to trip up users. The
reason is that support of recursion might require extra overhead in some
cases. Therefore, by telling the compiler which procedures need to work
recursively, the compiler can make those procedures work without
burdening every procedure in every program with the generally unneeded
overhead.

So no, you can't count of recursion to work without the recursive
keyword. I think that's what you were asking.

If you end up accidentally making an indirect recursive call to a
non-recursive procedure, that's a program bug, and unfortunately one
that might well pass your testing but give wrong answers when it
actually matters.

--
Richard Maine | Good judgment comes from experience;
email: last name at domain . net | experience comes from bad judgment.
domain: summertriangle | -- Mark Twain
From: glen herrmannsfeldt on
Aris Tofanis <aris.tofanis(a)6zbp6h.invalid> wrote:
(snip)

> I have never seen problems with g77 when creating a wrapper routine,
> which only calls the routine you want to call recursively:

> function wrapfunc(x,y)
> wrapfunc = func(x,y)
> end

> and call wrapfunc inside func. But I also never felt quite
> comfortable with this solution.

In general it won't work for pre-Fortran 90, and even for
Fortran 90 without the RECURSIVE attribute. Traditionally, Fortran
did static allocation, and the rules for Fortran 66 and 77 were
designed around that. The Fortran 77 SAVE attribute pretty much
asks for static allocation, but there is no requirement for
automatic allocation for non-SAVEd variables.

For compilers based on C compilers it is reasonably likely
that you have automatic local variables. Before g77 there
was f2c, which generated C code and then compiled that.
As long as the C code doesn't declare local variables static,
then recursion should be safe.

It seems that the requirement for a wrapper routine is a result
of a function name being a local variable in Fortran. It still
is for functions without the RESULT option. I think this means
that RESULT is needed for recursive functions that directly
call themselves, but I don't see the words in the standard
that say so.

In the Fortran 66 days, (I believe 1977) for testing purposes
I wrote a recursive function for TOPS-10 Fortran-10. That
compiler keeps the return address on the stack, but local variables
are static. To get around that, I used an array for local varaibles,
and incremented/decremented a variable with recursion depth.
This was recently discussed on the alt.sys.pdp10 newsgroup!
(There is a PDP-10 system run by PDPplanet that one can test
out such code on.) In that case, because of the local variable
problem, a wrapper function was needed.

The OS/360 Fortran 66 (and, as far as I know, Fortran 77) compilers
keep the return address in static storage. If you do manage
to do a recursive call, you can never return to the original caller.
I believe that was common for many Fortran 66 compilers.

-- glen