<div dir="ltr"><div class="gmail_extra"><br><div class="gmail_quote">On Sun, Mar 19, 2017 at 9:33 PM, Adam Bergmark <span dir="ltr"><<a href="mailto:adam@bergmark.nl" target="_blank">adam@bergmark.nl</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">Ed, If i understand you correctly then this poisoning doesn't scale. If I want to use it in my library I'm also forcing all my users to avoid these functions and it would split hackage in half. Effectively I'd only be able to use it for private code and applications. Or am I misunderstanding?</div></blockquote><div><br></div><div>This is why I mentioned at the end that if you're doing this for a library you probably only want to enable poisoning with a cabal build flag. That way you can use it to verify that you build clean even with the poison enabled without crippling your users. Think of it like -Werror. You don't ship cabal packages with it enabled but you often use it locally. For classroom teaching scenarios using a custom prelude that poisons things fits the bill. If you are concerned about certain instances leaking into your private code, you can also poison willy-nilly, and nobody needs care. If you poison behind a flag it doesn't leak out into the ecosystem, and if you choose not to poison behind a flag, then people can choose to accept or reject your poisoned instances on their own merits.</div><div><br></div><div>e.g. async had an instance of Monad for Concurrently that was incompatible with its Applicative until recently. Fortunately, Simon Marlow was willing to listen to reason. However, had he not been, it is a situation where I could bring myself to resort to poison. Er... that sounds rather more gruesome than intended. Sorry, Simon. :)</div><div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div></div><div>You can already do this in poisoning in a solid way by defining e.g. `class Unsatisfiable; instance Unsatisfiable => Show (a -> b) where show = undefined` and not exporting Unsatisfiable.</div></div></blockquote><div><br></div><div>Yes, if you want to ensure that an instance is never defined, but that doesn't work for things where there is already an instance in scope. You can't retroactively poison Foldable ((,) e) with this technique, as the class and instance are defined together in the same module (or the data type and instance are), as they have to be to avoid orphans, and so you never get a chance to interject a conflicting poisonous instance without GHC telling you that your instance collides with the existing instance as an error.</div><div><br></div><div>-Edward</div><div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div>Cheers,</div><div>Adam</div><div><br><div><br></div></div></div><div class="HOEnZb"><div class="h5"><br><div class="gmail_quote"><div dir="ltr">On Mon, 20 Mar 2017 at 01:56 <<a href="mailto:amindfv@gmail.com" target="_blank">amindfv@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="auto" class="m_-3925337202725456901gmail_msg"><div class="m_-3925337202725456901gmail_msg"></div><div class="m_-3925337202725456901gmail_msg">Edward: this is clever! I can't at the moment see any reason this wouldn't work for all parties: those who want the instances can have them, those who don't can "turn them off," and beginners can start with a prelude that turns them off also.</div><div class="m_-3925337202725456901gmail_msg"><br class="m_-3925337202725456901gmail_msg"></div><div class="m_-3925337202725456901gmail_msg">We will need to be clear about which packages (transitively) poison instances.</div><div class="m_-3925337202725456901gmail_msg"><br class="m_-3925337202725456901gmail_msg"></div><div class="m_-3925337202725456901gmail_msg">Tom</div></div><div dir="auto" class="m_-3925337202725456901gmail_msg"><div class="m_-3925337202725456901gmail_msg"><br class="m_-3925337202725456901gmail_msg"></div><div class="m_-3925337202725456901gmail_msg"><br class="m_-3925337202725456901gmail_msg">El 19 mar 2017, a las 19:21, Edward Kmett <<a href="mailto:ekmett@gmail.com" class="m_-3925337202725456901gmail_msg" target="_blank">ekmett@gmail.com</a>> escribió:<br class="m_-3925337202725456901gmail_msg"><br class="m_-3925337202725456901gmail_msg"></div><blockquote type="cite" class="m_-3925337202725456901gmail_msg"><div class="m_-3925337202725456901gmail_msg"><div dir="ltr" class="m_-3925337202725456901gmail_msg">Sadly, hlint remains fairly (er.. completely?) ignorant of the types of an expression. It has no idea what is in scope, and just provides syntax-directed guidance, so hlint isn't the answer here.<div class="m_-3925337202725456901gmail_msg"><br class="m_-3925337202725456901gmail_msg"></div><div class="m_-3925337202725456901gmail_msg">That said, there does seem to be a plausible solution available.<br class="m_-3925337202725456901gmail_msg"><br class="m_-3925337202725456901gmail_msg">I have zero objection to adding {-# POISON #-} pragma that users could include in their own code that just makes it so that whatever instance is named inside of it becomes unusable. You could view it as setting up an ambiguous instance declaration that is currently impossible to write, so any attempt to use the instance would complain about ambiguous instances (or preferably about the instance being poisoned and name the source of the poison).</div><div class="m_-3925337202725456901gmail_msg"><br class="m_-3925337202725456901gmail_msg"></div><div class="m_-3925337202725456901gmail_msg">This would make the status quo the norm, but then you could modify your custom Prelude or what have you to {-# POISON instance Foldable ((,) e) #-} and then any code that transitively depended on your Prelude would complain if it attempted to use that instance.</div><div class="m_-3925337202725456901gmail_msg"><br class="m_-3925337202725456901gmail_msg"><div class="m_-3925337202725456901gmail_msg">Such a poison pragma should be sound with respect to GHC's internals. It is effectively making an extra instance just to cause conflicts later on in the instance selection process. This is the same as if we had Foldable the class being defined in one module, the real instance in another, someone's poison instance in a third, then a fourth module that imports the whole diamond. Any attempt to use the instance that is defined in two contradictory ways in that 4th module today will complain.</div><div class="m_-3925337202725456901gmail_msg"><div class="m_-3925337202725456901gmail_msg"><br class="m_-3925337202725456901gmail_msg"></div></div></div><div class="m_-3925337202725456901gmail_msg">Folks who care about these instances would then have the choice about whether to avoid any package that poisoned any instances they cared about, and folks who fee strongly about this issue would be able to live in a world where these instances didn't affect any code they wrote and if they didn't want to turn off users that care about being poisoned, could turn on the poisoning through cabal flags so that they don't infect their API but get an opt-in internal consistency check for local compilation.<br class="m_-3925337202725456901gmail_msg"></div><div class="m_-3925337202725456901gmail_msg"><br class="m_-3925337202725456901gmail_msg"></div><div class="m_-3925337202725456901gmail_msg">-Edward Kmett<br class="m_-3925337202725456901gmail_msg"><br class="m_-3925337202725456901gmail_msg"><div class="m_-3925337202725456901gmail_msg"><div class="m_-3925337202725456901gmail_msg">P.S. The term poison above derives from the C convention of poisoning names you don't want to see in your code due to safety considerations. e.g. In GCC you can do so with</div><div class="m_-3925337202725456901gmail_msg"><br class="m_-3925337202725456901gmail_msg"></div><div class="m_-3925337202725456901gmail_msg"><span style="color:rgb(0,0,0)" class="m_-3925337202725456901gmail_msg"><font face="monospace, monospace" class="m_-3925337202725456901gmail_msg">#pragma GCC poison printf sprintf fprintf</font></span></div></div></div><div class="m_-3925337202725456901gmail_msg"><span style="color:rgb(0,0,0)" class="m_-3925337202725456901gmail_msg"><font face="monospace, monospace" class="m_-3925337202725456901gmail_msg"><br class="m_-3925337202725456901gmail_msg"></font></span></div></div><div class="gmail_extra m_-3925337202725456901gmail_msg"><br class="m_-3925337202725456901gmail_msg"><div class="gmail_quote m_-3925337202725456901gmail_msg">On Sat, Mar 18, 2017 at 8:51 PM,  <span dir="ltr" class="m_-3925337202725456901gmail_msg"><<a href="mailto:amindfv@gmail.com" class="m_-3925337202725456901gmail_msg" target="_blank">amindfv@gmail.com</a>></span> wrote:<br class="m_-3925337202725456901gmail_msg"><blockquote class="gmail_quote m_-3925337202725456901gmail_msg" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span class="m_-3925337202725456901gmail_msg"><br class="m_-3925337202725456901gmail_msg">
<br class="m_-3925337202725456901gmail_msg">
> El 18 mar 2017, a las 16:01, Lana Black <<a href="mailto:lanablack@amok.cc" class="m_-3925337202725456901gmail_msg" target="_blank">lanablack@amok.cc</a>> escribió:<br class="m_-3925337202725456901gmail_msg">
><br class="m_-3925337202725456901gmail_msg">
>> On 18/03/17 19:49, Henning Thielemann wrote:<br class="m_-3925337202725456901gmail_msg">
>><br class="m_-3925337202725456901gmail_msg">
>>> On Sat, 18 Mar 2017, Carter Schonwald wrote:<br class="m_-3925337202725456901gmail_msg">
>>><br class="m_-3925337202725456901gmail_msg">
>>> for what?<br class="m_-3925337202725456901gmail_msg">
>><br class="m_-3925337202725456901gmail_msg">
>> A warning if someone e.g. calls 'length (a,b)', or more generally, if<br class="m_-3925337202725456901gmail_msg">
>> certain instances are used.<br class="m_-3925337202725456901gmail_msg">
>> ______________________________<wbr>_________________<br class="m_-3925337202725456901gmail_msg">
>> Libraries mailing list<br class="m_-3925337202725456901gmail_msg">
>> <a href="mailto:Libraries@haskell.org" class="m_-3925337202725456901gmail_msg" target="_blank">Libraries@haskell.org</a><br class="m_-3925337202725456901gmail_msg">
>> <a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries" rel="noreferrer" class="m_-3925337202725456901gmail_msg" target="_blank">http://mail.haskell.org/cgi-<wbr>bin/mailman/listinfo/libraries</a><br class="m_-3925337202725456901gmail_msg">
><br class="m_-3925337202725456901gmail_msg">
> Please no. Many of us like our code Wall-clean while still being able to<br class="m_-3925337202725456901gmail_msg">
> write polymorphic functions. Adding more warnings that are often<br class="m_-3925337202725456901gmail_msg">
> triggered by correct code (redundant constraints, anyone?) only leads to<br class="m_-3925337202725456901gmail_msg">
> more headache.<br class="m_-3925337202725456901gmail_msg">
><br class="m_-3925337202725456901gmail_msg">
> You could make that an hlint rule on the other hand.<br class="m_-3925337202725456901gmail_msg">
<br class="m_-3925337202725456901gmail_msg">
</span>Can it be a hlint rule? It seems quite difficult to predict that "length" will not ever be passed e.g. a 2-tuple in the general case, within hlint.<br class="m_-3925337202725456901gmail_msg">
<br class="m_-3925337202725456901gmail_msg">
I would also favor a warning, and happily have -Wall not include it (though I'd prefer inclusion).<br class="m_-3925337202725456901gmail_msg">
<span class="m_-3925337202725456901m_-2207575623110575199HOEnZb m_-3925337202725456901gmail_msg"><font color="#888888" class="m_-3925337202725456901gmail_msg"><br class="m_-3925337202725456901gmail_msg">
Tom<br class="m_-3925337202725456901gmail_msg">
</font></span><div class="m_-3925337202725456901m_-2207575623110575199HOEnZb m_-3925337202725456901gmail_msg"><div class="m_-3925337202725456901m_-2207575623110575199h5 m_-3925337202725456901gmail_msg"><br class="m_-3925337202725456901gmail_msg">
<br class="m_-3925337202725456901gmail_msg">
> ______________________________<wbr>_________________<br class="m_-3925337202725456901gmail_msg">
> Libraries mailing list<br class="m_-3925337202725456901gmail_msg">
> <a href="mailto:Libraries@haskell.org" class="m_-3925337202725456901gmail_msg" target="_blank">Libraries@haskell.org</a><br class="m_-3925337202725456901gmail_msg">
> <a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries" rel="noreferrer" class="m_-3925337202725456901gmail_msg" target="_blank">http://mail.haskell.org/cgi-<wbr>bin/mailman/listinfo/libraries</a><br class="m_-3925337202725456901gmail_msg">
______________________________<wbr>_________________<br class="m_-3925337202725456901gmail_msg">
Libraries mailing list<br class="m_-3925337202725456901gmail_msg">
<a href="mailto:Libraries@haskell.org" class="m_-3925337202725456901gmail_msg" target="_blank">Libraries@haskell.org</a><br class="m_-3925337202725456901gmail_msg">
<a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries" rel="noreferrer" class="m_-3925337202725456901gmail_msg" target="_blank">http://mail.haskell.org/cgi-<wbr>bin/mailman/listinfo/libraries</a><br class="m_-3925337202725456901gmail_msg">
</div></div></blockquote></div><br class="m_-3925337202725456901gmail_msg"></div>
</div></blockquote></div>______________________________<wbr>_________________<br class="m_-3925337202725456901gmail_msg">
Libraries mailing list<br class="m_-3925337202725456901gmail_msg">
<a href="mailto:Libraries@haskell.org" class="m_-3925337202725456901gmail_msg" target="_blank">Libraries@haskell.org</a><br class="m_-3925337202725456901gmail_msg">
<a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries" rel="noreferrer" class="m_-3925337202725456901gmail_msg" target="_blank">http://mail.haskell.org/cgi-<wbr>bin/mailman/listinfo/libraries</a><br class="m_-3925337202725456901gmail_msg">
</blockquote></div>
</div></div></blockquote></div><br></div></div>