On 06-May-2000, S.D.Mechveliani <[EMAIL PROTECTED]> wrote:
> Fergus Henderson wrote:
> 
> > Consider the following scenario.  Alfred defines a type `T'
> > and writes such a vacuous instance declaration for `Set T'.
> > This is part of a large library package that Alfred has written.
> > Meanwhile, Betty has written another library package that provides
> > functions on `set a'.  Charles writes a program using both Alfred's 
> > and Betty's libraries.  Being pressed for time (aren't we all?), 
> > Charles does not test his program very thoroughly.  Instead, since 
> > his program type-checks, and it's late Friday evening 
> > [..]
> 
> Rather long thing. The impression is that the trouble is in 
> "late Friday evening" and such things, that may happen with 
> *everything*, independently on whether this thing is based on  
> basAlgPropos  or it is just in  Haskell-98. I try to understand it:
>    Alfred.hs  [or .o ?] : 
>                        type T a = ... 
>                        instance Set (T a) where baseSet = vacuous...
>                        ...
>    Betty.hs   [.o]:    f :: Set a => a -> T a ...
>                        ...

In my example, Betty's code does not use anything from Alfred's code.
In particular it does not use `T'.  So it should be something like
this instead:

     Betty.hs   [.o]:    f :: Set a => a -> Int
                        ...

>    Charles.hs [.o]:    import Alfred
>                        import Betty ...
>                        ...

The key point is that Charles.hs contains a call to Betty's
function, passing it Alfred's type:

        foo :: Alfred.T -> ...
        foo x = ... (Betty.f x) ...

> What you are saying is that setting things like 
>                                     baseSet = error "dummy_baseSet"
> for  T a
> creates the problems because Charles may like to exploit 
> essentially the result of  baseSet  on say  T Bool.
> Right? 

Not exactly.  Charles just wants to call Betty's function `f'.
Charles has never even heard of `baseSet'.

Betty is the one that wants to exploit the result of baseSet.
But Betty's code is polymorphic; she doesn't want to exploit
baseSet for type `T Bool', she wants to exploit it for a
value of type `Set a => a'.  Betty has never even heard of
the type `Alfred.T'.

> This critic looks strange: searching for problems where there are
> not any.
> Alfred defined *his* user type T and *his* Set instance for it.
> And Charles dislikes this instance.
> Why  basAlgPropos  is guilty?

Because basAlgPropos encouraged the poor coding style that Alfred
used.  How, I hear you ask?  That coding style was the only easy
option.  The only alternative would have been for Alfred to define
instances of a whole lot of methods that he doesn't understand and
doesn't intend to use, and that would have been both time-consuming
and error-prone.

> The same is with any other libraries.

No, libraries written in a good style won't force their users to
define instances of lots of methods that they don't understand and
don't intend to use.

> For example, writing the above program  Alfred.hs  under 
> basAlgPropos,  a good hacker has to put in documentation
>   " 
>    The program  Alfred  was compiled without  -fadvancedAlgebra:
>    the standard advanced algebra operations are put dummy.
>   "

If Alfred was a really good hacker, he would realize that defining
incomplete instance declarations like this will quite likely cause
trouble for the users of his library, and so he will prefer to give
proper instance declarations.  It's almost always better to fix a bug
rather than simply documenting it.

But, suppose Alfred does document his code like this.
Then how is Charles to know whether passing Alfred.T to Betty.f
will be safe?

Perhaps Charles reads Betty's documentation.  Now, some of the
time Betty will simply not have documented whether her library
depends on the standard advanced algebra operations.  In that
case, if Charles is being cautious, then he cannot use Betty's
library at all.

Other times, Betty may have documented that her library does not
depend on the standard advanced algebra operations.  In that case,
Charles can go ahead and use Betty's library.  But then the next
version of Betty's library may well use those operations! Betty will
need to be very careful to document this change in the release notes.
Of course, by this time Charles will have moved on to another job, and
there will be a new programmer Edward who is maintaining Charles'
program.  Edward will need to go through the WHOLE PROGRAM looking for
any place where it calls Betty's functions with an argument that might
not support the standard advanced algebra operations.  To do this,
Edward will also need to read the documentation of all of the
libraries that this program uses.  If Edward is very careful and
thorough, he may notice the dangerous call.  But most of the time
Edward will not be so careful and thorough, or either Alfred or
Betty will not be so careful with their documentation.  So the
problem may well slip through.

Of course, there is a much easier solution to this: rather than
relying on documentation, which ends up being very fallible, 
why not use the type system?!?

-- 
Fergus Henderson <[EMAIL PROTECTED]>  |  "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh>  |  of excellence is a lethal habit"
PGP: finger [EMAIL PROTECTED]        |     -- the last words of T. S. Garp.

Reply via email to