Hi

On 2 Sep 2011, at 16:34, Brandon Allbery wrote:

I hope I am misunderstanding this....


I wrote:
I agree that such a scenario is possible. The present situation gives
no choice but to do things badly, but things often get done badly the
first time around anyway. Perhaps I'm just grumpy, but I think we
should aim to make bad practice erroneous where practicable. Once
the mistake is no longer forced upon us, it becomes a mistake that
deserves its penalty in labour. Silent pre-emption is bad practice and

with the response:
So, when the whole point is that an unfortunate design years ago can't be reasonably fixed without rewriting massive amounts of code, the only correct answer is to rewrite massive amounts of code?

I'm not sure what you're asking here. Of course we should compare the
pain of the treatment with that of the symptoms.

Especially when the original proposal was put forward *specifically to avoid* rewriting massive amounts of code?

Which original proposal? How does it avoid rewriting code?

Yes, we'd love a perfect world. We don't have one. That's the *point*.

Recall that Option 2 resolves the duplicate superclass instances in favour of an explicit prior instance, but issues a warning (which should offer the
data to choose between explicit resolutions). That deals with a chunk of
the legacy scenario (although it doesn't handle the situation where some M is made a Monad in one module and made Applicative in a later module, which
is possible (common, even?) because Applicative is not currently a
superclass of Monad). If we make one existing class a superclass of another existing class, some disruption is inevitable: we can try to minimize that disruption, but we can't eliminate it entirely. For another example, if some F is made Applicative and Traversable in the same module, which default Functor
instance pre-empts the other?

We should question whether the disruption of even Option 2/3 makes it worth adding default superclass instances at all. Maybe, depressingly, we've reached the can't-fix-it stage. It would be good to get some data. It's also worth considering tools to support migration, using the diagnostics generated by
warnings.

If it is worth adding default superclass instances, Option 2 looks like a crucial disruption-minimizing expedience, while we have a legacy of newly extraneous instances to deal with. As far as "an unfortunate design years ago" is concerned, we should be careful to minimize the amount of rewriting
required. If that minimum is still too much, we'd better not go there.

I'm in favour of moving to Option 1 eventually, as somehow the better choice
for code comprehension. But I can see reasons to resist the changeover:

* too much unmigrated code still relying on pre-emption under Option 2;

  * new instances of the old problem (an existing S is suddenly made a
superclass of an existing C, with a default S instance for C) come
      into being,

The former is a real risk, but hopefully with a finite lifespan. It would be too costly to switch from a warning to an error while too much code relies on
the deprecated practice. Please don't imagine I'm in favour of that.

The latter, however, requires us to be a bit dim in a way which was certainly not in evidence when most of the current motivating examples arose. In the legacy code (Monad-Applicative-Functor, Traversable-Foldable-Functor), we've
had to choose between two bad options, but the candidate
superclass-with-default-implementation has usually been evident. I'm sure we're capable of being that dim. I'm also sure we're capable of screwing up by writing an instance and assuming we get the default superclass instance
we expect, without noticing that someone else's chunk of the codebase
pre-empts it. I'd be troubled if someone knackered my applicative- style use of Monad [] by adding a zipping Applicative [], or even an instance which
appeared to have the same functionality but also did some sneaky
unsafePerformIO badness. That's an example of the risk we take by allowing
pre-emption. We have to balance the risk of going back and resolving
duplicates with the risk of bugs caused by code meaning less than it says.

So, are default superclass instances just too disruptive?

All the best

Conor

PS We'd love a perfect world. We don't have one. That's why we change things.


_______________________________________________
Glasgow-haskell-users mailing list
[email protected]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users

Reply via email to