recursive integer function RECFAK (n)
implicit none
integer :: n
if (n == 0) then
RECFAK = 1
else
RECFAK = n * RECFAK(n-1)
endif
end function RECFAK
Is that because our compiler is more liberal than it should be?
Where in the Standard does it say that you NEED to use RESULT?
-- Dieter Britz. Visit me at http://www.kemi.aau.dk/~db
You must use RESULT if the function is array valued. This is because
Fortran makes no syntactic distinction between an array element
reference and a function call. Other languages do not have the
problem for another reason as well: in most other languages the
result of a function is returned as the expression on the RETURN
statement so that the function's name is never a variable within
the function. Fortran got caught with an ambiguity when they
wanted to add both array-valued functions and recursion to
the language. The RESULT clause was the fix.
--
J. Giles
>ou must use RESULT if the function is array valued.
FUNCTION funny (a,n) ! does not use RESULT
INTEGER :: n
REAL(8) :: a(n,n), funny(n,n)
funny = a ! this works
END FUNCTION
Is acceptable to FPS4 and DVF, (a discovery I made last week)...
Dave
Since the topic of this thread was clearly RECURSIVE functions,
I didn't think it necessary to constantly repeat it. I clearly stated
that the RESULT feature was a response to an ambiguity in the
language which exists when a function is *BOTH* array valued
*and* recursive.
Or are you just trying to drag me into one of your flame wars?
I get into enough of those. I don't need your help.
--
J. Giles
> Two Fortran 90 texts I have say that you have to use the RESULT(..)
> clause for a recursive function, because every reference to the
> function name would otherwise invoke that function. I got away without
> problems with this one:...
> Is that because our compiler is more liberal than it should be?
> Where in the Standard does it say that you NEED to use RESULT?
I'd say your compiler is just being liberal, whether by design or
accident is not clear. I can't off-hand find an explicit requirement
that you use RESULT with RECURSIVE. Indeed, the 4th para of 12.5.2.2
begins "If both RECURSIVE and RESULT are specified..." which implies
(but does not explicitly state) that it might be possible to specify
either one without the other. If there is no prohibition against it
(and I don't see one - its possible I missed it, but I don't think
so), then it is legal.
But I do see, in the 3rd para of 12.5.2.2 (the para about RESULT) words
very simillar to those you cited from your texts:
"If RESULT is not specified, the result variable is <function-name>
and all occurances of the function name in <execution-part> statements
in the scoping unit are references to the result variable."
Thus your example is illegal because you have occurances of the
function name that are not references to the result variable
(and syntactically couldn't be).
The quotation above pretty much rules out directly recursive
functions that don't speciufy RESULT. This is because a directly
recursive function is one that invokes itself directly. Hmmmm....
there might be a way if the function invoked itself under a different
name created by a rename in a USE statement....yes I think I see a
way to do that - but that's pretty quirky. In any case, that's not
what your sample does.
The obvious possibility for a recursive function that doesn't need
RESULT is an indirectly recursive function. This would be the case
where you have (for example) 2 functionx X and Y. Function Y invokes
X and function X invokes Y. But nowhere does function X directly
invoke itself. This is called indirect recursion. Unless I missed
something, it is perfectly legal to do this without using RESULT.
--
Richard Maine
ma...@altair.dfrc.nasa.gov
"If RESULT is specified, the name of the result variable of the
function is <result-name>, ..., and all occurrences of the
function name in <execution-part> statements ... are recursive
function references.
"If RESULT is not specified, the result variable is
<function-name> and all occurrences of the function name in
<execution-part> statements ... are references to the result
variable."
Consider the 6 possible cases: with/without RECURSIVE,
for with RECURSIVE direct/indirect recursion, and
with/without RESULT.
1) RECURSIVE function f(x) RESULT(r)
:
r = f(...) ! OK - sentence 1
2) RECURSIVE function f(x)
:
f = f(...) ! NO - sentence 2 says we now have the
! result variable on the rhs, not a function
! reference
3) function f(x)
:
f = ... ! OK - sentence 2
4) function f(x) RESULT(r)
:
r = ... ! OK - sentence 1
5) RECURSIVE function f(x) RESULT(r)
:
r = ... ! OK - sentence 1 (indirect recursion)
6) RECURSIVE function f(x)
:
f = ... ! OK - sentence 2 (indirect recursion)
Hope that helps,
Mike Metcalf
--
> To understand why the result clause is necessary for direct
> recursion, we must consider the standard, p. 207, lines 30-34.
> Other replies to this query have, I'm afraid, missed the point.
Indeed, and I'd like to put this question to those who say
RESULT, or reference to the result name instead of the function
name is not a big deal:
Q: What is passed to FOO below, the result value being
computed, or the function itself?
RECURSIVE FUNCTION F()
...
CALL FOO(F)
Clearly, if it is "okay" to write a statement like "F = 3.14" in
the above procedure, it should also be "okay" to pass F as an
actual argument to FOO, which might be written in a language
other than Fortran (or whatever, which means you can't insist on
seeing its interface to disambiguate this issue).
If *that* was true, though, how would one go about doing that --
passing the result value to FOO such that FOO can write to it?
If one can do *that* via CALL FOO(F), how does one go about
passing the recursive function F to FOO, so that it can call
it as an EXTERNAL dummy argument?
I can't see any obvious way to accommodate both possibilities
without introducing new syntax at least as "ugly" as the
current requirement for RESULT and the requirements regarding
naming.
The *real* answer is, indeed, that F refers to the function
itself, and thus a different name is needed to refer to the
result returned by the function. (Yes, that Fortran doesn't
provide a "direct return" facility a la C and PL/I partly
contributes to this need. However, it's maybe a bit convenient
that one needn't explicitly declare a temporary, and hope to
get the type right, as one does in C, and probably PL/I as well,
especially since doing that can lead to bugs when the type of
the temporary is not the same as that of the function...though
that can be mitigated in the language design via a better
type scheme, e.g. an easy way to say "`result' is a variable
of the same type as the return type of the enclosing function".
Of course, not all functions require such temporaries in the
first place.)
--
"Practice random senselessness and act kind of beautiful."
James Craig Burley, Software Craftsperson bur...@gnu.org