<!-- 
RSS generated by JIRA (4.4#649-r158309) at Thu Jun 20 03:16:06 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-414/CLJS-414.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-414] Implement specify, allowing instances to implement protocols</title>
                <link>http://dev.clojure.org/jira/browse/CLJS-414</link>
                <project id="10040" key="CLJS">ClojureScript</project>
                        <description>&lt;p&gt;Javascript objects are fully dynamic. Currently, ClojureScript has no mechanism to exploit that for protocol implementation. &lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://dev.clojure.org/jira/browse/CLJS-398&quot; title=&quot;new macro cljs.core/extend-instance&quot;&gt;&lt;del&gt;CLJS-398&lt;/del&gt;&lt;/a&gt; was a first attempt to implement an operation to extend single instances, but it fell short because it offered no control over which closures to attach onto the object (i.e. allocates every time). Also, specify is a much better name than extend-instance.&lt;/p&gt;

&lt;p&gt;extend-type can be implemented in terms of specify (by specifying the .prototype), but extend-type has grown from its humble beginnings &lt;br/&gt;
&lt;a href=&quot;https://github.com/clojure/clojurescript/blob/b75730da8abc3abc6134d8dd9ec426ab792d3662/src/clj/cljs/core.clj#L42&quot;&gt;https://github.com/clojure/clojurescript/blob/b75730da8abc3abc6134d8dd9ec426ab792d3662/src/clj/cljs/core.clj#L42&lt;/a&gt;&lt;br/&gt;
to an monster of complexity&lt;br/&gt;
&lt;a href=&quot;https://github.com/clojure/clojurescript/blob/72e55315c6973caa74af39b66052424f73872033/src/clj/cljs/core.clj#L438&quot;&gt;https://github.com/clojure/clojurescript/blob/72e55315c6973caa74af39b66052424f73872033/src/clj/cljs/core.clj#L438&lt;/a&gt;&lt;br/&gt;
Currently it does&lt;/p&gt;

&lt;ul class=&quot;alternate&quot; type=&quot;square&quot;&gt;
	&lt;li&gt;print warnings&lt;/li&gt;
	&lt;li&gt;optimize IFn impls&lt;/li&gt;
	&lt;li&gt;special case the Object &quot;protocol&quot;&lt;/li&gt;
	&lt;li&gt;special case js builtins&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;and all that in a single macro body. So this is also a good opportunity to do some refactoring.&lt;/p&gt;

&lt;p&gt;specify should have an interface similar to extend-type. Additionally a lower level operation is needed to attach existing lambdas as protocol methods. It&apos;s called specify* in my current implementation. It takes a lambda for every specified protocol-method-arity, with a syntax loosely based on clojure.core/extend.&lt;/p&gt;</description>
                <environment></environment>
            <key id="15807">CLJS-414</key>
            <summary>Implement specify, allowing instances to implement protocols</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="bendlas">Herwig Hochleitner</assignee>
                                <reporter username="bendlas">Herwig Hochleitner</reporter>
                        <labels>
                    </labels>
                <created>Tue, 30 Oct 2012 23:08:22 -0500</created>
                <updated>Fri, 3 May 2013 19:30:54 -0500</updated>
                                                                            <due></due>
                    <votes>0</votes>
                        <watches>1</watches>
                        <comments>
                    <comment id="29876" author="bendlas" created="Tue, 30 Oct 2012 23:21:59 -0500"  >&lt;p&gt;First patch implements specify, second switches extend-type to use it.&lt;/p&gt;</comment>
                    <comment id="29878" author="dnolen" created="Wed, 31 Oct 2012 09:30:58 -0500"  >&lt;p&gt;This is a big patch so it&apos;s going to take time to review. First question, if we&apos;re going to follow the footsteps of extend what&apos;s the purpose of changing the syntax like having to specify a map of arities?&lt;/p&gt;</comment>
                    <comment id="29879" author="bendlas" created="Wed, 31 Oct 2012 10:32:33 -0500"  >&lt;p&gt;The reason is that I wanted specify* to do as little as possible. It&apos;s basically just an abstraction over the name mangling for protocol methods, which was completely hidden till now. One of the purported use cases is:&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 methA-1 [&lt;span class=&quot;code-keyword&quot;&gt;this&lt;/span&gt;] ...)
