<?xml version="1.0" encoding="UTF-8"?><!-- generator="wordpress/2.0.12-alpha" -->
<rss version="2.0" 
	xmlns:content="http://purl.org/rss/1.0/modules/content/">
<channel>
	<title>Comments on: Folds and continuation-passing-style</title>
	<link>http://www.lshift.net/blog/2007/06/11/folds-and-continuation-passing-style</link>
	<description>What happens at LShift</description>
	<pubDate>Fri, 21 Nov 2008 21:06:02 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.0.12-alpha</generator>

	<item>
		<title>by: matthew</title>
		<link>http://www.lshift.net/blog/2007/06/11/folds-and-continuation-passing-style#comment-61730</link>
		<pubDate>Sat, 16 Jun 2007 20:48:58 +0000</pubDate>
		<guid>http://www.lshift.net/blog/2007/06/11/folds-and-continuation-passing-style#comment-61730</guid>
					<description>&lt;p&gt;Yes, I think you're right. The problem is that for a foldr, it's trivial to take the head of the list and apply the operator between the head and the tail of the last. With a foldl, you need to do the inverse: finding the last elem and applying the operator between the last elem and the inits. But in order to find the last elem you'll have to traverse the list.&lt;/p&gt;

&lt;p&gt;It makes me wonder whether the views (Wadler, but also recently has reappeared in the dependently typed stuff) of cons as snoc would give a better angle on this. Also, maybe the amortized unit cost queues stuff would better suit this as a foldl on the whole queue is a foldr on the "reading" side followed by a foldl on the "writing" side - so long as you typically shortcut before needing the /other/ list, you're laughing.&lt;/p&gt;
</description>
		<content:encoded><![CDATA[<p>Yes, I think you&#8217;re right. The problem is that for a foldr, it&#8217;s trivial to take the head of the list and apply the operator between the head and the tail of the last. With a foldl, you need to do the inverse: finding the last elem and applying the operator between the last elem and the inits. But in order to find the last elem you&#8217;ll have to traverse the list.</p>
<p>It makes me wonder whether the views (Wadler, but also recently has reappeared in the dependently typed stuff) of cons as snoc would give a better angle on this. Also, maybe the amortized unit cost queues stuff would better suit this as a foldl on the whole queue is a foldr on the &#8220;reading&#8221; side followed by a foldl on the &#8220;writing&#8221; side - so long as you typically shortcut before needing the /other/ list, you&#8217;re laughing.</p>
]]></content:encoded>
				</item>
	<item>
		<title>by: tonyg</title>
		<link>http://www.lshift.net/blog/2007/06/11/folds-and-continuation-passing-style#comment-61714</link>
		<pubDate>Sat, 16 Jun 2007 16:31:35 +0000</pubDate>
		<guid>http://www.lshift.net/blog/2007/06/11/folds-and-continuation-passing-style#comment-61714</guid>
					<description>&lt;p&gt;Sure, the kons operator will shortcut - but the left-fold will still traverse the entire list, won't it? If that's true, then even a shortcutting kons operator doesn't help terminate left-folds early.&lt;/p&gt;
</description>
		<content:encoded><![CDATA[<p>Sure, the kons operator will shortcut - but the left-fold will still traverse the entire list, won&#8217;t it? If that&#8217;s true, then even a shortcutting kons operator doesn&#8217;t help terminate left-folds early.</p>
]]></content:encoded>
				</item>
	<item>
		<title>by: matthew</title>
		<link>http://www.lshift.net/blog/2007/06/11/folds-and-continuation-passing-style#comment-61705</link>
		<pubDate>Sat, 16 Jun 2007 14:36:04 +0000</pubDate>
		<guid>http://www.lshift.net/blog/2007/06/11/folds-and-continuation-passing-style#comment-61705</guid>
					<description>&lt;p&gt;Tony, that's slightly a trick question.&lt;/p&gt;

