26

I'm currently delving into Fortran and I've come across the pure keyword specifying functions/subroutines that have no side effects.

I have a book, Fortran 90/95 by S Chapman which introduces the pure keyword but strangely provides no "good coding practice" uses.

I'm wondering how liberally one should use this keyword in their procedures. Just by looking around it's obvious to me that most procedures without side effects don't find it necessary to include the pure keyword.

So where is it best used? Only in procedures one wants to completely guarantee have no side effects? Or perhaps in procedures one plans to convert to elemental procedures later? (As elemental procedures must first be pure.)

Alexander Vogt
  • 17,879
  • 13
  • 52
  • 68
River
  • 8,585
  • 14
  • 54
  • 67
  • 4
    Well, I try to use `pure` routines as often as I can. It forces me to write clean code. However, only a small percentage of routines actually can be pure... But I have never seen any difference in terms of speed or such. – Alexander Vogt May 15 '15 at 16:52
  • 3
    It's not Fortran 90/95 but note that `elemental` procedures can be `impure`. – francescalus May 15 '15 at 16:56
  • @AlexanderVogt "Only a small percentage"? It seems to me that most functions/subroutines would be `pure` when correctly coded. As I understand it from my book, only procedures which modify variables specified with `intent(in)` or have I/O components would not be `pure`. That seems like the minority, not majority, to me. – River May 15 '15 at 16:59
  • Sadly, no... As soon as I/O enters play, this is not possible anymore. Pointers? Impure. C bindings? Some intrinsics are pure, some not. Even some intrinsics are impure with some compilers (versions)... As soon as a single routine is impure, all calling routines are impure as well :( – Alexander Vogt May 15 '15 at 17:05
  • Still, many small procedures can easily avoid pointer or I/O use, depending on what sort of program is being written, of course. Are you saying that the `pure` keyword should be used whenever possible? That does not appear to be the standard method of use based on the Fortran code I've viewed. – River May 18 '15 at 21:57

2 Answers2

18

PURE is required in some cases - for example, procedures called within specification expressions or from FORALL or DO CONCURRENT constructs. PURE is required in these case to give the Fortran processor flexibility in the ordering of procedure invocations while still having a reasonably deterministic outcome from a particular stretch of code.

Beyond those required cases, whether to use PURE or not is basically a question of style, which is somewhat subjective.

There are costs to use of PURE (inability to do IO within the procedure, inability to call procedures that are not PURE) and benefits (a pure procedure written today can be called from a context written tomorrow that requires a pure procedure, because PURE procedures have no side effects the implications of an invocation of such a procedure may be clearer to a reader of the code), the trade-off between the two depends on specifics.

The standard may give Fortran processors considerable lee-way in how they evaluate expressions and function references within expressions. It definitely constrains programs in some ways around side effects of function execution and modification of function arguments. The requirements on a pure function are consistent with that lee-way and those constraints, consequently some people use a style where most functions are pure. Again, it may still depend on specifics, and exceptions may have to exist for things like C interoperability or interaction with external API's.

River
  • 8,585
  • 14
  • 54
  • 67
IanH
  • 21,026
  • 2
  • 37
  • 59
  • Other answers bring up other useful information regarding the use of `pure` and should be looked at for more about how `pure` lets the compiler optimize with out-of-order parallelization. – River May 19 '15 at 05:25
  • @IanH If I define a pure function `f` and use it in an expression `x=f(a*b)+f(a*b)`, then is it the case that `f` is always called once? It seems that testing to see whether that's true is not possible, since that would require putting some sort of side-effect into the function. – Raul Laasner May 19 '15 at 10:50
  • 1
    @RaulLaasner No. `f` might be called zero, one or two times, and this is independent of whether `f` is pure. – IanH May 19 '15 at 19:59
  • you can sort of test this by simply making a pure function that runs a long time. Based of a grand total of one such test, intel fortran evidently does not optimize `f(arg)+f(arg)` to `2*f(arg)`, with or without `pure` declaration. – agentp May 19 '15 at 21:29
11

As suggested by chw21, the primary motivation of PURE is to allow the compiler to better optimize. In particular, the lack of PURE for a function will prevent parallelization due to unknown side effects. Note that PURE subroutines, unlike functions, may have INTENT(INOUT) arguments, but there is still the restriction on side effects (and that a PURE procedure can call only other PURE procedures.)

Up through Fortran 2003, ELEMENTAL procedures are implicitly PURE. Fortran 2008 adds an IMPURE prefix that can be used with ELEMENTAL procedures to disable that aspect.

River
  • 8,585
  • 14
  • 54
  • 67
Steve Lionel
  • 6,972
  • 18
  • 31
  • 1
    Do you have any benchmark available that the `pure` statement actually leads to a better optimization by the compiler? I'm just curious, I tried that in the past and could not see any benefit with `gfortran` or `ifort`. – Alexander Vogt May 16 '15 at 15:52
  • If I put the `PURE` keyword on a not-pure routine the compiler will throw an error. It follows quite obviously the compiler can make that determination on its own, so one might expect it to do that and thus optimize the code the same. – agentp May 18 '15 at 13:57
  • These answers help me better understand the benefits of the `pure` keyword but I'd still like more on how it is commonly used. Should it be used whenever possible or is it more akin to bit-fiddling, multi-threading, and other such things that are only common where speed is of great importance? – River May 18 '15 at 22:04
  • 1
    @agentp That assumes that the compiler can "see" the body of a procedure marked PURE when compiling a reference to the procedure. That is not always the case - consider the possibility of separate compilation of external or separate module procedures. – IanH May 19 '15 at 01:38