Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add short-circuit evaluation mode to expression evaluator #271

Open
raehik opened this issue May 16, 2023 · 4 comments
Open

Add short-circuit evaluation mode to expression evaluator #271

raehik opened this issue May 16, 2023 · 4 comments

Comments

@raehik
Copy link
Collaborator

raehik commented May 16, 2023

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
Copy link
Member

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
Copy link
Member

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
Copy link
Collaborator Author

raehik commented May 18, 2023

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
Copy link

gklimowicz commented May 18, 2023

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants