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

The way Psalm treats the concepts of pure and immutable is conceptually wrong and misleading #3135

Closed
still-dreaming-1 opened this issue Apr 13, 2020 · 4 comments

Comments

@still-dreaming-1
Copy link
Contributor

still-dreaming-1 commented Apr 13, 2020

Immutable is just supposed to mean something cannot be changed. It can still change other things and the outside world.

Annotating a class as @psalm-immutable should not require the entire class to be pure. Something can be immutable without being pure. The existence of @psalm-mutation-free and @psalm-external-mutation-free, without also having a @psalm-internal-mutation-free is strange, because that last one is what immutable normally means.

Referring to something as "mutation free" to differentiate it from the standard meaning of "immutable" is a little strange. That concept of mutation free seems more like what pure is supposed to mean. This leads me to want to annotate classes and non-static methods with @psalm-pure, but the documentation almost implies it is only supposed to apply to static methods and functions.

@still-dreaming-1 still-dreaming-1 changed the title The way Psalm treats the concepts of pure and immutable is conceptually wrong and confusing The way Psalm treats the concepts of pure and immutable is conceptually wrong and misleading Apr 13, 2020
@muglug
Copy link
Collaborator

muglug commented Apr 13, 2020

I agree that it’s a bit of a jump, but this allows you to construct immutable classes inside a pure function without violating that function’s purity.

This comes from the perspective that, in a well-designed codebase, classes with state that cannot be changed should just store data, and any additional functionality that manipulates state elsewhere should live outside those classes.

Does @Ocramius have anything to comment?

@still-dreaming-1
Copy link
Contributor Author

still-dreaming-1 commented Apr 13, 2020

What if pure was something you could apply to classes? I know it is a little abnormal to think of classes as pure or impure, and it is more normal to only think of functions that way, while at the same time thinking of classes as immutable or not is totally normal. But just thinking about the concept of purity, it makes sense. A pure class could be something that does not affect the outside world, and its object instances don't affect their properties/internal state after construction. So if a class is pure, it is also immutable, but if the class is immutable it is not required to be pure.

Then you could still construct a pure class instance inside a pure function, and avoid violating that function's purity.

@Ocramius
Copy link
Contributor

I kinda agree with the OP, but changing this now is a big deal (BC break).

Encouraging pure API is good, so maybe we just need to allow class-level @psalm-readonly and @psalm-pure to "separate church and state".

Very similar to #2812

@muglug
Copy link
Collaborator

muglug commented Apr 17, 2020

Yeah, not going to change this in the immediate future

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

No branches or pull requests

3 participants