Hi,<br><br>I would prefer it if packages would use DefaultSignatures conditionally, instead of creating new packages just to define a generic variant of a function. In general, though, I think it&#39;s good practice to define the defaults as separate functions (like `genericSize`) and export them, so that those not using DefaultSignatures can still write an instance easily.<br>

<br>As for the concerns about people using DefaultSignatures and not realizing their code is not portable, I guess we could reject programs that use a default signature (when writing an empty instance) unless they enable -XDefaultSignatures. Then people would know they are relying on an extension.<br>

<br><br>Cheers,<br>Pedro<br><div class="gmail_extra"><br><br><div class="gmail_quote">On Sun, Nov 11, 2012 at 9:06 PM, Herbert Valerio Riedel <span dir="ltr">&lt;<a href="mailto:hvr@gnu.org" target="_blank">hvr@gnu.org</a>&gt;</span> wrote:<br>

<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="im">Henning Thielemann &lt;<a href="mailto:lemming@henning-thielemann.de">lemming@henning-thielemann.de</a>&gt; writes:<br>


&gt; On Sun, 11 Nov 2012, Herbert Valerio Riedel wrote:<br>
&gt;&gt; E.g. consider the following hypothetical class definition:<br>
&gt;&gt;<br>
&gt;&gt;      class Size a where<br>
&gt;&gt;        size :: a -&gt; Int<br>
&gt;&gt;      #ifdef HAS_DEFAULT_SIGNATURE<br>
&gt;&gt;        default size :: Generic a =&gt; a -&gt; Int<br>
&gt;&gt;      size x = ...Generics based implementation...<br>
&gt;&gt;      #endif<br>
&gt;&gt;<br>
&gt;&gt; Now, if the client code doesn&#39;t exploit the default-signature<br>
&gt;&gt; implementation, then the client code is perfectly portable, and even if<br>
&gt;&gt; the conditional API features are available they have no visible effect<br>
&gt;&gt; whatsoever.<br>
&gt;&gt;<br>
&gt;&gt; OTOH, if the client code wants to make use of the default<br>
&gt;&gt; implementation, it needs to be built with a compiler supporting the<br>
&gt;&gt; Generics language feature, and due to a) the library is guaranteed to<br>
&gt;&gt; provide the default-signature implementation as well as soon as the<br>
&gt;&gt; client is able to use it. The client-code is now deliberately<br>
&gt;&gt; non-portable (but on the other hand, the operational semantics are<br>
&gt;&gt; guaranteed to be consistent, as there&#39;s only one case to consider)<br>
&gt;<br>
&gt; That is, if I want to write a package that is portable I have to<br>
&gt; implement &#39;size&#39; myself. But if I forget to do so then GHC will not<br>
&gt; warn me. That is, I have to know and remember that &#39;size&#39; is somehow<br>
&gt; special.<br>
<br>
</div> a) If you are allowed to forget to implement &#39;size&#39;, then your type was<br>
    able to provide a &#39;Generic&#39; instance, how was that instance possible<br>
    to come into existence in the first place?<br>
<br>
 b) what if GHC provided something akin to a<br>
    -fwarn-instantiate-default-signatures GHC option, which might even<br>
    be turned on by default?<br>
<br>
 c) what if GHC behaved like outlined in<br>
    <a href="http://hackage.haskell.org/trac/ghc/ticket/7395#comment:7" target="_blank">http://hackage.haskell.org/trac/ghc/ticket/7395#comment:7</a> instead?<br>
<div class="im"><br>
&gt; APIs that change according to available compiler features are more<br>
&gt; problematic than they look first. E.g. QuickCheck depends on<br>
&gt; TemplateHaskell if you run on GHC. That is, if you run on GHC then a<br>
&gt; module is included that provides TemplateHaskell functions. If you do<br>
&gt; not run on GHC this module is not included because you cannot use it<br>
&gt; anyway. However, this way QuickCheck becomes restricted to certain<br>
&gt; _versions_ of GHC, because TemplateHaskell changes from version to<br>
&gt; version of GHC. Thus when speaking about portability, we should always<br>
&gt; think about portability between GHC versions. (My proposal for a quote<br>
&gt; of the week is: GHC&#39;s strongest competitor is the next version of<br>
&gt; GHC.) Will the Generics based default implementation of &#39;size&#39; be<br>
&gt; portable to future version of Generics?<br>
<br>
</div>Fair enough, but breakage with newer GHCs can also happen when staying<br>
in the pure Haskell98/2010 domain (just think of the Num/Show/Eq<br>
superclass decoupling that occured in recent GHC versions). That is, for<br>
Haskell libraries there&#39;s always the risk needing maintainance when a<br>
new GHC version comes out. (But I&#39;m not arguing this to be a good thing<br>
either...)<br>
<div class="im"><br>
&gt; For a central package like deepseq I would prefer to provide functions<br>
&gt; like genericSize that other libraries can use if they want to rely on<br>
&gt; Generics. They would then write<br>
&gt;<br>
&gt;   instance Size Foo where<br>
&gt;      size = genericSize<br>
&gt;<br>
&gt; instead of<br>
&gt;<br>
&gt;   instance Size Foo where<br>
&gt;<br>
&gt;<br>
&gt; This would be ok, wouldn&#39;t it?<br>
<br>
</div>Are you preferring &#39;genericSize&#39; to avoid the implicity that comes with<br>
DefaultSignatures, and the resulting risk of inadvertently writing<br>
non-portable code because GHC currently doesn&#39;t warn you?<br>
<div class="HOEnZb"><div class="h5"><br>
<br>
_______________________________________________<br>
Libraries mailing list<br>
<a href="mailto:Libraries@haskell.org">Libraries@haskell.org</a><br>
<a href="http://www.haskell.org/mailman/listinfo/libraries" target="_blank">http://www.haskell.org/mailman/listinfo/libraries</a><br>
</div></div></blockquote></div><br></div>