[GHC] #12457: Deriving should be (more closely) integrated with other metaprogramming methods

#12457: Deriving should be (more closely) integrated with other metaprogramming methods -------------------------------------+------------------------------------- Reporter: mpickering | Owner: Type: feature | Status: new request | 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: -------------------------------------+------------------------------------- It is unfortunate that if we want to (efficiently) derive a new type class then we have to bake the derivation logic into GHC itself. It seems desirable to be able to implement new deriving methods in libraries in some manner. Ryan Scott says:
I think this would be a wonderful thing to have. Matthew Pickering (cc'd) has expressed a desire to have all the logic for the `bespoke` deriving strategies compartmentalized into a library that could easily be expanded on in the future to support more typeclasses in base. (Bifunctor, anyone?)
Unfortunately, each of the major players in today's Haskell metaprogramming scene that I'm aware of have some downfalls that make them unsuitable as `deriving` replacements:
* Template Haskell: Not portable. Staging issues make it hard to use as a drop-in replacement for the `deriving` keyword * GHC generics: Can't express all the optimizations that the bespoke `deriving` algorithms perform. Unperformant. * Haskell preprocessors: Difficult to integrate in a typical GHC workflow. Probably wouldn't have all the metadata you'd need to be feature-complete with what `deriving` does today.
The way I see it, the whole `deriving` business as it currently stands today is a somewhat-grotesque-but-darn-useful hack that gets around the lack of a truly nice metaprogramming facility in Haskell. I'm holding out hope that the work in https://github.com/shayan-najd/NativeMetaprogramming makes things nicer soon, and then we can revisit this idea. Until then, -XDerivingStrategies provides a way to contain some of the madness of `deriving` after having many features tacked onto it in recent GHC releases.
-- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/12457 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#12457: Deriving should be (more closely) integrated with other metaprogramming methods -------------------------------------+------------------------------------- Reporter: mpickering | Owner: Type: feature request | 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 mpickering): Richard comments:
* Template Haskell: Not portable. Staging issues make it hard to use as a drop-in replacement for the `deriving` keyword
I do not understand "not portable" here. Do you mean that some architectures don't support TH?
What staging issues?
I'm imagining here having `deriving Blah` be surface syntax that desugars into some TH splice. You keep the nice user-facing syntax, but make the deriving mechanism itself specified in TH code.
-- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/12457#comment:1 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#12457: Deriving should be (more closely) integrated with other metaprogramming methods -------------------------------------+------------------------------------- Reporter: mpickering | Owner: Type: feature request | 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 mpickering): * cc: RyanGlScott, goldfire (added) -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/12457#comment:2 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#12457: Deriving should be (more closely) integrated with other metaprogramming methods -------------------------------------+------------------------------------- Reporter: mpickering | Owner: Type: feature request | 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 osa1): * cc: osa1 (added) -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/12457#comment:3 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#12457: Deriving should be (more closely) integrated with other metaprogramming methods -------------------------------------+------------------------------------- Reporter: mpickering | Owner: Type: feature request | 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 goldfire): I'll also add: I think we'll need a better way of dealing with types than TH has now. But it's possible that clever `reify`s plus the new `addModFinalizer` behavior of #11832 will be enough. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/12457#comment:4 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#12457: Deriving should be (more closely) integrated with other metaprogramming methods -------------------------------------+------------------------------------- Reporter: mpickering | Owner: Type: feature request | 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 RyanGlScott): Some prior art we can draw on: Rust 1.15 has a "custom derive" feature that let's you derive any trait using its macro system: https://doc.rust- lang.org/book/procedural-macros.html. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/12457#comment:5 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#12457: Deriving should be (more closely) integrated with other metaprogramming methods -------------------------------------+------------------------------------- Reporter: mpickering | Owner: (none) Type: feature request | Status: new Priority: normal | Milestone: Component: Compiler | Version: 8.0.1 Resolution: | Keywords: deriving 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 RyanGlScott): * keywords: => deriving -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/12457#comment:6 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#12457: Deriving should be (more closely) integrated with other metaprogramming methods -------------------------------------+------------------------------------- Reporter: mpickering | Owner: (none) Type: feature request | Status: new Priority: normal | Milestone: Component: Compiler | Version: 8.0.1 Resolution: | Keywords: deriving 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 mpickering): I think this is solved by DerivingVia? -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/12457#comment:7 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#12457: Deriving should be (more closely) integrated with other metaprogramming methods -------------------------------------+------------------------------------- Reporter: mpickering | Owner: (none) Type: feature request | Status: new Priority: normal | Milestone: Component: Compiler | Version: 8.0.1 Resolution: | Keywords: deriving 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 RyanGlScott): I suppose it depends on what you mean by "solved" :) It's true that `DerivingVia` provides a much higher degree of configurability than other deriving strategies, but it falls short of some goals: * If one's goal is to have a equivalent of, say, `deriving Ord` that produces equally efficient code, then `DerivingVia` isn't up to the task. Ultimately, the closest you could get is by leveraging `GHC.Generics` under the hood, which isn't always going to produce as efficient of code as a non-generics–based `Ord` instance. * Speaking of which, combining `GHC.Generics` with `DerivingVia` will only get you so far. You wouldn't be able to use this approach to derive `Bifunctor`, for instance, since we only have the `Generic` and `Generic1` classes for handling classes of kinds `* -> Constraint` and `(k -> *) -> Constraint`, respectively. * Ultimately, `DerivingVia` still relies on compiler magic. The original ambition here was to make `deriving` syntactic sugar for a Template Haskell splice so that the code underlying `deriving` could be expressed as a normal TH program. (That way, folks could extend it quite naturally.) There's still a long ways to go before that is possible. I'm not sure if those are what you had in mind when opening this ticket, so if they're not, feel free to close this. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/12457#comment:8 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#12457: Deriving should be (more closely) integrated with other metaprogramming methods -------------------------------------+------------------------------------- Reporter: mpickering | Owner: (none) Type: feature request | Status: new Priority: normal | Milestone: Component: Compiler | Version: 8.0.1 Resolution: | Keywords: deriving Operating System: Unknown/Multiple | Architecture: | Unknown/Multiple Type of failure: None/Unknown | Test Case: Blocked By: | Blocking: Related Tickets: #15650 | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Changes (by RyanGlScott): * related: => #15650 Comment: Source plugins might offer one way forward here. See #15650. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/12457#comment:9 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler
participants (1)
-
GHC