▲ | wavemode 4 days ago | |||||||||||||||||||||||||
When people talk about the "expression problem", what they're describing is the fact that, (in your example) if you add a new method to the trait, you have to go around and implement that new method on every type that implements the trait. This is in contrast to if you had used an enum (sum type) instead, wherein adding a new operation is easy and can be done in a single place. But then in exchange, adding new variants requires going around and updating every existing pattern match to support the new variant. | ||||||||||||||||||||||||||
▲ | DarkSucker 4 days ago | parent | next [-] | |||||||||||||||||||||||||
Thanks. I wasn't thinking of enums. To the extent one designs a trait to use an enum type (or the enum to satisfy the trait), one wins. But it seems impossible to avoid code to handle all future {type, op} combinations. The nice thing I've seen with Rust is the ability to add to what's been done before without breaking what already works. I'm thinking of "orphan rules" here. | ||||||||||||||||||||||||||
▲ | TuringTest 4 days ago | parent | prev | next [-] | |||||||||||||||||||||||||
I'm thinking, didn't inheritance and abstract methods work to solve the problem? I know inheritance has its own severe problems, but adding a generic abstract method at the base class could create reusable code that can be accessed by any new class that inherits from it. P.S. ah ok, it's mentioned in the article at the Visitor section. | ||||||||||||||||||||||||||
| ||||||||||||||||||||||||||
▲ | jauntywundrkind 4 days ago | parent | prev [-] | |||||||||||||||||||||||||
This seems like it's easy to workaround by not modifying the existing trait but by defining a new trait with your new method, and impl'ing it atop the old trait. That seems like a pretty ok 90% solution, and in a lot of ways cleaner and more well defined a way to grow your types anyhow. |