<div dir="ltr"><div>Not sure if this helps, but the following two code snippets (taken from Rosetta code) for computing the generalized Cartesian product of a list of lists might exemplify a very important aspect of Haskell: Haskell programmers must invest a lot of time into learning functional programming, but once they speak this common language, the code tends to be easier to understand, maintain, and reason about.</div><div><br></div><div>The Java solution requires to think about all sort of lower level details on how to iterate the lists and construct the result. It even mixes iterations with more "functional" idioms:<br></div><div><br></div><div><span class="gmail-hljs-keyword" style="box-sizing:border-box;font-weight:bold;color:rgb(51,51,51);font-family:SFMono-Regular,Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:13.6px;white-space:pre;text-decoration-style:initial;text-decoration-color:initial">import</span><span style="color:rgb(51,51,51);font-family:SFMono-Regular,Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:13.6px;font-weight:normal;white-space:pre;background-color:rgb(248,248,248);text-decoration-style:initial;text-decoration-color:initial;display:inline;float:none"> </span><span class="gmail-hljs-keyword" style="box-sizing:border-box;font-weight:bold;color:rgb(51,51,51);font-family:SFMono-Regular,Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:13.6px;white-space:pre;text-decoration-style:initial;text-decoration-color:initial">static</span><span style="color:rgb(51,51,51);font-family:SFMono-Regular,Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:13.6px;font-weight:normal;white-space:pre;background-color:rgb(248,248,248);text-decoration-style:initial;text-decoration-color:initial;display:inline;float:none"> java.util.Arrays.asList;
</span><span class="gmail-hljs-keyword" style="box-sizing:border-box;font-weight:bold;color:rgb(51,51,51);font-family:SFMono-Regular,Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:13.6px;white-space:pre;text-decoration-style:initial;text-decoration-color:initial">import</span><span style="color:rgb(51,51,51);font-family:SFMono-Regular,Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:13.6px;font-weight:normal;white-space:pre;background-color:rgb(248,248,248);text-decoration-style:initial;text-decoration-color:initial;display:inline;float:none"> </span><span class="gmail-hljs-keyword" style="box-sizing:border-box;font-weight:bold;color:rgb(51,51,51);font-family:SFMono-Regular,Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:13.6px;white-space:pre;text-decoration-style:initial;text-decoration-color:initial">static</span><span style="color:rgb(51,51,51);font-family:SFMono-Regular,Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:13.6px;font-weight:normal;white-space:pre;background-color:rgb(248,248,248);text-decoration-style:initial;text-decoration-color:initial;display:inline;float:none"> java.util.Collections.emptyList;
</span><span class="gmail-hljs-keyword" style="box-sizing:border-box;font-weight:bold;color:rgb(51,51,51);font-family:SFMono-Regular,Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:13.6px;white-space:pre;text-decoration-style:initial;text-decoration-color:initial">import</span><span style="color:rgb(51,51,51);font-family:SFMono-Regular,Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:13.6px;font-weight:normal;white-space:pre;background-color:rgb(248,248,248);text-decoration-style:initial;text-decoration-color:initial;display:inline;float:none"> </span><span class="gmail-hljs-keyword" style="box-sizing:border-box;font-weight:bold;color:rgb(51,51,51);font-family:SFMono-Regular,Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:13.6px;white-space:pre;text-decoration-style:initial;text-decoration-color:initial">static</span><span style="color:rgb(51,51,51);font-family:SFMono-Regular,Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:13.6px;font-weight:normal;white-space:pre;background-color:rgb(248,248,248);text-decoration-style:initial;text-decoration-color:initial;display:inline;float:none"> java.util.Optional.of;
</span><span class="gmail-hljs-keyword" style="box-sizing:border-box;font-weight:bold;color:rgb(51,51,51);font-family:SFMono-Regular,Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:13.6px;white-space:pre;text-decoration-style:initial;text-decoration-color:initial">import</span><span style="color:rgb(51,51,51);font-family:SFMono-Regular,Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:13.6px;font-weight:normal;white-space:pre;background-color:rgb(248,248,248);text-decoration-style:initial;text-decoration-color:initial;display:inline;float:none"> </span><span class="gmail-hljs-keyword" style="box-sizing:border-box;font-weight:bold;color:rgb(51,51,51);font-family:SFMono-Regular,Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:13.6px;white-space:pre;text-decoration-style:initial;text-decoration-color:initial">static</span><span style="color:rgb(51,51,51);font-family:SFMono-Regular,Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:13.6px;font-weight:normal;white-space:pre;background-color:rgb(248,248,248);text-decoration-style:initial;text-decoration-color:initial;display:inline;float:none"> java.util.stream.Collectors.toList;
 
