Proposal: EPHEMERAL pragma

Hi all, Following up on a chat with Simon Peyton Jones at ICFP, I would like to discuss the possible introduction of a EPHEMERAL pragma. For example: {-# EPHEMERAL Rep #-}
data Rep = ...
This pragma would indicate that the programmer intends the Rep datatype not to be present in the final generated core code. Its proposed semantics are the following: 1. Make the compiler very keen to inline any functions that produce or consume Rep. 2. If Rep is exported, make all functions that operate on Rep INLINABLE (that is, make their code available for inlining in other modules). 3. Emit a warning if the generated core code still contains uses of Rep. My main use case for such a pragma is in the generic representation of datatypes in GHC.Generics. It's clear that we don't want sums and products lying around in user code, and in most cases we can get rid of them by inlining aggressively. Hopefully such a pragma can simplify or entirely replace the use of INLINE/INLINABLE pragmas in some cases. However, I'm not sure how well this can work in practice. Regarding (3), for instance, it's clear that functions that operate on Rep will be around in the final core code; perhaps only functions which do not directly produce or consume Rep, yet end up having values of Rep within them, should trigger a warning. (1) is hard to do well, in general. In particular when there are rewriting rules involving values of Rep, or functions that produce/consume Rep, the order in which they are inlined might affect the elimination of Rep values. In any case, I thought I'd share this with this list, in the hope to get feedback regarding how to improve the inliner (and the feedback programmers get regarding inlining). Cheers, Pedro

On a related note, it would be nice to have a little more tooling for
ensuring that SPECIALIZE pragmas take full effect. In particular, it's
nice to write generic code over numeric types (Double, Float), but if it
doesn't get specialized away, performance really tanks. Going through a
codebase and manually annotating all uses of the class can be really
laborious, and it's a brittle solution. It would be nice to indicate to
the compiler that a particular instance or even a particular class should
always be specialized away, and to get some warnings when this isn't
possible.
Of course, I have no idea what the ramifications of this would be; I just
thought I'd file the idea under this thread.
Ryan
On Thu, Oct 25, 2012 at 9:56 AM, José Pedro Magalhães
Hi all,
Following up on a chat with Simon Peyton Jones at ICFP, I would like to discuss the possible introduction of a EPHEMERAL pragma. For example:
{-# EPHEMERAL Rep #-}
data Rep = ...
This pragma would indicate that the programmer intends the Rep datatype not to be present in the final generated core code. Its proposed semantics are the following:
1. Make the compiler very keen to inline any functions that produce or consume Rep.
2. If Rep is exported, make all functions that operate on Rep INLINABLE (that is, make their code available for inlining in other modules).
3. Emit a warning if the generated core code still contains uses of Rep.
My main use case for such a pragma is in the generic representation of datatypes in GHC.Generics. It's clear that we don't want sums and products lying around in user code, and in most cases we can get rid of them by inlining aggressively. Hopefully such a pragma can simplify or entirely replace the use of INLINE/INLINABLE pragmas in some cases.
However, I'm not sure how well this can work in practice. Regarding (3), for instance, it's clear that functions that operate on Rep will be around in the final core code; perhaps only functions which do not directly produce or consume Rep, yet end up having values of Rep within them, should trigger a warning.
(1) is hard to do well, in general. In particular when there are rewriting rules involving values of Rep, or functions that produce/consume Rep, the order in which they are inlined might affect the elimination of Rep values.
In any case, I thought I'd share this with this list, in the hope to get feedback regarding how to improve the inliner (and the feedback programmers get regarding inlining).
Cheers, Pedro
_______________________________________________ Glasgow-haskell-users mailing list Glasgow-haskell-users@haskell.org http://www.haskell.org/mailman/listinfo/glasgow-haskell-users

Interesting idea.
On Thu, Oct 25, 2012 at 6:56 AM, José Pedro Magalhães
3. Emit a warning if the generated core code still contains uses of Rep.
I think this part will be really annoying, as GHC might end up generating warnings that the programmer can do nothing about (because some optimization failed to remove Rep). -- Johan

On 25.10.2012, at 16:45, Johan Tibell wrote:
Interesting idea.
On Thu, Oct 25, 2012 at 6:56 AM, José Pedro Magalhães
wrote: 3. Emit a warning if the generated core code still contains uses of Rep.
I think this part will be really annoying, as GHC might end up generating warnings that the programmer can do nothing about (because some optimization failed to remove Rep).
I think this is exactly the right idea. A compiler should emit errors about bad typing since type inference is somewhat complete, but should emit warnings about other incomplete analyses or optimizations. If you think that this is too noisy, by all means, don't emit these warnings by default and add a flag that enables them. my 2p, Axel

The question of whether the warnings should come by default or not is a question of how serious the programmer is when they declare a type as EPHEMERAL. In Pedro's use cases, I would be very serious about it — as Ryan said, performance tends to "tank" otherwise. ### Proposal Extensions I think a more granular pragma targeting value declarations would also be nice.
{-# EPHEMERAL T #-} x = …
This would tell GHC that I really don't want any values of type T in x's core. It might also make sense to have a EPHEMERAL pragma that has a module as it's scope. A related and more expressive pragma might be something like:
{-# USES foo 1, bar 2 #-} x = …
This hypothetical pragma would similarly a) guide GHC's inliner and b)
emit warnings if the programmer's declared expectations (eg that foo
occurs once and bar occurs twice) are not met by x's ultimate RHS in
Core.
Of course, the cost of the USES pragma's expressiveness is that it may
lead to "brittle" source code. However, if performance is important
enough to be part of your code's specification, then this may generate
legitimate warnings (perhaps even errors, with a sub-pragma!) —
especially in rather mature performance-focused packages.
On Thu, Oct 25, 2012 at 10:00 AM, Axel Simon
On 25.10.2012, at 16:45, Johan Tibell wrote:
Interesting idea.
On Thu, Oct 25, 2012 at 6:56 AM, José Pedro Magalhães
wrote: 3. Emit a warning if the generated core code still contains uses of Rep.
I think this part will be really annoying, as GHC might end up generating warnings that the programmer can do nothing about (because some optimization failed to remove Rep).
I think this is exactly the right idea. A compiler should emit errors about bad typing since type inference is somewhat complete, but should emit warnings about other incomplete analyses or optimizations.
If you think that this is too noisy, by all means, don't emit these warnings by default and add a flag that enables them.
my 2p, Axel
_______________________________________________ Glasgow-haskell-users mailing list Glasgow-haskell-users@haskell.org http://www.haskell.org/mailman/listinfo/glasgow-haskell-users

On Thu, Oct 25, 2012 at 9:45 AM, Johan Tibell
Interesting idea.
On Thu, Oct 25, 2012 at 6:56 AM, José Pedro Magalhães
wrote: 3. Emit a warning if the generated core code still contains uses of Rep.
I think this part will be really annoying, as GHC might end up generating warnings that the programmer can do nothing about (because some optimization failed to remove Rep).
This could be a new warning which is not included in -Wall by default. It would be more a report than a warning, I guess. Antoine

On Thu, Oct 25, 2012 at 9:56 AM, José Pedro Magalhães
Hi all,
Following up on a chat with Simon Peyton Jones at ICFP, I would like to discuss the possible introduction of a EPHEMERAL pragma. For example:
{-# EPHEMERAL Rep #-}
data Rep = ...
This pragma would indicate that the programmer intends the Rep datatype not to be present in the final generated core code. Its proposed semantics are the following:
1. Make the compiler very keen to inline any functions that produce or consume Rep.
2. If Rep is exported, make all functions that operate on Rep INLINABLE (that is, make their code available for inlining in other modules).
3. Emit a warning if the generated core code still contains uses of Rep.
Won't all of this require GHC to fix its handling of inlining in the presence of recursion (am I behind times? Or does Rep also end up with the restriction that it should never be an argument to or result from a recursive function? -Jan

On Thu, Oct 25, 2012 at 9:56 AM, José Pedro Magalhães
Hi all,
Following up on a chat with Simon Peyton Jones at ICFP, I would like to discuss the possible introduction of a EPHEMERAL pragma. For example:
{-# EPHEMERAL Rep #-}
data Rep = ...
This pragma would indicate that the programmer intends the Rep datatype not to be present in the final generated core code. Its proposed semantics are the following:
1. Make the compiler very keen to inline any functions that produce or consume Rep.
2. If Rep is exported, make all functions that operate on Rep INLINABLE (that is, make their code available for inlining in other modules).
3. Emit a warning if the generated core code still contains uses of Rep.
Are you restricting Rep to non-recursive uses? Or has GHC's inliner finally learned how to behave well in the presence of recursion? -Jan-Willem Maessen

Are you restricting Rep to non-recursive uses? Or has GHC's inliner finally learned how to behave well in the presence of recursion?
If anyone could explain (in precise terms) what it means to “behave well in the presence of recursion” then there’s a chance that it might. But up to now, no, it hasn’t I’m afraid.
Simon
From: glasgow-haskell-users-bounces@haskell.org [mailto:glasgow-haskell-users-bounces@haskell.org] On Behalf Of Jan-Willem Maessen
Sent: 25 October 2012 20:19
To: José Pedro Magalhães
Cc: GHC users
Subject: Re: Proposal: EPHEMERAL pragma
On Thu, Oct 25, 2012 at 9:56 AM, José Pedro Magalhães
participants (8)
-
Antoine Latter
-
Axel Simon
-
Jan-Willem Maessen
-
Johan Tibell
-
José Pedro Magalhães
-
Nicolas Frisby
-
Ryan Trinkle
-
Simon Peyton-Jones