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

print, exit, and die effect IO but they are considered pure. #6136

Closed
azjezz opened this issue Jul 19, 2021 · 8 comments · Fixed by #6188
Closed

print, exit, and die effect IO but they are considered pure. #6136

azjezz opened this issue Jul 19, 2021 · 8 comments · Fixed by #6188
Labels

Comments

@azjezz
Copy link
Contributor

azjezz commented Jul 19, 2021

ref: https://psalm.dev/r/f3713595ce

@psalm-github-bot
Copy link

I found these snippets:

https://psalm.dev/r/f3713595ce
<?php
/**
 * @return (pure-callable(string): int)
 * @pure
 */
function foo(): callable {
    return fn(string $a) => print($a);
}

/**
 * @pure
 */
function bar(): void {
  $_x_ = foo()('h');
}

/**
 * @pure
 */
function baz(): void {
  print('x');
}

/**
 * @pure
 */
function qux(): void {
  exit('x');
}


/**
 * @pure
 */
function quux(): void {
  die('x');
}
Psalm output (using commit 99bafa6):

No issues!

@azjezz
Copy link
Contributor Author

azjezz commented Jul 19, 2021

Note: foo() function in the example is pure, the error should be in the return type, as it claims to return a pure callable, while it returns an impure one ( uses print )

@weirdan weirdan added the bug label Jul 19, 2021
@orklah
Copy link
Collaborator

orklah commented Jul 26, 2021

I'm onboard for print, but can you explain what's the desired behaviour for die() and exit()? From what I see, purity is only useful in the context of the process still running. Is this only for principle or does this have practical applications?

@azjezz
Copy link
Contributor Author

azjezz commented Jul 26, 2021

a function signature might be noreturn ( never ), which is okay to use in pure code, it might throw an exception, or stops the process, however, interacting with I/O is not a pure behavior, as it results in a side effect, stopping the process and throwing are also side effects, however, in psalm it's kept simple, and they are not considered side effects ( even tho most other languages consider them that ).

I think die should only be considered pure when it's called without an argument.

@weirdan
Copy link
Collaborator

weirdan commented Jul 26, 2021

I can imagine cases where you may want to make sure no unexpected output generated. E.g. language server, generating images, etc.

@weirdan
Copy link
Collaborator

weirdan commented Jul 26, 2021

I think die should only be considered pure when it's called without an argument.

die() and exit() do not affect IO when called with integer argument (I don't think setting the exit code qualifies as IO).

@azjezz
Copy link
Contributor Author

azjezz commented Jul 26, 2021

die() and exit() do not affect IO when called with integer argument (I don't think setting the exit code qualifies as IO).

yea, so conditionally pure if the type of the argument is not a string.

@Jack97
Copy link
Contributor

Jack97 commented Jul 26, 2021

I can pick this up if it hasn't already been started, I've briefly looked into the issue and can see that it's caused by both the ExitAnalyzer and PrintAnalyzer lacking purity checks.

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

Successfully merging a pull request may close this issue.

4 participants