</span><span class="gmail-hljs-keyword" style="box-sizing:border-box;font-weight:bold;color:rgb(51,51,51);font-family:SFMono-Regular,Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:13.6px;white-space:pre;text-decoration-style:initial;text-decoration-color:initial">import</span><span style="color:rgb(51,51,51);font-family:SFMono-Regular,Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:13.6px;font-weight:normal;white-space:pre;background-color:rgb(248,248,248);text-decoration-style:initial;text-decoration-color:initial;display:inline;float:none"> java.util.List;
 
</span><span class="gmail-hljs-keyword" style="box-sizing:border-box;font-weight:bold;color:rgb(51,51,51);font-family:SFMono-Regular,Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:13.6px;white-space:pre;text-decoration-style:initial;text-decoration-color:initial">public</span><span style="color:rgb(51,51,51);font-family:SFMono-Regular,Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:13.6px;font-weight:normal;white-space:pre;background-color:rgb(248,248,248);text-decoration-style:initial;text-decoration-color:initial;display:inline;float:none"> </span><span class="gmail-hljs-class" style="box-sizing:border-box;color:rgb(51,51,51);font-family:SFMono-Regular,Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:13.6px;font-weight:normal;white-space:pre;text-decoration-style:initial;text-decoration-color:initial"><span class="gmail-hljs-keyword" style="box-sizing:border-box;font-weight:bold;color:rgb(51,51,51)">class</span> <span class="gmail-hljs-title" style="box-sizing:border-box;color:rgb(68,85,136);font-weight:bold">CartesianProduct</span> </span><span style="color:rgb(51,51,51);font-family:SFMono-Regular,Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:13.6px;font-weight:normal;white-space:pre;background-color:rgb(248,248,248);text-decoration-style:initial;text-decoration-color:initial;display:inline;float:none">{
 
    </span><span class="gmail-hljs-keyword" style="box-sizing:border-box;font-weight:bold;color:rgb(51,51,51);font-family:SFMono-Regular,Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:13.6px;white-space:pre;text-decoration-style:initial;text-decoration-color:initial">public</span><span style="color:rgb(51,51,51);font-family:SFMono-Regular,Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:13.6px;font-weight:normal;white-space:pre;background-color:rgb(248,248,248);text-decoration-style:initial;text-decoration-color:initial;display:inline;float:none"> List<?> product(List<?>... a) {
        </span><span class="gmail-hljs-keyword" style="box-sizing:border-box;font-weight:bold;color:rgb(51,51,51);font-family:SFMono-Regular,Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:13.6px;white-space:pre;text-decoration-style:initial;text-decoration-color:initial">if</span><span style="color:rgb(51,51,51);font-family:SFMono-Regular,Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:13.6px;font-weight:normal;white-space:pre;background-color:rgb(248,248,248);text-decoration-style:initial;text-decoration-color:initial;display:inline;float:none"> (a.length >= </span><span class="gmail-hljs-number" style="box-sizing:border-box;color:rgb(0,128,128);font-family:SFMono-Regular,Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:13.6px;font-weight:normal;white-space:pre;text-decoration-style:initial;text-decoration-color:initial">2</span><span style="color:rgb(51,51,51);font-family:SFMono-Regular,Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:13.6px;font-weight:normal;white-space:pre;background-color:rgb(248,248,248);text-decoration-style:initial;text-decoration-color:initial;display:inline;float:none">) {
            List<?> product = a[</span><span class="gmail-hljs-number" style="box-sizing:border-box;color:rgb(0,128,128);font-family:SFMono-Regular,Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:13.6px;font-weight:normal;white-space:pre;text-decoration-style:initial;text-decoration-color:initial">0</span><span style="color:rgb(51,51,51);font-family:SFMono-Regular,Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:13.6px;font-weight:normal;white-space:pre;background-color:rgb(248,248,248);text-decoration-style:initial;text-decoration-color:initial;display:inline;float:none">];
            </span><span class="gmail-hljs-keyword" style="box-sizing:border-box;font-weight:bold;color:rgb(51,51,51);font-family:SFMono-Regular,Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:13.6px;white-space:pre;text-decoration-style:initial;text-decoration-color:initial">for</span><span style="color:rgb(51,51,51);font-family:SFMono-Regular,Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:13.6px;font-weight:normal;white-space:pre;background-color:rgb(248,248,248);text-decoration-style:initial;text-decoration-color:initial;display:inline;float:none"> (</span><span class="gmail-hljs-keyword" style="box-sizing:border-box;font-weight:bold;color:rgb(51,51,51);font-family:SFMono-Regular,Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:13.6px;white-space:pre;text-decoration-style:initial;text-decoration-color:initial">int</span><span style="color:rgb(51,51,51);font-family:SFMono-Regular,Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:13.6px;font-weight:normal;white-space:pre;background-color:rgb(248,248,248);text-decoration-style:initial;text-decoration-color:initial;display:inline;float:none"> i = </span><span class="gmail-hljs-number" style="box-sizing:border-box;color:rgb(0,128,128);font-family:SFMono-Regular,Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:13.6px;font-weight:normal;white-space:pre;text-decoration-style:initial;text-decoration-color:initial">1</span><span style="color:rgb(51,51,51);font-family:SFMono-Regular,Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:13.6px;font-weight:normal;white-space:pre;background-color:rgb(248,248,248);text-decoration-style:initial;text-decoration-color:initial;display:inline;float:none">; i < a.length; i++) {
                product = product(product, a[i]);
            }
            </span><span class="gmail-hljs-keyword" style="box-sizing:border-box;font-weight:bold;color:rgb(51,51,51);font-family:SFMono-Regular,Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:13.6px;white-space:pre;text-decoration-style:initial;text-decoration-color:initial">return</span><span style="color:rgb(51,51,51);font-family:SFMono-Regular,Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:13.6px;font-weight:normal;white-space:pre;background-color:rgb(248,248,248);text-decoration-style:initial;text-decoration-color:initial;display:inline;float:none"> product;
        }
 
        </span><span class="gmail-hljs-keyword" style="box-sizing:border-box;font-weight:bold;color:rgb(51,51,51);font-family:SFMono-Regular,Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:13.6px;white-space:pre;text-decoration-style:initial;text-decoration-color:initial">return</span><span style="color:rgb(51,51,51);font-family:SFMono-Regular,Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:13.6px;font-weight:normal;white-space:pre;background-color:rgb(248,248,248);text-decoration-style:initial;text-decoration-color:initial;display:inline;float:none"> emptyList();
    }
 
    </span><span class="gmail-hljs-keyword" style="box-sizing:border-box;font-weight:bold;color:rgb(51,51,51);font-family:SFMono-Regular,Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:13.6px;white-space:pre;text-decoration-style:initial;text-decoration-color:initial">private</span><span style="color:rgb(51,51,51);font-family:SFMono-Regular,Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:13.6px;font-weight:normal;white-space:pre;background-color:rgb(248,248,248);text-decoration-style:initial;text-decoration-color:initial;display:inline;float:none"> <A, B> List<?> product(List<A> a, List<B> b) {
        </span><span class="gmail-hljs-keyword" style="box-sizing:border-box;font-weight:bold;color:rgb(51,51,51);font-family:SFMono-Regular,Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:13.6px;white-space:pre;text-decoration-style:initial;text-decoration-color:initial">return</span><span style="color:rgb(51,51,51);font-family:SFMono-Regular,Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:13.6px;font-weight:normal;white-space:pre;background-color:rgb(248,248,248);text-decoration-style:initial;text-decoration-color:initial;display:inline;float:none"> of(a.stream()
                .map(e1 -> of(b.stream().map(e2 -> asList(e1, e2)).collect(toList())).orElse(emptyList()))
                .flatMap(List::stream)
                .collect(toList())).orElse(emptyList());
    }
}</span><br></div><div><br></div><div>A programmer that spent a lot of time studying Monads and playing around with them, and that understands the Monad instances for lists, might come up with the following solution in Haskell:</div><div><br></div><div><span class="gmail-hljs-title" style="box-sizing:border-box;color:rgb(153,0,0);font-weight:bold;font-family:SFMono-Regular,Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:13.6px;white-space:pre;text-decoration-style:initial;text-decoration-color:initial">cartProdN</span><span style="color:rgb(51,51,51);font-family:SFMono-Regular,Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:13.6px;font-weight:normal;white-space:pre;background-color:rgb(248,248,248);text-decoration-style:initial;text-decoration-color:initial;display:inline;float:none"> :: [[a]] -> [[a]]
</span><span class="gmail-hljs-title" style="box-sizing:border-box;color:rgb(153,0,0);font-weight:bold;font-family:SFMono-Regular,Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:13.6px;white-space:pre;text-decoration-style:initial;text-decoration-color:initial">cartProdN</span><span style="color:rgb(51,51,51);font-family:SFMono-Regular,Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:13.6px;font-weight:normal;white-space:pre;background-color:rgb(248,248,248);text-decoration-style:initial;text-decoration-color:initial;display:inline;float:none"> = sequence</span></div><div><br></div><div>This also made me realize of two things:</div><div>0. Haskell will never be mainstream, because there are not a lot of programmers out there who are willing to do the investment required for learning the necessary concepts to understand and write code like the one shown above.</div><div>1. Haskell has rendered me unemployable for almost all jobs that do not involve Haskell codebases. Imagine having to maintain code like the first snippet, replicated in a 10K LOC codebase. <br></div><div><br></div><div>And yes, I did use the code above in production :)<br></div><div><br></div></div><br><div class="gmail_quote"><div dir="ltr">On Wed, Jul 11, 2018 at 2:10 PM Simon Peyton Jones via Haskell-Cafe <<a href="mailto:haskell-cafe@haskell.org">haskell-cafe@haskell.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">





