<!-- 
RSS generated by JIRA (4.4#649-r158309) at Wed Jun 19 11:12:10 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-369/CLJS-369.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-369] gensyms break re-analyze; prevents variable shadowing analysis</title>
                <link>http://dev.clojure.org/jira/browse/CLJS-369</link>
                <project id="10040" key="CLJS">ClojureScript</project>
                        <description>&lt;p&gt;From my email discussion with dnolon before making this patch:&lt;/p&gt;

&lt;p&gt;The current analyzer does some trickery to prepare for emitting to JavaScript. Among this trickery is gensyms for locals (including &quot;this&quot;), the new $ prefix on some namespaces, uniqify on parameters, and more. This must be mildly annoying for people writing alternate compiler backends, but for the most part non-blocking because &lt;b&gt;fewer&lt;/b&gt; symbol collisions should never be an additional problem for a target language with different symbol resolution rules. &lt;/p&gt;

&lt;p&gt;&lt;span class=&quot;error&quot;&gt;&amp;#91;snip lots more text&amp;#93;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;Consider what an ANF transform would look like for the :let form:&lt;/p&gt;

&lt;div class=&quot;code panel&quot; style=&quot;border-width: 1px;&quot;&gt;&lt;div class=&quot;codeContent panelContent&quot;&gt;
&lt;pre class=&quot;code-java&quot;&gt;(defmethod anf :let
  [{:keys [env bindings statements ret form] :as ast}]
  (let [bindings (mapcat (fn [{:keys [sym init] :as binding}]
                           [name (anf init)])
                         bindings)
        body-env (-&amp;gt; bindings last :env)]
    (ana/analyze env `(~(first form) [~@(map :form bindings)]
                          ~@(anf-block (assoc ast :env body-env))))))&lt;/pre&gt;
&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Simple enough, right? This walks each binding, ANF transforms the init expression, gets the environment in which to analyze the body, and then analyzes a new let (or loop) statement with the modified bindings.&lt;/p&gt;

&lt;p&gt;Unfortunately, this doesn&apos;t work. When the ana/analyze call happens, body-env contains gensymed locals. The result is that body-env is invalidated by the outer analyze call, which is re-generating the symbols for the local variables. If you take the gensyms out of analyze-let, then analyze becomes pure (modulo def forms) and this code magically becomes correct. I&apos;ve run into this same problem anywhere gensyms are used in analyze.&lt;/p&gt;



&lt;p&gt;Commit message on the patch:&lt;/p&gt;

&lt;div class=&quot;code panel&quot; style=&quot;border-width: 1px;&quot;&gt;&lt;div class=&quot;codeContent panelContent&quot;&gt;
&lt;pre class=&quot;code-java&quot;&gt;AST Changes
    
    * Anywhere a binding was introduced &lt;span class=&quot;code-keyword&quot;&gt;for&lt;/span&gt; a local used to be a symbol,
      now it is a map with a :name key and potentially a :shadow key.
    
    * Bindings vectors are no longer alternating symbols, then init maps.
      Instead, the are a vector of maps of the shape described &lt;span class=&quot;code-keyword&quot;&gt;for&lt;/span&gt; locals
      plus an :init key.
    
    * The :gthis key &lt;span class=&quot;code-keyword&quot;&gt;for&lt;/span&gt; functions has been replaced with :type, which
      is the symbol describing the type name of the enclosing deftype form.
    
    * recur frames now expose :params as binding maps, instead of :names
    
    Benefits:
    
    * Shadowed variables are now visible to downstream AST transforms.
    
    * :tag, :mutable, and other metadata are now uniform across ops
    
    * Eliminates usages of gensym inside the analyzer, which was a source
      of state that made the analyzer impossible to use &lt;span class=&quot;code-keyword&quot;&gt;for&lt;/span&gt; some
      transformations of let, letfn, etc which require re-analyzing forms.
    
    * Removes JavaScript shadowing semantics from the analyze phase.&lt;/pre&gt;
&lt;/div&gt;&lt;/div&gt;</description>
                <environment></environment>
            <key id="15664">CLJS-369</key>
            <summary>gensyms break re-analyze; prevents variable shadowing analysis</summary>
                <type id="1" iconUrl="http://dev.clojure.org/jira/images/icons/bug.gif">Defect</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="1">Completed</resolution>
                                <assignee username="-1">Unassigned</assignee>
                                <reporter username="bbloom">Brandon Bloom</reporter>
                        <labels>
                        <label>patch</label>
                        <label>patch,</label>
                    </labels>
                <created>Sat, 1 Sep 2012 19:14:31 -0500</created>
                <updated>Wed, 17 Oct 2012 10:53:50 -0500</updated>
                    <resolved>Mon, 15 Oct 2012 23:02:04 -0500</resolved>
                                                                    <due></due>
                    <votes>0</votes>
                        <watches>1</watches>
                        <comments>
                    <comment id="29339" author="dnolen" created="Mon, 3 Sep 2012 13:13:19 -0500"  >&lt;p&gt;Can we please get the ticket number in the first line of the patch? If you look at the ClojureScript commit history you can see the convention that&apos;s been adopted. Thanks!&lt;/p&gt;</comment>
                    <comment id="29340" author="bbloom" created="Mon, 3 Sep 2012 14:02:11 -0500"  >&lt;p&gt;Reworded commit message to meet new convention.&lt;/p&gt;</comment>
                    <comment id="29563" author="dnolen" created="Fri, 28 Sep 2012 17:55:25 -0500"  >&lt;p&gt;Can we put the shadow patch in another ticket with the patch referencing the new ticket #. Thanks!&lt;/p&gt;</comment>
                    <comment id="29564" author="bbloom" created="Fri, 28 Sep 2012 18:11:14 -0500"  >&lt;p&gt;Not sure what good a separate ticket would do. How about this new title?&lt;/p&gt;</comment>
                    <comment id="29573" author="dnolen" created="Sat, 29 Sep 2012 12:39:59 -0500"  >&lt;p&gt;They are separate patches. One is a enhancement to the compiler. The other one is an enhancement to my simplistic shadowing solution using the improvements to the compiler in the other enhancement. Thanks!&lt;/p&gt;</comment>
                    <comment id="29582" author="bbloom" created="Sun, 30 Sep 2012 12:34:53 -0500"  >&lt;p&gt;Are you talking about the namespace shadowing? This patch affects &lt;b&gt;all variable shadowing&lt;/b&gt;. For example, (fn &lt;span class=&quot;error&quot;&gt;&amp;#91;x x&amp;#93;&lt;/span&gt; x) will produce `function (x x__$1) { return x__$1; }` instead of `function (x_&lt;em&gt;G12 x&lt;/em&gt;_G13) { return x__G13; }` or something like that.&lt;/p&gt;

&lt;p&gt;I&apos;m not sure how I can break this patch down into smaller pieces. All of the gensyms were there before to eliminate potential shadowing; the two issues are tightly related. If you eliminated all the gensyms, the compiler would work fine... unless you shadowed a variable (which several tests cover).&lt;/p&gt;

&lt;p&gt;Have you studied the patch? Can you suggest a concrete way to break it up into smaller patches? I&apos;m not sure it&apos;s worth the trouble.&lt;/p&gt;</comment>
                    <comment id="29589" author="dnolen" created="Wed, 3 Oct 2012 10:59:38 -0500"  >&lt;p&gt;Right sorry, makes sense now. I will review both patches more closely. Thanks again.&lt;/p&gt;</comment>
                    <comment id="29654" author="dnolen" created="Mon, 15 Oct 2012 22:43:24 -0500"  >&lt;p&gt;I&apos;ve finally found some time go through this patch. It&apos;s great but it no longer applies to master. If I get an updated patch I&apos;;; apply promptly. Thank you very much and sorry for the delay.&lt;/p&gt;</comment>
                    <comment id="29656" author="dnolen" created="Mon, 15 Oct 2012 23:01:50 -0500"  >&lt;p&gt;Went ahead and applied it, only needed a minor change. &lt;/p&gt;</comment>
                    <comment id="29657" author="dnolen" created="Mon, 15 Oct 2012 23:02:04 -0500"  >&lt;p&gt;fixed, &lt;a href=&quot;http://github.com/clojure/clojurescript/commit/19afb31a52504293ba2182c584b1867917316662&quot;&gt;http://github.com/clojure/clojurescript/commit/19afb31a52504293ba2182c584b1867917316662&lt;/a&gt;&lt;/p&gt;</comment>
                    <comment id="29660" author="bbloom" created="Mon, 15 Oct 2012 23:45:14 -0500"  >&lt;p&gt;Awesome. Glad to see this applied.&lt;/p&gt;

&lt;p&gt;Off topic: I like to keep tabs on my open source contributions semi-automatically using the author information stored in git. Sadly, your minor change switched the author to you. If it&apos;s not too much to ask, could you please preserve the author info in the future? Either via a separate fixup commit, or by using the --author flag when editing commits. Thanks!&lt;/p&gt;</comment>
                    <comment id="29669" author="dnolen" created="Wed, 17 Oct 2012 10:53:50 -0500"  >&lt;p&gt;Brandon, yep of course! I didn&apos;t know about the --author flag otherwise I would have used it. Thanks again.&lt;/p&gt;</comment>
                </comments>
                    <attachments>
                    <attachment id="11471" name="CLJS-369-v2.patch" size="19887" author="bbloom" created="Mon, 3 Sep 2012 14:02:11 -0500" />
                    <attachment id="11469" name="shadowing.patch" size="19861" author="bbloom" created="Sat, 1 Sep 2012 19:40:09 -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>