<div dir="ltr">Polymorphic code is not always a win.  When I see e.g. "x * x" it's very clear what's happening.  But when someone instead uses "join (*) x"[1], it takes a while to piece together what's going on[2].  First you need to figure out what "join" is, and then you need to unify types:<div>

<br></div><div>join :: Monad m => m (m a) -> m a</div><div>(*) :: Num a => a -> a -> a</div><div><br></div><div>I hate unifying types.  That's what the compiler is for.</div>
<div><br></div><div>I'm not against polymorphic functions, but it's not always a win.  If your polymorphism is making a maintenance programmer invoke their mental type inferencer, you can expect a poor outcome.</div>
<div><br></div><div>John</div>
<div><div><br></div><div>[1] Why would anyone do that?  What possible advantage does this form provide?  Paid by the character?  And yes, I've actually seen exactly this, I don't mean the slightly-more-defensible "join (*)" in a pipeline.</div>
<div>[2] Unless you've already done this once and therefore are familiar with the idiom.</div>
</div></div><div class="gmail_extra"><br><br><div class="gmail_quote">On Wed, Jun 18, 2014 at 10:23 AM, Carter Schonwald <span dir="ltr"><<a href="mailto:carter.schonwald@gmail.com" target="_blank">carter.schonwald@gmail.com</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">I think polymorphic code, subject to it "obeying laws/equations" is generally a win. Fewer ways to have funny corner cases. :) </div>
<div class="HOEnZb"><div class="h5"><div class="gmail_extra"><br><br><div class="gmail_quote">On Wed, Jun 18, 2014 at 12:00 PM, David Thomas <span dir="ltr"><<a href="mailto:davidleothomas@gmail.com" target="_blank">davidleothomas@gmail.com</a>></span> wrote:<br>


<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Of course, you can always add type annotations to be more specific<br>
about your types.  And that actually might be clearer than having to<br>
remember all the various names for all the various monomorphic<br>
variants.  Or it might not.<br>
<div><div><br>
On Wed, Jun 18, 2014 at 6:06 AM, Erik Hesselink <<a href="mailto:hesselink@gmail.com" target="_blank">hesselink@gmail.com</a>> wrote:<br>
> I think it's a pretty clear tradeoff: if you write 'map f xs' you know<br>
> that 'xs' must be a list. If you write 'fmap f xs', you know only that<br>
> 'xs' is a Functor. So you gain flexibility in when you can use 'fmap',<br>
> but you lose the local information you get from the more constrained<br>
> type of 'map'. The same argument applies when generalizing 'mapM' and<br>
> friends. I'm still in favor of generalizing the Prelude functions to<br>
> their Foldable/Traversable variants, but the downside is also clear to<br>
> me.<br>
><br>
> This seems like a perfect problem for an IDE to solve, by the way.<br>
><br>
> Erik<br>
><br>
> On Wed, Jun 18, 2014 at 2:49 PM, Jake McArthur <<a href="mailto:jake.mcarthur@gmail.com" target="_blank">jake.mcarthur@gmail.com</a>> wrote:<br>
>> I find this argument against polymorphism baffling. Do I really have to<br>
>> state the benefits of parametricity here? Probably not. Most likely, there<br>
>> is some specific style of polymorphism in mind going unsaid here, such as<br>
>> ListLike type classes that have tons of methods and don't really have any<br>
>> meaningful laws. Is this the case, or do you *really* mean to argue that<br>
>> polymorphism makes code confusing? If the latter, would you mind explaining<br>
>> why?<br>
>><br>
>> Please forgive me for any weird autocorrections, typos, or bad grammar. This<br>
>> was written on my phone, which is hard to write and proofread on.<br>
>><br>
>> Richard Eisenberg wrote:<br>
>>> Having lots of polymorphism in the Prelude is great, but for two problems:<br>
>>>   1) It's very confusing to novices.<br>
>>>   2) In the case of using Control.Category definitions: kind-polymorphism<br>
>>> is<br>
>>> not portable<br>
>>><br>
>>> I wish to ignore (2) for now, as it's a smaller concern given that it<br>
>>> affects only a portion of the proposed changes.<br>
>><br>
>> In my opinion, Richard missed the most important reason:<br>
>><br>
>> 3) Gratuitous polymorphism makes code much less readable<br>
>>    and much costlier to maintain, usually for almost no gain.<br>
>><br>
>> One of the biggest strengths of Haskell is semantic clarity.<br>
>> You can often look at a Haskell expression, recognize its type,<br>
>> and then immediately understand exactly what the expression<br>
>> is doing. That is immensely valuable, not only for writing code,<br>
>> but for maintaining and refactoring it over the lifetime of an<br>
>> application, often by people other than the original author.<br>
>><br>
>> Adding polymorphism to code is semantically lossy.<br>
>> One of the biggest disasters I have ever suffered in software<br>
>> engineering was when someone went through an entire fairly<br>
>> large code base and changed it to use a more polymorphic<br>
>> Prelude, then left the company. Adding the polymorphism was<br>
>> mostly mechanical, but undoing it required hours upon hours of<br>
>> puzzling out the meaning of the code, line by line.<br>
>><br>
>> And do not relegate Richard's point #1 to CS 101 at university.<br>
>> Most software maintenance is done by the developers with<br>
>> the least Haskell experience. And that is the largest cost<br>
>> of software over time.<br>
>><br>
>> Polymorphism can be very powerful, of course, and there are<br>
>> a lot of great tools and techniques that use it in various ways.<br>
>> But why force some particular polymorphic generalization<br>
>> down everyone's throat when the cost of enabling it if you<br>
>> want it is essentially zero?<br>
>><br>
>> If you use a different Prelude in a large project, or in many small<br>
>> projects, take a few minutes to set up your dev environment<br>
>> accordingly.<br>
>><br>
>> As a case in point: Yesod uses many GHC extensions universally,<br>
>> among them NoImplicitPrelude. These are all listed in the<br>
>> automatically-generated default cabal file; they never need to be<br>
>> typed, and never appear in any source files. There is a single extra<br>
>> line in each file which sets up the whole environment:<br>
>><br>
>> import Import<br>
>><br>
>> You can bind that to an editor key if you'd like. You can write<br>
>> scripts. There are packages on Haskell which automate a lot<br>
>> of things. Need I go on with these trivialities?<br>
>><br>
>> A lot of thought went into making it easy to use GHC extensions.<br>
>> Advanced and experienced developers who need them should<br>
>> have no trouble at all using them, including alternative Preludes.<br>
>><br>
>> That is not to say that no changes should be made to the Prelude.<br>
>> Now that people are using a number of different alternative Preludes<br>
>> more regularly, I would hope we can use that experience to<br>
>> make much-needed improvements to the default Prelude.<br>
>> But the principal design considerations should be simplicity,<br>
>> ease of use even for beginners, and semantic clarity of code<br>
>> using it.<br>
>><br>
>> Thanks,<br>
>> Yitz<br>
>> _______________________________________________<br>
>> Libraries mailing list<br>
>> <a href="mailto:Libraries@haskell.org" target="_blank">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>
>><br>
>> _______________________________________________<br>
>> Libraries mailing list<br>
>> <a href="mailto:Libraries@haskell.org" target="_blank">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>
>><br>
> _______________________________________________<br>
> Libraries mailing list<br>
> <a href="mailto:Libraries@haskell.org" target="_blank">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>
_______________________________________________<br>
Libraries mailing list<br>
<a href="mailto:Libraries@haskell.org" target="_blank">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>
</div></div><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>
<br></blockquote></div><br></div>