[Haskell-cafe] The amount of CPP we have to use is getting out of hand

Johan Tibell johan.tibell at gmail.com
Fri Jan 9 14:51:01 UTC 2015


To complete the list, here are my other three packages:

network-uri 1/1
ekg-statsd 1/3
ekg-core 1/8


On Fri, Jan 9, 2015 at 3:46 PM, Johan Tibell <johan.tibell at gmail.com> wrote:

> If anyone would like to compute the CPP usage for your modules, you can
> use this command:
>
> for lib in hashable cabal/Cabal cabal/cabal-install containers
> unordered-containers cassava ekg network; do
>   echo $lib
>   find $lib -type d \( -name tests -o -name benchmarks -o -name dist -o
> -name .cabal-sandbox -o -name tests-ghc \) -prune \
>     -o -name Setup.hs -prune -o -name '*.hs' -exec grep -l 'LANGUAGE.*CPP'
> {} \; | wc -l
>   find $lib -type d \( -name tests -o -name benchmarks -o -name dist -o
> -name .cabal-sandbox -o -name tests-ghc \) -prune \
>     -o -name Setup.hs -prune -o -name '*.hs' -print | wc -l
> done
>
> Replace the list in the 'in' clause with your list of packages (which
> should all be in a per-package directory under $CWD).
>
> On Fri, Jan 9, 2015 at 2:55 PM, Johan Tibell <johan.tibell at gmail.com>
> wrote:
>
>> Hi,
>>
>> (This was initially written as a Google+ post, but I'm reposting it here
>> to raise awareness of the issue.)
>>
>> 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:
>>
>> containers 18/18
>> hashable 4/5
>> unordered-containers 6/9
>> network 3/7
>> cassava 4/16
>> cabal/cabal-install 13/75
>> cabal/Cabal 7/78
>> ekg 1/15
>>
>> 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).
>>
>> CPP really sucks from a maintenance perspective:
>>
>>  * It's not Haskell, but this bizarre string concatenation language.
>>  * The code is harder to read, bitrots more easily, and is harder to test.
>>  * 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.
>>
>> 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.
>>
>> 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 *both* the
>> old "unclean" API *and* the new "clean" API.
>>
>> The right way to move to evolve an new API is to add new functions and
>> data types, not modify old ones, whenever possible.
>>
>> * 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.
>>
>> -- Johan
>>
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.haskell.org/pipermail/haskell-cafe/attachments/20150109/20262b25/attachment.html>


More information about the Haskell-Cafe mailing list