<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	>
<channel>
	<title>Comments on: scala.List.foldLeft for Java programmers</title>
	<atom:link href="http://blog.tmorris.net/scalalistfoldleft-for-java-programmers/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.tmorris.net/scalalistfoldleft-for-java-programmers/</link>
	<description>The weblog of Tony Morris</description>
	<pubDate>Tue, 06 Jan 2009 14:41:46 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.6</generator>
		<item>
		<title>By: Jason</title>
		<link>http://blog.tmorris.net/scalalistfoldleft-for-java-programmers/#comment-22605</link>
		<dc:creator>Jason</dc:creator>
		<pubDate>Tue, 11 Nov 2008 17:34:31 +0000</pubDate>
		<guid isPermaLink="false">http://blog.tmorris.net/scalalistfoldleft-for-java-programmers/#comment-22605</guid>
		<description>This helped me tell my left from my right...

class FoldDemoTest extends TestCase("folddemo") {
  def f(a:String, b:String):String = {
    "f(" + a + ", " + b + ")"
  }
  val list = List("A", "B", "C")
  
  def testFoldLeft() = {
    val value = list.foldLeft[String]("0")(f)
    assertEquals("f(f(f(0, A), B), C)", value)
  }

  def testFoldRight() = {
    val value = list.foldRight[String]("0")(f)
    assertEquals("f(A, f(B, f(C, 0)))", value)
  }
}</description>
		<content:encoded><![CDATA[<p>This helped me tell my left from my right&#8230;</p>
<p>class FoldDemoTest extends TestCase(&#8221;folddemo&#8221;) {<br />
  def f(a:String, b:String):String = {<br />
    &#8220;f(&#8221; + a + &#8220;, &#8221; + b + &#8220;)&#8221;<br />
  }<br />
  val list = List(&#8221;A&#8221;, &#8220;B&#8221;, &#8220;C&#8221;)</p>
<p>  def testFoldLeft() = {<br />
    val value = list.foldLeft[String](&#8221;0&#8243;)(f)<br />
    assertEquals(&#8221;f(f(f(0, A), B), C)&#8221;, value)<br />
  }</p>
<p>  def testFoldRight() = {<br />
    val value = list.foldRight[String](&#8221;0&#8243;)(f)<br />
    assertEquals(&#8221;f(A, f(B, f(C, 0)))&#8221;, value)<br />
  }<br />
}</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Tony Morris</title>
		<link>http://blog.tmorris.net/scalalistfoldleft-for-java-programmers/#comment-1976</link>
		<dc:creator>Tony Morris</dc:creator>
		<pubDate>Mon, 11 Feb 2008 20:20:01 +0000</pubDate>
		<guid isPermaLink="false">http://blog.tmorris.net/scalalistfoldleft-for-java-programmers/#comment-1976</guid>
		<description>Hi Gavin,
Try this:

&lt;pre&gt;
scala&gt; val alist = 1 :: 2 :: 3 :: Nil // can also be written List(1, 2, 3)
alist: List[Int] = List(1, 2, 3)

scala&gt; alist.foldRight(0)((a,b) =&gt; a + b)
res0: Int = 6

scala&gt; alist.foldRight(0)(_ + _) // better form
res1: Int = 6

scala&gt; alist.foldLeft(0)(_ + _) // best form
res2: Int = 6

scala&gt; (alist :\\ 0)((a,b) =&gt; a + b ) // thanks Ricky
res3: Int = 6
&lt;/pre&gt;</description>
		<content:encoded><![CDATA[<p>Hi Gavin,<br />
Try this:</p>
<pre>
scala> val alist = 1 :: 2 :: 3 :: Nil // can also be written List(1, 2, 3)
alist: List[Int] = List(1, 2, 3)

scala> alist.foldRight(0)((a,b) => a + b)
res0: Int = 6

scala> alist.foldRight(0)(_ + _) // better form
res1: Int = 6

scala> alist.foldLeft(0)(_ + _) // best form
res2: Int = 6

scala> (alist :\\ 0)((a,b) => a + b ) // thanks Ricky
res3: Int = 6
</pre>
]]></content:encoded>
	</item>
	<item>
		<title>By: Gavin Bong</title>
		<link>http://blog.tmorris.net/scalalistfoldleft-for-java-programmers/#comment-1975</link>
		<dc:creator>Gavin Bong</dc:creator>
		<pubDate>Mon, 11 Feb 2008 10:28:13 +0000</pubDate>
		<guid isPermaLink="false">http://blog.tmorris.net/scalalistfoldleft-for-java-programmers/#comment-1975</guid>
		<description>Tony,

I tried to run this on the prompt but couldn't figure out how to call foldLeft/foldRight.

scala&#38;gt; val alist = 1 :: 2 :: 3 :: Nil
alist: List[Int] = List(1, 2, 3)

scala&#38;gt; alist.foldRight( 0, (a,b) =&#38;gt; a + b )
&#38;lt;console&#38;gt;:6: error: wrong number of arguments for method foldRight: (B)((Int, B) =&#38;gt; B)B
       alist.foldRight( 0, (a,b) =&#38;gt; a + b )

scala&#38;gt; ( alist :\ 1 )( (a,b) =&#38;gt; a + b )
res7: Int = 7

What am I doing wrong ?

Thanks</description>
		<content:encoded><![CDATA[<p>Tony,</p>
<p>I tried to run this on the prompt but couldn&#8217;t figure out how to call foldLeft/foldRight.</p>
<p>scala&#38;gt; val alist = 1 :: 2 :: 3 :: Nil<br />
alist: List[Int] = List(1, 2, 3)</p>
<p>scala&#38;gt; alist.foldRight( 0, (a,b) =&#38;gt; a + b )<br />
&#38;lt;console&#38;gt;:6: error: wrong number of arguments for method foldRight: (B)((Int, B) =&#38;gt; B)B<br />
       alist.foldRight( 0, (a,b) =&#38;gt; a + b )</p>
<p>scala&#38;gt; ( alist :\ 1 )( (a,b) =&#38;gt; a + b )<br />
res7: Int = 7</p>
<p>What am I doing wrong ?</p>
<p>Thanks</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Tony Morris</title>
		<link>http://blog.tmorris.net/scalalistfoldleft-for-java-programmers/#comment-1974</link>
		<dc:creator>Tony Morris</dc:creator>
		<pubDate>Mon, 11 Feb 2008 01:35:43 +0000</pubDate>
		<guid isPermaLink="false">http://blog.tmorris.net/scalalistfoldleft-for-java-programmers/#comment-1974</guid>
		<description>"it just seems like it's covering a fairly minor use-case."

I know it's probably hard to "just trust anyone", but I assure you that it is such a major use-case, that I am willing to bet that what you think I think is a severe under-estimate of what I really think, if you know what I mean ;)

You say you have seen instances that could be described as "they were really maps or flatMaps". Do you know that these are specific types of right folds? As are filter, List append, concatenation of Lists and many many more. This is just right folds; what about left? There is reverse, length, sum as you have mentioned and again, *many more*.

In the same Scala course, I have the students write functions in terms of foldRight and foldLeft. For example, here is an exercise, complete this code:

&lt;pre&gt;
def flatMap[A, B](as: List[A], f: A =&gt; List[B]): List[B] = as.foldRight
&lt;/pre&gt;

Here is another one:

&lt;pre&gt;
def map[A, B](as: List[A], f: A =&gt; B): List[B] = as.foldRight
&lt;/pre&gt;

And let's make this clear; we're only talking about Lists here. What about Binary Trees and BTrees and lazy lists and...?

You can hopefully see that it is the complete opposite (if such a thing could exist) of "minor use case" that is the reality.

I hope this helps a bit; again, sorry for the brevity :)

Oh and by the way, that paper you mention is an excellent read for anyone!</description>
		<content:encoded><![CDATA[<p>&#8220;it just seems like it&#8217;s covering a fairly minor use-case.&#8221;</p>
<p>I know it&#8217;s probably hard to &#8220;just trust anyone&#8221;, but I assure you that it is such a major use-case, that I am willing to bet that what you think I think is a severe under-estimate of what I really think, if you know what I mean <img src='http://blog.tmorris.net/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /><br />
You say you have seen instances that could be described as &#8220;they were really maps or flatMaps&#8221;. Do you know that these are specific types of right folds? As are filter, List append, concatenation of Lists and many many more. This is just right folds; what about left? There is reverse, length, sum as you have mentioned and again, *many more*.</p>
<p>In the same Scala course, I have the students write functions in terms of foldRight and foldLeft. For example, here is an exercise, complete this code:</p>
<pre>
def flatMap[A, B](as: List[A], f: A => List[B]): List[B] = as.foldRight
</pre>
<p>Here is another one:</p>
<pre>
def map[A, B](as: List[A], f: A => B): List[B] = as.foldRight
</pre>
<p>And let&#8217;s make this clear; we&#8217;re only talking about Lists here. What about Binary Trees and BTrees and lazy lists and&#8230;?</p>
<p>You can hopefully see that it is the complete opposite (if such a thing could exist) of &#8220;minor use case&#8221; that is the reality.</p>
<p>I hope this helps a bit; again, sorry for the brevity <img src='http://blog.tmorris.net/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /><br />
Oh and by the way, that paper you mention is an excellent read for anyone!</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Dave</title>
		<link>http://blog.tmorris.net/scalalistfoldleft-for-java-programmers/#comment-1973</link>
		<dc:creator>Dave</dc:creator>
		<pubDate>Mon, 11 Feb 2008 01:22:11 +0000</pubDate>
		<guid isPermaLink="false">http://blog.tmorris.net/scalalistfoldleft-for-java-programmers/#comment-1973</guid>
		<description>It's okay for there not to be an easy answer, but it does seem to be a very serious question.   Most of the for-loops I write in Java seem to be maps (85%) or flat-maps (10%), with sums and concatenations filling out most of the remaining 5%.  (Curiously, it's been years since I wrote a while or do-while loop, which are probably some lower-level fixed-point operation, mathematically speaking.)  I get the theory of fold, think I understand the different use-cases of foldRight and foldLeft, get the relation to Monoids, and even fought my way through the bananas/lenses/barbed-wire paper to get some vague idea of catamorphisms, but it just seems like it's covering a fairly minor use-case.</description>
		<content:encoded><![CDATA[<p>It&#8217;s okay for there not to be an easy answer, but it does seem to be a very serious question.   Most of the for-loops I write in Java seem to be maps (85%) or flat-maps (10%), with sums and concatenations filling out most of the remaining 5%.  (Curiously, it&#8217;s been years since I wrote a while or do-while loop, which are probably some lower-level fixed-point operation, mathematically speaking.)  I get the theory of fold, think I understand the different use-cases of foldRight and foldLeft, get the relation to Monoids, and even fought my way through the bananas/lenses/barbed-wire paper to get some vague idea of catamorphisms, but it just seems like it&#8217;s covering a fairly minor use-case.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Tony Morris</title>
		<link>http://blog.tmorris.net/scalalistfoldleft-for-java-programmers/#comment-1972</link>
		<dc:creator>Tony Morris</dc:creator>
		<pubDate>Mon, 11 Feb 2008 01:03:07 +0000</pubDate>
		<guid isPermaLink="false">http://blog.tmorris.net/scalalistfoldleft-for-java-programmers/#comment-1972</guid>
		<description>Hi Dave,
I'm a little apprehensive to answer your question, since the answer is quite deep and I wouldn't want you to think otherwise. I don't quite have the time to answer it in full for now, so I'll just add a little to what Ricky has said:

* Ruby's inject on non-empty lists is called reduce in Scala (you'll find the method on List, Stream, etc.)
* Actually, it is possible to write a sum and concatenation on the scala.List[A] type; it would require an extra argument of type Monoid[A]

Furthermore, to answer your question without providing any explanation whatsoever (I hope you don't mind), the answer is "an awful lot". How many loops have you written in your time? They can all be abstracted to folds (more correctly called catamorphisms) and some can probably even be specialised to other Higher-Order Functions.

Sorry for the brevity in this response. I'll have to think about how I'd tackle answering your (very common!) question. I think it comes about because the true answer to your question is so far removed (i.e. to the opposite extreme) from the intuition of who is typically asking it.</description>
		<content:encoded><![CDATA[<p>Hi Dave,<br />
I&#8217;m a little apprehensive to answer your question, since the answer is quite deep and I wouldn&#8217;t want you to think otherwise. I don&#8217;t quite have the time to answer it in full for now, so I&#8217;ll just add a little to what Ricky has said:</p>
<p>* Ruby&#8217;s inject on non-empty lists is called reduce in Scala (you&#8217;ll find the method on List, Stream, etc.)<br />
* Actually, it is possible to write a sum and concatenation on the scala.List[A] type; it would require an extra argument of type Monoid[A]</p>
<p>Furthermore, to answer your question without providing any explanation whatsoever (I hope you don&#8217;t mind), the answer is &#8220;an awful lot&#8221;. How many loops have you written in your time? They can all be abstracted to folds (more correctly called catamorphisms) and some can probably even be specialised to other Higher-Order Functions.</p>
<p>Sorry for the brevity in this response. I&#8217;ll have to think about how I&#8217;d tackle answering your (very common!) question. I think it comes about because the true answer to your question is so far removed (i.e. to the opposite extreme) from the intuition of who is typically asking it.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Ricky Clarkson</title>
		<link>http://blog.tmorris.net/scalalistfoldleft-for-java-programmers/#comment-1971</link>
		<dc:creator>Ricky Clarkson</dc:creator>
		<pubDate>Mon, 11 Feb 2008 00:54:59 +0000</pubDate>
		<guid isPermaLink="false">http://blog.tmorris.net/scalalistfoldleft-for-java-programmers/#comment-1971</guid>
		<description>Dave,

Summing and stringifying are just the easiest cases to show.  Fold gets used often throughout computing, though most people prefer to use a less abstract version.  Haskell, for instance, has a 'sum' function, which just delegates to foldl.  Ruby has inject, which is more convenient, provided the list is not empty.

Java, C and others have a far less abstract version, the for loop, which is a small subset of what fold can do, if you include foldRight as a fold* - as it can handle folding over infinite lists.  Poor programmers tend to feel more comfortable with this less abstract fold.

* To quickly understand how foldRight might work for an infinite list, if you have an infinite list of booleans, where the first is true and the rest false (or undefined, or unevaluated), you can easily see that folding with &#124;&#124; across those only requires the 1st to be evaluated.</description>
		<content:encoded><![CDATA[<p>Dave,</p>
<p>Summing and stringifying are just the easiest cases to show.  Fold gets used often throughout computing, though most people prefer to use a less abstract version.  Haskell, for instance, has a &#8217;sum&#8217; function, which just delegates to foldl.  Ruby has inject, which is more convenient, provided the list is not empty.</p>
<p>Java, C and others have a far less abstract version, the for loop, which is a small subset of what fold can do, if you include foldRight as a fold* - as it can handle folding over infinite lists.  Poor programmers tend to feel more comfortable with this less abstract fold.</p>
<p>* To quickly understand how foldRight might work for an infinite list, if you have an infinite list of booleans, where the first is true and the rest false (or undefined, or unevaluated), you can easily see that folding with || across those only requires the 1st to be evaluated.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: afsina</title>
		<link>http://blog.tmorris.net/scalalistfoldleft-for-java-programmers/#comment-1969</link>
		<dc:creator>afsina</dc:creator>
		<pubDate>Sun, 10 Feb 2008 23:36:40 +0000</pubDate>
		<guid isPermaLink="false">http://blog.tmorris.net/scalalistfoldleft-for-java-programmers/#comment-1969</guid>
		<description>i find the syntax very confusing.</description>
		<content:encoded><![CDATA[<p>i find the syntax very confusing.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Dave</title>
		<link>http://blog.tmorris.net/scalalistfoldleft-for-java-programmers/#comment-1970</link>
		<dc:creator>Dave</dc:creator>
		<pubDate>Sun, 10 Feb 2008 23:05:50 +0000</pubDate>
		<guid isPermaLink="false">http://blog.tmorris.net/scalalistfoldleft-for-java-programmers/#comment-1970</guid>
		<description>Purely out of curiousity, how often does fold get used over methods other than arithmetic sum and string concatenation?  I can see those being very handy, but I can't easily see many other use cases.  I understand that Scala's type system won't support sum or concat as methods on List (because they only work for certain types of Lists, not all), but if it did, why would I ever use foldLeft?</description>
		<content:encoded><![CDATA[<p>Purely out of curiousity, how often does fold get used over methods other than arithmetic sum and string concatenation?  I can see those being very handy, but I can&#8217;t easily see many other use cases.  I understand that Scala&#8217;s type system won&#8217;t support sum or concat as methods on List (because they only work for certain types of Lists, not all), but if it did, why would I ever use foldLeft?</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Matt Hellige</title>
		<link>http://blog.tmorris.net/scalalistfoldleft-for-java-programmers/#comment-1968</link>
		<dc:creator>Matt Hellige</dc:creator>
		<pubDate>Tue, 15 Jan 2008 17:35:44 +0000</pubDate>
		<guid isPermaLink="false">http://blog.tmorris.net/scalalistfoldleft-for-java-programmers/#comment-1968</guid>
		<description>I agree that this is a really natural way for Java programmers to comprehend a fold. I'd love to see an IDE for Scala (or Haskell, etc.) that allowed selective (and temporary) inlining of higher-order functions so that it would be possible to click on a line of code containing a fold and view/edit it as the expanded loop or recursive definition. This seems like the best of both worlds: easy to view the code in an expanded form when desired, but still avoiding the duplication and error-prone boilerplate.

It might seem like purely a tool for the inexperienced, but I've seen some pretty incomprehensible point-free definitions, and a tool like this might really help encourage the use of higher abstractions.</description>
		<content:encoded><![CDATA[<p>I agree that this is a really natural way for Java programmers to comprehend a fold. I&#8217;d love to see an IDE for Scala (or Haskell, etc.) that allowed selective (and temporary) inlining of higher-order functions so that it would be possible to click on a line of code containing a fold and view/edit it as the expanded loop or recursive definition. This seems like the best of both worlds: easy to view the code in an expanded form when desired, but still avoiding the duplication and error-prone boilerplate.</p>
<p>It might seem like purely a tool for the inexperienced, but I&#8217;ve seen some pretty incomprehensible point-free definitions, and a tool like this might really help encourage the use of higher abstractions.</p>
]]></content:encoded>
	</item>
</channel>
</rss>
