<div dir="ltr"><div><span style="color:rgb(64,64,64);font-family:Roboto,arial,sans-serif;font-size:13px;line-height:18.2000007629395px">Hi,</span></div><div><span style="color:rgb(64,64,64);font-family:Roboto,arial,sans-serif;font-size:13px;line-height:18.2000007629395px"><br></span></div><div><font color="#404040" face="Roboto, arial, sans-serif"><span style="line-height:18.2000007629395px">(This was initially written as a Google+ post, but I'm reposting it here to raise awareness of the issue.)</span></font></div><div><span style="color:rgb(64,64,64);font-family:Roboto,arial,sans-serif;font-size:13px;line-height:18.2000007629395px"><br></span></div><span style="color:rgb(64,64,64);font-family:Roboto,arial,sans-serif;font-size:13px;line-height:18.2000007629395px">The amount of CPP we have to use in Haskell is getting a bit out of hand. Here are the number of modules, per library, that use CPP for some of the libraries I maintain:</span><br style="color:rgb(64,64,64);font-family:Roboto,arial,sans-serif;font-size:13px;line-height:18.2000007629395px"><br style="color:rgb(64,64,64);font-family:Roboto,arial,sans-serif;font-size:13px;line-height:18.2000007629395px"><span style="color:rgb(64,64,64);font-family:Roboto,arial,sans-serif;font-size:13px;line-height:18.2000007629395px">containers 18/18</span><br style="color:rgb(64,64,64);font-family:Roboto,arial,sans-serif;font-size:13px;line-height:18.2000007629395px"><span style="color:rgb(64,64,64);font-family:Roboto,arial,sans-serif;font-size:13px;line-height:18.2000007629395px">hashable 4/5</span><br style="color:rgb(64,64,64);font-family:Roboto,arial,sans-serif;font-size:13px;line-height:18.2000007629395px"><span style="color:rgb(64,64,64);font-family:Roboto,arial,sans-serif;font-size:13px;line-height:18.2000007629395px">unordered-containers 6/9</span><br style="color:rgb(64,64,64);font-family:Roboto,arial,sans-serif;font-size:13px;line-height:18.2000007629395px"><span style="color:rgb(64,64,64);font-family:Roboto,arial,sans-serif;font-size:13px;line-height:18.2000007629395px">network 3/7</span><br style="color:rgb(64,64,64);font-family:Roboto,arial,sans-serif;font-size:13px;line-height:18.2000007629395px"><span style="color:rgb(64,64,64);font-family:Roboto,arial,sans-serif;font-size:13px;line-height:18.2000007629395px">cassava 4/16</span><br style="color:rgb(64,64,64);font-family:Roboto,arial,sans-serif;font-size:13px;line-height:18.2000007629395px"><span style="color:rgb(64,64,64);font-family:Roboto,arial,sans-serif;font-size:13px;line-height:18.2000007629395px">cabal/cabal-install 13/75</span><br style="color:rgb(64,64,64);font-family:Roboto,arial,sans-serif;font-size:13px;line-height:18.2000007629395px"><span style="color:rgb(64,64,64);font-family:Roboto,arial,sans-serif;font-size:13px;line-height:18.2000007629395px">cabal/Cabal 7/78</span><br style="color:rgb(64,64,64);font-family:Roboto,arial,sans-serif;font-size:13px;line-height:18.2000007629395px"><span style="color:rgb(64,64,64);font-family:Roboto,arial,sans-serif;font-size:13px;line-height:18.2000007629395px">ekg 1/15</span><br style="color:rgb(64,64,64);font-family:Roboto,arial,sans-serif;font-size:13px;line-height:18.2000007629395px"><br style="color:rgb(64,64,64);font-family:Roboto,arial,sans-serif;font-size:13px;line-height:18.2000007629395px"><span style="color:rgb(64,64,64);font-family:Roboto,arial,sans-serif;font-size:13px;line-height:18.2000007629395px">If this doesn't look like a lot to you (I hope it does!) consider than some languages don't use CPP at all (e.g. Java).</span><br style="color:rgb(64,64,64);font-family:Roboto,arial,sans-serif;font-size:13px;line-height:18.2000007629395px"><br style="color:rgb(64,64,64);font-family:Roboto,arial,sans-serif;font-size:13px;line-height:18.2000007629395px"><span style="color:rgb(64,64,64);font-family:Roboto,arial,sans-serif;font-size:13px;line-height:18.2000007629395px">CPP really sucks from a maintenance perspective:</span><br style="color:rgb(64,64,64);font-family:Roboto,arial,sans-serif;font-size:13px;line-height:18.2000007629395px"><br style="color:rgb(64,64,64);font-family:Roboto,arial,sans-serif;font-size:13px;line-height:18.2000007629395px"><span style="color:rgb(64,64,64);font-family:Roboto,arial,sans-serif;font-size:13px;line-height:18.2000007629395px"> * It's not Haskell, but this bizarre string concatenation language.</span><br style="color:rgb(64,64,64);font-family:Roboto,arial,sans-serif;font-size:13px;line-height:18.2000007629395px"><span style="color:rgb(64,64,64);font-family:Roboto,arial,sans-serif;font-size:13px;line-height:18.2000007629395px"> * The code is harder to read, bitrots more easily, and is harder to test.</span><br style="color:rgb(64,64,64);font-family:Roboto,arial,sans-serif;font-size:13px;line-height:18.2000007629395px"><span style="color:rgb(64,64,64);font-family:Roboto,arial,sans-serif;font-size:13px;line-height:18.2000007629395px"> * The code can't be compiled without using Cabal (which generates some of the CPP macros for us.) This hurts e.g. ad-hoc testing/benchmarking.</span><br style="color:rgb(64,64,64);font-family:Roboto,arial,sans-serif;font-size:13px;line-height:18.2000007629395px"><br style="color:rgb(64,64,64);font-family:Roboto,arial,sans-serif;font-size:13px;line-height:18.2000007629395px"><span style="color:rgb(64,64,64);font-family:Roboto,arial,sans-serif;font-size:13px;line-height:18.2000007629395px">There are a couple of reasons we use CPP, but the main one is breaking changes in GHC and libraries we depend on. We need to reduce these kind of breakages in the future. Dealing with breakages and maintaining the resulting CPP-ed code is costing us time we could spend on other things, such as improving our libraries or writing new ones. I for one would like to get on with writing applications instead of spending time on run-of-the-mill libraries.</span><br style="color:rgb(64,64,64);font-family:Roboto,arial,sans-serif;font-size:13px;line-height:18.2000007629395px"><br style="color:rgb(64,64,64);font-family:Roboto,arial,sans-serif;font-size:13px;line-height:18.2000007629395px"><span style="color:rgb(64,64,64);font-family:Roboto,arial,sans-serif;font-size:13px;line-height:18.2000007629395px">Often these breaking changes are done in the name of "making things cleaner". Breaking changes, no matter how well-intended, doesn't make code cleaner, it makes it less clean*. Users end up having to use </span><b style="color:rgb(64,64,64);font-family:Roboto,arial,sans-serif;font-size:13px;line-height:18.2000007629395px">both</b><span style="color:rgb(64,64,64);font-family:Roboto,arial,sans-serif;font-size:13px;line-height:18.2000007629395px"> the old "unclean" API </span><b style="color:rgb(64,64,64);font-family:Roboto,arial,sans-serif;font-size:13px;line-height:18.2000007629395px">and</b><span style="color:rgb(64,64,64);font-family:Roboto,arial,sans-serif;font-size:13px;line-height:18.2000007629395px"> the new "clean" API.</span><br style="color:rgb(64,64,64);font-family:Roboto,arial,sans-serif;font-size:13px;line-height:18.2000007629395px"><br style="color:rgb(64,64,64);font-family:Roboto,arial,sans-serif;font-size:13px;line-height:18.2000007629395px"><span style="color:rgb(64,64,64);font-family:Roboto,arial,sans-serif;font-size:13px;line-height:18.2000007629395px">The right way to move to evolve an new API is to add new functions and data types, not modify old ones, whenever possible.</span><br style="color:rgb(64,64,64);font-family:Roboto,arial,sans-serif;font-size:13px;line-height:18.2000007629395px"><br style="color:rgb(64,64,64);font-family:Roboto,arial,sans-serif;font-size:13px;line-height:18.2000007629395px"><span style="color:rgb(64,64,64);font-family:Roboto,arial,sans-serif;font-size:13px;line-height:18.2000007629395px">* It takes about 3 major GHC releases (~3 years) before you can remove the CPP, but since new things keep breaking all the time you always have a considerable amount of CPP.</span><br><div><span style="color:rgb(64,64,64);font-family:Roboto,arial,sans-serif;font-size:13px;line-height:18.2000007629395px"><br></span></div><div><span style="color:rgb(64,64,64);font-family:Roboto,arial,sans-serif;font-size:13px;line-height:18.2000007629395px">-- Johan</span></div><div><span style="color:rgb(64,64,64);font-family:Roboto,arial,sans-serif;font-size:13px;line-height:18.2000007629395px"><br></span></div></div>