<!-- 
RSS generated by JIRA (4.4#649-r158309) at Sat May 25 06:15:34 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/CLJ-993/CLJ-993.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>[CLJ-993] `range` reducer</title>
                <link>http://dev.clojure.org/jira/browse/CLJ-993</link>
                <project id="10010" key="CLJ">Clojure</project>
                        <description>&lt;p&gt;Rich mentioned in IRC today he&apos;d welcome a reducer implementation of clojure.core/range. Now that I&apos;ve figured out how to do iterate, I figure I&apos;ll knock out range as well by the end of the night. Just opening the issue early to announce my intentions to anyone else interested in doing it.&lt;/p&gt;</description>
                <environment></environment>
            <key id="15431">CLJ-993</key>
            <summary>`range` reducer</summary>
                <type id="4" iconUrl="http://dev.clojure.org/jira/images/icons/improvement.gif">Enhancement</type>
                                <priority id="3" iconUrl="http://dev.clojure.org/jira/images/icons/priority_major.gif">Major</priority>
                    <status id="1" iconUrl="http://dev.clojure.org/jira/images/icons/status_open.gif">Open</status>
                    <resolution id="-1">Unresolved</resolution>
                                <assignee username="-1">Unassigned</assignee>
                                <reporter username="amalloy">Alan Malloy</reporter>
                        <labels>
                    </labels>
                <created>Thu, 10 May 2012 21:47:40 -0500</created>
                <updated>Sat, 18 Aug 2012 19:18:48 -0500</updated>
                                    <version>Release 1.5</version>
                                                        <due></due>
                    <votes>1</votes>
                        <watches>2</watches>
                        <comments>
                    <comment id="28443" author="amalloy" created="Thu, 10 May 2012 22:45:49 -0500"  >&lt;p&gt;Implemented range. A separate commit is attached, making iterate and range also Seqable, since I&apos;m not sure if that&apos;s desired. Apply it or not, as you prefer.&lt;/p&gt;</comment>
                    <comment id="28457" author="jasonjckn" created="Fri, 11 May 2012 11:20:32 -0500"  >&lt;p&gt;Range should be foldable&lt;/p&gt;</comment>
                    <comment id="28462" author="amalloy" created="Fri, 11 May 2012 12:53:50 -0500"  >&lt;p&gt;Yep, so it should. Time for me to dig into the folding implementations!&lt;/p&gt;</comment>
                    <comment id="28464" author="amalloy" created="Fri, 11 May 2012 14:42:20 -0500"  >&lt;p&gt;Should I fold (har har) all of these commits into one? I don&apos;t know what is preferred on JIRA, and I also don&apos;t know whether range/iterate should be seqable or if I should just drop the second commit.&lt;/p&gt;</comment>
                    <comment id="28465" author="richhickey" created="Fri, 11 May 2012 15:21:42 -0500"  >&lt;p&gt;Yes, please merge these together, it&apos;s hard to see otherwise (I can barely read diffs as is &lt;img class=&quot;emoticon&quot; src=&quot;http://dev.clojure.org/jira/images/icons/emoticons/smile.gif&quot; height=&quot;20&quot; width=&quot;20&quot; align=&quot;absmiddle&quot; alt=&quot;&quot; border=&quot;0&quot;/&gt;. range and iterate shouldn&apos;t be novel in reducers, but just enhanced return values of core fns. The enhancement (e.g. protocol extensions) &lt;em&gt;can&lt;/em&gt; come by requiring reducers since it can&apos;t be leveraged without it. Also, I&apos;m not sure how I feel about an allocating protocol for &apos;splittable&apos; - I&apos;ve avoided it thus far.&lt;/p&gt;</comment>
                    <comment id="28466" author="amalloy" created="Fri, 11 May 2012 15:30:02 -0500"  >&lt;p&gt;So you want clojure.core/range to return some object (a Range), which implements Counted and Seqable (but isn&apos;t just a lazy-seq), and then inside of clojure.core.reducers I extend CollReduce and CollFold to that type? Okay, I can do that.&lt;/p&gt;

&lt;p&gt;I don&apos;t quite follow what you mean by an allocating protocol. I see your point that my fold-by-halves which takes a function in is analogous to a protocol with a single function, but it doesn&apos;t allocate anything more than foldvec already does - I just pulled that logic out so that the fork/join fiddly work doesn&apos;t need to be repeated in everything foldable. Do you have an alternative recommendation, or is it just something that makes you uneasy and you&apos;re still thinking about?&lt;/p&gt;</comment>
                    <comment id="28468" author="richhickey" created="Fri, 11 May 2012 15:52:39 -0500"  >&lt;p&gt;While vector-fold allocs subvecs, the halving-fn must return a new vector, for all implementations. It&apos;s ok, I don&apos;t think it&apos;s likely to dominate (since fj needs new closures anyway). Please proceed, but keep range and iterate in core. They are sources, not transformers, and only transformers (which must be different from their seq-based counterparts) must reside in reducers. Thanks!&lt;/p&gt;</comment>
                    <comment id="28470" author="stuart.sierra" created="Fri, 11 May 2012 17:01:30 -0500"  >&lt;p&gt;One big patch file is preferred, although that file may contain multiple commits if that makes the intent clearer.&lt;/p&gt;

&lt;p&gt;When adding a patch, update the description of the ticket to indicate which file is the most recent. Leave old patch files around for historical reference.&lt;/p&gt;</comment>
                    <comment id="28472" author="amalloy" created="Fri, 11 May 2012 21:00:47 -0500"  >&lt;p&gt;It&apos;s looking harder than I expected to move iterate and range into core.clj. My plan was to just have them implement Seqable, which is easy enough, but currently they are actually instances of ISeq, because they inherit from LazySeq. A bunch of code all over the place (eg, to print them in the repl) depends on them being ISeq, so I can&apos;t just ignore it. To implement all of these methods (around thirty) would take a large amount of code, which can&apos;t easily be shared between Iteration, Range, and any future reducible sources that are added to core.clj.&lt;/p&gt;

&lt;p&gt;I could write a macro like (defseq Range &lt;span class=&quot;error&quot;&gt;&amp;#91;start end step&amp;#93;&lt;/span&gt; Counted (count &lt;span class=&quot;error&quot;&gt;&amp;#91;this&amp;#93;&lt;/span&gt; ...) ...) which takes normal deftype args and also adds in implementations for ISeq, Collection, and so forth in terms of (.seq this), which will be a LazySeq. However, this seems like a somewhat awkward approach that I would be a little embarrassed to clutter up core.clj with. If anyone has a better alternative I will be pleased to hear it. In the mean time, I will go ahead with this macro implementation, in case it turns out to be the best choice.&lt;/p&gt;</comment>
                    <comment id="28473" author="amalloy" created="Fri, 11 May 2012 23:52:28 -0500"  >&lt;p&gt;&amp;#8211; This patch subsumes all previous patches to this issue and to &lt;a href=&quot;http://dev.clojure.org/jira/browse/CLJ-992&quot; title=&quot;`iterate` reducer&quot;&gt;CLJ-992&lt;/a&gt; &amp;#8211;&lt;/p&gt;

&lt;p&gt;In order to create an object which is both a lazy sequence and a&lt;br/&gt;
reducible source, I needed to add a macro named defseq to core_deftype.&lt;br/&gt;
It is basically a reimplementation of clojure.lang.LazySeq as a clojure&lt;br/&gt;
macro, so that I can &quot;mix in&quot; lazy-sequence functions into a new class&lt;br/&gt;
with whatever methods are needed for reducing and folding.&lt;/p&gt;

&lt;p&gt;If we wanted, we could use this macro to implement lazy-seq in clojure instead of in java, but that&apos;s unrelated so I didn&apos;t do that in this patch.&lt;/p&gt;

&lt;p&gt;As noted in a previous comment, defseq may not be the right approach, but this works until something better is suggested.&lt;/p&gt;</comment>
                    <comment id="28474" author="amalloy" created="Fri, 11 May 2012 23:58:40 -0500"  >&lt;p&gt;I accidentally included an implementation of drop-while in this patch, which I was playing around with to make sure I understood how this all works. I guess I&apos;ll leave it in for the moment, since it works and is useful, but I can remove it, or move it to a new JIRA ticket, if it&apos;s not wanted at this time.&lt;/p&gt;</comment>
                    <comment id="28479" author="richhickey" created="Sat, 12 May 2012 10:52:52 -0500"  >&lt;p&gt;Ok, I think this patch is officially off the rails. There must be a better way. Let&apos;s start with: touching core/deftype and reimplementing lazy-seq as a macro are off the table. The return value of range doesn&apos;t have to &lt;em&gt;be&lt;/em&gt; a LazySeq, it has to be a lazy seq, .e.g. implement ISeq (7 methods, not 30) which it can do by farming out to its existing impl. It can also implement some new interface for use by the reducer logic. There is also still clojure.lang.Range still there, which is another approach. Please take an extremely conservative approach in these things.&lt;/p&gt;</comment>
                    <comment id="28480" author="amalloy" created="Sat, 12 May 2012 17:53:26 -0500"  >&lt;p&gt;Okay, thanks for the feedback - I&apos;m glad I went into that last patch knowing it was probably wrong &lt;img class=&quot;emoticon&quot; src=&quot;http://dev.clojure.org/jira/images/icons/emoticons/smile.gif&quot; height=&quot;20&quot; width=&quot;20&quot; align=&quot;absmiddle&quot; alt=&quot;&quot; border=&quot;0&quot;/&gt;. I thought I would need to implement the java collection interfaces that LazySeq does, eg java.util.List, in order to avoid breaking interop functions like (defn range-list &lt;span class=&quot;error&quot;&gt;&amp;#91;n&amp;#93;&lt;/span&gt; (ArrayList. (range n))). If it&apos;s sufficient to implement ISeq (and thus IPersistentCollection), then that&apos;s pretty manageable. &lt;/p&gt;

&lt;p&gt;It&apos;s still an unpleasant chunk of boilerplate for each new source, though; would you welcome a macro like defseq if I didn&apos;t put it in core_deftype? If so, it seems like it might as well implement the interop interfaces; if not, I can skip them and implement the 7 (isn&apos;t it more like 9?) methods in ISeq, IPersistentCollection, and Seqable for each new source type.&lt;/p&gt;

&lt;p&gt;Thanks for pointing out clojure.lang.Range to me - I didn&apos;t realize we had it there. Of course with implementation inheritance it would be easy to make Range, Iteration, etc inherit from LazySeq and just extend protocols from them. But that means moving functionality out of clojure and into java, which I didn&apos;t think we&apos;d want to do.&lt;/p&gt;

&lt;p&gt;I&apos;ll put together a patch that just implements ISeq by hand for both of these new types, and attach it probably later today.&lt;/p&gt;</comment>
                    <comment id="28481" author="amalloy" created="Sat, 12 May 2012 19:49:45 -0500"  >&lt;p&gt;So I&apos;ve written a patch that implements ISeq, but not the java Collections interfaces, and it mostly works but there are definitely assumptions in some parts of clojure.core and clojure.lang that assume seqs are Collections. The most obvious to me (ie, it shows up when running mvn test) is RT/toArray - it tests for Collection, but never for ISeq, implying that it&apos;s not willing to handle an ISeq that is not also a collection. Functions which rely on toArray (eg to-array and vec) now fail.&lt;/p&gt;

&lt;p&gt;This patch subsumes all previous patches on this issue, but is not suitable for application because it leaves some failing tests behind - it is intended only for intermediate feedback.&lt;/p&gt;</comment>
                    <comment id="28488" author="richhickey" created="Sun, 13 May 2012 08:50:39 -0500"  >&lt;p&gt;It would be a great help if, time permitting, you could please write up the issues, challenges and options you&apos;ve discovered somewhere on the dev wiki (even a simple table would be fantastic). I realize this has been a challenging task, and at this point perhaps we should opt for the more modest reducers/range and reducers/iterate and leave the two worlds separate. I&apos;d like at some point to unify range, as there are many extant ranges it would be nice to be able to fold, as we can extant vectors.&lt;/p&gt;</comment>
                    <comment id="28489" author="jasonjckn" created="Sun, 13 May 2012 09:24:04 -0500"  >&lt;p&gt;Should r/range return something Seqable and Counted?&lt;/p&gt;

&lt;p&gt;If so, I&apos;ll do the same for r/repeat.&lt;/p&gt;</comment>
                    <comment id="28496" author="amalloy" created="Sun, 13 May 2012 13:59:42 -0500"  >&lt;p&gt;I&apos;ve sketched out a description of the issues and options. I&apos;m not very familiar with the dev wiki and couldn&apos;t figure out where was the right place to put this. &quot;release.next&quot; seems to still be about 1.4 issues, and I don&apos;t know if it&apos;s &quot;appropriate&quot; to create a whole new category for this. It&apos;s available &lt;a href=&quot;https://gist.github.com/1586b2460329dde1c374&quot;&gt;as a gist&lt;/a&gt; until a better home can be found for it.&lt;/p&gt;</comment>
                    <comment id="28575" author="amalloy" created="Wed, 23 May 2012 19:54:24 -0500"  >&lt;p&gt;Here&apos;s a single patch summing up the state Rich suggested &quot;rolling back&quot; to: separate r/range and r/iterate functions. I haven&apos;t heard any feedback since doing the writeup Rich asked for, so am not making any further progress at the moment; if something other than this patch is desired just let me know.&lt;/p&gt;</comment>
                    <comment id="29141" author="richhickey" created="Tue, 14 Aug 2012 14:07:11 -0500"  >&lt;p&gt;I prefer not to see the use of extend like this for new types. Perhaps this code is too DRY? Also, it does a lot in one patch which makes it hard to parse and accept. This adds Range, switches impl of vector folds etc. Can it be broken up into separate tickets that do each step that builds on the previous, e.g. one ticket could be: capture vector fold impl for reuse by similar things.&lt;/p&gt;</comment>
                    <comment id="29225" author="amalloy" created="Sat, 18 Aug 2012 18:19:54 -0500"  >&lt;p&gt;Okay, I should be able to split it up over the weekend. I&apos;ll also see about converting fold-by-halves into a function that is used by Range/Vector, rather than a function that gets extended onto them.&lt;/p&gt;</comment>
                    <comment id="29227" author="amalloy" created="Sat, 18 Aug 2012 19:18:48 -0500"  >&lt;p&gt;As requested, I have split up the large patch on this issue into four smaller tickets. The other three are: &lt;a href=&quot;http://dev.clojure.org/jira/browse/CLJ-1045&quot; title=&quot;Generalize/refactor implementation of PersistentVector/coll-fold&quot;&gt;CLJ-1045&lt;/a&gt;, &lt;a href=&quot;http://dev.clojure.org/jira/browse/CLJ-1046&quot; title=&quot;Drop-while as a reducer&quot;&gt;CLJ-1046&lt;/a&gt;, and &lt;a href=&quot;http://dev.clojure.org/jira/browse/CLJ-992&quot; title=&quot;`iterate` reducer&quot;&gt;CLJ-992&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://dev.clojure.org/jira/browse/CLJ-1045&quot; title=&quot;Generalize/refactor implementation of PersistentVector/coll-fold&quot;&gt;CLJ-1045&lt;/a&gt; contains the implementation of fold-by-halves, and as such this patch cannot be applied until &lt;a href=&quot;http://dev.clojure.org/jira/browse/CLJ-1045&quot; title=&quot;Generalize/refactor implementation of PersistentVector/coll-fold&quot;&gt;CLJ-1045&lt;/a&gt; is accepted. This ticket does not depend on the other two, but there will be minor merge conflicts if this is merged before them.&lt;/p&gt;</comment>
                </comments>
                    <attachments>
                    <attachment id="11246" name="0001-CLJ-993-implement-range-and-iterate-as-reducers.patch" size="7633" author="amalloy" created="Wed, 23 May 2012 19:54:24 -0500" />
                    <attachment id="11206" name="0001-CLJ-993-implement-range-and-iterate-as-reducers.patch" size="15264" author="amalloy" created="Fri, 11 May 2012 23:52:28 -0500" />
                    <attachment id="11193" name="0001-CLJ-993-implement-range-as-a-reducer.patch" size="2941" author="amalloy" created="Thu, 10 May 2012 22:45:49 -0500" />
                    <attachment id="11194" name="0002-Make-iterate-and-range-Seqable.patch" size="1193" author="amalloy" created="Thu, 10 May 2012 22:45:49 -0500" />
                    <attachment id="11203" name="0003-Implement-fold-for-Range-objects.patch" size="6204" author="amalloy" created="Fri, 11 May 2012 14:40:36 -0500" />
                    <attachment id="11210" name="just-iseq.patch" size="11691" author="amalloy" created="Sat, 12 May 2012 19:49:45 -0500" />
                    <attachment id="11447" name="range-reducer.patch" size="3740" author="amalloy" created="Sat, 18 Aug 2012 19:18:48 -0500" />
                </attachments>
            <subtasks>
        </subtasks>
                <customfields>
                                                                                            <customfield id="customfield_10010" key="com.pyxis.greenhopper.jira:gh-global-rank">
                <customfieldname>Global Rank</customfieldname>
                <customfieldvalues>
                    
                </customfieldvalues>
            </customfield>
                                            <customfield id="customfield_10000" key="com.atlassian.jira.plugin.system.customfieldtypes:select">
                <customfieldname>Patch</customfieldname>
                <customfieldvalues>
                        <customfieldvalue key="10002">Code and Test</customfieldvalue>

                </customfieldvalues>
            </customfield>
                                                                                        </customfields>
    </item>
</channel>
</rss>