Haskell-prime Digest, Vol 1, Issue 4
rjmh at cs.chalmers.se
Thu Jan 26 09:01:32 EST 2006
Ross Paterson wrote:
> I suggest = for bind-by-name, and
> := for bind-by-need.
You're proposing that the =/:= distinction both decides whether
constrained type variables are monomorphic and whether the binding
should be implemented using sharing. If it only did the former (and the
expectation was that all pattern bindings with unconstrained types used
sharing), then existing legal programs would still be legal, and the
examples that currently trip over the MR would be legal but inefficient.
(Also, what does the shared/unshared distinction mean for functions?)
Not just constrained type variables. All type variables. Because changes
in the program
elsewhere can easily change the status of a type variable from
unconstrained to constrained,
thus triggering monomorphism unexpectedly--that was the point of my
introducing an equality test in a function called from the definition.
Changing the status
of a type variable should not change the way it is treated by any
replacement for the M-R.
I don't quite follow what you're suggesting above. The main point of a
=/:= distinction is
to distinguish between sharing and non-sharing, isn't it? And sharing
means you have to
be monomorphic, at least for constrained type variables, and (by the
thus for unconstrained ones too. How can sharing/unsharing and
I'd really like to avoid ANOTHER rule that "guesses" what method to use,
based on the
form of the definition (your reference to pattern bindings above). That
leads to surprises
for the programmer, at least the less-than-expert one, when a definition
is replaced by
something that LOOKS equivalent, but type-checking or sharing suddenly
differently. Much preferable is a simple and obvious rule: = means
polymorphic, := means shared and monomorphic.
Shared/unshared doesn't matter for function definitions, but
can still be important. There is an interaction with implicit parameters
suppose might make it into Haskell'. A := definition says: resolve all
Thus, if there is an implicit parameter in the RHS of such a definition,
then it refers
to the instance of that parameter in scope at the point of definition.
With a = definition,
it refers to the instance in scope at the point of use. This is an
whether you're defining a function or anything else. This is discussed
in my paper
on Global Variables in Haskell, which suggested using implicit
parameters to refer
to global variables, rather than an unsafe unsafePerformIO applied to a
What if one has mutually recursive bindings, some using = and some := ?
Does monomorphism kick in if some of the variables in a binding group
use :=, or would we just require that all bindings in the same group
use the same binder? (At first I couldn't see why one would ever use :=
with function bindings, but perhaps that's the reason.)
I don't think there's really a problem in allowing a mixture of = and :=
in the same
mutually recursive group, even if it could be quite confusing to do so!
= just means
that type variables and dictionaries should be abstracted, and that the
should be by-name... let's assume that we're translating to System F,
and we always
insert at least a \()-> on such bindings in the translation. := means,
on the other hand,
that type variables and dictionaries are not abstracted, and so must be
an enclosing scope. So in a group of the form
f = ...g...
g := ...f...
then any type variables in the definition of g must refer to the
enclosing scope, which
means that they cannot be generalised in the definition of f either
(since they are
"free in the context"). But if there are type variables in the
definition of f which do
NOT occur in the type of g, then they can be generalised as usual.
Meanwhile f can
be bound by name, and g by need--there's no difficulty with that. This
would be an
odd thing to do, but I think it makes perfect sense. (I wonder what
if you write mutually recursive definitions where the M-R applies to
Of course, polymorphic recursion would REQUIRE an = binding, but that
More information about the Haskell-prime