<div lang="EN-GB" link="#0563C1" vlink="#954F72">
<div class="m_8274231558867678434WordSection1">
<p class="MsoNormal"><span style="font-family:"Calibri",sans-serif">Friends<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-family:"Calibri",sans-serif">In a few weeks I’m giving a talk to a bunch of genomics folk at the
<a href="https://www.sanger.ac.uk/" target="_blank">Sanger Institute</a> about Haskell.   They do lots of programming, but they aren’t computer scientists.<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-family:"Calibri",sans-serif">I can tell them plenty about Haskell, but I’m ill-equipped to answer the main question in their minds:
<i>why should I even care about Haskell</i>?  I’m too much of a biased witness.<br>
<br>
<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-family:"Calibri",sans-serif">So I thought I’d ask you for help.  War stories perhaps – how using Haskell worked (or didn’t) for you.  But rather than talk generalities, I’d love to illustrate with copious examples of beautiful
 code. <u></u><u></u></span></p>
<ul style="margin-top:0cm" type="disc">
<li class="m_8274231558867678434MsoListParagraph" style="margin-left:0cm"><span style="font-family:"Calibri",sans-serif">Can you identify a few lines of Haskell that best characterise what you think makes Haskell distinctively worth caring about?   Something
 that gave you an “aha” moment, or that feeling of joy when you truly make sense of something for the first time.<u></u><u></u></span></li></ul>
