Sorry for the delayed response/read.
I also feel like capabilities and effects are both exciting tools for having intentional management for extensibility. I’m somewhat wary of the concept of marking every function call as an effect; I’m not positive but I think this is just implementing your own interpreter to intercept function calls. It seems like you’d have to do a careful job knowing what function it was you were intercepting. In the example both the color picker and palette are free variables so it’s also possible to consider that the level of interception by fully functorizing all dependencies like Newspeak so that you can dependency inject everything.
I talked about the distinction between open/closed extensibility in my post and it seems like this is most centered around modifying systems that are not built composable enough to have first class modification. If the original implementation is using an effect for either picking a color or adding colors to the palette, this would be a form of open extensibility where you could write a custom handler to transform the color at the handler level.
The larger issue is how you handle the case that the existing implementation is not factored in such a way that is amenable to you introducing the extension point you want. As an aside, I think this is the same issue that Kay was trying to solve with behavioral inheritance but you have the same issue with methods not being at the right granularity. One way in which I would like to be able to address this is by exposing the source program to a user and giving them behavior-preserving refactors that allow them to change the original program to be more amenable to extension without changing the original program. So in the color picker example even if the colorPicker.choose
and palette.add
functions weren’t already separated you could refactor the source into those programs and intercept on that level. There’s an open question on how amenable this would be to updates from the original author and dealing with conflicts.