RE: [Haskell] boilerplate boilerplate

[Redirecting to haskell-cafe; the main list is a good place to open discussions but not so good for continuing them] | > derive (Ord,Eq,Read,Show,Typeable) (BlogEntry Name Title Body Emai) | | according to the most recent status report, the syntax is not quite | settled yet, so what is in ghc head might still change. more info here: | | http://haskell.org/haskellwiki/GHC/StandAloneDeriving Indeed... but nothing much is happening at the moment because there's not been much feedback so it's drifted off the radar (so to speak). Refining the wiki and evolving a consensus would be great. Simon

| according to the most recent status report, the syntax is not quite | settled yet, so what is in ghc head might still change. more info here: | | http://haskell.org/haskellwiki/GHC/StandAloneDeriving
Indeed... but nothing much is happening at the moment because there's not been much feedback so it's drifted off the radar (so to speak). Refining the wiki and evolving a consensus would be great.
feedback, as requested:-) - i definitely would like to have standalone deriving, not just in ghc (in HaRe, we used to run a script over the various Programatica ast sources to extract all the data types we needed to run DrIFT over, to get ast traversal operations; the only alternative would have been to modify their sources, but those were evolving separately; the same problem has arisen again and again, be it template haskell asts or ghc api asts or Language.Haskell or ..) - syntaxwise, i'm partial to 'derived instance ..', but i can see the appeal of 'instance .. derived' (what comes after the instance head determines what is going on: 'where..' / 'derived' / '' ) - there should at least be the option of specifying the context (if one wants context inference, that is a separate issue which should be handled consistently in all instances) does that help to keep it on the radar?-) claus

| does that help to keep it on the radar?-) | claus Indeed! But please modify the wiki. Email has a half life of about 1 day! S

Actually, standalone deriving doesn't really solve the boilerplate boilerplate problem. My original complaint here is that I don't want to explicitly declare a deriving (Data,Typeable) for every type used somewhere inside a larger type I am using. In this particular case, I am using SYB to autogenerate/autoparse XML. The Atom/RSS datatype has a lot of elements in it. Having to do an explicit declaration of deriving (Data,Typeable) for each of them is just a tremendous beat-down no matter where I do it. A simple solution to the problem is just to have the compiler automatically derive Data and Typeable for all classes. Perhaps initially there is some compiler flag like -fSYB. Slightly more elegant would be to not automatically derive if the user has done so explicitly and to add syntax to the deriving clause like "deriving ... not (Data,Typeable)" to tell the compiler that these instances should be unavailable for this type. A substantially more general/elegant solution would be for the compiler to derive instances automatically for any classes whose methods I use and for which there has been no explicit contradictory declaration. But I assume that is harder and having Data and Typeable means you can use SYB and not worry so much about deriving instances anymore. Most elegant would be for the user to be able to add derivable classes via import declarations, but again simply having Data and Typeable is a 95% solution and the perfect should not be the enemy of the good. -Alex- Simon Peyton-Jones wrote:
| does that help to keep it on the radar?-) | claus
Indeed! But please modify the wiki. Email has a half life of about 1 day!
S _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe

Actually, standalone deriving doesn't really solve the boilerplate boilerplate problem. My original complaint here is that I don't want to explicitly declare a deriving (Data,Typeable) for every type used somewhere inside a larger type I am using. In this particular case, I am using SYB to autogenerate/autoparse XML. The Atom/RSS datatype has a lot of elements in it. Having to do an explicit declaration of deriving (Data,Typeable) for each of them is just a tremendous beat-down no matter where I do it.
A simple solution to the problem is just to have the compiler automatically derive Data and Typeable for all classes.
it still sounds as if you might want to follow Neil's suggestions about using Data.Derive, which does seem to have a derive-this-for-all feature. but one of the nice things about just separating data and deriving is that one can add derived instances without changing, or even having the source, and without having to add the individual derivings by hand. as i mentioned, we did such a scripted deriving, then based on the old DrIFT, for HaRe, over Programatica's data types for Haskell syntax. these days, one might use something like the two-liner sketched below. btw, i've found that even major publishers have trouble keeping their RSS feeds valid, not to mention the variety of standards, and the variety of (not) using those standards for recording essential information in those feeds. that frequently breaks strict XML processing, so if i had to do it again, i'd try a fast&loose heuristic approach instead, extracting the information from whereever it has been hidden in the feed, valid or broken.. claus $ ghc -e ':b Language.Haskell.Syntax' | \ > sed -n -e '/data/{s/^data\s*\([^=\r]*\).*$/deriving MyClass for ( \1 )/; p}' deriving MyClass for ( HsGuardedAlt ) deriving MyClass for ( HsGuardedAlts ) deriving MyClass for ( HsAlt ) deriving MyClass for ( HsFieldUpdate ) deriving MyClass for ( HsStmt ) deriving MyClass for ( HsPatField ) deriving MyClass for ( HsPat ) deriving MyClass for ( HsExp ) deriving MyClass for ( HsLiteral ) deriving MyClass for ( HsType ) deriving MyClass for ( HsQualType ) deriving MyClass for ( HsSafety ) deriving MyClass for ( HsGuardedRhs ) deriving MyClass for ( HsRhs ) deriving MyClass for ( HsBangType ) deriving MyClass for ( HsConDecl ) deriving MyClass for ( HsMatch ) deriving MyClass for ( HsDecl ) deriving MyClass for ( HsAssoc ) deriving MyClass for ( HsImportSpec ) deriving MyClass for ( HsImportDecl ) deriving MyClass for ( HsExportSpec ) deriving MyClass for ( HsModule ) deriving MyClass for ( HsCName ) deriving MyClass for ( HsOp ) deriving MyClass for ( HsQOp ) deriving MyClass for ( HsName ) deriving MyClass for ( HsQName ) deriving MyClass for ( HsSpecialCon ) deriving MyClass for ( SrcLoc )