(def methA-2 [&lt;span class=&quot;code-keyword&quot;&gt;this&lt;/span&gt; x] ...)
(def methB-1 [&lt;span class=&quot;code-keyword&quot;&gt;this&lt;/span&gt;] ...)

(defn specify-to-P [o]
  (specify* o
    P {methA {1 methA-1
              2 methA-2}
       methB {1 methB-1}}))&lt;/pre&gt;
&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Here the method bodies are not allocated every time specify-to-P is called, as opposed to what the more high-level specify would do. If we didn&apos;t know which arities are to be generated, there would be simply no way to infer it:&lt;/p&gt;

&lt;ul class=&quot;alternate&quot; type=&quot;square&quot;&gt;
	&lt;li&gt;there is no simple way to know at compile time which arities an fn has&lt;/li&gt;
	&lt;li&gt;if there was we wouldn&apos;t be able to get the fn at compile time in all cases&lt;/li&gt;
	&lt;li&gt;defprotocol doesn&apos;t expose it&apos;s methods or their arities&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;EDIT:&lt;/p&gt;

&lt;p&gt;As for using symbols instead of keywords: I could do this, since specify* is a macro, not a function.&lt;br/&gt;
Making specify* a function may have its own merits, which I frankly hadn&apos;t thought about. Actually, that might be sweet, I&apos;ll look into that possibility.&lt;/p&gt;</comment>
                    <comment id="29880" author="bendlas" created="Wed, 31 Oct 2012 12:59:09 -0500"  >&lt;p&gt;&lt;del&gt;As for specify* being a function: It uses a map in its syntax and at the same time is used to define PersistentHashMap, so that wouldn&apos;t work.&lt;/del&gt;&lt;br/&gt;
EDIT: the real reason is name mangling, see comment below&lt;/p&gt;