&lt;p&gt;foldr works left to right, and &#124;&#124; shortcuts on the left, thus all is well. foldl works right to left, so if you have operators that shortcut to the right then yes, the combination of said operator with foldl would shortcut as you desire.&lt;/p&gt;
</description>
		<content:encoded><![CDATA[<p>Tony, that&#8217;s slightly a trick question.</p>
<p>foldr works left to right, and || shortcuts on the left, thus all is well. foldl works right to left, so if you have operators that shortcut to the right then yes, the combination of said operator with foldl would shortcut as you desire.</p>
]]></content:encoded>
				</item>
	<item>
		<title>by: tonyg</title>
		<link>http://www.lshift.net/blog/2007/06/11/folds-and-continuation-passing-style#comment-61623</link>
		<pubDate>Fri, 15 Jun 2007 17:13:19 +0000</pubDate>
		<guid>http://www.lshift.net/blog/2007/06/11/folds-and-continuation-passing-style#comment-61623</guid>
					<description>&lt;p&gt;Matthew, that's true for right folds - what about left folds?&lt;/p&gt;
</description>
		<content:encoded><![CDATA[<p>Matthew, that&#8217;s true for right folds - what about left folds?</p>
]]></content:encoded>
				</item>
	<item>
		<title>by: matthew</title>
		<link>http://www.lshift.net/blog/2007/06/11/folds-and-continuation-passing-style#comment-61616</link>
		<pubDate>Fri, 15 Jun 2007 16:18:23 +0000</pubDate>
		<guid>http://www.lshift.net/blog/2007/06/11/folds-and-continuation-passing-style#comment-61616</guid>
					<description>&lt;p&gt;In defense of Haskell (not that it was really being attacked at all), I'd probably say that the laziness gets you short circuiting for free when you need it. For example, the definition of "or" (which is &#124;&#124; throughout a list):&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;or    =  foldr (&#124;&#124;) False

