John Hughes wrote:

> Everybody agrees the monomorphism restriction is a pain:

Hmm well, it's really not a nice thing.

> Some suggest that it is enough for compilers to issue a warning when using
> call-by-name. I disagree strongly. Such a warning may alert the programmer
> at the time the overloaded definition is compiled. But programmers need to
> understand programs at other times also. The person reading through the code
> of a library, for example, trying to understand why a program using that
> library is so slow or uses so much memory, will not be helped by warnings
> issued when the library was compiled. The distinction between call-by-need
> and call-by-name is vital for understanding programs operationally, and it
> should be visible in the source.

In a library I'd really expect to see a big comment when such a thing
happens. 

> So, let's make it visible, in the simplest possible way. Let there be TWO
> forms of binding: x = e, and x := e (say). A binding of the form `x = e' is
> interpreted using call-by-name, and may of course be overloaded: it makes `x'
> and `e' exactly equivalent. A binding of the form `x := e' is interpreted
> using call-by-need, and is monomorphic; `x' behaves as though it were
> lambda-bound. Now, for example,
> 
>       pi = 4*arcsin 1
> 
> is an overloaded definition which (visibly) risks duplicated computation,
> while
> 
>       pi := 4*arcsin 1
> 
> is a monomorphic definition at a particular instance which (visibly) does not.

But which instance? In this case the default mechanism can give the
answer, but in general, you would have to give a type unless `e'
already has a monotype. So you could use `x:=e' without a signature
exactly when you now could use `x=e' without one. 


> Advantages of this idea over the existing MR:
> 
> * Monomorphism is decoupled from the syntactic form of the definition. There
>   is no need to `eta-convert' definitions to get them into a form that the MR
>   does not apply to.

The difference between `x=e' and `x:=e' is surely a syntactic one,
though arguably one that is easier to justify.

> * Monomorphism is decoupled from overloading. With this proposal, x := e is
>   always a monomorphic definition, whether the type of e is
>   overloaded or not.

Again: how can this be?

>   Thus small changes to e cannot suddenly bring the MR into effect, perhaps
>   invalidating many uses of x.
> 
> * Monomorphism is decoupled from type inference. One may leave the type of 
>   a variable to be inferred regardless of whether it is bound by name or by
>   need.
> 
> Disadvantages:
> 
> * Requires another reserved symbol.
>
> * When converting Haskell 1.x to Haskell 2, many := would need to be inserted.
>   Failure to do so could make programs much less efficient. An (optional)
>   compiler warning could help here.

I don't see this. Or do you want to always recalculate any value
defined with `=' instead of `:=' ?
 
> An alternative design would be to use := to indicate polymorphism/overloading
> in pattern bindings, but retain = for polymorphic function bindings. That
> would make conversion from Haskell 1 to Haskell 2 simpler (one would simply
> replace = by := in pattern bindings with an overloaded type signature), but is
> an unattractively inconsistent design.


I don't like this idea (yet?), and would prefer the compiler-warning
version, or even keep the MR - we could make our editors smarter and
let them add the types if they change too often or are just too weird
for us, rather than introduce new syntax only in order to be able to
leave them out.


Christian Sievers


Reply via email to