[GHC] #13290: Data constructors should not have RULES

#13290: Data constructors should not have RULES -------------------------------------+------------------------------------- Reporter: simonpj | Owner: (none) Type: bug | Status: new Priority: normal | Milestone: Component: Compiler | Version: 8.0.1 Keywords: | Operating System: Unknown/Multiple Architecture: | Type of failure: None/Unknown Unknown/Multiple | Test Case: | Blocked By: Blocking: | Related Tickets: Differential Rev(s): | Wiki Page: -------------------------------------+------------------------------------- GHC has never (knowingly) supported rules for data constructors, like {{{ {-# RULES "BadBadBad" Just [x,y] = Just [] #-} Notice that the rule is for the ''constructor itself''. Presumably the intent is that any occurrence of `Just` appplied to a two-element list will rewrite to `Just []`. But currently they are accidentally allowed through, and then behave in mysterious ways because of constructor wrappers. Duncan Coutts says {{{
Well I've certainly tried to use that in the past. A previous version of the cbor lib which used a different representation did a lot of matching on constructors to re-arrange input to an interpreter, until I discovered that GHC actually uses constructor wrappers and that matching on constructors was thus not reliable }}} I think we should simply make it illegal for now. If you really want it, use a smart constructor thus {{{ mkJust x = Just x {-# INLINE [0] mkJust #-} {-# RULES “Good” mkJust [x,y] = mkJust [] #-} }}} So let us
* Check in that you don't try to write a rule for a data constructor. * Document in the user manual -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/13290 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#13290: Data constructors should not have RULES -------------------------------------+------------------------------------- Reporter: simonpj | Owner: dfeuer Type: bug | Status: new Priority: normal | Milestone: Component: Compiler | Version: 8.0.1 Resolution: | Keywords: Operating System: Unknown/Multiple | Architecture: | Unknown/Multiple Type of failure: None/Unknown | Test Case: Blocked By: | Blocking: Related Tickets: | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Changes (by simonpj): * owner: (none) => dfeuer Comment: David might you do this? -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/13290#comment:1 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#13290: Data constructors should not have RULES -------------------------------------+------------------------------------- Reporter: simonpj | Owner: dfeuer Type: bug | Status: new Priority: normal | Milestone: Component: Compiler | Version: 8.0.1 Resolution: | Keywords: 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 dfeuer): I can give it a go, sure. But with your fix for matching strict constructors, is there any reason to prohibit it aside from the as-yet- undecided static data optimization? -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/13290#comment:2 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#13290: Data constructors should not have RULES -------------------------------------+------------------------------------- Reporter: simonpj | Owner: dfeuer Type: bug | Status: new Priority: normal | Milestone: Component: Compiler | Version: 8.0.1 Resolution: | Keywords: Operating System: Unknown/Multiple | Architecture: | Unknown/Multiple Type of failure: None/Unknown | Test Case: Blocked By: | Blocking: Related Tickets: | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Description changed by simonpj: Old description:
GHC has never (knowingly) supported rules for data constructors, like {{{ {-# RULES "BadBadBad" Just [x,y] = Just [] #-} Notice that the rule is for the ''constructor itself''. Presumably the intent is that any occurrence of `Just` appplied to a two-element list will rewrite to `Just []`.
But currently they are accidentally allowed through, and then behave in mysterious ways because of constructor wrappers. Duncan Coutts says {{{
Well I've certainly tried to use that in the past. A previous version of the cbor lib which used a different representation did a lot of matching on constructors to re-arrange input to an interpreter, until I discovered that GHC actually uses constructor wrappers and that matching on constructors was thus not reliable }}} I think we should simply make it illegal for now. If you really want it, use a smart constructor thus {{{ mkJust x = Just x {-# INLINE [0] mkJust #-} {-# RULES “Good” mkJust [x,y] = mkJust [] #-} }}} So let us
* Check in that you don't try to write a rule for a data constructor. * Document in the user manual
New description: GHC has never (knowingly) supported rules for data constructors, like {{{ {-# RULES "BadBadBad" Just [x,y] = Just [] #-} }}} Notice that the rule is for the ''constructor itself''. Presumably the intent is that any occurrence of `Just` appplied to a two-element list will rewrite to `Just []`. But currently they are accidentally allowed through, and then behave in mysterious ways because of constructor wrappers. Duncan Coutts says {{{
Well I've certainly tried to use that in the past. A previous version of the cbor lib which used a different representation did a lot of matching on constructors to re-arrange input to an interpreter, until I discovered that GHC actually uses constructor wrappers and that matching on constructors was thus not reliable }}} I think we should simply make it illegal for now. If you really want it, use a smart constructor thus {{{ mkJust x = Just x {-# INLINE [0] mkJust #-} {-# RULES “Good” mkJust [x,y] = mkJust [] #-} }}} So let us
* Check in that you don't try to write a rule for a data constructor. * Document in the user manual -- -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/13290#comment:3 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#13290: Data constructors should not have RULES -------------------------------------+------------------------------------- Reporter: simonpj | Owner: dfeuer Type: bug | Status: new Priority: normal | Milestone: Component: Compiler | Version: 8.0.1 Resolution: | Keywords: 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 simonpj):
But with your fix for matching strict constructors, is there any reason to prohibit it aside from the as-yet-undecided static data optimization?
I don't know and I don't even want to think about it until we have a powerful reason for wanting it. It feel Wrong Wrong Wrong for a passive data constructor to start rewriting itself. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/13290#comment:4 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#13290: Data constructors should not have RULES -------------------------------------+------------------------------------- Reporter: simonpj | Owner: dfeuer Type: bug | Status: new Priority: normal | Milestone: Component: Compiler | Version: 8.0.1 Resolution: | Keywords: Operating System: Unknown/Multiple | Architecture: | Unknown/Multiple Type of failure: None/Unknown | Test Case: Blocked By: | Blocking: Related Tickets: #7398 | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Changes (by rwbarton): * related: => #7398 Comment: #7398 is related (in that we can close it too if we do this). -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/13290#comment:5 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#13290: Data constructors should not have RULES -------------------------------------+------------------------------------- Reporter: simonpj | Owner: dfeuer Type: bug | Status: new Priority: normal | Milestone: Component: Compiler | Version: 8.0.1 Resolution: | Keywords: Operating System: Unknown/Multiple | Architecture: | Unknown/Multiple Type of failure: None/Unknown | Test Case: Blocked By: | Blocking: Related Tickets: #7398 | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Comment (by rwbarton): For what it's worth the documentation implicitly disallows these rules already, as it says
The left hand side of a rule must consist of a top-level variable applied to arbitrary expressions.
and "variable" is used in the Haskell Report to refer to lowercase things, not constructors. Of course explicit is better than implicit, and probably the author of that sentence was not thinking about the case of constructors at the time. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/13290#comment:6 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#13290: Data constructors should not have RULES -------------------------------------+------------------------------------- Reporter: simonpj | Owner: dfeuer Type: bug | Status: new Priority: normal | Milestone: Component: Compiler | Version: 8.0.1 Resolution: | Keywords: Operating System: Unknown/Multiple | Architecture: | Unknown/Multiple Type of failure: None/Unknown | Test Case: Blocked By: | Blocking: Related Tickets: #7398 | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Comment (by nomeata): I’d just like to chime in that from a user point of view, it feels very much right and natural that I can define rules that match on constructors, and I am honestly surprised that this has not been a supported use-case right from the beginning. Here is an example: {{{#!hs data FreeMonad a = Return a | Bind (FreeMonad a) (a -> FreeMonad b) {-# RULES "monadLaw1" forall x f . Bind (Return x) f = f x #-} }}} Looks very benign to me! -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/13290#comment:7 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#13290: Data constructors should not have RULES -------------------------------------+------------------------------------- Reporter: simonpj | Owner: dfeuer Type: bug | Status: new Priority: normal | Milestone: 8.2.1 Component: Compiler | Version: 8.0.1 Resolution: | Keywords: Operating System: Unknown/Multiple | Architecture: | Unknown/Multiple Type of failure: None/Unknown | Test Case: Blocked By: | Blocking: Related Tickets: #7398 | Differential Rev(s): Phab:D3169 Wiki Page: | -------------------------------------+------------------------------------- Changes (by bgamari): * differential: => Phab:D3169 * milestone: => 8.2.1 -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/13290#comment:8 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#13290: Data constructors should not have RULES -------------------------------------+------------------------------------- Reporter: simonpj | Owner: dfeuer Type: bug | Status: new Priority: normal | Milestone: 8.2.1 Component: Compiler | Version: 8.0.1 Resolution: | Keywords: Operating System: Unknown/Multiple | Architecture: | Unknown/Multiple Type of failure: None/Unknown | Test Case: Blocked By: | Blocking: Related Tickets: #7398 | Differential Rev(s): Phab:D3169 Wiki Page: | -------------------------------------+------------------------------------- Comment (by dfeuer): Implemented by bc332b3159613190a4dc33a067c1ab31039a8434 {{{ Prohibit RULES changing constructors Previously, RULES like {-# RULES "JustNothing" forall x . Just x = Nothing #-} were allowed. Simon Peyton Jones say this seems to have been a mistake, that such rules have never been supported intentionally, and that he doesn't know if they can break in horrible ways. Furthermore, Ben Gamari and Reid Barton are considering trying to detect the presence of "static data" that the simplifier doesn't need to traverse at all. Such rules do not play well with that. So for now, we ban them altogether. In most cases, it's possible to work around the ban using hand-written wrapper functions. Reviewers: austin, simonpj, bgamari Reviewed By: simonpj, bgamari Subscribers: thomie Differential Revision: https://phabricator.haskell.org/D3169 }}} -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/13290#comment:9 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#13290: Data constructors should not have RULES -------------------------------------+------------------------------------- Reporter: simonpj | Owner: dfeuer Type: bug | Status: closed Priority: normal | Milestone: 8.2.1 Component: Compiler | Version: 8.0.1 Resolution: fixed | Keywords: Operating System: Unknown/Multiple | Architecture: | Unknown/Multiple Type of failure: None/Unknown | Test Case: Blocked By: | Blocking: Related Tickets: #7398 | Differential Rev(s): Phab:D3169 Wiki Page: | -------------------------------------+------------------------------------- Changes (by dfeuer): * status: new => closed * resolution: => fixed -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/13290#comment:10 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler
participants (1)
-
GHC