-
Notifications
You must be signed in to change notification settings - Fork 665
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
Immutable storage [breaking change proposal] #8132
Comments
IIRC, we discussed making Unions immutable (and Atomics would follow) once with @AndrolGenhald. I think it's a very good idea but It may be a massive work: Psalm change properties a lot on Unions and Atomics... I'm not sure I get the appeal of having both Mutable and Immutable classes though |
I've gone ahead with a draft refactoring, currently settling more on always-immutable Atomics and Unions and a mutable MutableUnion. |
I'd like to avoid |
I've wanted this for a long time, but it's a lot of work. I've been thinking a good way to refactor it would be to add a
Absolutely, I'd rather not have everything duplicated. Maybe it'd be better to work bit by bit and make more classes immutable over time? For some of them it'll probably be easier to make individual properties readonly instead of trying to work through the entire class at once (especially I think there were also some performance worries about this. I recently discovered that If we eventually have all of the type-related classes immutable hopefully it will become less of an issue. There's no point having |
I don't have a lot of experience about immutability in large codebase, but potentially, having immutable unions could be more performant. Changing a type would imply making a new clone, but a lot of places where we clone types "just to be safe" would disappear because the called code won't be able to change the object. Cloning may become better targeted and only needed when changing something |
This is correct — cloning was removed there for performance reasons, and it led to a bunch of hard-to-debug issues. But the performance gains were very real — when rewriting most of Psalm in Rust that was one of the big speedups, aside from paralellisation. Immutable union types (and thus immutable atomic types) could be a performance benefit, but it would add quite a lot of extra code. I'm skeptical that it's worth it, but happy if someone wants to try — it would be easy to add the annotation, and hard to fix all the very many issues that crop up. |
Is that available somewhere? I've semi-seriously considered trying something like that a few times, but I've never had the time. |
No, and I added some extra detail here: #8137 |
Wow, that's a lot of useful information and feedback!
Sure, I could work around this by making Edit: actually, I don't like the idea of using references in methods like
I thought of the exact same thing, it would be awesome!
I spent the last month writing a php-to-C transpiler based on zephir to try and obtain easy performance gains in Psalm, currently the project is on hold due to the absolute unusability of the pre-alpha quality official zephir toolchain. |
I think this would be a better route to go than rewriting in Rust, and there's some precedent with other typecheckers — MyPy uses Mypyc to generate a transpiled version. But I still think it's beyond the scope of the Psalm project, and would have to be taken up by a well-resourced company (MyPy's development is sponsored by a number of them, including Dropbox). |
This has been implemented. |
Opening this issue to allow discussion of possible breaking changes in psalm v5 to allow the immutability of types stored inside storages.
I've been encountering a good number of parallelism bugs, that are actually execution order bugs caused by corruption of some part of function, method, class or argument storages.
To debug this, in my fork I have "frozen" the contents of all storages after scanning, by recursively rendering immutable all stored Unions, using a flag that triggers exceptions when using mutator methods.
While this has helped me a lot in finding bugs (which led to bugfix PR #8131), another bug I manually found and fixed in #8098 isn't detected by rendering Unions immutable, and is probably caused by a reassignment of the
as
property in aTTemplate*
Atomic type, which is obviously not detected even if the Union in theas
itself is also marked immutable.This is more problematic, and highlights a problem with the struct-like nature of
Atomic
types: lacking encapsulation, one can't easily detect the re-assignment of properties inAtomic
types.The breaking change I'm proposing to solve this issue (and to help detect misuse through static analysis) is to render all
Atomic
classes@immutable
, and create a separateAtomicMutable
class hierarchy which is mutable, with methods to convert between the two, sharing common methods between the two using traits; the same could be done for Unions, using MutableUnions instead.This would allow statically detecting misuse of types (including in plugins, etc), and even at runtime if we were to require PHP 8.1 for psalm v5 to use
readonly
properties.The text was updated successfully, but these errors were encountered: