[GHC] #14917: Allow levity polymorphism in binding position
GHC
ghc-devs at haskell.org
Mon Apr 9 14:09:50 UTC 2018
#14917: Allow levity polymorphism in binding position
-------------------------------------+-------------------------------------
Reporter: andrewthad | Owner: (none)
Type: feature request | Status: new
Priority: normal | Milestone:
Component: Compiler | Version: 8.2.2
Resolution: | Keywords:
| LevityPolymorphism
Operating System: Unknown/Multiple | Architecture:
| Unknown/Multiple
Type of failure: None/Unknown | Test Case:
Blocked By: | Blocking:
Related Tickets: | Differential Rev(s):
Wiki Page: |
-------------------------------------+-------------------------------------
Comment (by goldfire):
I, too, have pondered template polymorphism for some time, but never
fleshed it out even to this level. There are a few problems with this
design, however:
> More formally: A call to a template polymorphic function must
instantiate all template polymorphic type parameters. These parameters
must be instantiated with either fully ground types without any variables,
or variables bound by "V", the template polymorphic quantifier.
This means that, with your `id` definition, you couldn't have
{{{#!hs
idList :: [a] -> [a]
idList = id
}}}
even though you could have
{{{#!hs
idListInt :: [Int] -> [Int]
idListInt = id
}}}
So it seems template polymorphism would be infectious, generally requiring
callers of template-polymorphic functions also to be template-polymorphic.
I don't think that's a good thing.
On the flip side, I don't see concretely why we need the "no variables"
restriction.
> It is likely possible to support special cases of polymorphic recursion,
but it is not clear to me that it is worth the extra work.
Generally, these schemes fail on polymorphic recursion, and I think we
should do so here, too.
> This can lead to a situation where a module has two imports which
exports the same specialization of a function they in turn imported. But
there is no real problem here, because it doesn't matter which one we pick
since both specializations will be the same.
I think there ''is'' a real problem here. First off, it means that the
`.o` files that GHC produces won't be able to be linked by, e.g., `ld`:
multiple `.o` files might have the same definitions. In the end, I think
we'd have to implement some deduplication algorithm during linking, or end
up with horrid code bloat.
> One of the interesting things about this proposal is that generalizes
nicely to data types.
Under your "no variables" rule, this `List` type would have to be
specialized at every possible data parameter. I'm worried about bloat.
> However, supporting [data] specialization in different modules might
require a bit of thought.
This is also a thorny question. Here, we absolutely have to get
deduplication correct, as it's a matter of correctness, not just
efficiency (in size of the executable).
One unaddressed question here is: what restrictions would there be on
template-polymorphic levity-polymorphic variables? Presumably, none, but
I'm not sure.
Also, how is this different from the "compulsory unfoldings" idea earlier
in this thread (started in comment:3)? The user declares template
polymorphism directly (the compulsory unfoldings idea didn't have any user
direction -- but perhaps it should have), and the specializations here
happen by creating new bindings instead of inlining, but I'm not sure a
user would really see the difference here.
--
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/14917#comment:16>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler
More information about the ghc-tickets
mailing list