<!-- 
RSS generated by JIRA (4.4#649-r158309) at Sat May 25 17:29:27 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/LOGIC-44/LOGIC-44.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>[LOGIC-44] ex* could expand macros in patterns</title>
                <link>http://dev.clojure.org/jira/browse/LOGIC-44</link>
                <project id="10020" key="LOGIC">core.logic</project>
                        <description>&lt;p&gt;So, tagged data structures are probably interesting in a relational context. Say you have a relation with some default logic about dogs:&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;(defna friendlyo [Dog-Or-Breed]
    ([:Spot] succeed)
    ([:Spike] fail)
    ([Other-Dog] (fresh [Breed] (dog-breed Other-Dog Breed) (friendlyo Breed)))
    ([(breed :miniature-dachshund)] fail)
    ([(breed :golden-retriever)] succeed)
    ;. . .)&lt;/pre&gt;
&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Assume there&apos;s a (defmacro breed &lt;span class=&quot;error&quot;&gt;&amp;#91;t&amp;#93;&lt;/span&gt; `&lt;span class=&quot;error&quot;&gt;&amp;#91;:breed ~t&amp;#93;&lt;/span&gt;).&lt;/p&gt;

&lt;p&gt;That&apos;s nicer than having to drop &lt;span class=&quot;error&quot;&gt;&amp;#91;:breed :golden-retriever&amp;#93;&lt;/span&gt; in there or whatever, since it&apos;s compile-time-checkable, less error-prone, reduces duplication, etc.&lt;/p&gt;

&lt;p&gt;This little patch makes ex* expand macros in patterns so it doesn&apos;t treat e.g. (breed :golden-retriever) as introducing a new LVar called &quot;breed&quot;. Test also provided.&lt;/p&gt;</description>
                <environment></environment>
            <key id="15582">LOGIC-44</key>
            <summary>ex* could expand macros in patterns</summary>
                <type id="4" iconUrl="http://dev.clojure.org/jira/images/icons/improvement.gif">Enhancement</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="dnolen">David Nolen</assignee>
                                <reporter username="joeosborn">Joe Osborn</reporter>
                        <labels>
                        <label>enhancement</label>
                        <label>patch</label>
                        <label>test</label>
                    </labels>
                <created>Thu, 19 Jul 2012 16:32:01 -0500</created>
                <updated>Sun, 17 Mar 2013 19:05:17 -0500</updated>
                                                                            <due></due>
                    <votes>0</votes>
                        <watches>1</watches>
                        <comments>
                    <comment id="28996" author="dnolen" created="Thu, 19 Jul 2012 16:41:30 -0500"  >&lt;p&gt;I&apos;m surprised that this doesn&apos;t already work. We have support for unifying expressions in the pattern already. Look at line 1230 in tests.clj in the master branch.&lt;/p&gt;

&lt;p&gt;So this should just work, no need to explicitly support macros as far as I can tell. If it&apos;s not working, then there&apos;s a bug.&lt;/p&gt;</comment>
                    <comment id="28997" author="joeosborn" created="Thu, 19 Jul 2012 17:18:48 -0500"  >&lt;p&gt;At least on 0.7.5, matching against a macro gives a runtime error:&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;Exception in thread &lt;span class=&quot;code-quote&quot;&gt;&quot;main&quot;&lt;/span&gt; java.lang.ClassCastException: clojure.core.logic.LVar cannot be &lt;span class=&quot;code-keyword&quot;&gt;cast&lt;/span&gt; to clojure.lang.IFn
	at rl.core$glyph_$fn__123$fn__144$fn__165$fn__166$_inc__167$fn__168.invoke(core.clj:61)
	at clojure.core.logic.Substitutions.bind(logic.clj:211)
	at rl.core$glyph_$fn__123$fn__144$fn__165$fn__166$_inc__167.invoke(core.clj:58)
	at clojure.core.logic$fn__1056$_inc__1057.invoke(logic.clj:1160)
	at clojure.core.logic$fn__1056$_inc__1057.invoke(logic.clj:1160)
	at clojure.core.logic$fn__898$_inc__899.invoke(logic.clj:823)
	at clojure.core.logic$fn__890$fn__891.invoke(logic.clj:828)&lt;/pre&gt;
&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Using a fn instead of a macro gives the same:&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;Exception in thread &lt;span class=&quot;code-quote&quot;&gt;&quot;main&quot;&lt;/span&gt; java.lang.ClassCastException: clojure.core.logic.LVar cannot be &lt;span class=&quot;code-keyword&quot;&gt;cast&lt;/span&gt; to clojure.lang.IFn
	at rl.core$drawable_$fn__235$fn__248$fn__249$_inc__250$fn__251.invoke(core.clj:67)
	at clojure.core.logic.Substitutions.bind(logic.clj:211)
	at rl.core$drawable_$fn__235$fn__248$fn__249$_inc__250.invoke(core.clj:65)
	at clojure.core.logic$fn__1056$_inc__1057.invoke(logic.clj:1160)
	at clojure.core.logic$fn__894$_inc__895.invoke(logic.clj:826)
	at clojure.core.logic$fn__1056$_inc__1057.invoke(logic.clj:1160)
	at clojure.core.logic$fn__898$_inc__899.invoke(logic.clj:823)
	at clojure.core.logic$fn__898$_inc__899.invoke(logic.clj:823)
	at clojure.core.logic$fn__898$_inc__899.invoke(logic.clj:823)
	at clojure.core.logic$fn__890$fn__891.invoke(logic.clj:828)&lt;/pre&gt;
&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Here&apos;s (glyph-) for reference (don&apos;t mind all the extra [], I have a weird key/value thing because of some conveniences for maintaining fact identity in a temporal database):&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;(defna glyph- [Key Val]
	([[Thing] [Glyph]] (thing- [Thing]) (on-fire_ *turn* [Thing]) (== Glyph \&#948;))
	([[Thing] [Glyph]] (thing- [Thing]) (fresh [Type] (type- [Thing] [Type]) (glyph- [Type] [Glyph])))
	([[(type-&lt;span class=&quot;code-keyword&quot;&gt;enum&lt;/span&gt; :player)] [Glyph]] (== Glyph \@))
	([[(type-&lt;span class=&quot;code-keyword&quot;&gt;enum&lt;/span&gt; :dragon)] [Glyph]] (== Glyph \D))
	([[Type] [Glyph]] (== Glyph \?)))&lt;/pre&gt;
&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;and type-enum as a macro:&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;(defmacro type-&lt;span class=&quot;code-keyword&quot;&gt;enum&lt;/span&gt; [v] `[:&lt;span class=&quot;code-keyword&quot;&gt;enum&lt;/span&gt; :type ~v])&lt;/pre&gt;
&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;and as a fn:&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;(defn type-&lt;span class=&quot;code-keyword&quot;&gt;enum&lt;/span&gt; [v] [:&lt;span class=&quot;code-keyword&quot;&gt;enum&lt;/span&gt; :type ~v])&lt;/pre&gt;
&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;I&apos;ll mess around and see if my example works in HEAD.&lt;/p&gt;</comment>
                    <comment id="28998" author="joeosborn" created="Thu, 19 Jul 2012 17:37:36 -0500"  >&lt;p&gt;Same exception with this test case in HEAD (sorry for all the facts):&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;(defrel thing- [Thing])
(defrel type- [Thing] [Type])
(fact thing- [0])
(fact thing- [1])
(fact thing- [2])
(fact type- [0] [:player])
(fact type- [1] [:dragon])
(fact type- [2] [:pig])
(defn type-&lt;span class=&quot;code-keyword&quot;&gt;enum&lt;/span&gt; [t] [:type t])
(defna drawable- [Key]
  ([[Thing]] (thing- [Thing]) (fresh [Type] (type- [Thing] [Type]) (drawable- [Type])))
  ([[(type-&lt;span class=&quot;code-keyword&quot;&gt;enum&lt;/span&gt; :player)]] succeed)
  ([[(type-&lt;span class=&quot;code-keyword&quot;&gt;enum&lt;/span&gt; :dragon)]] succeed))

(deftest &lt;span class=&quot;code-keyword&quot;&gt;do&lt;/span&gt;-fns-work
	(is (= (run* [q] (drawable- [q])) &apos;(0 1))))&lt;/pre&gt;
&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Now that I look at it, I may be expecting a wrong-format return value, but the point is that I don&apos;t even get that far.&lt;/p&gt;

&lt;p&gt;Using the REPL, I checked out how (defna drawable- . . .) expands (tidied up slightly):&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;(def drawable- (clojure.core/fn ([Key] 
  (clojure.core.logic/conda 
	  ((clojure.core.logic/fresh [Thing] (clojure.core.logic/== [Thing] Key) (thing- [Thing]) (fresh [Type] (type- [Thing] [Type]) (drawable- [Type])))) 
		((clojure.core.logic/fresh [type-&lt;span class=&quot;code-keyword&quot;&gt;enum&lt;/span&gt;] 
		  (clojure.core.logic/== [(type-&lt;span class=&quot;code-keyword&quot;&gt;enum&lt;/span&gt; :player)] Key) succeed))
		((clojure.core.logic/fresh [type-&lt;span class=&quot;code-keyword&quot;&gt;enum&lt;/span&gt;] 
		  (clojure.core.logic/== [(type-&lt;span class=&quot;code-keyword&quot;&gt;enum&lt;/span&gt; :dragon)] Key) succeed))))))&lt;/pre&gt;
&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Note the (clojure.core.logic/fresh &lt;span class=&quot;error&quot;&gt;&amp;#91;type-enum&amp;#93;&lt;/span&gt; . . .) forms, which are exactly what I would not want to see in this case.&lt;/p&gt;

&lt;p&gt;I&apos;m not really sure why this doesn&apos;t work here yet works for the matche test case.&lt;/p&gt;</comment>
                    <comment id="28999" author="dnolen" created="Thu, 19 Jul 2012 17:47:23 -0500"  >&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;[(type-&lt;span class=&quot;code-keyword&quot;&gt;enum&lt;/span&gt; :dragon)]&lt;/pre&gt;
&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This pattern make it seem like you want to match:&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;[[:type :dragon]]&lt;/pre&gt;
&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Note extra level of brackets here. Is this the case?&lt;/p&gt;

&lt;p&gt;Even so I agree that the expansion doesn&apos;t look quite right. We should never descend into a seq form like that.&lt;/p&gt;</comment>
                    <comment id="29001" author="joeosborn" created="Thu, 19 Jul 2012 17:57:03 -0500"  >&lt;p&gt;Yes, that&apos;s exactly the desired outcome in this case--a tagged value in my naive interpretation. Is the reason it fails whereas the test on :1230 doesn&apos;t the fact that it&apos;s producing a vector and not a list? Changing the fn to return a list instead of a vector didn&apos;t seem to help.&lt;/p&gt;

&lt;p&gt;My patch, fwiw, doesn&apos;t exhibit that behavior (at least for macros, haven&apos;t tested it with fns).&lt;/p&gt;</comment>
                    <comment id="29002" author="dnolen" created="Thu, 19 Jul 2012 21:11:27 -0500"  >&lt;p&gt;What I mean is don&apos;t you want the following instead?&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;(defna drawable- [Key]
  ([[Thing]] (thing- [Thing]) (fresh [Type] (type- [Thing] [Type]) (drawable- [Type])))
  ([(type-&lt;span class=&quot;code-keyword&quot;&gt;enum&lt;/span&gt; :player)] succeed)
  ([(type-&lt;span class=&quot;code-keyword&quot;&gt;enum&lt;/span&gt; :dragon)] succeed))&lt;/pre&gt;
&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Note that I removed a layer of square brackets.&lt;/p&gt;</comment>
                    <comment id="29005" author="joeosborn" created="Fri, 20 Jul 2012 10:28:39 -0500"  >&lt;p&gt;Nope! I actually want both. I&apos;m doing some temporal logic stuff and I wanted some conveniences for &quot;updating&quot; a fluent, so I wanted to distinguish between the &quot;key part&quot; and the &quot;value part&quot; of the arguments. It looks silly for facts with no &quot;value part&quot;, but it lets me write procedures and fns something like this:&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;(defrel heldo Time Fluent)
(defrel &#172;heldo Time Fluent)
(declare fluent-obtainedo) ; most recent &apos;held&apos; not terminated by a &apos;&#172;held&apos;, or fail
(defn alter-fluent [Time Rel Key NewVal]
  ;todo: error check, ensure old != &lt;span class=&quot;code-keyword&quot;&gt;new&lt;/span&gt;, old obtains, &lt;span class=&quot;code-keyword&quot;&gt;new&lt;/span&gt; does not obtain
  (doseq [old-val (run* [old-val] (fluent-obtainedo Time [Rel Key old-val]))]
    (fact &#172;heldo Time [Rel Key old-val]))
  (fact heldo Time [Rel Key NewVal]))
. . .
(fact heldo 0 [&apos;pos [0] [0 0]])
. . .
(alter-fluent 1 &apos;pos [0] [1 1])&lt;/pre&gt;
&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;And I write all the non-temporal fluents that way too for consistency and to help prevent mistakes.&lt;/p&gt;</comment>
                    <comment id="29009" author="dnolen" created="Fri, 20 Jul 2012 14:58:13 -0500"  >&lt;p&gt;I&apos;ll try to give a closer look at this issue over the weekend.&lt;/p&gt;</comment>
                    <comment id="30787" author="dnolen" created="Sun, 17 Mar 2013 19:05:17 -0500"  >&lt;p&gt;We&apos;re thinking about a more general solution here: &lt;a href=&quot;http://github.com/clojure/core.logic/wiki/Better-syntax-support&quot;&gt;http://github.com/clojure/core.logic/wiki/Better-syntax-support&lt;/a&gt;&lt;/p&gt;</comment>
                </comments>
                    <attachments>
                    <attachment id="11389" name="exstar-macros.patch" size="1931" author="joeosborn" created="Thu, 19 Jul 2012 16:32:01 -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>