SPECIALIZE pragma

Simon Peyton-Jones simonpj at microsoft.com
Mon Jun 28 08:12:21 EDT 2004


There's no reason in principle.  I looked into why it's not happening in
practice, and there is a reason, although it's not a good one.
Briefly, the way specialisation works is this:

* We find all calls to 'f' in this module
* We float them up to the definition of f, along with their
instantiating types and dictionaries
	(these are called the "call instances")
* We instantiate the body of 'f' with these types and dictionaries, and
record the results as a RULE

All this is done by a core-to-core pass called 'specialise'.

All the type checker does with a SPECIALISE pragma is to create a pseudo
definition
	foo = (f Int dInt)
or whatever, where foo is unused, containing a call instance that the
specialise pass will find.

Problem: what if the dictionary passed at a call mentions a type
variable (as in this case)
GHC non-solution: discard such call instances => no specialisation.

Possible alternative: abstract over such type variables.  But tricky in
full generality

A better solution is probably for the type checker itself to create the
specialised copy. Then it could do more, and deal with partial
specialisation.   It's also much more direct -- no danger of a requested
specialisation being silently dropped as now.

This would take a little work (a few hrs I guess).  I'm inclined to
tackle it, but only after the POPL deadline

Simon

| -----Original Message-----
| From: glasgow-haskell-users-bounces at haskell.org
[mailto:glasgow-haskell-users-
| bounces at haskell.org] On Behalf Of Ross Paterson
| Sent: 28 June 2004 12:28
| To: glasgow-haskell-users at haskell.org
| Subject: Re: SPECIALIZE pragma
| 
| On Thu, Jun 17, 2004 at 10:53:28AM +0100, I wrote:
| > Digging around in the source code comments, I found a restriction
that
| > is biting me:
| >
| > > We *insist* that all overloaded type variables are specialised to
ground
| > > types, (and hence there can be no context inside a SPECIALIZE
pragma).
| >
| > The latter is fine, but the former seems too restrictive.  For
example,
| > a function with constraints (Storable a, Eq a) can't be specialized
to
| > Ptr b, even though b would be unconstrained.  Any hope of relaxing
this?
| 
| After a bit of experimentation: if we have
| 
| 	f :: (Storable a, Eq a) => T a
| 	{-# SPECIALIZE f :: T (Ptr a) #-}
| 
| not only do we not get the requested polymorphic specialization, but
| if we use f at the ground types T (Ptr Foo) and T (Ptr Bar), we get a
| specialization for each, and these are essentially the same.  Is there
| any reason not to generate the polymorphic one?
| _______________________________________________
| Glasgow-haskell-users mailing list
| Glasgow-haskell-users at haskell.org
| http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


More information about the Glasgow-haskell-users mailing list