In addition, variables aren't allowed to have the SAVE attribute
(static in some other languages).

Also, I/O isn't allowed. That seems to make sense. Then you try to
debug a program, even a fatal error, by printing something out and
find that you can't. Maybe not so bad, but the STOP statement (like
exit() in C) is also disallowed. Again it makes sense until you try
to debug something.

> I put "purely functional" in quotes because I'm using the term> pretty loosely, since assignments and such would be allowed inside> foo. But they all have to be to local variables (i.e. not to an> alias whose data is in some outer scope).

I believe PURE allows compilers to optimize two calls with the
same arguments into one. That is:

X=FUN(1)+FUN(1)

into

X=2*FUN(1)

(so don't make random number routines PURE) Though some say
that Fortran can do that even if a function isn't pure.

In addition, Fortran has ELEMENTAL, which is more restrictive than
PURE. ELEMENTAL allows a function (or subroutine) with only scalar
dummy arguments to be called with array actual arguments, such that it
is called for each array element. Similar to the way you can say:

Y=SQRT(X)

with X and Y arrays, for element by element operations.

> Can a compiler do this sort of checking, or would the complexity get> out of hand? I'm thinking that at least a limited form must be> possible in order to do any sort of inter-procedural register> allocation.

I believe that most of the checks are pretty easy. Though the general
rule with language restrictions is that they are restrictions on the
programmer, not the compiler. If you don't follow the rules, the
compiler is not required to diagnose them, and in addition you can't
rely on the results.

In the case of ELEMENTAL, the compiler could evaluate more than one
array element at the same time. If you did manage to modify something
outside, or local static, the results may be surprising. That could
also be true of PURE.