Prev: Selecting the first element of a array returned by pack()
Next: size of a derived type containing pointers...
From: Aris Tofanis on 25 Mar 2010 14:59 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 25 Mar 2010 16:36 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 25 Mar 2010 19:47 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 25 Mar 2010 20:06 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 25 Mar 2010 21:18
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 |