
Hi Sorry to be late again...I'm trying to have what's laughably described as a holiday, but it seems more like the common cold to me. On 31 Aug 2011, at 08:52, Jonas Almström Duregård wrote:
| > There seems to be a lot of support for Option 3... but what about Option 2 (ie pre-empt but give a warning)?
At least in the short term, I think Option 2 is a good compromise. It's true that when I started using default superclass instances (which SHE supports) in the Epigram codebase, the first thing I had to do was delete a bunch of dull default instance stacks. That was fun, but it wasn't nothing.
I think option 2 sounds very good. Possibly with the exception of only warning when the manual instance is in another module, since you will never experience the "perplexity" described in option 3 if you have written the instance yourself.
I become perplexed very easily. I think we should warn whenever silent pre-emption (rather than explicit) hiding is used to suppress a default instance, because it is bad --- it makes the meaning of an instance declaration rather more context dependent. Perhaps a design principle should be that to understand an instance declaration, you need only know (in addition) the tower of class declaration s above it: it is subtle and worrying to make the meaning of one instance declaration depend on the presence or absence of others. Arguably, option 1 does not conflict with design goal 1. Design goal 1 supports a methodology for refining a class into a hierarchy without creating the need for stacks of default instances or breaking code. If the new superclass is a brand new thing without legacy instances, there's no problem. If we'd had this mechanism in place, Functor would always have been made a superclass of Monad, Applicative would have been easily inserted, and we wouldn't have the stacks of manually added default instances to worry about. The main problem with Option 1 is in dealing with the legacy of classes which currently require a stack of default instances, creating a hierarchy from parts which already exist. Option 1 would create a bunch of instance conflicts and thus demand changes to code. Design goal 1 isn't very explicit (sorry!) about this distinction between introducing new classes as superclasses and building hierarchies from legacy classes, but it was the former I intended. I always expected the latter to cause trouble. If it is also a design goal to minimize damage with respect to the current unfortunate situation, then Option 1 is problematic. Whatever we might wish, we are where we are. We should be pragmatic. I think we should set Option 1 as the direction of travel, but go with Option 2 for the moment. We should make sure that the warnings generated by Option 2 are sufficiently informative that it is easy to track down the conflicts and resolve them explicitly, for Option 1 compliance. Does this sound plausible? Conor