On 2 Sep 2011, at 18:19, Jonas Almström Duregård wrote:
I agree. Option 2 FTW :)
The recent discussion concerns whether option 2 should eventually be
shifted to option 1. Everyone seems to agree that option 2 should be
used initially.
A similar warning should perhaps indicate that a "hiding" clause has
nothing to hide, as Jonas suggests.
I'm in favour of Option 2 now and Option 1 later, where "later" has
non-disruptiveness criteria attached. A bit like being in favour of
the pound now and the euro later.
As I've mentioned in another message just now, even Option 2 entails
some disruption, when you make one old class a new superclass-with-
default
of another (e.g. Functor for Monad): if old code makes M a Functor in a
later module than its Monad instance, that Functor M instance comes too
late to pre-empt the default and is rejected as a duplicate.
All the best
Conor
Regards,
Jonas
On 2 September 2011 18:55, Simon Peyton-Jones
<simo...@microsoft.com> wrote:
Too many words! I'm losing track. What I'm proposing is Option 2
under "The design of the opt-out mechanism" on http://hackage.haskell.org/trac/ghc/wiki/DefaultSuperclassInstances
I believe that meets everyone's goals:
* A warning encourages you to fix the client code
* But you can turn it off, and it's not fatal.
Does anyone advocate something else?
Simon
| -----Original Message-----
| From: glasgow-haskell-users-boun...@haskell.org [mailto:glasgow-haskell-users-
| boun...@haskell.org] On Behalf Of Jonas Almström Duregård
| Sent: 02 September 2011 16:50
| To: Conor McBride
| Cc: GHC users
| Subject: Re: Superclass defaults
|
| > The question then comes down to whether that warning should
ever be
| > strengthened to an error.
|
| Indeed.
|
| > 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
| > code which relies on it should be fixed: it's not good to
misconstrue
| > an instance declaration because you don't know which instance
| > declarations are somewhere else. Nonmonotonic reasoning is
always a
| > bit scary.
| >
| > From a library design perspective, we should certainly try to
get these
| > hierarchical choices right when we add classes. I accept that
it should
| > be cheap to fix mistakes (especially when the mistake is lack of
| > foresight. Sticking with the warning rather than the error
reduces the
| > price of this particular legacy fix at the cost of tolerating
misleading
| > code. I agree that the balance of this trade-off is with the
warning,
| > for the moment, but I expect it to shift over time towards the
error.
| > But if it's clear what the issue is, then we can at least keep
it under
| > review.
|
| I agree. Making bad practice erroneous is good, but its not
really the
| bad practice that raises the error here. You have no serious
problems
| until you try to change your bad design to a good one. Like you
say it
| should be cheap to fix mistakes.
|
| >> Will there be a solution to this dilemma that I have missed?
Should
| >> the client code be allowed opt-out from the superclass
preemptively
| >> before it is given a default? Won't that cause a similar
perplexity?
| >
| > I don't know what you mean by this. Perhaps you could expand on
it?
|
| What I'm trying to ask is if you can write compatible code that
will
| work across gradual changes of the compiler and the libraries.
|
| Suppose we have library with class C. In a newer version of the
| library we add an intrinsic superclass S. Also suppose the compiler
| implements option 1. Now the users of the library want to write
code
| that uses both C and S, and that's compatible with both the new and
| the old library. From what I can tell there are three situations
that
| needs to be covered:
|
| 1) Old compiler - Old library
| Here we need to specify both instances, and we cant hide the
default S
| instance because its not supported by the compiler. This also
applies
| for other situations where the client must use Haskell 2010
compatible
| code.
|
| 2) New compiler - Old library
| Here we also need to specify both instances.
|
| 3) New compiler - New library
| We can either write both instances and hide the default or we can
just
| write an instance for C.
|
| Clearly code that covers situation 1 will never be compatible
with situation 3.
|
| The question I was asking was if we are allowed to hide the default
| instance of S in situation 2. In that case you can write compatible
| code for situation 2 and 3. The possible confusion from this is
that
| you hide a default implementation thats not defined. Maybe it's
not as
| bad as overriding silently, but there is some room for error
where you
| think you have blocked a superclass instance but really you have
just
| blocked some completely unrelated class.
|
| Of course we can get compatibility across all three using CPP but I
| really wish we won't need that.
|
| As time passes, situation 1 will become more rare, although
situation
| 2 and 3 can reoccur endlessly as new libraries are designed and
| redesigned.
|
| Regards,
| Jonas
|
| _______________________________________________
| Glasgow-haskell-users mailing list
| Glasgow-haskell-users@haskell.org
| http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
_______________________________________________
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users