RFC: Can DefaultSignature compile-time conditional APIs be regarded "benign"?

Henning Thielemann lemming at henning-thielemann.de
Sun Nov 11 21:21:51 CET 2012

On Sun, 11 Nov 2012, Herbert Valerio Riedel wrote:

> E.g. consider the following hypothetical class definition:
> 	class Size a where
> 	  size :: a -> Int
> 	  default size :: Generic a => a -> Int
>      size x = ...Generics based implementation...
> 	#endif
> Now, if the client code doesn't exploit the default-signature
> implementation, then the client code is perfectly portable, and even if
> the conditional API features are available they have no visible effect
> whatsoever.
> OTOH, if the client code wants to make use of the default
> implementation, it needs to be built with a compiler supporting the
> Generics language feature, and due to a) the library is guaranteed to
> provide the default-signature implementation as well as soon as the
> client is able to use it. The client-code is now deliberately
> non-portable (but on the other hand, the operational semantics are
> guaranteed to be consistent, as there's only one case to consider)

That is, if I want to write a package that is portable I have to implement 
'size' myself. But if I forget to do so then GHC will not warn me. That 
is, I have to know and remember that 'size' is somehow special.

APIs that change according to available compiler features are more 
problematic than they look first. E.g. QuickCheck depends on 
TemplateHaskell if you run on GHC. That is, if you run on GHC then a 
module is included that provides TemplateHaskell functions. If you do not 
run on GHC this module is not included because you cannot use it anyway. 
However, this way QuickCheck becomes restricted to certain _versions_ of 
GHC, because TemplateHaskell changes from version to version of GHC. Thus 
when speaking about portability, we should always think about portability 
between GHC versions. (My proposal for a quote of the week is: GHC's 
strongest competitor is the next version of GHC.) Will the Generics based 
default implementation of 'size' be portable to future version of 

For a central package like deepseq I would prefer to provide functions 
like genericSize that other libraries can use if they want to rely on 
Generics. They would then write

   instance Size Foo where
      size = genericSize

instead of

   instance Size Foo where

This would be ok, wouldn't it?

More information about the Libraries mailing list