▲ | naasking 4 days ago | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
> In rust you would add a NEW trait, which is brought in scope by those who need it. No, that's not sufficient if done naively as I think you're describing. You seem to be missing the context of this discussion as described by the article. Other code already depends on the current compiled abstraction, and you want to extend it in various ways, safely, so that existing code continues to work without recompilation, but you can extend the abstraction that code is already safely handling with new types and new operations without modifying the original source code. If you want to add a new node type to an AST, with algebraic data types you would have to modify the original source code of the original functions that match on those types, so types are closed to extension. You can leave the type open to extension via traits, but now the operations are closed to extension without modifying the original source code. > It sounds like, for example, wanting to add a new variant to an enum while also not wanting to modify match statements which now fail exhaustive testing. That’s a direct contradiction. No it's not, if enums and match statements were safely open to extension rather than closed. That's exactly what would solve the expression problem. This can and has been done [1] as the article described, via multimethods or via lifting data constructors to the type class level. It's obtuse and awkward, but in theory it doesn't have to be. The ultimate goal is that the new type and/or pattern matching cases have to be provided together to cover all of missing combinations, but importantly "together" means by the time the final program is assembled and not in the source code that defined the original types or operations. [1] open pattern matching and open algebraic data types have also been done in research languages | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
▲ | adastra22 4 days ago | parent [-] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
> No, that's not sufficient if done naively as I think you're describing. You seem to be missing the context of this discussion as described by the article. Other code already depends on the current compiled abstraction, and you want to extend it in various ways, safely, so that existing code continues to work without recompilation, but you can extend the abstraction that code is already safely handling with new types and new operations without modifying the original source code. That is exactly what a new trait would accomplish. I remain confused as to the distinction you are making. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|