camfort / fortran-src

Fortran parsing and static analysis infrastructure
https://hackage.haskell.org/package/fortran-src
Other
48 stars 20 forks source link

Add short-circuit evaluation mode to expression evaluator #271

Open raehik opened 1 year ago

raehik commented 1 year ago

This was present in fortran-vars' evaluator. Currently, all arguments for functions and operators are eagerly evaluated. (I picked this because it was easier to write, since I couldn't find any relevant standards/expectations for compilers.) It would be straightforward to add a switch for selecting between short-circuit and eager-evaluation.

We would add the switch by extending the evaluator monad to include some Reader environment -- this was always the plan, we simply didn't have any config yet. Then the binary operator and function call evaluation code would be changed to inspect the current mode and provide the appropriate behaviour.

dorchard commented 1 year ago

Good idea. Worth noting that test/EvalSpec.hs in fortran-vars has tests relating to this that show the shortcircuting behaviour is more powerful in an analysis setting.

dorchard commented 1 year ago

Although it seems that short-circuiting behaviour is the exception rather than the norm when it comes to compilers: https://www.scivision.dev/fortran-short-circuit-logic/

raehik commented 1 year ago

A concise example from @dorchard that demonstrates short-circuiting changing behaviour:

program ShortCircuit
  implicit none

  logical :: k

  if (.true. .OR. effects()) then
  end if

  if (.false. .AND. effects()) then
  end if

contains

  function effects()
    logical :: effects
    write(*,*) "HELLO"
    effects = .false.
  end function effects

end program ShortCircuit

gfortran -O0 prints HELLO twice. gfortran -O1 prints nothing.

gklimowicz commented 1 year ago

Just a comment from a standards dweeb: Here's the relevant text from the Fortran 2018 standard:

10.1.5.4.2 Evaluation of logical intrinsic operations Once the interpretation of a logical intrinsic operation is established, the processor may evaluate any other expression that is logically equivalent, provided that the integrity of parentheses in any expression is not violated.

So, a programmer shouldn't rely on side effects in the RHS of .AND. and .OR. expressions.

The referenced link at scivision.dev has a statement that I believe is not correct.

Compilers not short-circuiting (standard Fortran behavior):

Gfortran -O0 NAG Intel

Short circuiting (non-standard behavior)

Gfortran -O1 or higher

Short-circuiting is indeed standard-conforming behavior. Just not common enough for programmers to avoid the pitfalls.