&lt;p&gt;&lt;del&gt;What could conceivably be done is to have a core function&lt;/del&gt; (specify-method &lt;span class=&quot;error&quot;&gt;&amp;#91;proto method arity impl&amp;#93;&lt;/span&gt;).&lt;br/&gt;
EDIT: can&apos;t be done without reflection, same reason&lt;/p&gt;

&lt;p&gt;That way we could support consumers that want to determine the set of implemented protocols at runtime, similar to extend. This can be a separate ticket where we work out whether it&apos;s :method &apos;method or &quot;method&quot;.&lt;/p&gt;

&lt;p&gt;As for specify* using symbols: My gut feeling tells me that since it will always be a compiler macro (or builtin) and takes the arities, there is no merit in making it superficially more similar to extend.&lt;/p&gt;

&lt;p&gt;OTOH, it occurs to me that given specify-method, we could leave out specify* completely. I think I&apos;ll try that when I get home from work. Thoughts on that approach?&lt;/p&gt;</comment>
                    <comment id="29881" author="bendlas" created="Wed, 31 Oct 2012 19:59:14 -0500"  >&lt;p&gt;Actually, I had a rationale for using symbols in specify*, which I just now rediscovered while trying to implement aforementioned specify-method.&lt;br/&gt;
It uses symbols to highlight the fact, that the method names are subject to the same (gclosure) minification as every other name.&lt;/p&gt;

&lt;p&gt;This is also the real reason specify* (or specify-method) can&apos;t be a function: It would need a reflective layer to go from &lt;span class=&quot;error&quot;&gt;&amp;#91;proto method arity&amp;#93;&lt;/span&gt; to the &lt;em&gt;gclosure minified&lt;/em&gt; version of $proto$method$arity$a. We don&apos;t have that in clojurescript, since it would considerably add to the output size.&lt;/p&gt;

&lt;p&gt;Considering that all, I think specify* in the current form is appropriate after all.&lt;/p&gt;

&lt;p&gt;Nevertheless I found an unrelated issue in the patch where &apos;Object would be resolved (with an unused result), triggering a warning. I added the 0001_1 patch, which supersedes 0001 and is functionally equivalent modulo the warning issue. 0002 still applies.&lt;/p&gt;</comment>
                    <comment id="29884" author="bendlas" created="Thu, 1 Nov 2012 00:09:23 -0500"  >&lt;p&gt;Attached patch set 01** supersedes patch set 00**&lt;/p&gt;

&lt;p&gt;The differences are&lt;/p&gt;

&lt;ul class=&quot;alternate&quot; type=&quot;square&quot;&gt;
	&lt;li&gt;Make ^:skip-protocol-flag work&lt;/li&gt;
	&lt;li&gt;Added tests&lt;/li&gt;
&lt;/ul&gt;
</comment>
                    <comment id="29896" author="bendlas" created="Sat, 3 Nov 2012 00:53:19 -0500"  >&lt;p&gt;Set up a design page &lt;a href=&quot;http://dev.clojure.org/display/design/specify+i.e.+reify+for+instances&quot;&gt;http://dev.clojure.org/display/design/specify+i.e.+reify+for+instances&lt;/a&gt;&lt;/p&gt;</comment>
                    <comment id="29902" author="bendlas" created="Sun, 4 Nov 2012 22:06:14 -0600"  >&lt;p&gt;Attached patch 0104, applies on top of other 01* patches.&lt;br/&gt;
It adds capability to specify* IFn and allows specify* to take an expression too.&lt;/p&gt;</comment>
                    <comment id="31046" author="bendlas" created="Fri, 3 May 2013 19:30:54 -0500"  >&lt;p&gt;rebased to current master&lt;br/&gt;
see also &lt;a href=&quot;https://groups.google.com/d/topic/clojure-dev/1UegnkLSwhE/discussion&quot;&gt;https://groups.google.com/d/topic/clojure-dev/1UegnkLSwhE/discussion&lt;/a&gt;&lt;/p&gt;</comment>
                </comments>
                    <attachments>
                    <attachment id="11647" name="0001_1-CLJS-414-specify-and-specify-macros.patch" size="7728" author="bendlas" created="Wed, 31 Oct 2012 19:59:14 -0500" />
                    <attachment id="11645" name="0001-CLJS-414-specify-and-specify-macros.patch" size="7798" author="bendlas" created="Tue, 30 Oct 2012 23:21:59 -0500" />
                    <attachment id="11646" name="0002-CLJS-414-Implement-extend-type-in-terms-of-specify.patch" size="8790" author="bendlas" created="Tue, 30 Oct 2012 23:21:59 -0500" />
                    <attachment id="11651" name="0101-CLJS-414-specify-and-specify-macros.patch" size="7722" author="bendlas" created="Thu, 1 Nov 2012 00:09:23 -0500" />
                    <attachment id="11652" name="0102-CLJS-414-Implement-extend-type-in-terms-of-specify.patch" size="8790" author="bendlas" created="Thu, 1 Nov 2012 00:09:23 -0500" />
                    <attachment id="11650" name="0103-CLJS-414-Test-specify-features-deprecation-nowarn-an.patch" size="1594" author="bendlas" created="Thu, 1 Nov 2012 00:09:23 -0500" />
                    <attachment id="11664" name="0104-CLJS-414-Update-specify-to-allow-implementing-IFn-an.patch" size="6172" author="bendlas" created="Sun, 4 Nov 2012 22:06:14 -0600" />
                    <attachment id="11983" name="0201-CLJS-414-specify-and-specify-macros.patch" size="7705" author="bendlas" created="Fri, 3 May 2013 19:30:54 -0500" />
                    <attachment id="11982" name="0202-CLJS-414-Implement-extend-type-in-terms-of-specify.patch" size="8765" author="bendlas" created="Fri, 3 May 2013 19:30:54 -0500" />
                    <attachment id="11981" name="0203-CLJS-414-Test-specify-features-deprecation-nowarn-an.patch" size="1802" author="bendlas" created="Fri, 3 May 2013 19:30:54 -0500" />
                    <attachment id="11980" name="0204-CLJS-414-Update-specify-to-allow-implementing-IFn-an.patch" size="6163" author="bendlas" created="Fri, 3 May 2013 19:30:54 -0500" />
                </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>