<!-- 
RSS generated by JIRA (4.4#649-r158309) at Sun May 19 18:31:59 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/CLJS-289/CLJS-289.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>[CLJS-289] Represent ast :children as a vector of keys</title>
                <link>http://dev.clojure.org/jira/browse/CLJS-289</link>
                <project id="10040" key="CLJS">ClojureScript</project>
                        <description>&lt;p&gt;See discussion here: &lt;a href=&quot;https://groups.google.com/d/topic/clojure-dev/vZLVKmKX0oc/discussion&quot;&gt;https://groups.google.com/d/topic/clojure-dev/vZLVKmKX0oc/discussion&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Summary: Duplication of ast nodes in various keys and in :children is problematic for some users. In particular, it doesn&apos;t play nicely with printing. A solution is needed which preserves &quot;The AST is data. Period.&quot;&lt;/p&gt;

&lt;p&gt;The attached patch makes no changes to how the sub nodes are currently stored outside of the :children key. Instead, it replaces :children values with a vector of keys into the main ast node. This preserves child ordering and allows a children function to be defined as:&lt;/p&gt;

&lt;p&gt;(defn children &lt;span class=&quot;error&quot;&gt;&amp;#91;ast&amp;#93;&lt;/span&gt;&lt;br/&gt;
  (mapcat #(if (coll? %) % &lt;span class=&quot;error&quot;&gt;&amp;#91;%&amp;#93;&lt;/span&gt;) ((apply juxt (:children ast)) ast)))&lt;/p&gt;

&lt;p&gt;The attached patch has two caveats: 1) Many (but not all?) blocks will now be present in the children hierarchy as &apos;do forms. 2) Interleaved forms are intentionally bugged with respect to ordering. The :children vector for those forms match the actual behavior, not the expected behavior. This can be fixed along with &lt;a href=&quot;http://dev.clojure.org/jira/browse/CLJS-288&quot;&gt;http://dev.clojure.org/jira/browse/CLJS-288&lt;/a&gt;&lt;/p&gt;</description>
                <environment></environment>
            <key id="15497">CLJS-289</key>
            <summary>Represent ast :children as a vector of keys</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="5" iconUrl="http://dev.clojure.org/jira/images/icons/status_resolved.gif">Resolved</status>
                    <resolution id="2">Declined</resolution>
                                <assignee username="-1">Unassigned</assignee>
                                <reporter username="bbloom">Brandon Bloom</reporter>
                        <labels>
                        <label>patch</label>
                        <label>patch,</label>
                    </labels>
                <created>Thu, 31 May 2012 17:51:17 -0500</created>
                <updated>Wed, 29 Aug 2012 00:09:12 -0500</updated>
                    <resolved>Tue, 5 Jun 2012 08:09:05 -0500</resolved>
                                                                    <due></due>
                    <votes>0</votes>
                        <watches>3</watches>
                        <comments>
                    <comment id="28692" author="dnolen" created="Sun, 3 Jun 2012 10:00:41 -0500"  >&lt;p&gt;the result of the discussion did not end with agreement on representing :children as a vector of keys&lt;/p&gt;</comment>
                    <comment id="28694" author="bbloom" created="Sun, 3 Jun 2012 11:24:01 -0500"  >&lt;p&gt;I realize that, but it was one approach suggested and seemed entirely viable, so I tried it. From what I can tell, it seems like a solution that meets all of the criteria that came up during the discussion.&lt;/p&gt;

&lt;p&gt;Did I overlook a requirement?&lt;/p&gt;

&lt;p&gt;Who is currently using :children and could weigh in on whether or not this still meets their needs?&lt;/p&gt;</comment>
                    <comment id="28696" author="jonase" created="Sun, 3 Jun 2012 11:52:00 -0500"  >&lt;p&gt;I&apos;m using :children and I don&apos;t think this patch (currently) meets my needs. At least {:op :let ...} is broken IMO. (something like `(map :init bes)` is missing from the patch) &lt;/p&gt;</comment>
                    <comment id="28697" author="bbloom" created="Sun, 3 Jun 2012 12:09:10 -0500"  >&lt;p&gt;Ah OK, you&apos;re right. It&apos;s the same problem there that I ran into with :statements and analyze-block: There is a pseudo AST node that needs to be traversed down into.&lt;/p&gt;

&lt;p&gt;The easy fix for that here would be to merge {:children &lt;span class=&quot;error&quot;&gt;&amp;#91;:init&amp;#93;&lt;/span&gt;} into each binding, but the binding hash will be missing :op and :form. For analyze-block, I was able to use :op :do and :form (list &apos;do ...), but there isn&apos;t an obvious analogy here without inventing a :binding op or relaxing the requirement for :op and :form.&lt;/p&gt;

&lt;p&gt;Interestingly, each successive binding can be treated as a single nested binding. What if we defined let as a macro which expands to a series of let1 forms? (let &lt;span class=&quot;error&quot;&gt;&amp;#91;x 1 y 2&amp;#93;&lt;/span&gt; (* x y)) --&amp;gt; (let1 &lt;span class=&quot;error&quot;&gt;&amp;#91;x 1&amp;#93;&lt;/span&gt; (let1 &lt;span class=&quot;error&quot;&gt;&amp;#91;y 2&amp;#93;&lt;/span&gt; (* x y))&lt;/p&gt;

&lt;p&gt;That may increase the depth of the AST, but it would really simplify traversal into binding clauses. Each let op would have :name, :init, and children as &lt;span class=&quot;error&quot;&gt;&amp;#91;:init&amp;#93;&lt;/span&gt;.&lt;/p&gt;

&lt;p&gt;In general, it may be worth while to consider doing the same thing with the various analyze-blocks situations, such that &apos;do is the only place multiple statements can occur.&lt;/p&gt;</comment>
                    <comment id="28698" author="bbloom" created="Sun, 3 Jun 2012 12:16:27 -0500"  >&lt;p&gt;Er, I mean: a hypothetical let1 op would have children &lt;span class=&quot;error&quot;&gt;&amp;#91;:init :statements :ret&amp;#93;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;However, if you also expanded the implicit do blocks, you&apos;d be able to simplify to &lt;span class=&quot;error&quot;&gt;&amp;#91;:init :body&amp;#93;&lt;/span&gt; or something like that.&lt;/p&gt;</comment>
                    <comment id="28699" author="bbloom" created="Sun, 3 Jun 2012 12:34:16 -0500"  >&lt;p&gt;Forgive me for repeatedly commenting, but it also occurs to me that you can change &apos;do to a macro which expands to a series of &apos;do2 forms:&lt;/p&gt;

&lt;p&gt;(do x y z) --&amp;gt; (do2 x (do2 y z)) or (do2 (do2 x y) z)&lt;/p&gt;

&lt;p&gt;That do2 op could have children &lt;span class=&quot;error&quot;&gt;&amp;#91;:left :right&amp;#93;&lt;/span&gt; and all other :statements and :ret children could be simplified down to &apos;do2 expansions.&lt;/p&gt;

&lt;p&gt;With that in mind, the children fn becomes simply (defn children &lt;span class=&quot;error&quot;&gt;&amp;#91;ast&amp;#93;&lt;/span&gt; ((apply juxt (:children ast)) ast)) and a lot of analyze and emit code gets much simpler by not having to map over many collections all over the place.&lt;/p&gt;

&lt;p&gt;Kinda a wild idea and probably not the right forum for it, but worth suggesting. Thoughts?&lt;/p&gt;</comment>
                    <comment id="28710" author="dnolen" created="Mon, 4 Jun 2012 11:35:32 -0500"  >&lt;p&gt;I see little benefit to changing core macros. I also see no problem with creating a :binding ast node.&lt;/p&gt;</comment>
                    <comment id="28717" author="jonase" created="Tue, 5 Jun 2012 00:44:40 -0500"  >&lt;p&gt;Every node (i.e. an map with :op, :form and :env keys, called an &quot;Expression Object&quot; in the docstring for analyze) in ClojureScript corresponds to a self-contained expression. A binding form is not self-contained, it is a part of the let expression.&lt;/p&gt;

&lt;p&gt;Another similar example is functions. There is a node {:op :fn ...} but there is no {:op :fn-method} even thou there are maps under the :methods key describing function methods. The same argument goes for this: A function method is not self-contained, it is part of the function and should not be a node.&lt;/p&gt;

&lt;p&gt;The nodes (expression objects) which make up the ClojureScript AST seems to be really well thought out and I would be careful in making the proposed change.&lt;/p&gt;</comment>
                    <comment id="28719" author="dnolen" created="Tue, 5 Jun 2012 08:09:05 -0500"  >&lt;p&gt;Agreed I think it&apos;s far too early to have a ticket for this. Confluence page first.&lt;/p&gt;</comment>
                    <comment id="29283" author="bbloom" created="Wed, 29 Aug 2012 00:09:12 -0500"  >&lt;p&gt;Design page here: &lt;a href=&quot;http://dev.clojure.org/display/design/AST+children&quot;&gt;http://dev.clojure.org/display/design/AST+children&lt;/a&gt;&lt;/p&gt;</comment>
                </comments>
                    <attachments>
                    <attachment id="11276" name="children-keys.patch" size="8838" author="bbloom" created="Thu, 31 May 2012 17:51:17 -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="10001">Code</customfieldvalue>

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