True  &#124;&#124; _ =  True
False &#124;&#124; x =  x
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And it works happily on infinite lists:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;Prelude&#62; or (True: repeat False)
True
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;(sheesh, I hope this code doesn't get mangled up...)&lt;/p&gt;
</description>
		<content:encoded><![CDATA[<p>In defense of Haskell (not that it was really being attacked at all), I&#8217;d probably say that the laziness gets you short circuiting for free when you need it. For example, the definition of &#8220;or&#8221; (which is || throughout a list):</p>
<pre><code>or    =  foldr (||) False

True  || _ =  True
False || x =  x
</code></pre>
<p>And it works happily on infinite lists:</p>
<pre><code>Prelude&gt; or (True: repeat False)
True
</code></pre>
<p>(sheesh, I hope this code doesn&#8217;t get mangled up&#8230;)</p>
]]></content:encoded>
				</item>
	<item>
		<title>by: tonyg</title>
		<link>http://www.lshift.net/blog/2007/06/11/folds-and-continuation-passing-style#comment-61507</link>
		<pubDate>Thu, 14 Jun 2007 11:43:20 +0000</pubDate>
		<guid>http://www.lshift.net/blog/2007/06/11/folds-and-continuation-passing-style#comment-61507</guid>
					<description>&lt;p&gt;Good question.&lt;/p&gt;

&lt;p&gt;Languages I know of that guarantee proper tail calls (it's not really an optimisation, it's more of a correctness thing ;-) ): Scheme, SML, O'Caml, Haskell. Languages that should, but don't: Smalltalk, Javascript.&lt;/p&gt;

&lt;p&gt;Of the properly tail-recursive languages above, only Scheme offers first-class continuations. SML/NJ has an implementation-specific extension for them. Haskell lets you work in the continuation monad for some parts of your program but provides no general continuation-reification operator.&lt;/p&gt;

&lt;p&gt;Even in Scheme, there can be tradeoffs involved in using call/cc - some implementations make it very expensive, for instance. Sometimes explicit CPS just seems to be the Right Thing, even though call/cc is available.&lt;/p&gt;
</description>
		<content:encoded><![CDATA[<p>Good question.</p>
<p>Languages I know of that guarantee proper tail calls (it&#8217;s not really an optimisation, it&#8217;s more of a correctness thing ;-) ): Scheme, SML, O&#8217;Caml, Haskell. Languages that should, but don&#8217;t: Smalltalk, Javascript.</p>
<p>Of the properly tail-recursive languages above, only Scheme offers first-class continuations. SML/NJ has an implementation-specific extension for them. Haskell lets you work in the continuation monad for some parts of your program but provides no general continuation-reification operator.</p>
<p>Even in Scheme, there can be tradeoffs involved in using call/cc - some implementations make it very expensive, for instance. Sometimes explicit CPS just seems to be the Right Thing, even though call/cc is available.</p>
]]></content:encoded>
				</item>
	<item>
		<title>by: Holger</title>
		<link>http://www.lshift.net/blog/2007/06/11/folds-and-continuation-passing-style#comment-61499</link>
		<pubDate>Thu, 14 Jun 2007 09:58:33 +0000</pubDate>
		<guid>http://www.lshift.net/blog/2007/06/11/folds-and-continuation-passing-style#comment-61499</guid>
					<description>&lt;p&gt;Ah, I see.  Yes indeed that is more general.  &lt;/p&gt;

&lt;p&gt;But out of curiosity:  How many languages actually guarantee the tail call optimisation needed to make the explicit CPS coding feasible?  And how many of those do not offer continuations?&lt;/p&gt;
</description>
		<content:encoded><![CDATA[<p>Ah, I see.  Yes indeed that is more general.  </p>
<p>But out of curiosity:  How many languages actually guarantee the tail call optimisation needed to make the explicit CPS coding feasible?  And how many of those do not offer continuations?</p>
]]></content:encoded>
				</item>
	<item>
		<title>by: tonyg</title>
		<link>http://www.lshift.net/blog/2007/06/11/folds-and-continuation-passing-style#comment-61472</link>
		<pubDate>Wed, 13 Jun 2007 16:36:08 +0000</pubDate>
		<guid>http://www.lshift.net/blog/2007/06/11/folds-and-continuation-passing-style#comment-61472</guid>
					<description>&lt;p&gt;@Holger: You're right, and this is the traditional way of exiting (for instance) a for-each or fold loop early in Scheme. However, what if there are no first-class continuations, no call/cc? At that point, explicit reification of the continuations involved, via the CPS foldl, becomes necessary.&lt;/p&gt;
</description>
		<content:encoded><![CDATA[<p>@Holger: You&#8217;re right, and this is the traditional way of exiting (for instance) a for-each or fold loop early in Scheme. However, what if there are no first-class continuations, no call/cc? At that point, explicit reification of the continuations involved, via the CPS foldl, becomes necessary.</p>
]]></content:encoded>
				</item>
	<item>
		<title>by: matthias</title>
		<link>http://www.lshift.net/blog/2007/06/11/folds-and-continuation-passing-style#comment-61469</link>
		<pubDate>Wed, 13 Jun 2007 12:31:38 +0000</pubDate>
		<guid>http://www.lshift.net/blog/2007/06/11/folds-and-continuation-passing-style#comment-61469</guid>
					<description>&lt;p&gt;See also Oleg Kiselyov's work on &lt;a href="http://okmij.org/ftp/Computation/Continuations.html#enumerator-stream" rel="nofollow"&gt;the best collection traversal interface&lt;/a&gt;, which, amongst other things, features a "left fold enumerator supporting a premature termination".&lt;/p&gt;
</description>
		<content:encoded><![CDATA[<p>See also Oleg Kiselyov&#8217;s work on <a href="http://okmij.org/ftp/Computation/Continuations.html#enumerator-stream" rel="nofollow">the best collection traversal interface</a>, which, amongst other things, features a &#8220;left fold enumerator supporting a premature termination&#8221;.</p>
]]></content:encoded>
				</item>
	<item>
		<title>by: Holger</title>
		<link>http://www.lshift.net/blog/2007/06/11/folds-and-continuation-passing-style#comment-61467</link>
		<pubDate>Wed, 13 Jun 2007 12:02:35 +0000</pubDate>
		<guid>http://www.lshift.net/blog/2007/06/11/folds-and-continuation-passing-style#comment-61467</guid>
					<description>&lt;p&gt;But is it necessary to put the continuation code in the folding function?  You could just use the continuations where you need it, e.g. a short-cicuited contains? can use the standard foldl thus:&lt;/p&gt;

&lt;p&gt;(define (contains? predicate val elements)
  (call/cc
   (lambda (cont)
     (foldl (lambda (elt acc)
              (if (predicate elt val)
                  (cont #t)
                  #f))
            #f
            elements))))&lt;/p&gt;
</description>
		<content:encoded><![CDATA[<p>But is it necessary to put the continuation code in the folding function?  You could just use the continuations where you need it, e.g. a short-cicuited contains? can use the standard foldl thus:</p>
<p>(define (contains? predicate val elements)<br />
  (call/cc<br />
   (lambda (cont)<br />
     (foldl (lambda (elt acc)<br />
              (if (predicate elt val)<br />
                  (cont #t)<br />
                  #f))<br />
            #f<br />
            elements))))</p>
]]></content:encoded>
				</item>
</channel>
</rss>