Claus Reinke wrote:
Actually, standalone deriving doesn't really solve the boilerplate boilerplate problem. My original complaint here is that I don't want to explicitly declare a deriving (Data,Typeable) for every type used somewhere inside a larger type I am using. In this particular case, I am using SYB to autogenerate/autoparse XML. The Atom/RSS datatype has a lot of elements in it. Having to do an explicit declaration of deriving (Data,Typeable) for each of them is just a tremendous beat-down no matter where I do it.
A simple solution to the problem is just to have the compiler automatically derive Data and Typeable for all classes.
it still sounds as if you might want to follow Neil's suggestions about using Data.Derive, which does seem to have a derive-this-for-all feature.
The problem with Data.Derive is that I now have a pre-processor cycle as part of my build process. Automatic and universal Data and Typeable instance deriving should just be built into Haskell. I totally agree that, if you don't have this deriving by default, it is totally useful to be able to derive in a location different from where the type is declared, but that is a separate issue. My main point is that Data and Typeable should always be there without extra futzing on the part of the programmer. Speaking of which, any thoughts on fixing my SYB code in the other thread? -Alex-

Hi Alex,
The problem with Data.Derive is that I now have a pre-processor cycle as part of my build process. Automatic and universal Data and Typeable instance deriving should just be built into Haskell.
Not if you use the template haskell support. We don't currently have a "deriveAll" command, but I'm sure it could be added, which applied a given definition to every data type in that module. Thanks Neil

I suppose a deriveAll command from template haskell would work. Is that really possible? -Alex- Neil Mitchell wrote:
Hi Alex,
The problem with Data.Derive is that I now have a pre-processor cycle as part of my build process. Automatic and universal Data and Typeable instance deriving should just be built into Haskell.
Not if you use the template haskell support. We don't currently have a "deriveAll" command, but I'm sure it could be added, which applied a given definition to every data type in that module.
Thanks
Neil

Hi
On 6/1/07, Alex Jacobson
I suppose a deriveAll command from template haskell would work. Is that really possible?
Asking people who have more knowledge of template haskell, I'm still not sure. What it would really rely on is: getDataDeclarationsInCurrentModule :: Q [Dec] Whether that can be done or not is still not something I'm sure on. We may be able to do a deriveTransitive which would work if you had one over-arching type that contained all the other types (which you almost always will). I'm waiting for information about that on another thread. Thanks Neil

I suppose a deriveAll command from template haskell would work. Is that really possible?
Asking people who have more knowledge of template haskell, I'm still not sure.
What it would really rely on is:
getDataDeclarationsInCurrentModule :: Q [Dec]
Whether that can be done or not is still not something I'm sure on.
it's been a while since i played with TH, but the "stage fright" (staging restrictions) are likely to get in the way. you could do something like the two-level approach below, though, giving you: *Main> ds "[DataD [] Hi [] [NormalC Hi [(NotStrict,ConT GHC.Base.String)]] []]" *Main> ds' "[DataD [] Hi [] [NormalC Hi [(NotStrict,ConT GHC.Base.String)]] [GHC.Show.Show]]" *Main> :i Hi data Hi = Hi String -- Defined at C:/Documents and Settings/cr3/Desktop/TH.hs:12:2 instance Show Hi -- Defined at C:/Documents and Settings/cr3/Desktop/TH.hs:12:2 but do you want to go down that route? what is the reason for avoiding simple preprocessing using sed or Data.Derive or just Haskell? it isn't as if your clients would have to know about where those generated modules came from, is it? all they would see would be another Haskell module to compile. all you would see would be an extra line in the build script for creating a source distribution. claus ----------------------------------------------------- {-# OPTIONS_GHC -fth #-} module THI where import Language.Haskell.TH import Language.Haskell.TH.Syntax rds = [d| data Hi = Hi String |] add c (DataD ctxt n ns cs ds) = DataD ctxt n ns cs (c:ds) add c d = d rds' = rds >>= return . map (add ''Show) ----------------------------------------------------- {-# OPTIONS_GHC -fth #-} module Main where import Language.Haskell.TH import Language.Haskell.TH.Syntax import THI ds = $(rds >>= lift . show) ds' = $(rds' >>= lift . show) $(rds')

| lot of elements in it. Having to do an explicit declaration of deriving | (Data,Typeable) for each of them is just a tremendous beat-down no | matter where I do it. I hate to see you beaten down, Alex. Make a feature request. I don't want to make promises, but having a well-specified feature request, perhaps with some other people chiming in and saying what they want, is a good start. Incidentally, for those interested in 'deriving', there's an open question about what the syntax of standalone deriving should be http://haskell.org/haskellwiki/GHC/StandAloneDeriving I'd like to get this settled for 6.8. Simon
participants (4)
-
Alex Jacobson
-
Claus Reinke
-
Neil Mitchell
-
Simon Peyton-Jones