<div dir="ltr"><div>Purity makes type signatures astonishingly informative. Often -- in fact usually! -- one can determine what a function does simply from its name and type signature.</div><div><br></div><div>The opportunities for bad coding are fewer in Haskell. Before Haskell, I was a proud Python programmer -- proud, thinking I was good at selecting the right way from a forest of wrong ways. In Haskell I find less opportunity for self-congratulation, because most of the wrong ways are no longer available.</div></div><div class="gmail_extra"><br><div class="gmail_quote">On Tue, Dec 15, 2015 at 9:00 AM, derek riemer <span dir="ltr"><<a href="mailto:driemer.riemer@gmail.com" target="_blank">driemer.riemer@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 bgcolor="#FFFFFF" text="#000000">
    Hey guys,<br>
    This conversation is really interesting. I am not a haskell expert
    (I haven't progressed into monads in haskell yet, and have only
    briefly studied the state monad in scala. Studying fp concepts has
    changed the way I think about problems that are complicated. I am
    not quite there yet, (I still catch myself updating states when I
    don't need to) and wondering how the hell to break a problem into
    recursive little bits. I now notice that I am less tempted to do
    things that would have bugs in complicated data structures , prefer
    map to do something to a list, and folds to for loops that update a
    ``state'' variable, and finally, I can reason about where the weak
    points in my code may be. The learning I have achieved do to fp, and
    my principals of programming languages class that relied on fp, have
    made doing things with code easier because I don't try to do stupid
    things like overrun the end of an array with a misplaced loop
    counter variable. It is way too easy to learn fold, filter, map, and
    list comprehensions, you then have a powerful weapon to use against
    those ugly off by one errors. <br>
    Also, I learned how people who learned programming in
    non-traditional languages might think to approach problems earlier
    this year. My stats professor was showing us things in r. She showed
    us a complicated set of formula that we needed to do, and then
    explained we were calculating something to each element of a list.
    She showed a function sapply(vector, function(elem)) that returns a
    vector. She said to think about how sapply applies that function to
    each vector element, and returns the transformed list. She didn't
    approach it as if it were this big bad function that takes a
    function, mainly i think because she hadn't learned programming from
    people who insist on the idea of c. It also really made sense to the
    class who mainly had little to no programming experience, where
    explaining a for loop in all it's glory would normally take a couple
    of lectures. She is a really solid programmer and really understands
    how to use programming to solve real world problems, so I am not
    saying that she didn't know enough to have not learned for loops,
    just that she immediately realized that the sapply function really
    was better for the situation. If we teach people these patterns from
    the get go, I think some of the horror of learning functional
    programming would be solved because the number of applications that
    a generic function can be applied in far outnumbers the number of
    cases a for loop or state momad is needed. I would also now argue
    that all data structures classes should be taught in functional
    programming languages. I never solidly understood trees and could
    confidently traverse and change them until I actually got introduced
    to pattern matching and folds. I was taught binary search trees, and
    red-black trees, and worked with tree like structures, but it was
    always hard for me to comprehend how to do things with them. I
    learned linked lists in c++ but hated them with a passion because I
    had to write forloops that updated a temporary variable and write
    while loops that did the same, but often jumped off the end of the
    list and then I couldn't go back. The beauty of recursion and lists
    is that recursion allows you to backtrack when things go wrong (as
    they always will for any real input in a program). The second I
    learned about Haskell for the first time, linked list traversing
    became second nature to me, even in non-functional (inferier) c++.
    The argument that "recursion results in overriding the stack" is
    kind of a flawed one since the compiler wizards have figured out
    ways to optimize tail recursive functions to do exactly what we
    humans are bad at (running recursive functions as if they were
    unrolled, with large inputs, and fast). <br>
    Thanks,<br>
    Derek<div><div class="h5"><br>
    <br>
    <div>On 12/11/2015 11:32 AM, Thomas Jakway
      wrote:<br>
    </div>
    <blockquote type="cite">
      <pre>Building on that, I think coming to Haskell with a very specific goal in mind (like swap Haskell for Java in my map reduce problem) kind of misses the point.  Haskell may or may not be faster/better suited to map reduce vs Java, but the real reason to use/learn Haskell is elegance and correctness.  The lack of side effects and referential transparency means you're far more likely to prevent bugs.  And there's a pretty substantial learning curve coming from imperative languages so if you need to speed up map reduce on a deadline you will be more productive in the imperative language of your choice (for now).

Dont take this as discouragement, I think Haskell (and FP in general) is very well suited to that kind of problem.  I'm a beginner in Haskell and it's already had a huge impact on how I think about all the code I write, not just the occasional toy Haskell project.

On Dec 11, 2015 1:08 PM, MJ Williams <a href="mailto:matthewjwilliams101@gmail.com" target="_blank"><matthewjwilliams101@gmail.com></a> wrote:
</pre>
      <blockquote type="cite">
        <pre>A pure functional language enables you to reason about your code, 
something you can't easily achieve with your average C or Java. And by 
`reason' I am referring to mathematical proof. Haskell makes it very 
simple, actually.  Why should you want to reason about your code? 
Think the hassle you could avoid if you knew what your code really 
meant and did when executed. 

The absence of side effects is part of another concept in FP, namely, 
`referential transparency'.  If your function `f' maps a value `x' to 
a value `y' then `f x' will always equal `y' and no more. In other 
words, your function `f' won't change anything e.g. assign to 
variables, or other state changes as well as mapping `x' to `y', and 
that's an absolute certainty, in theory, at any rate. 

That's a very crude overview of at least part of what functional 
programming is about.  I'm hoping it'll encourage others on this list 
with far more in-depth knowledge of the subject matter to come in and 
fill in the gaps and iron out the ambiguities. 

Matthew 


On 11/12/2015, Daniel Bergey <a href="mailto:bergey@alum.mit.edu" target="_blank"><bergey@alum.mit.edu></a> wrote: 
</pre>
        <blockquote type="cite">
          <pre>On 2015-12-11 at 10:07, Abhishek Kumar <a href="mailto:abhishekkmr18@gmail.com" target="_blank"><abhishekkmr18@gmail.com></a> wrote: 
</pre>
          <blockquote type="cite">
            <pre>I am a beginner in haskell.I have heard a lot about haskell being great 
for 
parallel programming and concurrency but couldn't understand why?Aren't 
iterative algorithms like MapReduce more suitable to run parallely?Also 
how 
immutable data structures add to speed?I'm having trouble understanding 
very philosophy of functional programming, how do we gain by writing 
everything as functions and pure code(without side effects)? 
Any links or references will be a great help. 
</pre>
          </blockquote>
          <pre>Functional languages make it easy to decompose problems in the way that 
MapReduce frameworks require.  A few examples (fold is another name for 
reduce): 

sum :: [Double] -> Double 
sum xs = foldr (+) 0 xs 

sumSquares :: [Double] -> Double 
sumSquares xs = foldr (+) 0 (map (**2) xs) 

-- foldMap combines the map & fold steps 
-- The Monoid instance for String specifies how to combine 2 Strings 
-- Unlike numbers, there's only one consistent option 
unlines :: [Text] -> Text 
unlines xs = foldMap (`snoc` '\n') xs 

We'd need a few changes[1] to make this parallel and distribute across many 
computers, but expressing the part that changes for each new MapReduce 
task should stay easy. 

Immutable data by default helps with concurrency.  Speed may or may not be 
the goal.  We want to be able to distribute tasks (eg, function calls) 
across processor cores, and run them in different order, without 
introducing race conditions. 

Simon Marlow's book is great at explaining parallel & concurrent 
concepts, and the particular tools for applying them in Haskell: 
<a href="http://chimera.labs.oreilly.com/books/1230000000929" target="_blank">http://chimera.labs.oreilly.com/books/1230000000929</a> 

bergey 

Footnotes: 
[1]  OK, many changes. 

_______________________________________________ 
Beginners mailing list 
<a href="mailto:Beginners@haskell.org" target="_blank">Beginners@haskell.org</a> 
<a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners" target="_blank">http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners</a> 

</pre>
        </blockquote>
        <pre>_______________________________________________ 
Beginners mailing list 
<a href="mailto:Beginners@haskell.org" target="_blank">Beginners@haskell.org</a> 
<a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners" target="_blank">http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners</a> 
</pre>
      </blockquote>
      <pre>_______________________________________________
Beginners mailing list
<a href="mailto:Beginners@haskell.org" target="_blank">Beginners@haskell.org</a>
<a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners" target="_blank">http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners</a>
</pre>
    </blockquote>
    <br>
    </div></div><div>-- <br>
      <hr>
      <h2> Derek Riemer </h2>
      <ul>
        <li> Department of computer science, third year undergraduate
          student. </li>
        <li> Proud user of the NVDA screen reader.</li>
        <li> Open source enthusiast.</li>
        <li> Member of Bridge Cu </li>
        
        <li> Avid skiier.</li>
      </ul>
      <p> Websites: <br>
        <a href="http://derekriemer.drupalgardens.com" target="_blank">Honors portfolio</a>
        <br>
        <a href="http://derekriemer.pythonanywhere.com/personal" target="_blank">
          Non-proffessional website.</a> <br>
        <a href="http://derekriemer.pythonanywhere.com/weather" target="_blank">Awesome
          little hand built weather app that rocks!</a> <br>
      </p>
      <p>
        <a href="mailto:derek.riemer@colorado.edu" target="_blank"> email me at
          derek.riemer@colorado.edu</a>
        <br>
        Phone: <a href="tel:%28303%29%20906-2194" value="+13039062194" target="_blank">(303) 906-2194</a>
      </p>
    </div>
  </div>

<br>_______________________________________________<br>
Beginners mailing list<br>
<a href="mailto:Beginners@haskell.org">Beginners@haskell.org</a><br>
<a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners" rel="noreferrer" target="_blank">http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners</a><br>
<br></blockquote></div><br><br clear="all"><div><br></div>-- <br><div class="gmail_signature"><div dir="ltr">Jeffrey Benjamin Brown</div></div>
</div>