<p class="MsoNormal"><span style="font-family:"Calibri",sans-serif">The challenge is, of course, that this audience will know no Haskell, so muttering about Cartesian Closed Categories isn’t going to do it for them.  I need examples that I can present in 5
 minutes, without needing a long setup.<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-family:"Calibri",sans-serif">To take a very basic example, consider Quicksort using list comprehensions, compared with its equivalent in C.  It’s so short, so obviously right, whereas doing the right thing with in-place
 update in C notoriously prone to fencepost errors etc.  But it also makes much less good use of memory, and is likely to run slower.  I think I can do that in 5 minutes.<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-family:"Calibri",sans-serif">Another thing that I think comes over easily is the ability to abstract: generalising sum and product to fold by abstracting out a functional argument; generalising at the type level by polymorphism,
 including polymorphism over higher-kinded type constructors.   Maybe 8 minutes.<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-family:"Calibri",sans-serif">But you will have more and better ideas, and (crucially) ideas that are more credibly grounded in the day to day reality of writing programs that get work done.<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-family:"Calibri",sans-serif">Pointers to your favourite blog posts would be another avenue.  (I love the Haskell Weekly News.)<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-family:"Calibri",sans-serif">Finally, I know that some of you use Haskell specifically for genomics work, and maybe some of your insights would be particularly relevant for the Sanger audience.<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-family:"Calibri",sans-serif">Thank you!  Perhaps your responses on this thread (if any) may be helpful to more than just me.<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-family:"Calibri",sans-serif">Simon<u></u><u></u></span></p>
</div>
</div>

_______________________________________________<br>
Haskell-Cafe mailing list<br>
To (un)subscribe, modify options or view archives go to:<br>
<a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe" rel="noreferrer" target="_blank">http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe</a><br>
Only members subscribed via the mailman list are allowed to post.</blockquote></div>