<!-- 
RSS generated by JIRA (4.4#649-r158309) at Thu May 23 22:02:14 CDT 2013

It is possible to restrict the fields that are returned in this document by specifying the 'field' parameter in your request.
For example, to request only the issue key and summary add field=key&field=summary to the URL of your request.
For example:
http://dev.clojure.org/jira/si/jira.issueviews:issue-xml/ALGOM-5/ALGOM-5.xml?field=key&field=summary
-->
<rss version="0.92" >
<channel>
    <title>Clojure JIRA</title>
    <link>http://dev.clojure.org/jira</link>
    <description>This file is an XML representation of an issue</description>
    <language>en-us</language>    <build-info>
        <version>4.4</version>
        <build-number>649</build-number>
        <build-date>25-07-2011</build-date>
    </build-info>

<item>
            <title>[ALGOM-5] continuation monad can easily overflow stack</title>
                <link>http://dev.clojure.org/jira/browse/ALGOM-5</link>
                <project id="10072" key="ALGOM">algo.monads</project>
                        <description>&lt;p&gt;The continuation monad uses tail calls, and because they aren&apos;t optimized out it&apos;s vulnerable to stack overflows for large computations:&lt;/p&gt;

&lt;p&gt;;; there is a function clojure.algo.monads/m-reduce, but it has a&lt;br/&gt;
;; wierdly unuseful type.&lt;br/&gt;
(defmonadfn fold-m&lt;br/&gt;
  &lt;span class=&quot;error&quot;&gt;&amp;#91;f a xs&amp;#93;&lt;/span&gt; (reduce (fn &lt;span class=&quot;error&quot;&gt;&amp;#91;macc x&amp;#93;&lt;/span&gt; (m-bind macc #(f % x))) (m-result a) xs))&lt;/p&gt;

&lt;p&gt;(defn add &lt;span class=&quot;error&quot;&gt;&amp;#91;s&amp;#93;&lt;/span&gt;&lt;br/&gt;
  (run-cont&lt;br/&gt;
   (with-monad cont-m&lt;br/&gt;
     (call-cc&lt;br/&gt;
      (fn &lt;span class=&quot;error&quot;&gt;&amp;#91;k&amp;#93;&lt;/span&gt;&lt;br/&gt;
        (fold-m (fn &lt;span class=&quot;error&quot;&gt;&amp;#91;a n&amp;#93;&lt;/span&gt;&lt;br/&gt;
                  (if (== n 8888) (k 1)&lt;br/&gt;
                      (m-result (+ a n))))&lt;br/&gt;
                0 s))))))&lt;/p&gt;

&lt;p&gt;(add (range 1 10000)) ;; stack overflow&lt;/p&gt;


&lt;p&gt;Can be worked around with a trampoline:&lt;/p&gt;


&lt;p&gt;(defmonad cont-tramp-m&lt;br/&gt;
  [m-result m-result-cont&lt;br/&gt;
   m-bind m-bind-cont])&lt;/p&gt;

&lt;p&gt;(defn call-cc-tramp &lt;span class=&quot;error&quot;&gt;&amp;#91;f&amp;#93;&lt;/span&gt;&lt;br/&gt;
  (fn &lt;span class=&quot;error&quot;&gt;&amp;#91;c&amp;#93;&lt;/span&gt; [(f (fn &lt;span class=&quot;error&quot;&gt;&amp;#91;v&amp;#93;&lt;/span&gt; (fn &lt;span class=&quot;error&quot;&gt;&amp;#91;_&amp;#93;&lt;/span&gt; &lt;span class=&quot;error&quot;&gt;&amp;#91;c v ::cont&amp;#93;&lt;/span&gt;))) c ::cont]))&lt;/p&gt;

&lt;p&gt;(defn run-cont-tramp &lt;span class=&quot;error&quot;&gt;&amp;#91;cont&amp;#93;&lt;/span&gt;&lt;br/&gt;
  (loop &lt;span class=&quot;error&quot;&gt;&amp;#91;cv (cont identity)&amp;#93;&lt;/span&gt;&lt;br/&gt;
    (if (and (vector? cv)&lt;br/&gt;
             (= ::cont (nth cv 2)))&lt;br/&gt;
      (recur ((first cv) (second cv)))&lt;br/&gt;
      cv)))&lt;/p&gt;

&lt;p&gt;(defn add2 &lt;span class=&quot;error&quot;&gt;&amp;#91;s&amp;#93;&lt;/span&gt;&lt;br/&gt;
  (run-cont-tramp&lt;br/&gt;
   (with-monad cont-tramp-m&lt;br/&gt;
     (call-cc-tramp&lt;br/&gt;
      (fn &lt;span class=&quot;error&quot;&gt;&amp;#91;k&amp;#93;&lt;/span&gt;&lt;br/&gt;
        (fold-m (fn &lt;span class=&quot;error&quot;&gt;&amp;#91;a n&amp;#93;&lt;/span&gt;&lt;br/&gt;
                  (if (= n 8888)&lt;br/&gt;
                    (k 1)&lt;br/&gt;
                    (m-result (+ a n))))&lt;br/&gt;
                0 s))))))&lt;/p&gt;

&lt;p&gt;(add2 (range 1 1000000)) ;; -&amp;gt; 1&lt;/p&gt;</description>
                <environment></environment>
            <key id="15688">ALGOM-5</key>
            <summary>continuation monad can easily overflow stack</summary>
                <type id="1" iconUrl="http://dev.clojure.org/jira/images/icons/bug.gif">Defect</type>
                                <priority id="4" iconUrl="http://dev.clojure.org/jira/images/icons/priority_minor.gif">Minor</priority>
                    <status id="1" iconUrl="http://dev.clojure.org/jira/images/icons/status_open.gif">Open</status>
                    <resolution id="-1">Unresolved</resolution>
                                <assignee username="khinsen">Konrad Hinsen</assignee>
                                <reporter username="wolfson">ben wolfson</reporter>
                        <labels>
                    </labels>
                <created>Mon, 10 Sep 2012 11:51:56 -0500</created>
                <updated>Mon, 10 Sep 2012 12:01:47 -0500</updated>
                                                                            <due></due>
                    <votes>0</votes>
                        <watches>0</watches>
                        <comments>
                    <comment id="29418" author="wolfson" created="Mon, 10 Sep 2012 12:01:47 -0500"  >&lt;p&gt;I neglected to include m-result-cont and m-bind-cont for the cont-tramp-m call!&lt;/p&gt;

&lt;p&gt;(defn m-result-cont &lt;span class=&quot;error&quot;&gt;&amp;#91;v&amp;#93;&lt;/span&gt; (fn &lt;span class=&quot;error&quot;&gt;&amp;#91;c&amp;#93;&lt;/span&gt; &lt;span class=&quot;error&quot;&gt;&amp;#91;c v ::cont&amp;#93;&lt;/span&gt;))&lt;/p&gt;

&lt;p&gt;(defn m-bind-cont &lt;span class=&quot;error&quot;&gt;&amp;#91;mv f&amp;#93;&lt;/span&gt; (fn &lt;span class=&quot;error&quot;&gt;&amp;#91;c&amp;#93;&lt;/span&gt; [mv (fn &lt;span class=&quot;error&quot;&gt;&amp;#91;v&amp;#93;&lt;/span&gt; &lt;span class=&quot;error&quot;&gt;&amp;#91;(f v) c ::cont &amp;#93;&lt;/span&gt;) ::cont]))&lt;/p&gt;</comment>
                </comments>
                    <attachments>
                </attachments>
            <subtasks>
        </subtasks>
                <customfields>
                                                                                            <customfield id="customfield_10010" key="com.pyxis.greenhopper.jira:gh-global-rank">
                <customfieldname>Global Rank</customfieldname>
                <customfieldvalues>
                    
                </customfieldvalues>
            </customfield>
                                                                                                            </customfields>
    </item>
</channel>
</rss>