Clojure JIRAhttp://dev.clojure.org/jira/secure/IssueNavigator.jspa?reset=true&jqlQuery=project+%3D+CLJ+AND+status+in+%28Open%2C+%22In+Progress%22%2C+Reopened%29+AND+Approval+IS+NULL
An XML representation of a search requesten-us4.464925-07-2011[CLJ-1668] ns macro throws NPE if empty reference is specifiedhttp://dev.clojure.org/jira/browse/CLJ-1668
Clojure<p>The following invocations of `ns` will all throw a NPE</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">(ns foo ())
(ns foo [])
(ns foo (:require clojure.core) ())
;; <span class="code-keyword">throw</span>
1. Unhandled java.lang.NullPointerException
(No message)
core.clj: 1518 clojure.core/name
core.clj: 5330 clojure.core/ns/process-reference
core.clj: 2559 clojure.core/map/fn
LazySeq.java: 40 clojure.lang.LazySeq/sval
LazySeq.java: 49 clojure.lang.LazySeq/seq
RT.java: 484 clojure.lang.RT/seq
core.clj: 133 clojure.core/seq
core.clj: 694 clojure.core/concat/cat/fn
LazySeq.java: 40 clojure.lang.LazySeq/sval
LazySeq.java: 49 clojure.lang.LazySeq/seq
Cons.java: 39 clojure.lang.Cons/next
RT.java: 1654 clojure.lang.RT/boundedLength
AFn.java: 148 clojure.lang.AFn/applyToHelper
Var.java: 700 clojure.lang.Var/applyTo</pre>
</div></div>
<p>I'd expect an exception that is describing the cause of the error, not an "symptom".</p>CLJ-1668ns macro throws NPE if empty reference is specifiedDefectMinorOpenUnresolvedUnassignedPhilipp MeiererrormsgsmacronamespaceMon, 2 Mar 2015 06:09:29 -0600Mon, 2 Mar 2015 10:38:15 -0600Release 1.6Release 1.710Global Rank[CLJ-1664] Inconsistency in overflow-handling between type-hinted and reflective callshttp://dev.clojure.org/jira/browse/CLJ-1664
Clojure<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">(<span class="code-keyword">import</span> 'java.io.DataOutputStream)
(<span class="code-keyword">import</span> 'java.io.ByteArrayOutputStream)
(defn- -&gt;bytes
<span class="code-quote">"Convert a Java primitive to its <span class="code-object">byte</span> representation."</span>
[write v]
(let [output-stream (ByteArrayOutputStream.)
data-output (DataOutputStream. output-stream)]
(write data-output v)
(seq (.toByteArray output-stream))))
(defn <span class="code-object">int</span>-&gt;bytes [n]
(-&gt;bytes
#(.writeInt ^DataOutputStream %1 %2)
n))
(defn <span class="code-object">int</span>-&gt;bytes-ref [n]
(-&gt;bytes
#(.writeInt %1 %2)
n))
user=&gt; (<span class="code-object">int</span>-&gt;bytes 5)
(0 0 0 5)
user=&gt; (<span class="code-object">int</span>-&gt;bytes-ref 5)
(0 0 0 5)
user=&gt; (<span class="code-object">int</span>-&gt;bytes (inc <span class="code-object">Integer</span>/MAX_VALUE))
IllegalArgumentException Value out of range <span class="code-keyword">for</span> <span class="code-object">int</span>: 2147483648 clojure.lang.RT.intCast (RT.java:1115)
user=&gt; (<span class="code-object">int</span>-&gt;bytes-ref (inc <span class="code-object">Integer</span>/MAX_VALUE))
(-128 0 0 0)</pre>
</div></div>
<p>So it looks like type-hinting the DataOutputStream results in bytecode calling RT.intCast, which throws because the value is too large. In the reflective case, we locate the method writeInt at runtime, and then do not call RT.intCast, but instead allow the long to be downcast without bounds checking.</p>
<p>It seems like we should be calling RT.intCast in both cases?</p>CLJ-1664Inconsistency in overflow-handling between type-hinted and reflective callsDefectMinorOpenUnresolvedUnassignedMichael BlumenumericsreflectionThu, 19 Feb 2015 14:10:33 -0600Thu, 19 Feb 2015 14:10:33 -060000Global Rank[CLJ-1662] folding over hash-map nested hash-map throws exceptionhttp://dev.clojure.org/jira/browse/CLJ-1662
Clojure<p>I got a baffling exception in a recursive function that folds. REPL transcript below:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">nREPL server started on port 57818 on host 127.0.0.1 - nrepl:<span class="code-comment">//127.0.0.1:57818
</span>REPL-y 0.3.5, nREPL 0.2.6
Clojure 1.7.0-alpha5
Java HotSpot(TM) 64-Bit Server VM 1.7.0_76-b13
Docs: (doc function-name-here)
(find-doc <span class="code-quote">"part-of-name-here"</span>)
Source: (source function-name-here)
Javadoc: (javadoc java-object-or-class-here)
Exit: Control+D or (exit) or (quit)
Results: Stored in vars *1, *2, *3, an exception in *e
user=&gt; (use 'foldtest.core)
nil
user=&gt; (source leafs)
(defn leafs [xs]
(-&gt;&gt; (r/mapcat (fn [k v]
(<span class="code-keyword">if</span> (map? v)
(leafs v)
[[k v]])) xs)
(r/foldcat)))
nil
user=&gt; (leafs (hash-map :a (hash-map :b 1 :c 2)))
ClassCastException clojure.lang.PersistentHashMap$1 cannot be <span class="code-keyword">cast</span> to clojure.lang.IFn clojure.core.reducers/fjinvoke (reducers.clj:48)
user=&gt; (pst)
ClassCastException clojure.lang.PersistentHashMap$1 cannot be <span class="code-keyword">cast</span> to clojure.lang.IFn
clojure.core.reducers/fjinvoke (reducers.clj:48)
clojure.lang.PersistentHashMap.fold (PersistentHashMap.java:207)
clojure.core.reducers/eval1347/fn--1348 (reducers.clj:367)
clojure.core.reducers/eval1220/fn--1221/G--1211--1232 (reducers.clj:81)
clojure.core.reducers/folder/reify--1247 (reducers.clj:130)
clojure.core.reducers/fold (reducers.clj:98)
clojure.core.reducers/fold (reducers.clj:96)
clojure.core.reducers/foldcat (reducers.clj:318)
foldtest.core/leafs (core.clj:5)
foldtest.core/leafs/fn--1367 (core.clj:7)
clojure.core.reducers/mapcat/fn--1277/fn--1280 (reducers.clj:185)
clojure.lang.PersistentHashMap$NodeSeq.kvreduce (PersistentHashMap.java:1127)
nil
user=&gt;</pre>
</div></div>
<p>Note that it <b>must</b> be a hash-map nested in a hash-map. Other combinations of array and hash maps seem fine:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">user=&gt; (leafs (array-map :a (hash-map :b 1 :c 2)))
[[:c 2] [:b 1]]
user=&gt; (leafs (hash-map :a (array-map :b 1 :c 2)))
[[:b 1] [:c 2]]
user=&gt; (leafs (hash-map :a (hash-map :b 1 :c 2)))
ClassCastException clojure.lang.PersistentHashMap$1 cannot be <span class="code-keyword">cast</span> to clojure.lang.IFn clojure.core.reducers/fjinvoke (reducers.clj:48)
user=&gt; (leafs (array-map :a (array-map :b 1 :c 2)))
[[:b 1] [:c 2]]
user=&gt;</pre>
</div></div>
<p>Possibly related: <a href="http://dev.clojure.org/jira/browse/CLJCLR-63" title="Mistake in Java translation in clojure.core.reducers/fold">CLJCLR-63</a></p>
<p>It took me a while to discover this because of this inconsistency (which I am not sure is a bug):</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">user=&gt; (def a {:a 1})
#'user/a
user=&gt; (type a)
clojure.lang.PersistentHashMap
user=&gt; (let [a {:a 1}] (type a))
clojure.lang.PersistentArrayMap
user=&gt; (type {:a 1})
clojure.lang.PersistentArrayMap
user=&gt;</pre>
</div></div>
<p>(I had put test input in a def, but using the defed var always failed but literals always worked!)</p>
JVM 1.7.0_76CLJ-1662folding over hash-map nested hash-map throws exceptionDefectMajorOpenUnresolvedUnassignedFrancis AvilareducersTue, 17 Feb 2015 15:45:10 -0600Tue, 17 Feb 2015 15:45:10 -0600Release 1.6Release 1.700Global Rank[CLJ-1661] Varargs protocol impls can be defined but not calledhttp://dev.clojure.org/jira/browse/CLJ-1661
Clojure<p>The compiler accepts this:</p>
<p>(deftype foo []<br/>
clojure.lang.IFn<br/>
(invoke <span class="error">&#91;this &amp; xs&#93;</span>))</p>
<p>However calling ((foo.) :bar) will throw an AbstractMethodError. Wouldn't some checking be desirable?</p>CLJ-1661Varargs protocol impls can be defined but not calledEnhancementMinorOpenUnresolvedUnassignedReno RecklingTue, 17 Feb 2015 11:07:05 -0600Thu, 19 Feb 2015 14:23:43 -0600Release 1.403<p>This is a clone of <a href="http://dev.clojure.org/jira/browse/CLJ-1024">http://dev.clojure.org/jira/browse/CLJ-1024</a> because the original with its attached patches was forgotten with the reason that "It has to wait and cannot be applied in 1.5" which is 2 major versions ago now, with 1.7 underway.</p>
<p>I would like to reopen it, or continue working on it in this ticket because i just stumbled over this issue the second time and the debugging sessions that follow this are annoying.</p><p>Fix Version/s was Release 1.5, but that field should only be set by Clojure screeners.</p><p>Yes, i just cloned the original issue. Later i realized that I'm unable to edit any of the fields.<br/>
The issue is just concerned with a missing warning/error when trying to compile protocols with "&amp;" in the argument list as they are interpreted as a variable name "&amp;" instead of a varargs placeholder which the user probably expects.</p><p>Here's a forward-port of the 1024 patch</p>Global RankPatchCode[CLJ-1660] Unify Stepper and MultiStepper in LazyTransformerhttp://dev.clojure.org/jira/browse/CLJ-1660
Clojure<p>This seemed worthwhile to me mainly because some of the stepper logic is actually pretty fiddly, so it seems better not to have it duplicated.</p>CLJ-1660Unify Stepper and MultiStepper in LazyTransformerEnhancementMinorOpenUnresolvedUnassignedMichael BlumeMon, 16 Feb 2015 18:07:25 -0600Mon, 16 Feb 2015 18:08:16 -060002Global RankPatchCode[CLJ-1657] proxy creates bytecode that calls super methods of abstract classeshttp://dev.clojure.org/jira/browse/CLJ-1657
Clojure<p>When proxy is used to extend abstract classes (e.g. java.io.Writer), the bytecode it produces include the call to non-existing super methods. For example, here's decompiled method from clojure/pprint/column_writer.clj:</p>
<div class="code panel" style="border-style: solid;border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java"><span class="code-keyword">public</span> void close()
{
<span class="code-object">Object</span> obj;
label0:
{
obj = RT.get(__clojureFnMap, <span class="code-quote">"close"</span>);
<span class="code-keyword">if</span>(obj == <span class="code-keyword">null</span>)
<span class="code-keyword">break</span> label0;
((IFn)obj).invoke(<span class="code-keyword">this</span>);
<span class="code-keyword">break</span> MISSING_BLOCK_LABEL_31;
}
JVM INSTR pop ;
<span class="code-keyword">super</span>.close();
}</pre>
</div></div>
<p>As you can see on the last line, super.close() tries to call a non-defined method (because close() is abstract in Writer).</p>
<p>This hasn't been an issue anywhere until Android 5.0 came out. Its bytecode optimizer is very aggressive and rejects such code. Google guys claim that it is a bug in their code, which they already fixed<span class="error">&#91;1&#93;</span>. Still I wonder if having faulty bytecode, that is not valid by Java standards, might cause issues in future (not only on Android, but in other enviroments too).</p>
<p><span class="error">&#91;1&#93;</span> <a href="https://code.google.com/p/android/issues/detail?id=80687">https://code.google.com/p/android/issues/detail?id=80687</a></p>Everywhere, but so far relevant only on Android 5.0 CLJ-1657proxy creates bytecode that calls super methods of abstract classesDefectMinorOpenUnresolvedUnassignedAlexander YakushevSun, 8 Feb 2015 04:42:54 -0600Sun, 8 Feb 2015 04:44:39 -0600Release 1.600Global Rank[CLJ-1655] Dorun's behavior when called with two argument's is both unintuitive and undocumented.http://dev.clojure.org/jira/browse/CLJ-1655
Clojure<p>Dorun can be called as (dorun n coll). When called this way, dorun will force n+1 elements from coll, which seems unintuitive. I can't <b>necessarily</b> call this a defect, though. It doesn't deviate from the documented behavior because there is no documented behavior &#8211; the two-argument arity is not mentioned in the docstring.</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">user=&gt; (defn printing-range [n] (lazy-seq (println n) (cons n (printing-range (inc n)))))
#'user/printing-range
user=&gt; (dorun 0 (printing-range 1))
1
nil
user=&gt; (dorun 3 (printing-range 1))
1
2
3
4
nil</pre>
</div></div>CLJ-1655Dorun's behavior when called with two argument's is both unintuitive and undocumented.DefectMinorOpenUnresolvedUnassignedMichael BlumeWed, 4 Feb 2015 11:34:30 -0600Wed, 4 Feb 2015 11:34:30 -060001Global Rank[CLJ-1651] Erroneous error message when using into to create a map.http://dev.clojure.org/jira/browse/CLJ-1651
Clojure<p>If you provide a sequence instead of a vector type for the entries provided to into for creating a hash-map, the error message is misleading.</p>
<p> org.noisesmith.orsos=&gt; (into {} '((:a 0) (:b 1)))</p>
<p> ClassCastException clojure.lang.Keyword cannot be cast to java.util.Map$Entry clojure.lang.ATransientMap.conj (ATransientMap.java:44)</p>
<p>As we see, it reports the type of the first item in the entry, rather than the actual error, the type of the entry itself, which can be particularly confusing if the key in the entry is actually a valid type to be an entry:</p>
<p> =&gt; (into {} '((<span class="error">&#91;&quot;a&quot; 1&#93;</span> <span class="error">&#91;&quot;b&quot; 2&#93;</span>) (<span class="error">&#91;&quot;c&quot; 3&#93;</span> <span class="error">&#91;&quot;d&quot; 4&#93;</span>)))</p>
<p> ClassCastException clojure.lang.PersistentVector cannot be cast to java.util.Map$Entry clojure.lang.ATransientMap.conj (ATransientMap.java:44)</p>CLJ-1651Erroneous error message when using into to create a map.DefectMinorOpenUnresolvedUnassignedJustin Glenn Smitherror-reportingThu, 29 Jan 2015 12:31:35 -0600Thu, 29 Jan 2015 12:31:35 -0600Release 1.701Global Rank[CLJ-1649] Hash/equality inconsistency for floats & doubleshttp://dev.clojure.org/jira/browse/CLJ-1649
Clojure<p>This is closely related to <a href="http://dev.clojure.org/jira/browse/CLJ-1036" title="hash is inconsistent with = for some BigInteger and floating point values"><del>CLJ-1036</del></a>, but there was a suggestion to make a new ticket.</p>
<p>The issue is that for a float <tt>f</tt> and a double <tt>d</tt>, we can have <tt>(= f d)</tt> but not <tt>(= (hash f) (hash d))</tt>, which breaks a fundamental assumption about hash/equality consistency and leads to weirdness like this (from Immo Heikkinen's email to the Clojure mailing list):</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">(= (<span class="code-object">float</span> 0.5) (<span class="code-object">double</span> 0.5))
=&gt; <span class="code-keyword">true</span>
(= #{(<span class="code-object">float</span> 0.5)} #{(<span class="code-object">double</span> 0.5)})
=&gt; <span class="code-keyword">true</span>
(= {:a (<span class="code-object">float</span> 0.5)} {:a (<span class="code-object">double</span> 0.5)})
=&gt; <span class="code-keyword">true</span>
(= #{{:a (<span class="code-object">float</span> 0.5)}} #{{:a (<span class="code-object">double</span> 0.5)}})
=&gt; <span class="code-keyword">false</span></pre>
</div></div>
<p>One way to resolve this would be to tweak the hashing of floats and/or doubles, but that suggestion has apparently been rejected.</p>
<p>An alternative would be to modify <tt>=</tt> so that it never returns true for float/double comparisons. One should never compare floats with doubles using <tt>=</tt> anyway, so such a change should have minimal impact beyond restoring hash/equality consistency.</p>CLJ-1649Hash/equality inconsistency for floats & doublesDefectMinorOpenUnresolvedUnassignedMichael GardnernumericsFri, 23 Jan 2015 11:08:19 -0600Fri, 23 Jan 2015 11:08:19 -0600Release 1.4Release 1.5Release 1.6Release 1.723Global Rank[CLJ-1630] Destructuring allows multiple &-paramshttp://dev.clojure.org/jira/browse/CLJ-1630
Clojure<p>(let [<span class="error">&#91;foo &amp; bar &amp; baz&#93;</span> []]) compiles and probably shouldn't.</p>CLJ-1630Destructuring allows multiple &-paramsDefectMajorOpenUnresolvedUnassignedMichael BlumeWed, 31 Dec 2014 14:21:46 -0600Thu, 1 Jan 2015 12:28:20 -060001<p>I see:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">user=&gt; (defn foo [bar &amp; baz &amp; qux])
CompilerException java.lang.RuntimeException: Invalid parameter list, compiling:(/<span class="code-keyword">private</span>/<span class="code-keyword">var</span>/folders/7r/_1fj0f517rgcxwx79mn79mfc0000gn/T/form-init3743582784321941885.clj:1:1)</pre>
</div></div>
<p>?</p><p>Sorry, I was working on memory rather than actually typing the thing I put in the description into a REPL, which was dumb.</p>
<p>user=&gt; (let [<span class="error">&#91;foo &amp; bar &amp; baz&#93;</span> []])<br/>
nil</p>Global RankPatchCode and Test[CLJ-1628] Accept list as lib specification in clojure.core/require and clojure.core/usehttp://dev.clojure.org/jira/browse/CLJ-1628
Clojure<p>Currently function clojure.core/load-libs treats '(a.namespace.name) as prefix list so this construct has no effect at all (as if it was prefix list without suffixes). At the same time '<span class="error">&#91;a.namespace.name&#93;</span> causes require call (require 'a.namespace.name). In other cases functions require or use are ambivalent about differences between [] and (). In this particular case there is difference between no-op and lib loading. E.g. Clojure validation tool Eastwood includes rule for this case since the behavior of (require '(a.namespace.name)) is not obvious.</p>
<p>The suggested change lets to avoid this special case in require or use calls (including ones that stem from ns macro expansion). Accepting both list and vector as library specification makes behavior uniform and similar to the way suffix items are handled in prefix lists.</p>
<p>The patch is minimal in order to avoid reordering sequential? functions in clojure/core.clj<br/>
Should I include tests for these cases also?</p>CLJ-1628Accept list as lib specification in clojure.core/require and clojure.core/useEnhancementMinorOpenUnresolvedUnassignedPetr GladkikhSun, 28 Dec 2014 10:06:02 -0600Tue, 30 Dec 2014 02:39:58 -060001<p>If on the other hand representing prefix lists as Clojure lists is intentional and list-for-prefix, vector-for-libspec-or-suffix should be distinguishing feature then we should issue error when</p>
<ul>
<li>prefix list is enclosed in Clojure vector</li>
<li>libspec or suffix is in Clojure list</li>
</ul>
<p>If backwards compatibility is important then one may at least write a warning in ':verbose' mode.</p>
<p>Also there should be error or warning if prefix list is empty.</p>Global RankPatchCode[CLJ-1626] ns macro: compare ns name during macroexpansion. http://dev.clojure.org/jira/browse/CLJ-1626
Clojure<p>Macroexpansion of 'ns' produces 'if' form that is executed at runtime. However comparison can be done during macroexpansion phase producing clearer resulting form in most cases.</p>
<p>Patch for suggested change is in attachment.</p>CLJ-1626ns macro: compare ns name during macroexpansion. EnhancementTrivialOpenUnresolvedUnassignedPetr GladkikhTue, 23 Dec 2014 08:28:57 -0600Tue, 23 Dec 2014 08:30:42 -0600Release 1.6Release 1.711Global Rank[CLJ-1625] Cannot implement protocol methods of the same name inlinehttp://dev.clojure.org/jira/browse/CLJ-1625
Clojure<p>One major benefit of protocols (IMHO) is that the protocol methods are properly namespace qualified. Thus I can have multiple protocols in different namespaces that define a foo method and extend them all (or a subset of them) upon existing types. However, that's not true with extending protocols inline with defrecord and deftype, or with extending protocols on the Java side by implementing their interfaces.</p>
<p>Example:</p>
<div class="preformatted panel" style="border-width: 1px;"><div class="preformattedContent panelContent">
<pre>;; file: protocoltest/foo.clj
(ns prototest.foo)
(defprotocol Foo
(mymethod [this]))
;; file: protocoltest/bar.clj
(ns prototest.bar)
(defprotocol Bar
(mymethod [this]))
;; file: protocoltest/core.clj
(ns prototest.core
(:require [prototest.foo :as foo]
[prototest.bar :as bar]))
;; inline extension of both mymethod methods doesn't work
(defrecord MyRec [x]
foo/Foo
(mymethod [this] :foo)
bar/Bar
(mymethod [this] :bar))
;;=&gt; java.lang.ClassFormatError
;; Duplicate method name&amp;signature in class file prototest/core/MyRec
;; I have to resort to either half-inline-half-dynamic...
(defrecord MyRec [x]
foo/Foo
(mymethod [this] :foo))
(extend-type MyRec
bar/Bar
(mymethod [this] :bar))
;; ... or fully dynamic extension.
(defrecord MyRec [x])
(extend-type MyRec
foo/Foo
(mymethod [this] :foo)
bar/Bar
(mymethod [this] :bar))
;; Then things work just fine.
(foo/mymethod (-&gt;MyRec 1))
;;=&gt; :foo
(bar/mymethod (-&gt;MyRec 1))
;;=&gt; :bar
</pre>
</div></div>
<p>I know that I get the error because both the Foo and the Bar interfaces backing the protocols have a mymethod method and thus they cannot be implemented both at once (at least not with different behavior).</p>
<p>But why throw away the namespacing advantages we have with protocols? E.g., why is the protocoltest.foo.Foo method not named protocoltest$foo$mymethod (or some other munged name) in the corresponding interface? That way, both methods can be implemented inline where you gain the speed advantage, and you can do the same even from the Java side. (Currently, invoking clojure.core.extend from the Java side using clojure.java.api is no fun because you have to construct maps, intern keywords, define functions, etc.)</p>
<p>Of course, the ship of changing the default method naming scheme has sailed long ago, but maybe a :ns-qualified-method-names option could be added to defprotocol.</p>CLJ-1625Cannot implement protocol methods of the same name inlineDefectMajorOpenUnresolvedUnassignedTassilo HornprotocolsTue, 23 Dec 2014 02:20:59 -0600Tue, 23 Dec 2014 02:20:59 -0600Release 1.6Release 1.700Global Rank[CLJ-1623] Support zero-depth structures for update and update-inhttp://dev.clojure.org/jira/browse/CLJ-1623
Clojure<p>Currently "update" and "update-in" assume a nested associative structure at least 1 level deep.</p>
<p>For greater generality, it would be preferable to also support the case of 0 levels deep (i.e. a nested associative structure where there is only a leaf node)</p>
<p>examples:</p>
<p>;; Zero-length paths would be supported in update-in<br/>
(update-in 1 [] inc) =&gt; 2</p>
<p>;; update would get an extra arity which simply substitutes the new value<br/>
(update :old :new) =&gt; :new</p>CLJ-1623Support zero-depth structures for update and update-inEnhancementMinorReopenedUnresolvedUnassignedMike AndersonMon, 22 Dec 2014 23:26:17 -0600Wed, 24 Dec 2014 07:55:10 -0600Release 1.700<p>Duplicate of <a href="http://dev.clojure.org/jira/browse/CLJ-373" title="update-in with empty key paths"><del>CLJ-373</del></a> which has been declined?</p><p>Rich has declined similar requests in the past.</p><p>I disagree with the reasons for rejecting the previous patch. Can we revisit this?</p>
<p>Yes, it is a (very minor) behaviour change for update-in, but only only on undefined implementation behaviour, and even then only on the error case. If people are relying on this then their code is already very broken.</p>
<p>On the plus side, is makes the behaviour more logical and consistent. There is clearly demand for the change (see the various comments in favour of improving this in <a href="http://dev.clojure.org/jira/browse/CLJ-373" title="update-in with empty key paths"><del>CLJ-373</del></a>)</p>
<p>As an aside: if you really want to keep the old behaviour of disallowing empty paths then it would be better to convert the NullPointerException into a meaningful error message e.g. "Empty key paths are not allowed"</p>
<p>Also, I am proposing a corresponding change to update which doesn't have the above concern (since it is introducing a whole new arity)</p><p>Sorry, Rich has said he's not interested.</p>Global Rank[CLJ-1622] No way to AOT class with interface or parent whose fully qualified name doesn't contain a periodhttp://dev.clojure.org/jira/browse/CLJ-1622
Clojure<p>I'm trying to interop with some java code. I have a class files in a jar that contains an interface called `Player` which I can't modify. The issue is that a bare name like this automatically has java.lang prepended to it by the gen-class macro. My ns looks something like</p>
<p> (ns PlayerAI<br/>
(:gen-class :implements <span class="error">&#91;Player&#93;</span>))</p>
<p>which throws an error</p>
<p> java.lang.ClassNotFoundException: java.lang.Player, compiling:(PlayerAI.clj:1:1)</p>
<p>There is no way to avoid this based on what I see in the source <a href="https://github.com/clojure/clojure/blob/ae5e679111b3b72e2a8e3d2ebb1439ff0ca695a7/src/clj/clojure/genclass.clj#L104">here</a>.</p>CLJ-1622No way to AOT class with interface or parent whose fully qualified name doesn't contain a periodDefectMinorOpenUnresolvedUnassignedMark SikorabuginteropMon, 22 Dec 2014 02:53:50 -0600Mon, 22 Dec 2014 02:53:50 -0600Release 1.610Global Rank[CLJ-1615] transient set "keys" and "values" wind up with different metadatahttp://dev.clojure.org/jira/browse/CLJ-1615
Clojure<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">(let [s (-&gt; #{}
<span class="code-keyword">transient</span>
(conj! (clojure.core/with-meta [-7] {:mynum 0}))
(conj! (clojure.core/with-meta [-7] {:mynum -1}))
persistent!)]
[(meta (s [-7])) (meta (first s))])
=&gt; [{:mynum -1} {:mynum 0}]</pre>
</div></div>
<p>basically it looks like the "key" (the value we get by seqing on the set) retains the metadata from the first conj! but the "value" (what we get by calling invoke with the "key") carries the metadata from the second conj!. This does <b>not</b> match the behavior if we don't use transients:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">(let [s (-&gt; #{}
(conj (clojure.core/with-meta [-7] {:mynum 0}))
(conj (clojure.core/with-meta [-7] {:mynum -1})))]
[(meta (s [-7])) (meta (first s))])
=&gt; [{:mynum 0} {:mynum 0}]</pre>
</div></div>
<p>(found playing with zach tellman's collection-check)</p>CLJ-1615transient set "keys" and "values" wind up with different metadataDefectMinorOpenUnresolvedUnassignedMichael BlumecollectionsmetatransientFri, 12 Dec 2014 16:38:54 -0600Sat, 13 Dec 2014 14:40:52 -0600Release 1.601<p>Attached patch demonstrating problem (not a fix)</p><p>More investigation:</p>
<p>The difference between "keys" and "vals" arises from the fact that clojure sets use maps under the covers.</p>
<p>The difference between persistent and transient seems to be because PersistentHashSet.cons short-circuits on contains (<a href="https://github.com/clojure/clojure/blob/clojure-1.6.0/src/jvm/clojure/lang/PersistentHashSet.java#L97">https://github.com/clojure/clojure/blob/clojure-1.6.0/src/jvm/clojure/lang/PersistentHashSet.java#L97</a>) and ATransientSet.conj does not (<a href="https://github.com/clojure/clojure/blob/clojure-1.6.0/src/jvm/clojure/lang/ATransientSet.java#L27">https://github.com/clojure/clojure/blob/clojure-1.6.0/src/jvm/clojure/lang/ATransientSet.java#L27</a>)</p>
<p>Adding a contains check to ATransientSet.conj makes the behavior consistent and passes the attached test, but I imagine this could cause a performance hit. Thoughts?</p><p>Attached proposed fix &#8211; note that this may cause a performance hit for transient sets.</p><p>Attaching an alternative fix &#8211; instead of doing a contains check on every transient conj, back set.get with entryAt. More invasive but possibly faster.</p>Global RankPatchCode and Test[CLJ-1614] Clojure does not start: ClassCastExceptionhttp://dev.clojure.org/jira/browse/CLJ-1614
Clojure<p>The clojure.lang.Compiler class static code throws the ClassCastException when reading compiler options from System properties (Compiler.java, line 260 in the git master release). When running Clojure from Eclipse RCP application the System properties may have non-string values.</p>
<p>Checking if the value is String and ignoring non-strings fixes this problem.</p>Eclipse RCPCLJ-1614Clojure does not start: ClassCastExceptionDefectMinorOpenUnresolvedUnassignedVladimir TsichevskicompilerFri, 12 Dec 2014 11:03:19 -0600Fri, 12 Dec 2014 12:40:03 -0600Release 1.701Global Rank[CLJ-1613] :or defaults should refer to enclosing scope in map destructuringhttp://dev.clojure.org/jira/browse/CLJ-1613
Clojure<p>Michael Blume noticed that :or defaults can depend on the values of other keys, see <a href="https://groups.google.com/d/msg/clojure/6kOhpPOpHWM/ITjWwQFS_VQJ">https://groups.google.com/d/msg/clojure/6kOhpPOpHWM/ITjWwQFS_VQJ</a></p>
<p>Michael's Gist <a href="https://gist.github.com/MichaelBlume/4891dafdd31f0dcbc727">https://gist.github.com/MichaelBlume/4891dafdd31f0dcbc727</a> displays a case where an associative form involving :keys and :or compiles or not depending on the order of symbols in :keys. By tweaking that case one can arrive at expressions which always compile, but produce different values depending on :keys:</p>
<div class="preformatted panel" style="border-width: 1px;"><div class="preformattedContent panelContent">
<pre>(let [foo 1
bar 2
{:keys [bar foo]
:or {foo 3 bar (inc foo)}} {}]
{:foo foo :bar bar})
;= {:foo 3, :bar 4}
(let [foo 1
bar 2
{:keys [foo bar]
:or {foo 3 bar (inc foo)}} {}]
{:foo foo :bar bar})
;= {:foo 3, :bar 2}
</pre>
</div></div>
<p>I believe that the most natural solution is to demand that :or defaults be evaluated in an enclosing scope where none of the destructuring-introduced locals are present. This approach is taken by the 0001 patch.</p>CLJ-1613:or defaults should refer to enclosing scope in map destructuringDefectMajorOpenUnresolvedMichał MarczykMichał MarczykFri, 12 Dec 2014 02:16:37 -0600Wed, 31 Dec 2014 14:37:55 -060012<p>I suspect that this is the right thing to do but I think it's important to note that this will break existing code <a href="https://github.com/ngrunwald/ring-middleware-format/blob/master/src/ring/middleware/format_params.clj#L214">https://github.com/ngrunwald/ring-middleware-format/blob/master/src/ring/middleware/format_params.clj#L214</a></p>Global RankPatchCode and Test[CLJ-1612] clojure.core.reducers/mapcat can call f1 with undefined arity of 0 arguments?http://dev.clojure.org/jira/browse/CLJ-1612
Clojure<p>I have not run across this with running code, so perhaps it is impossible for reasons I have not understood. Also not sure whether fixing issues with reducers is of any importance, given transducers. This was found while testing the Eastwood lint tool on some Clojure namespaces, including clojure.core.reducers.</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">(defcurried mapcat
"Applies f to every value in the reduction of coll, concatenating the result
colls of (f val). Foldable."
{:added <span class="code-quote">"1.5"</span>}
[f coll]
(folder coll
(fn [f1]
(let [f1 (fn
([ret v]
(let [x (f1 ret v)] (<span class="code-keyword">if</span> (reduced? x) (reduced x) x)))
([ret k v]
(let [x (f1 ret k v)] (<span class="code-keyword">if</span> (reduced? x) (reduced x) x))))]
(rfn [f1 k]
([ret k v]
(reduce f1 ret (f k v))))))))</pre>
</div></div>
<p>The definition of macro rfn expands to a (fn ...) that can call f1 with no arguments, which is not a defined arity for f1.</p>CLJ-1612clojure.core.reducers/mapcat can call f1 with undefined arity of 0 arguments?DefectMajorOpenUnresolvedUnassignedAndy FingerhutreducersWed, 10 Dec 2014 20:18:22 -0600Wed, 10 Dec 2014 20:52:41 -0600Release 1.6Release 1.700Global Rank[CLJ-1597] Allow ISeq args to map conjhttp://dev.clojure.org/jira/browse/CLJ-1597
Clojure<p>Currently conj on maps can take only maps or vectors, this patch allows it to take any ISeq:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">user=&gt; (conj {} '(1 2))
{1 2}</pre>
</div></div>CLJ-1597Allow ISeq args to map conjEnhancementMinorOpenUnresolvedUnassignedNicola MomettocollectionsmapsSat, 22 Nov 2014 09:48:53 -0600Sat, 22 Nov 2014 09:48:53 -060000Global RankPatchCode and Test[CLJ-1595] Nested doseqs leak with sequence of huge lazy-seqshttp://dev.clojure.org/jira/browse/CLJ-1595
Clojure<p>Hello!</p>
<p>This little snippet demonstrates the problem:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">(doseq [<span class="code-keyword">outer</span>-seq (list (range)) <span class="code-keyword">inner</span>-seq <span class="code-keyword">outer</span>-seq])</pre>
</div></div>
<p>That's it. It is not just eats my processor, but also eats all available memory. Practically it can affect (and it is) at consuming of complex lazy structures like huge XML-documents.</p>
<p>I think this is at least non trivial behaviour.</p>
<p>It can be fixed by this small patch. We can get next element before current iteration, not after, so outer loop will not hold reference to the head of inner-seq.</p>
<p>This patch doesn't solve all problems, for example this code:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">(doseq [<span class="code-keyword">outer</span>-seq [(range)] <span class="code-keyword">inner</span>-seq <span class="code-keyword">outer</span>-seq])</pre>
</div></div>
<p>leaks. Because chunked-seqs (vector in this case) holds current element by design.</p>CLJ-1595Nested doseqs leak with sequence of huge lazy-seqsDefectMinorOpenUnresolvedUnassignedAndrew RudenkoThu, 20 Nov 2014 10:54:08 -0600Thu, 20 Nov 2014 10:54:08 -060001Global RankPatchCode[CLJ-1593] Use PAM for small maps when assigned to a var rather than always using PHMshttp://dev.clojure.org/jira/browse/CLJ-1593
Clojure<p>I'm reproposing the fix I implemented for <a href="http://dev.clojure.org/jira/browse/CLJ-944">http://dev.clojure.org/jira/browse/CLJ-944</a> a while ago as an enhancement rather than as a defect.</p>
<p>Currently when a map is used as the value of a `def` expression, unless it's an empty map, it will always be a PersistentHashMap even if it's a small map.</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">user=&gt; (def a {:foo :bar})
#'user/a
user=&gt; (class a)
clojure.lang.PersistentHashMap</pre>
</div></div>
<p>The current patch makes makes small maps be compiled to PAMs, consistently with how it's handled in lexical contexts, only using PHMs when the number of elements is above the threshold</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">user=&gt; (def a {:foo :bar})
#'user/a
user=&gt; (class a)
clojure.lang.PersistentArrayMap
user=&gt; (class (let [a {:foo :bar}] a))
clojure.lang.PersistentArrayMap
user=&gt; (def a {0 0 1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9})
#'user/a
user=&gt; (class a)
clojure.lang.PersistentHashMap</pre>
</div></div>
CLJ-1593Use PAM for small maps when assigned to a var rather than always using PHMsEnhancementMinorOpenUnresolvedUnassignedNicola MomettocollectionscompilermapsSat, 15 Nov 2014 12:14:29 -0600Mon, 8 Dec 2014 09:47:00 -060000<p>This might be subsumed under the small collections <a href="http://dev.clojure.org/jira/browse/CLJ-1517" title="Unrolled small vectors">CLJ-1517</a>, not sure. </p><p>This is now out of scope for <a href="http://dev.clojure.org/jira/browse/CLJ-1517" title="Unrolled small vectors">CLJ-1517</a> now that's focused only on vectors.</p><p>We're just splitting the ticket apart, maps will be a separate ticket/patch.</p>Global RankPatchCode[CLJ-1592] Ability to suppress warnings on name conflict with clojure.corehttp://dev.clojure.org/jira/browse/CLJ-1592
Clojure<p>In numerical code, it is often useful and idiomatic to replace clojure.core functions with augmented versions (e.g. clojure.core.matrix.operators defines + in a way that works with whole arrays, not just scalar numbers)</p>
<p>Currently there seems to be no way to avoid a warning in client code when a library does this, e.g.:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">;; library namespace
(ns foo
(:refer-clojure :exclude [+]))
(def + clojure.core/+)
;; later on, in some other namespace
(require '[foo :refer :all])
=&gt; WARNING: + already refers to: #'clojure.core/+ in namespace: bar, being replaced by: #'foo/+</pre>
</div></div>
<p>A workaround exists by using (:refer-clojure :exclude ...) in the user namespace, however this creates unnecessary work for the user and requires maintenance of boilerplate code.</p>
<p>Proposed solution is to allow vars to be annotated with additional metadata (e.g. ^:replace-var ) that when added to library functions will suppress this warning. This will allow library authors to specify that a function should work as a drop-in replacement for clojure.core (or some other namespace), and that a warning is therefore not required.</p>CLJ-1592Ability to suppress warnings on name conflict with clojure.coreEnhancementMinorOpenUnresolvedUnassignedMike AndersonFri, 14 Nov 2014 21:37:00 -0600Fri, 14 Nov 2014 22:26:24 -0600Release 1.6Release 1.701<p>Duplicate with <a href="http://dev.clojure.org/jira/browse/CLJ-1257" title="Suppress warnings when clojure.core symbols are explicitly replaced with &quot;use&quot; or &quot;refer&quot;">CLJ-1257</a> ?</p><p>Hi Andy, it refers to the same warning - but the scope of the solution is different:</p>
<ul class="alternate" type="square">
<li><a href="http://dev.clojure.org/jira/browse/CLJ-1257" title="Suppress warnings when clojure.core symbols are explicitly replaced with &quot;use&quot; or &quot;refer&quot;">CLJ-1257</a> is more like a global way to turn off this warning</li>
<li><a href="http://dev.clojure.org/jira/browse/CLJ-1592" title="Ability to suppress warnings on name conflict with clojure.core">CLJ-1592</a> is for suppressing this warning on specific vars</li>
</ul>
<p>If <a href="http://dev.clojure.org/jira/browse/CLJ-1257" title="Suppress warnings when clojure.core symbols are explicitly replaced with &quot;use&quot; or &quot;refer&quot;">CLJ-1257</a> is implemented and the warning is off be default, <a href="http://dev.clojure.org/jira/browse/CLJ-1592" title="Ability to suppress warnings on name conflict with clojure.core">CLJ-1592</a> becomes mostly unnecessary. Without <a href="http://dev.clojure.org/jira/browse/CLJ-1257" title="Suppress warnings when clojure.core symbols are explicitly replaced with &quot;use&quot; or &quot;refer&quot;">CLJ-1257</a> or if the warning defaults to on, <a href="http://dev.clojure.org/jira/browse/CLJ-1592" title="Ability to suppress warnings on name conflict with clojure.core">CLJ-1592</a> is needed.</p>Global Rank[CLJ-1587] PersistentArrayMap's assoc doesn't respect HASHTABLE_THRESHOLDhttp://dev.clojure.org/jira/browse/CLJ-1587
Clojure<p>Currently a map with more than 8 elements will be converted from a PersistentArrayMap to a PersistentHashMap, but if using assoc, it will take 9 elements before the conversion happens:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">user=&gt; (class {0 0 1 1 2 2 3 3 4 4 5 5 6 6 7 7})
clojure.lang.PersistentArrayMap
user=&gt; (class {0 0 1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8})
clojure.lang.PersistentHashMap
user=&gt; (class (assoc {0 0 1 1 2 2 3 3 4 4 5 5 6 6 7 7} 8 8))
clojure.lang.PersistentArrayMap
user=&gt; (class (assoc {0 0 1 1 2 2 3 3 4 4 5 5 6 6 7 7} 8 8 9 9))
clojure.lang.PersistentHashMap</pre>
</div></div>
<p>After patch:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">user=&gt; (class {0 0 1 1 2 2 3 3 4 4 5 5 6 6 7 7})
clojure.lang.PersistentArrayMap
user=&gt; (class {0 0 1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8})
clojure.lang.PersistentHashMap
user=&gt; (class (assoc {0 0 1 1 2 2 3 3 4 4 5 5 6 6 7 7} 8 8))
clojure.lang.PersistentHashMap
user=&gt; (class (assoc {0 0 1 1 2 2 3 3 4 4 5 5 6 6 7 7} 8 8 9 9))
clojure.lang.PersistentHashMap</pre>
</div></div>CLJ-1587PersistentArrayMap's assoc doesn't respect HASHTABLE_THRESHOLDDefectMinorOpenUnresolvedUnassignedNicola Momettocollectionsdata-structuresmapsWed, 12 Nov 2014 12:02:59 -0600Wed, 12 Nov 2014 12:05:13 -060011Global RankPatchCode[CLJ-1583] Apply forces the evaluation of one element more than necessaryhttp://dev.clojure.org/jira/browse/CLJ-1583
Clojure<p>Given a function with one fixed argument and a vararg, it should be sufficient to force evaluation of 2 elements for apply to know which arity it should select, however it currently forces 3:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">user=&gt; (defn x ([a &amp; b]))
#'user/x
user=&gt; (apply x (map println (iterate inc 0)))
0
1
2
nil</pre>
</div></div>
<p>This makes lazy functions that use apply (for example mapcat) less lazy than they could be.<br/>
The proposed patch makes RT.boundedLength short-circuit immediately after the seq count is greater than the max fixed arity:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">user=&gt; (defn x ([a &amp; b]))
#'user/x
user=&gt; (apply x (map println (iterate inc 0)))
0
1
nil</pre>
</div></div>CLJ-1583Apply forces the evaluation of one element more than necessaryEnhancementMajorOpenUnresolvedUnassignedNicola MomettoFri, 7 Nov 2014 18:06:50 -0600Sun, 9 Nov 2014 15:38:58 -060001<p>The patch in this ticket slightly improves the issue reported at <a href="http://dev.clojure.org/jira/browse/CLJ-1218">http://dev.clojure.org/jira/browse/CLJ-1218</a></p>Global RankPatchCode[CLJ-1582] Overriding in-ns and ns is problematic http://dev.clojure.org/jira/browse/CLJ-1582
Clojure<p>Currently it is possible to override clojure.core/in-ns and clojure.core/ns, but it is not possible to refer to the namespace-specific vars without fully qualifying them:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">user=&gt; (ns foo (:refer-clojure :exclude [in-ns]))
nil
foo=&gt; (def in-ns 1)
#'foo/in-ns
foo=&gt; in-ns
#&lt;clojure.lang.RT$1@76b5e4c5&gt;</pre>
</div></div>
<p>After this patch, overriding in-ns and ns works like for every other clojure.core var:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">user=&gt; (ns foo (:refer-clojure :exclude [in-ns]))
nil
foo=&gt; (def in-ns 1)
#'foo/in-ns
foo=&gt; in-ns
1</pre>
</div></div>CLJ-1582Overriding in-ns and ns is problematic DefectMajorOpenUnresolvedUnassignedNicola MomettoFri, 7 Nov 2014 11:42:49 -0600Fri, 7 Nov 2014 11:46:42 -060011<p>This is motivated by <a href="https://github.com/jonase/eastwood/issues/100">https://github.com/jonase/eastwood/issues/100</a></p>Global RankPatchCode[CLJ-1577] Some hints accept both symbols and class objects, others only symbolshttp://dev.clojure.org/jira/browse/CLJ-1577
Clojure<p>In order to hint primitives, such as longs, you can hint with the symbol 'long. In some places, you can also use the class object java.lang.Long/TYPE. However, in some places, that doesn't work. This is particularly problematic when working with hints in macros, where subtle changes to when metadata is evaluated can lead to changes in whether or not hints are respected.</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">user=&gt; (set! *unchecked-math* :warn-on-boxed)
:warn-on-boxed
user=&gt; (defmacro mac []
(let [field (with-meta 'x {:tag '<span class="code-object">long</span>})]
(-&gt; field meta :tag class prn)
`(deftype Foo# [~field]
clojure.lang.IDeref
(deref [<span class="code-keyword">this</span>#]
(inc ~(with-meta field nil))))))
#'user/mac
user=&gt; (mac)
clojure.lang.Symbol
#&lt;java.lang.<span class="code-object">Class</span>@1c76c583 class user.Foo__13651__auto__&gt;
user=&gt; (defmacro mac []
(let [field (with-meta 'x {:tag java.lang.<span class="code-object">Long</span>/TYPE})]
(-&gt; field meta :tag class prn)
`(deftype Foo# [~field]
clojure.lang.IDeref
(deref [<span class="code-keyword">this</span>#]
(inc ~(with-meta field nil))))))
#'user/mac
user=&gt; (mac)
java.lang.<span class="code-object">Class</span>
Boxed math warning, /<span class="code-keyword">private</span>/<span class="code-keyword">var</span>/folders/43/mnwlkd2s7r1gbjwq6t__mgt40000gn/T/form-init5463347341158437534.clj:1:1 - call: <span class="code-keyword">public</span> <span class="code-keyword">static</span> java.lang.<span class="code-object">Number</span> clojure.lang.Numbers.unchecked_inc(java.lang.<span class="code-object">Object</span>).
#&lt;java.lang.<span class="code-object">Class</span>@74626b21 class user.Foo__13663__auto__&gt;</pre>
</div></div>CLJ-1577Some hints accept both symbols and class objects, others only symbolsDefectMinorOpenUnresolvedUnassignedBrandon BloomtypehintsThu, 30 Oct 2014 21:00:46 -0500Thu, 30 Oct 2014 21:17:21 -0500Release 1.713Global Rank[CLJ-1575] Using a (def ^:const instance) of a deftype that implements IPersistentCollection, triggers compiler errorshttp://dev.clojure.org/jira/browse/CLJ-1575
Clojure<p>The compiler has a lot of assumptions about the possible types of IPersistentCollection literals and rightfully so. The strange thing with this case is, that taking the (constant) value works as soon as count is defined, but using it as an argument hits a closed dispatch for emitting the empty variants of the various literals.</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">&gt; (deftype T [] clojure.lang.IPersistentCollection (count [_] 0)
&gt; (def ^:<span class="code-keyword">const</span> t (T.))
&gt; (meta t)
java.lang.UnsupportedOperationException: Unknown Collection type
<span class="code-object">Compiler</span>.java:2860 clojure.lang.<span class="code-object">Compiler</span>$EmptyExpr.emit
<span class="code-object">Compiler</span>.java:3632 clojure.lang.<span class="code-object">Compiler</span>$InvokeExpr.emitArgsAndCall
...</pre>
</div></div>
<p>EDIT updated the ticket after some investigation<br/>
NOTE attached test patch doesn't even implement (count []) for the deftype, which just triggers a rightful AbstractMethodError</p>fresh replCLJ-1575Using a (def ^:const instance) of a deftype that implements IPersistentCollection, triggers compiler errorsDefectMinorOpenUnresolvedUnassignedHerwig HochleitnerWed, 29 Oct 2014 21:34:45 -0500Thu, 30 Oct 2014 07:14:08 -0500Release 1.6Release 1.702<p>The test had a typo, sorry</p><p>Looks like a variant of <a href="http://dev.clojure.org/jira/browse/CLJ-1093" title="Empty PersistentCollections get incorrectly evaluated as their generic clojure counterpart">CLJ-1093</a>.</p>Global Rank[CLJ-1573] Support (Java) transient fields in deftype, e.g. for hashcodeshttp://dev.clojure.org/jira/browse/CLJ-1573
Clojure<p>Enhance deftypes to allow fields to be marked ACC_TRANSIENT.</p>
<p>strawman syntax:<br/>
(deftype AType <span class="error">&#91;^:transient hash&#93;</span>)</p>
<p>Came across this need while experimenting with a <a href="https://github.com/ghadishayban/clojure/commit/906cd6ed4d7c624dc4e553373dabfd57550eeff2">reified range written in a deftype</a>, not in Java.</p>
<p>Patch doesn't include docstring change, but has a test.</p>CLJ-1573Support (Java) transient fields in deftype, e.g. for hashcodesEnhancementMinorOpenUnresolvedUnassignedGhadi ShaybancompilerdeftypeSun, 26 Oct 2014 21:04:02 -0500Mon, 29 Dec 2014 12:25:53 -060042<p>Perhaps ^:transient-mutable would be a more appropriate modifier name to be consistent with the ^:unsynchronized-mutable and ^:volatile-mutable field modifiers. In any event, this feature would eliminate the need to drop down to Java for types that require transient fields. </p><p>Roberto, there is a "Vote" word you can click on to actually vote for tickets, and ticket wranglers actually look at those votes at times to examine popular ones sooner. +1 comments don't do that.</p>Global RankPatchCode and Test[CLJ-1570] Core clojure code mixes tabs with spaceshttp://dev.clojure.org/jira/browse/CLJ-1570
Clojure<p>A handful of functions in clojure.core, clojure.core-proxy, clojure.inspector, clojure.xml, clojure.pprint, clojure.stacktrace, clojure.set, and clojure.test switch partway through from indenting with spaces to indenting with tabs. This may cause them to display incorrectly depending on how the developer's editor is configured.</p>
<p>(not sure if this should be marked defect or task)</p>CLJ-1570Core clojure code mixes tabs with spacesDefectTrivialOpenUnresolvedUnassignedMichael BlumeMon, 20 Oct 2014 13:30:47 -0500Mon, 20 Oct 2014 13:41:01 -0500Release 1.3Release 1.4Release 1.5Release 1.601<p>Some similarities to <a href="http://dev.clojure.org/jira/browse/CLJ-1026" title="Mixed end-of-line endings in the source code">CLJ-1026</a>, although this problem does not cause the same issues with warnings on git patches as <a href="http://dev.clojure.org/jira/browse/CLJ-1026" title="Mixed end-of-line endings in the source code">CLJ-1026</a> does, as far as I know.</p>
<p>One similarity is that <em>if</em> it is of interest (I don't know if it is), Alex or other Clojure screeners may want a procedure to clean them all up, and perhaps repeat that process periodically, e.g. before each major release.</p>Global Rank[CLJ-1566] Documentation for clojure.core/require does not document :renamehttp://dev.clojure.org/jira/browse/CLJ-1566
Clojure<p>By contrast, clojure.core/use does mention :rename.</p>
<p>I attach a patch</p>CLJ-1566Documentation for clojure.core/require does not document :renameDefectMinorOpenUnresolvedUnassignedJames LaverThu, 16 Oct 2014 11:19:06 -0500Sun, 19 Oct 2014 04:36:48 -050000<p>James, your patch removes any mention of the :all keyword, and that keyword is not mentioned in the doc string for clojure.core/refer.</p>
<p>I haven't checked whether refer can take :all as an argument, but clojure.core/require definitely can.</p><p>Ah, you're quite right. Fixed now. See updated patch in a sec.</p><p>For sake of reduced confusion, it would be better if you could either name your patches differently, or delete obsolete ones with identical names as later ones. JIRA allows multiple patches to have the same names, without replacing the earlier ones.</p><p>Okay, that's done. The JIRA interface is a bit tedious in places.</p><p>Seems to me the sentence should end with a dot.</p><p>Added a dot.</p>Global RankPatchCode[CLJ-1563] How About Default Implementations on Protocolshttp://dev.clojure.org/jira/browse/CLJ-1563
Clojure<p>Consider this example</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">user=&gt; (defprotocol Foo (foo [x] x))
Foo
user=&gt; (defrecord Bar [gaz waka] Foo)
user.Bar
user=&gt; (def bar (Bar. 1 2))
#'user/bar
user=&gt; (.foo bar)
AbstractMethodError user.Bar.foo()Ljava/lang/<span class="code-object">Object</span>; sun.reflect.NativeMethodAccessorImpl.invoke0 (NativeMethodAccessorImpl.java:-2)
user=&gt;</pre>
</div></div>
<p>What about the default implementation.</p>CLJ-1563How About Default Implementations on ProtocolsEnhancementMinorOpenUnresolvedUnassignedDavid WilliamsSat, 11 Oct 2014 20:46:32 -0500Sun, 12 Oct 2014 12:36:38 -050001<p>As it stands you have to workaround with this</p>
<p><a href="http://stackoverflow.com/questions/15039431/clojure-mix-protocol-default-implementation-with-custom-implementation">http://stackoverflow.com/questions/15039431/clojure-mix-protocol-default-implementation-with-custom-implementation</a></p><p>I don't think we need it. What's the rationale behind extending some protocol, not implementing its methods, and then calling those methods, expecting them not to throw. Be explicit about what yout type should do, whether it is a default or custom behavior. You basically have three options</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">(defn <span class="code-keyword">default</span>-foo
[<span class="code-keyword">this</span>]
:foo)
(defprotocol P
(-foo [<span class="code-keyword">this</span>]))
(deftype T
P
(-foo [<span class="code-keyword">this</span>] (<span class="code-keyword">default</span>-foo))
(defn foo
[x]
(-foo x))</pre>
</div></div>
<p>or</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">(defprotocol P
(-foo [<span class="code-keyword">this</span>]))
(deftype T)
(defn foo
[x]
(<span class="code-keyword">if</span> (satisfies? P x)
(-foo x)
:foo))</pre>
</div></div>
<p>or</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">(defprotocol P
(-foo [<span class="code-keyword">this</span>]))
(extend-protocol P
java.lang.<span class="code-object">Object</span>
(-foo [<span class="code-keyword">this</span>] :foo))
(deftype T)
(defn foo
[x]
(-foo x))</pre>
</div></div>
<p>I think however that my first approach is unidiomatic and you should prefer the latter ones.</p><p>I agree, this is a low priority enhancement. I think it could make the Protocol experience more DWIMy, and Java 8 has default implementations on interfaces for the same kind of convenience.</p>Global Rank[CLJ-1560] Forbid closing over mutable fields completelyhttp://dev.clojure.org/jira/browse/CLJ-1560
Clojure<p>Closing over mutable fields should be forbidden completely (and generate compiler exception), not just when trying to set! them. As the change of the mutable field does not propagate into closed over ones, this leads to surprising bugs:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">(defprotocol P
(-set [<span class="code-keyword">this</span>])
(-get [<span class="code-keyword">this</span>])
(-get-fn [<span class="code-keyword">this</span>]))
(deftype T [^:unsynchronized-mutable val]
P
(-set [<span class="code-keyword">this</span>] (set! val :bar))
(-get [<span class="code-keyword">this</span>] val)
(-get-fn [<span class="code-keyword">this</span>] (fn [] val)))
(def x (-&gt;T :foo))
(def xf (-get-fn x))
user&gt; (-set x)
:bar
user&gt; (-get x)
:bar
user&gt; (xf)
:foo ;; should be :bar !!!</pre>
</div></div>CLJ-1560Forbid closing over mutable fields completelyDefectMajorOpenUnresolvedUnassignedJozef WagnerFri, 10 Oct 2014 13:41:18 -0500Mon, 29 Dec 2014 02:32:48 -0600Release 1.601<p>related issue <a href="http://dev.clojure.org/jira/browse/CLJ-274" title="cannot close over mutable fields (in deftype)">CLJ-274</a></p><p>In the given example, the close-over happens before the set!, so the closure gets the value, not an assignable container. This is consistent with the rest of the language (pass-by-value not by mutable container)</p><p>Thanks for explanation. The ticket is about a proposal that closing over a mutable field should result in error being thrown, an not in a value. If value is desired, an explicit let binding will have to be used. So far, I haven't found a valid use case where closing over mutable field and getting the value closed over is the intended and wanted behavior.</p>Global Rank[CLJ-1556] Add instance check functions to defrecord/deftypehttp://dev.clojure.org/jira/browse/CLJ-1556
Clojure<p>It is often necessarty to test for instance? on deftypes/defrecords, this patch makes the two macros automatically generate a type? function implemented as (fn <span class="error">&#91;x&#93;</span> (instance? type x)), to complement &#45;&gt;type and map&#45;&gt;type <br/>
Example:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">user=&gt;(deftype x [])
user.x
user=&gt;(x? (x.))
<span class="code-keyword">true</span></pre>
</div></div>CLJ-1556Add instance check functions to defrecord/deftypeEnhancementMinorOpenUnresolvedUnassignedNicola MomettodefrecorddeftypeThu, 9 Oct 2014 08:05:50 -0500Thu, 9 Oct 2014 09:17:34 -050000<p>What about camel cased types? predicate <tt>SomeType?</tt> does not look like an idiomatic type predicate. I suggest to have this type predicate function and its name optional, through e.g. :predicate metadata on a type name. Moreover, it is far more useful to have such predicate on protocols, rather than types.</p><p>I don't think camel cased types should pose any issue. we use -&gt;SomeType just as fine, I don't see why SomeType? should be problematic.</p>
<p>I disagree that it's more useful to have a predicate for protocols since protocols are already regular Vars and it's just a matter of (satisfies? theprotocol x), the value of the predicate on types/record is to minimize the necessity of having to import the actual class</p>Global RankPatchCode[CLJ-1550] Classes generated by deftype and defrecord don't play nice with .getPackagehttp://dev.clojure.org/jira/browse/CLJ-1550
Clojure<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">(.getPackage <span class="code-object">String</span>)
;; =&gt; #&lt;Package <span class="code-keyword">package</span> java.lang, Java Platform API Specification, version 1.7&gt;
(deftype T [])
(.getPackage T)
;; =&gt; nil</pre>
</div></div>
<p>This seems like a bug to me as it's not obvious why the class generated by <b>deftype</b> should exhibit different behaviour. </p>CLJ-1550Classes generated by deftype and defrecord don't play nice with .getPackageDefectMajorOpenUnresolvedUnassignedBozhidar BatsovbugTue, 7 Oct 2014 08:46:56 -0500Tue, 7 Oct 2014 12:13:33 -0500Release 1.602<p>According to <a href="http://docs.oracle.com/javase/7/docs/api/java/lang/Class.html#getPackage(">http://docs.oracle.com/javase/7/docs/api/java/lang/Class.html#getPackage(</a>) this method returns the package information found by the class loader or null if there is none. Its not clear to me that the current behavior is wrong per the spec. I would need to experiment more to see if this is unusual or not.</p><p>A bit of <a href="https://github.com/clojure-emacs/cider-nrepl/pull/127">background</a> for the issue. I'm no expert on the topic, but being able to procure all the class information except its package definitely looks strange to me. </p><p>if you AOT compile(generate a class file on disk for a deftype), getPackage works fine, which suggests to me it is a jvm issue</p><p>actually, it must just be that dynamicclassloader doesn't define a package for classes it loads</p><p>Yep, I believe that's correct.</p>Global Rank[CLJ-1548] primitive type hints on protocol methods break call siteshttp://dev.clojure.org/jira/browse/CLJ-1548
Clojure<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">user=&gt; (defprotocol P (f [<span class="code-keyword">this</span> ^<span class="code-object">long</span> x]))
P
user=&gt; (deftype T [] P (f [_ x] x))
#&lt;java.lang.<span class="code-object">Class</span> class user.T&gt;
user=&gt; (f (T.) 5)
ClassCastException user$eval7289$fn__7290$G__7280__7297 cannot be <span class="code-keyword">cast</span> to clojure.lang.IFn$OLO user/eval7313 (NO_SOURCE_FILE:1)</pre>
</div></div>CLJ-1548primitive type hints on protocol methods break call sitesDefectMinorOpenUnresolvedUnassignedBrandon BloomSat, 4 Oct 2014 13:29:44 -0500Sat, 4 Oct 2014 13:29:44 -0500Release 1.602Global Rank[CLJ-1543] Type tags on argument vector appear to help avoid reflection when used with defn, but not with def foo (fn ...)http://dev.clojure.org/jira/browse/CLJ-1543
Clojure<p>I would have expected that both of the Java interop calls below would avoid reflection, but only the first involving f1 does.</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">Clojure 1.6.0
user=&gt; (set! *warn-on-reflection* <span class="code-keyword">true</span>)
<span class="code-keyword">true</span>
user=&gt; (defn f1 ^java.util.LinkedList [coll] (java.util.LinkedList. coll))
#'user/f1
user=&gt; (def f2 (fn ^java.util.LinkedList [coll] (java.util.LinkedList. coll)))
#'user/f2
user=&gt; (.size (f1 [2 3 4]))
3
user=&gt; (.size (f2 [2 3 4]))
Reflection warning, NO_SOURCE_PATH:5:1 - reference to field size can't be resolved.
3</pre>
</div></div>
<p>Not sure if this has anything to do with <a href="http://dev.clojure.org/jira/browse/CLJ-1232" title="Functions with non-qualified return type hints force import of hinted classes when called from other namespace">CLJ-1232</a>, but was discovered when testing variants of that issue.</p>CLJ-1543Type tags on argument vector appear to help avoid reflection when used with defn, but not with def foo (fn ...)DefectMinorOpenUnresolvedUnassignedAndy FingerhutinteroptypehintsTue, 30 Sep 2014 21:06:28 -0500Thu, 2 Oct 2014 07:15:17 -0500Release 1.602<p>What a nice number for a ticket, 1543. The year Copernicus's most celebrated book was published: <a href="http://en.wikipedia.org/wiki/Nicolaus_Copernicus">http://en.wikipedia.org/wiki/Nicolaus_Copernicus</a></p><p>Isn't type hinting of arg vector meant only for primitive type hints? AFAIK non-primitive type hints should be on a function name, everything else is non idiomatic.</p><p>This isn't an issue of arg vector hinting vs function name hinting.<br/>
The issue here is that return type hinting cannot be put on anonymous functions but only on defns as the :arglists will be added by defn on the Var's metadata.</p>
<p>This is one of the reasons why I'd like to have that information as a field on the fn rather than as metadata on the Var</p><p>Jozef, you may be correct that non-primitive type hints on the argument vector are non idiomatic. Do you have any source for that I could read?</p><p>Only the version with hints on the argument vectors is documented at <a href="http://clojure.org/java_interop#Java">http://clojure.org/java_interop#Java</a> Interop-Type Hints. However, in the case you have just one arity (or all arities return a value of the same type) the hint on the var name also works. But the two versions seem to have different semantics. Have a look at <a href="http://dev.clojure.org/jira/browse/CLJ-1232" title="Functions with non-qualified return type hints force import of hinted classes when called from other namespace">CLJ-1232</a>.</p><p>Type hinting is a very intricate part of Clojure but you can almost always apply a <b>'place hint on a symbol'</b> idiom. Type hinting on an arg vector must be done only in two cases:</p>
<ul class="alternate" type="square">
<li>primitive hints</li>
<li>different return classes for different arities</li>
</ul>
<p>In the first case, compiler needs type hints when compiling fn* (see <span class="error">&#91;1&#93;</span>), not later, thus you must specify them on arg vector.</p>
<p>Second case, which is the issue discussed here, must be used only when defining with defn. Compiler first looks for the tag in the metadata of a var, and if it does not find one, it has a special case in which it looks for a return class inside :arglist metadata. This is clearly a very special case <span class="error">&#91;2&#93;</span> to handle situations where you have different return classes for different arities. Obviously, using def instead of defn won't create an :arglist metadata for you thus you see a reflection warning. Example:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">user=&gt; (def f2 (fn ^java.util.LinkedList [coll] (java.util.LinkedList. coll)))
#'user/f2
user=&gt; (.size (f2 [2 3 4]))
Reflection warning, /tmp/form-init.clj:1:1 - reference to field size can't be resolved.
3
user=&gt; (alter-meta! #'f2 assoc :arglists '(^java.util.LinkedList [coll]))
{:ns #&lt;Namespace user&gt;, :name f2, :file <span class="code-quote">"/tmp/form-init.clj"</span>, :column 1, :line 1, :arglists ([coll])}
user=&gt; (.size (f2 [2 3 4]))
3</pre>
</div></div>
<p>BTW <a href="http://dev.clojure.org/jira/browse/CLJ-1491" title="External type hint inconsistency between regular functions and primitive functions"><del>CLJ-1491</del></a> has a discussion slightly relevant to this topic.</p>
<p><span class="error">&#91;1&#93;</span> <a href="https://github.com/clojure/clojure/blob/03cd9d159a2c49a21d464102bb6d6061488b4ea2/src/jvm/clojure/lang/Compiler.java#L5134">https://github.com/clojure/clojure/blob/03cd9d159a2c49a21d464102bb6d6061488b4ea2/src/jvm/clojure/lang/Compiler.java#L5134</a><br/>
<span class="error">&#91;2&#93;</span> <a href="https://github.com/clojure/clojure/blob/03cd9d159a2c49a21d464102bb6d6061488b4ea2/src/jvm/clojure/lang/Compiler.java#L3572">https://github.com/clojure/clojure/blob/03cd9d159a2c49a21d464102bb6d6061488b4ea2/src/jvm/clojure/lang/Compiler.java#L3572</a></p>
<p>Andy, I've found sources that speak against my recommendations <img class="emoticon" src="http://dev.clojure.org/jira/images/icons/emoticons/smile.gif" height="20" width="20" align="absmiddle" alt="" border="0"/> See <a href="http://dev.clojure.org/jira/browse/CLJ-811" title="Support hinting arg vectors"><del>CLJ-811</del></a> and <span class="error">&#91;1&#93;</span>.</p>
<p><span class="error">&#91;1&#93;</span> <a href="https://groups.google.com/d/msg/clojure/b005zQCPxOQ/6G0AlWKKKa0J">https://groups.google.com/d/msg/clojure/b005zQCPxOQ/6G0AlWKKKa0J</a></p>Global Rank[CLJ-1538] Set literal duplicate check occurs too early.http://dev.clojure.org/jira/browse/CLJ-1538
Clojure<p>I cannot use literal syntax to create a set/map with unique members/keys if the elements are generated with an identical form. Examples of such legal forms: (rand), (read), (clojure.core.async/&lt;!!), etc. I will use (rand) in these examples.</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">user=&gt; #{(rand) (rand)}
IllegalArgumentException Duplicate key: (rand) clojure.lang.PersistentHashSet.createWithCheck (PersistentHashSet.java:68)
user=&gt; {(rand) 1, (rand) 2}
IllegalArgumentException Duplicate key: (rand) clojure.lang.PersistentArrayMap.createWithCheck (PersistentArrayMap.java:70)</pre>
</div></div>
<p>It appears that the input is being checked for duplicates <b>before</b> the arguments to the collection constructors are evaluated. However, this doesn't prevent the need to run the check again later.</p>
<p>Note that duplicates are still (correctly) detected, <b>after</b> evaluation, even if duplicates do not appear as literals in the source:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">user=&gt; #{(+ 1 1) 2}
IllegalArgumentException Duplicate key: 2 clojure.lang.PersistentHashSet.createWithCheck (PersistentHashSet.java:56)
user=&gt; {(+ 1 1) :a, 2 :b}
IllegalArgumentException Duplicate key: 2 clojure.lang.PersistentArrayMap.createWithCheck (PersistentArrayMap.java:70)</pre>
</div></div>
<p>The first duplicate check therefore seems to be both redundant and incorrect.</p>
<p>Note that this eager duplicate-checking seems to have higher precedence even than the syntax-quote reader macro.</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">user=&gt; `#{~(rand) ~(rand)}
IllegalArgumentException Duplicate key: (clojure.core/unquote (rand)) clojure.lang.PersistentHashSet.createWithCheck (PersistentHashSet.java:68)
user=&gt; `{~(rand) 1, ~(rand) 2}
IllegalArgumentException Duplicate key: (clojure.core/unquote (rand)) clojure.lang.PersistentArrayMap.createWithCheck (PersistentArrayMap.java:70)</pre>
</div></div>
<p>This is odd &#8211; since syntax-quote should not realize a collection at all at read time:</p>
<blockquote><p>For Lists/Vectors/Sets/Maps, syntax-quote establishes a template of the corresponding data structure. Within the template, unqualified forms behave as if recursively syntax-quoted, but forms can be exempted from such recursive quoting by qualifying them with unquote or unquote-splicing, in which case they will be treated as expressions and be replaced in the template by their value, or sequence of values, respectively. (<a href="http://clojure.org/reader">http://clojure.org/reader</a>)</p></blockquote>
<p>Definitions aside, based on the apparent expansion of syntax-quote, I would expect the previous to have worked correctly.</p>
<p>If I fake the expected macroexpansion by manually substituting the desired inputs, I get the expected results:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">user=&gt; '`#{~:a ~:b}
(clojure.core/apply clojure.core/hash-set (clojure.core/seq (clojure.core/concat (clojure.core/list :b) (clojure.core/list :a))))
user=&gt; (clojure.core/apply clojure.core/hash-set (clojure.core/seq (clojure.core/concat (clojure.core/list (rand)) (clojure.core/list (rand)))))
#{0.27341896385866227 0.3051522362827035}
user=&gt; '`{~:a 1, ~:b 2}
(clojure.core/apply clojure.core/hash-map (clojure.core/seq (clojure.core/concat (clojure.core/list :a) (clojure.core/list 1) (clojure.core/list :b) (clojure.core/list 2))))
user=&gt; (clojure.core/apply clojure.core/hash-map (clojure.core/seq (clojure.core/concat (clojure.core/list (rand)) (clojure.core/list 1) (clojure.core/list (rand)) (clojure.core/list 2))))
{0.12476921225204185 2, 0.5807961046096718 1}</pre>
</div></div>
<p>It seems to me that there is a superfluous duplicate check being run before the set/map reader macros evaluate their arguments. This check should seemingly be removed. Even if the check did not catch some false-positive duplicates (as it does), it would be unnecessary since the apparent second post-evaluation check would catch all true duplicates.</p>
<p>All that said, it's unclear that this check should happen at all. If I try to create sets/map with duplicate members/keys, I don't get an error. The duplicates are silently removed or superseded.</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">user=&gt; (set (list 1 1))
#{1}
user=&gt; (hash-map 1 2 1 3)
{1 3}</pre>
</div></div>
<p>It seems it would be most consistent for literals constructed by the reader syntax to do the same.</p>
<p>I can see the argument that a literal representation is not a 'request to construct' but rather an attempt to simulate the printed representation of a literal data object. From that perspective, disallowing 'illegal' printed representations seems reasonable. Unfortunately, the possibility of evaluated forms inside literal vectors, sets, and maps (since lists are evaluated at read time) already breaks this theory. That is, the printed representation of such collections is <b>not</b> an accurately readable form, so read-time duplicate checking still cannot prevent seeming inconsistencies in print/read representations:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">user=&gt; '#{(+ 1 1) 2}
#{(+ 1 1) 2}
user=&gt; #{(+ 1 1) 2}
IllegalArgumentException Duplicate key: 2 clojure.lang.PersistentHashSet.createWithCheck (PersistentHashSet.java:56)</pre>
</div></div>
<p>Given that the problem cannot be completely avoided at all, it seems simplest and most consistent to treat reader literal constructors like their run-time counterparts, as syntax quote would in the absence of the spurious duplicate check.</p>CLJ-1538Set literal duplicate check occurs too early.DefectMinorOpenUnresolvedUnassignedChhi'mèd KünzangreaderSat, 27 Sep 2014 00:03:12 -0500Thu, 9 Oct 2014 08:09:17 -0500Release 1.6Release 1.701<p>Also see <a href="http://dev.clojure.org/jira/browse/CLJ-1555" title="Set literal duplicate check not consistent with set semantics"><del>CLJ-1555</del></a></p><p>Potentially related: <a href="http://dev.clojure.org/jira/browse/CLJ-1425">http://dev.clojure.org/jira/browse/CLJ-1425</a></p>Global Rank[CLJ-1536] Remove usage of sun.misc.Signal (which may not be available in Java 9)http://dev.clojure.org/jira/browse/CLJ-1536
Clojure<p>It looks like Java 9 will not continue to provide access to "internal" classes like sun.misc.Signal. Clojure currently uses this in the REPL to trap ctrl-c (SIGINT) and cancel current evaluation instead of process shutdown.</p>
<p>There is a page of alternatives here:<br/>
<a href="https://wiki.openjdk.java.net/display/JDK8/Java+Dependency+Analysis+Tool">https://wiki.openjdk.java.net/display/JDK8/Java+Dependency+Analysis+Tool</a></p>
<p>But there is no suggested alternative for sun.misc.Signal and I'm not aware of a portable solution to it.</p>CLJ-1536Remove usage of sun.misc.Signal (which may not be available in Java 9)EnhancementMajorOpenUnresolvedUnassignedAlex MillerFri, 26 Sep 2014 11:01:23 -0500Fri, 26 Sep 2014 11:01:23 -0500Release 1.703Global Rank[CLJ-1534] Adding condp-> and condp->> macros to core libraryhttp://dev.clojure.org/jira/browse/CLJ-1534
Clojure<p>After introduction of cond-&gt; and cond-&gt;&gt; macros in 1.5. It makes sense to have condp-&gt; and condp-&gt;&gt; macros in the core library.</p>
<p> (condp-&gt; {}<br/>
(complement :a) (assoc :a 1)<br/>
:a (assoc :b 2)) ;=&gt; {:b 2, :a 1}</p>
<p>In the above example the result of each expr which was evaluated is being passed to the next predicate.</p>CLJ-1534Adding condp-> and condp->> macros to core libraryEnhancementMajorOpenUnresolvedUnassignedKuldeepenhancementmacroWed, 24 Sep 2014 23:17:43 -0500Wed, 28 Jan 2015 11:31:07 -0600Release 1.700<p>Kuldeep, I cannot comment on whether this change is of interest to the Clojure developers, because I do not know.</p>
<p>I can say that the patch you have attached is not in the expected format. See the page below for instructions on creating a patch in the expected format:</p>
<p><a href="http://dev.clojure.org/display/community/Developing+Patches">http://dev.clojure.org/display/community/Developing+Patches</a></p><p>Rebased against master and generated patch as described in wiki.</p>Global RankPatchCode[CLJ-1532] pr-str captures stdout from printing side-effects of lazily evaluated expressions.http://dev.clojure.org/jira/browse/CLJ-1532
Clojure<p>Because clojure.core/pr-str uses with-out-str to capture the output of pr (and pr cannot be parsed a writable thing - just uses <b>out</b>). </p>
<p>If you pr-str the result of something lazy you can get side-effects written to stdout with println interspersed with the output. For example in my case I was extracting benchmarks from the library criterium and trying to print the data structure to the file. The solution would be to provide an overload of pr/pr-str that takes a writer. I note that pr-on provides some of the functionality but it is private.</p>
<p>This is an ugly bug when you're trying to persist program output in EDN, because the randomly interspersed stdout messages make it invalid for read-string. We shouldn't need our functions to be pure for pr-str to work as expected.</p>
<p>I've omitted a patch because although I think a fix is straight-forward I'm not sure quite where it should go (e.g. make pr-on public, change pr, change pr-str)</p>LinuxCLJ-1532pr-str captures stdout from printing side-effects of lazily evaluated expressions.DefectMinorOpenUnresolvedUnassignedSilas DavisprintTue, 23 Sep 2014 09:45:00 -0500Tue, 23 Sep 2014 15:33:44 -0500Release 1.600Global Rank[CLJ-1530] Make foo/bar/baz unreadablehttp://dev.clojure.org/jira/browse/CLJ-1530
Clojure<p>Currently keywords and symbols containing more than one slash are disallowed by the spec, but allowed by the readers.<br/>
This trivial patch makes them unreadable by the readers too.</p>
<p>Pre:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">user=&gt; :foo/bar/baz
:foo/bar/baz</pre>
</div></div>
<p>Post:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">user=&gt; :foo/bar/baz
RuntimeException Invalid token: :foo/bar/baz clojure.lang.Util.runtimeException (Util.java:221)</pre>
</div></div>CLJ-1530Make foo/bar/baz unreadableEnhancementMajorOpenUnresolvedUnassignedNicola MomettoMon, 22 Sep 2014 12:03:41 -0500Tue, 28 Oct 2014 04:36:17 -050002<p>Perhaps overlap with <a href="http://dev.clojure.org/jira/browse/CLJ-1527" title="Harmonize accepted / documented symbol and keyword syntax over various readers">CLJ-1527</a> ?</p><p>Please notice that keywords with more than one slash has a different hashcode across clojure version 1.5 and 1.6 </p>
<p>This creates a problem when using a datomic version that works with clojure 1.5 under clojure 1.6 and the schema have one or more keys with more than one slash.</p>
Global RankPatchCode and Test[CLJ-1526] clojure.core/> inconsistent behavior wrt to documentation.http://dev.clojure.org/jira/browse/CLJ-1526
Clojure<p>The &gt; function is inconsistent wrt to their behaviour for 0 arity.</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">user&gt; (doc &gt;)
-------------------------
clojure.core/&gt;
([x] [x y] [x y &amp; more])
Returns non-nil <span class="code-keyword">if</span> nums are in monotonically decreasing order,
otherwise <span class="code-keyword">false</span>.
nil
user&gt; (&gt; 3 2)
<span class="code-keyword">true</span>
user&gt; (&gt; 3)
<span class="code-keyword">true</span>
user&gt; (&gt;)
ArityException Wrong number of args (0) passed to: core/&gt; clojure.lang.AFn.throwArity (AFn.java:429)</pre>
</div></div>
<p>This is mostly likely to become problematic when using &gt; via apply where</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">(or (= 0 (count l))
(apply &gt; l))</pre>
</div></div>
<p>It seems that the documentation should be updated, 0-arg case should return true, or the 1-arg case should also throw an exception.</p>
<p>This affects the other comparators also.</p>CLJ-1526clojure.core/> inconsistent behavior wrt to documentation.EnhancementMinorOpenUnresolvedUnassignedPhillip LordmathWed, 17 Sep 2014 08:38:30 -0500Mon, 22 Sep 2014 09:47:38 -050011<p>As per my original post on this (here: <a href="https://groups.google.com/d/msg/clojure/8zkpO9FBN64/u2LAQsR93IgJ">https://groups.google.com/d/msg/clojure/8zkpO9FBN64/u2LAQsR93IgJ</a>), while the question of whether an empty set has monotonic order perhaps has more than one answer in theory, from a purely pragmatic engineering perspective, it makes the most sense to evaluate to true here.</p>
<p>This /should/ not be a breaking change. Therefore it is fairly safe to introduce into a minor revision. It's a also a trivial fix. But it is <b>possible</b> (though highly unlikely) that someone could have code that depends on the exception being raised at runtime (as it does now) to handle empty lists in some special way. Such code is horrible and ought to be rewritten, so should not be seen as justification for retaining the current behaviour, which limits the general usefulness of these functions and may be responsible for subtle bugs in existing production code.</p>
<p>However such a change should probably not be backported to existing 1.6.x branches, just to be 100% safe, since it is not a security issue. My suggestion therefore would be to add a note to the docs in existing maintenance branches (any future 1.6.x) and evaluate to true in future versions (1.7+).</p>Global Rank[CLJ-1523] Add 'doseq' like macro for transducershttp://dev.clojure.org/jira/browse/CLJ-1523
Clojure<p>Doseq is currently a good way to execute a lazy sequence and perform side-effects. It would be nice to have a matching macro for transducers. </p>
<p><b>Approach:</b> The included patch simply calls transduce with the provided xform, collection, and a reducing function that throws away the accumulated value at each step. The value from each reducing step is bound to the provided symbol. A shorter arity is provided for those cases when no xform is desired, but fast doseq-like semantics are still wanted. </p>
<p><b>Patch:</b> doreduced2.diff</p>CLJ-1523Add 'doseq' like macro for transducersEnhancementTrivialOpenUnresolvedUnassignedTimothy BaldridgeMon, 8 Sep 2014 23:24:24 -0500Tue, 9 Sep 2014 07:54:58 -0500Release 1.721<p>How about making xform parameter optional? And you have a typo in docstring example, doseq -&gt; doreduced.</p><p>Good point, fixed typeo, added other arity.</p>Global RankPatchCode and Test[CLJ-1522] Enhance multimethods metadatahttp://dev.clojure.org/jira/browse/CLJ-1522
Clojure<p>I think that multimethod metadata can be extended a bit with some property indicating the var in question is referring to a multimethod (we have something similar for macros) and some default arglists property. </p>
<p>I'm raising this issue because as a tool writer (CIDER) I'm having hard time determining if something is a multimethod (I have to resort to code like (instance? clojure.lang.MultiFn obj) which is acceptable, but not ideal I think (compared to macros and special forms)). There's also the problem that I cannot provide the users with eldoc (function signature) as it's not available in the metadata (this issue was raised on the mailing list as well <a href="https://groups.google.com/forum/#!topic/clojure/crje_RLTWdk">https://groups.google.com/forum/#!topic/clojure/crje_RLTWdk</a>). </p>
<p>I feel that we really have a problem with the missing arglist and we should solve it somehow. I'm not sure I'm suggesting the best solution and I'll certainly take any solution.</p>CLJ-1522Enhance multimethods metadataEnhancementMinorOpenUnresolvedUnassignedBozhidar BatsovmetadataMon, 8 Sep 2014 15:25:27 -0500Tue, 9 Sep 2014 04:24:08 -0500Release 1.600<p>Btw, I failed to mention this as I thought it was obvious, but I think we should use the dispatch function's arglist in the multimethod metadata.</p>Global Rank[CLJ-1521] A little improvement for parsing let exprhttp://dev.clojure.org/jira/browse/CLJ-1521
Clojure<p>The recurMismatches vector in LetExpr parser as see in </p>
<p><a href="https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/Compiler.java#L6062-6065">https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/Compiler.java#L6062-6065</a></p>
<p>There is not necessary to add initialize value 'false' into it when it is not a loop expression.</p>
<p>We can rewrite it into:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java"><span class="code-keyword">if</span>(isLoop)
{
<span class="code-keyword">for</span> (<span class="code-object">int</span> i = 0; i &lt; bindings.count()/2; i++)
{
recurMismatches = recurMismatches.cons(RT.F);
}
}</pre>
</div></div>
<p>It's a little improvement for parsing let expression.</p>Mac OSX 10.9.4
<br/>
java version &quot;1.7.0_17&quot;
<br/>
Java(TM) SE Runtime Environment (build 1.7.0_17-b02)
<br/>
Java HotSpot(TM) 64-Bit Server VM (build 23.7-b01, mixed mode)CLJ-1521A little improvement for parsing let exprEnhancementTrivialOpenUnresolvedUnassigneddennis zhuangletparserSun, 7 Sep 2014 04:02:11 -0500Mon, 8 Sep 2014 02:36:05 -0500Release 1.700<p>Dennis, you might want to clarify the description a little bit, if I understand this ticket correctly. The proposed change would be no change to the behavior of the compiler, except a small speed improvement during compilation?</p><p>Yep,the patch doesn't change the behavior of the compiler.All test is fine.</p>
<p>The recurMismatches vector in LetExpr parser as see in</p>
<p><a href="https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/Compiler.java#L6062-6065">https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/Compiler.java#L6062-6065</a></p>
<p>is only used when detecting type mismatch for loop special form,it's not necessary to be initialized for let special form.So i just added a if(isLoop) clause before initializing it.</p>Global RankPatchCode[CLJ-1520] assoc-in with empty key path assoc-es to nilhttp://dev.clojure.org/jira/browse/CLJ-1520
Clojure<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">(assoc-in {} [] 1) ;=&gt; {nil 1}</pre>
</div></div>
<p>This should probably throw an exception.</p>
<p><a href="http://dev.clojure.org/jira/browse/CLJ-373" title="update-in with empty key paths"><del>CLJ-373</del></a> has a patch (<a href="http://dev.clojure.org/jira/secure/attachment/12897/CLJ-373-nested-ops.patch">CLJ-373-nested-ops.patch</a>) which fixes this (by throwing an exception on empty key paths), the related broken behavior of update-in, and documents empty key path behavior in get-in et al. I can pull just the assoc-in stuff out of that into a separate patch, but I am really hoping that all the issues in the patch addresses are resolved at once, I.e.:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">(get-in {} [] :notfound) ;=&gt; {} ; ok
(get-in {nil 1} [] :notfound) ;=&gt; {nil 1} ; ok
(assoc-in {} [] 1) ;=&gt; {nil 1} ; wat?
(assoc-in {nil 0} [] 1) ;=&gt; {nil 1} ; wat?
(update-in {} [] identity) ;=&gt; {nil nil} ; wat?
(update-in {nil 0} [] inc) ;=&gt; {nil 1} ; wat?</pre>
</div></div>CLJ-1520assoc-in with empty key path assoc-es to nilDefectMajorOpenUnresolvedUnassignedFrancis AvilaFri, 5 Sep 2014 13:00:45 -0500Fri, 5 Sep 2014 13:00:45 -0500Release 1.601Global Rank[CLJ-1519] Added extra arity to clojure.core/ns-* fnshttp://dev.clojure.org/jira/browse/CLJ-1519
Clojure<p>Hello,</p>
<p>Adds another arity where the "ns" parameter is set to a default value of &#42;ns&#42; in these fns:</p>
<p>ns-unmap, ns-resolve, ns-name, ns-map, ns-publics, ns-imports, ns-interns, ns-refers, ns-aliases, ns-unalias</p>
<p>I find I very often use ns-unalias and ns-unmap from the repl, and passing the &#42;ns&#42; arg gets a little tedious.</p>CLJ-1519Added extra arity to clojure.core/ns-* fnsEnhancementMajorOpenUnresolvedUnassignedAlex BaranoskyenhancementpatchThu, 4 Sep 2014 23:51:09 -0500Wed, 10 Sep 2014 14:51:12 -050030Global RankPatchCode and Test[CLJ-1514] Use qualified class names for return type hints of standard Clojure functionshttp://dev.clojure.org/jira/browse/CLJ-1514
Clojure<p>The attached patch converts all function return type hints to spell out the class name fully qualified. There are two reasons for doing this:</p>
<p> 1. Simple names in return type hints cause the issue described in <a href="http://dev.clojure.org/jira/browse/CLJ-1232">http://dev.clojure.org/jira/browse/CLJ-1232</a>. That's usually not a problem with return type hints referring to java.lang-classes because those are always imported. However, using `ns-unmap` you can remove them. For example, after `(ns-unmap <b>ns</b> 'String)` in my namespace, `(.length (format "foo = %s") 1)` throws an IllegalArgumentException: Unable to resolve classname: String. By using fully-qualified class names, that problem goes away.</p>
<p> 2. tools.analyzer (used by the Clojure lint tool Eastwood) crashes when encountering such a simple-named return type hint. So currently, I cannot lint parts of my project because there's code that calls `clojure.core/format`.</p>CLJ-1514Use qualified class names for return type hints of standard Clojure functionsEnhancementMinorOpenUnresolvedUnassignedTassilo HornenhancementinteroppatchtypehintsThu, 28 Aug 2014 03:07:24 -0500Thu, 28 Aug 2014 14:16:39 -0500Release 1.601<p>1. that seems like a pretty weird thing to do<br/>
2. sounds like an issue with tools.analyzer, not with Clojure?</p><p>Just to clarify, tools.analyzer(.jvm) can analyze just fine forms in the form (defn x ^Class []) as long as Class is resolvable, whereas it will throw an exception if that function is then used in a namespace where that class is no longer resolvable, which is similar to what Clojure already does, except tools.analyzer.jvm will throw an exception even if the type hint is not used.</p>
<p>Since version 0.5.1 there's an handler that can be provided to change that behaviour, see <a href="https://github.com/clojure/tools.analyzer.jvm/blob/master/src/main/clojure/clojure/tools/analyzer/passes/jvm/validate.clj#L232">https://github.com/clojure/tools.analyzer.jvm/blob/master/src/main/clojure/clojure/tools/analyzer/passes/jvm/validate.clj#L232</a></p><p>Now a comment regarding this ticket: the patch in this ticket is just a work-around for the issue exposed in <a href="http://dev.clojure.org/jira/browse/CLJ-1232">http://dev.clojure.org/jira/browse/CLJ-1232</a>, IMHO the correct move would be to actually recognize that issue as a bug rather than as an accepted "limitation" as Rich's comment seems to suggest so that a fix might be commited.</p><p>@Alex: 1. is not as weird as it sounds at first. For example, consider you have macros that generate complete APIs for something into some new namespace. Then it can make sense to use a real vanilla namespace, i.e., without referring clojure.core and importing java.lang. With 2. I side with Nicola and consider <a href="http://dev.clojure.org/jira/browse/CLJ-1232" title="Functions with non-qualified return type hints force import of hinted classes when called from other namespace">CLJ-1232</a> a bug.</p>
<p>@Nicola: Today I've used Eastwood (0.1.4) to lint my project. It crashed when it encountered this definition:</p>
<div class="preformatted panel" style="border-width: 1px;"><div class="preformattedContent panelContent">
<pre>(defmacro error
"Throws an exception with the given message and cause."
([msg]
`(error ~msg nil))
([msg cause]
`(throw (java.lang.Exception. ~msg ~cause))))
(defmacro errorf
"Throws an exception with the given `msg` and `objs` passed to `format`.
`msg` is a format string."
[msg &amp; objs]
`(error (format ~msg ~@objs))) ;; This is line 112 where the crash occurs
</pre>
</div></div>
<p>The message was:</p>
<div class="preformatted panel" style="border-width: 1px;"><div class="preformattedContent panelContent">
<pre>Exception thrown during phase :analyze+eval of linting namespace funnyqt.tg-test
A function, macro, protocol method, var, etc. named clojure.core/format has been used here:
{:file "funnyqt/utils.clj",
:end-column 19,
:column 12,
:line 112,
:end-line 112}
Wherever it is defined, or where it is called, it has a type of String
This appears to be a Java class name with no package path.
Library tools.analyzer, on which Eastwood relies, cannot analyze such files.
If this definition is easy for you to change, we recommend you prepend it with
a full package path name, e.g. java.net.URI
Otherwise import the class by adding a line like this to your ns statement:
(:import (java.net URI))
An exception was thrown while analyzing namespace funnyqt.tg-test
Lint results may be incomplete. If there are compilation errors in
your code, try fixing those. If not, check above for info on the
exception.
</pre>
</div></div>
<p>So it seems it crashes because `format` has a `^String` return type hint. The namespace containing the `errorf` macro above has no modified ns-imports, i.e., all java.lang classes are imported there, too.</p><p>Tassilo, since `errorf` is a macro, that error is probably caused at the expansion point of that macro in a namespace that unmaps 'String.<br/>
If that's not the case, please open a ticket in the eastwood repo</p><p>Nicola, you are correct. As I've explained above to Alex, I generate APIs in fresh namespaces that don't refer clojure.core and also ns-unmap all java.lang classes, and the generated code also contains `errorf`-forms.</p>
<p>Well, since `ns-unmap` is there, I think it's legit to use it. So that makes <a href="http://dev.clojure.org/jira/browse/CLJ-1232" title="Functions with non-qualified return type hints force import of hinted classes when called from other namespace">CLJ-1232</a> even more important. But until that gets fixed which requires a common agreement that it is indeed a bug, I'd be very happy if this patch could be accepted. I mean, when it cannot do any harm and doesn't obscure anything but helps at least one person, then why not do it?</p>Global RankPatchCode[CLJ-1513] Enhancing readerhttp://dev.clojure.org/jira/browse/CLJ-1513
Clojure<p>Attach "character start" and "character end" to the meta information of read forms produced by clojure.lang.EdnReader and clojure.lang.LispReader.<br/>
This will allows for better code inspection by linters for example. Currently only line number and column are attached to the meta information.</p>CLJ-1513Enhancing readerEnhancementTrivialOpenUnresolvedUnassignedAnton RamboldednreaderMon, 25 Aug 2014 16:17:44 -0500Mon, 25 Aug 2014 16:59:47 -050000<p>I am not certain, but perhaps the EDN and regular reader in the tools.reader contrib library already do what you want here? That is, besides :line and :column metadata, they also have :end-line and :end-column metadata for the end of the expression.</p>Global Rank[CLJ-1508] Supplied-p parameter in clojurehttp://dev.clojure.org/jira/browse/CLJ-1508
Clojure<p>As see in <a href="https://groups.google.com/forum/?hl=en#!topic/clojure/jWc51JOkvsA">https://groups.google.com/forum/?hl=en#!topic/clojure/jWc51JOkvsA</a></p>
<p>I think we can add a <img class="emoticon" src="http://dev.clojure.org/jira/images/icons/emoticons/tongue.gif" height="20" width="20" align="absmiddle" alt="" border="0"/>? option for destructure ,then we can write a test like :</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">(deftest supplied-p-in-destructuring
(let [{:keys [a b c d] :p? {a a-p? b b-p? c c-p? d d-p?} :or {a 1}} {:b 2 :c 3 }]
(is (= a 1))
(is (<span class="code-keyword">false</span>? a-p?))
(is (= 2 b))
(is (<span class="code-keyword">true</span>? b-p?))
(is (= 3 c))
(is (<span class="code-keyword">true</span>? c-p?))
(is (nil? d))
(is (<span class="code-keyword">false</span>? d-p?))))</pre>
</div></div>
<p>Even if the a var has a default value 1 by :or option,but the a-p? is still false.<br/>
Just like the supplied-p-parameter in Commons LISP.</p>
<p>The patch is attached with code and test.</p>
Mac OSX 10.9.4
<br/>
<br/>
java version &quot;1.7.0_17&quot;
<br/>
Java(TM) SE Runtime Environment (build 1.7.0_17-b02)
<br/>
Java HotSpot(TM) 64-Bit Server VM (build 23.7-b01, mixed mode)CLJ-1508Supplied-p parameter in clojureEnhancementMinorOpenUnresolvedUnassigneddennis zhuangdestructuringMon, 18 Aug 2014 02:13:14 -0500Mon, 18 Aug 2014 13:07:46 -0500Release 1.701<p>As mentioned on the mailing list, you could use {:as arg} destructuring to get same information. Here's a slightly modified example that works in the current Clojure:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">(deftest supplied-p-in-destructuring
;; (let [{:keys [a b c d] :p? {a a-p? b b-p? c c-p? d d-p?} :or {a 1}} {:b 2 :c 3 }]
(let [{:keys [a b c d] :or {a 1} :as argmap} {:b 2 :c 3 }
supplied? (partial contains? argmap)
a-p? (supplied? :a)
b-p? (supplied? :b)
c-p? (supplied? :c)
d-p? (supplied? :d)]
(is (= a 1))
(is (<span class="code-keyword">false</span>? a-p?))
(is (= 2 b))
(is (<span class="code-keyword">true</span>? b-p?))
(is (= 3 c))
(is (<span class="code-keyword">true</span>? c-p?))
(is (nil? d))
(is (<span class="code-keyword">false</span>? d-p?))))</pre>
</div></div>Global RankPatchCode and Test[CLJ-1507] Throw NPE in eval readerhttp://dev.clojure.org/jira/browse/CLJ-1507
Clojure<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">Clojure 1.7.0-master-SNAPSHOT
user=&gt; #=(<span class="code-keyword">var</span> a)
NullPointerException clojure.lang.Symbol.hashCode (Symbol.java:84)
user=&gt; (.printStackTrace *e)
clojure.lang.LispReader$ReaderException: clojure.lang.LispReader$ReaderException: java.lang.NullPointerException
at clojure.lang.LispReader.read(LispReader.java:218)
at clojure.core$read.invoke(core.clj:3580)
at clojure.core$read.invoke(core.clj:3578)
at clojure.core$read.invoke(core.clj:3576)
at clojure.core$read.invoke(core.clj:3574)
at clojure.main$repl_read.invoke(main.clj:139)
at clojure.main$repl$read_eval_print__6807$fn__6808.invoke(main.clj:237)
at clojure.main$repl$read_eval_print__6807.invoke(main.clj:237)
at clojure.main$repl$fn__6816.invoke(main.clj:257)
at clojure.main$repl.doInvoke(main.clj:257)
at clojure.lang.RestFn.invoke(RestFn.java:421)
at clojure.main$repl_opt.invoke(main.clj:323)
at clojure.main$main.doInvoke(main.clj:421)
at clojure.lang.RestFn.invoke(RestFn.java:397)
at clojure.lang.Var.invoke(Var.java:375)
at clojure.lang.AFn.applyToHelper(AFn.java:152)
at clojure.lang.Var.applyTo(Var.java:700)
at clojure.main.main(main.java:37)
Caused by: clojure.lang.LispReader$ReaderException: java.lang.NullPointerException
at clojure.lang.LispReader.read(LispReader.java:218)
at clojure.lang.LispReader$CtorReader.invoke(LispReader.java:1164)
at clojure.lang.LispReader$DispatchReader.invoke(LispReader.java:609)
at clojure.lang.LispReader.read(LispReader.java:183)
... 17 more
Caused by: java.lang.NullPointerException
at clojure.lang.Symbol.hashCode(Symbol.java:84)
at java.util.concurrent.ConcurrentHashMap.hash(ConcurrentHashMap.java:332)
at java.util.concurrent.ConcurrentHashMap.get(ConcurrentHashMap.java:987)
at clojure.lang.Namespace.findOrCreate(Namespace.java:173)
at clojure.lang.RT.<span class="code-keyword">var</span>(RT.java:341)
at clojure.lang.LispReader$EvalReader.invoke(LispReader.java:1042)
at clojure.lang.LispReader$DispatchReader.invoke(LispReader.java:616)
at clojure.lang.LispReader.read(LispReader.java:183)
... 20 more</pre>
</div></div>
<p>If the var symbol doesn't contains namespace ,it will throw the NPE exception in above code.Instead,i think it should use Compiler.currentNS() when doesn't find the var's namespace.</p>
<p>The patch is attached, after patched:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">Clojure 1.7.0-master-SNAPSHOT
user=&gt; #=(<span class="code-keyword">var</span> a)
#'user/a</pre>
</div></div>
Mac OSX 10.9.4
<br/>
java version &quot;1.7.0_17&quot;
<br/>
Java(TM) SE Runtime Environment (build 1.7.0_17-b02)
<br/>
Java HotSpot(TM) 64-Bit Server VM (build 23.7-b01, mixed mode)CLJ-1507Throw NPE in eval readerDefectMinorOpenUnresolvedUnassigneddennis zhuangeval-readerSat, 16 Aug 2014 09:27:04 -0500Sat, 16 Aug 2014 09:27:04 -0500Release 1.700Global RankPatchCode[CLJ-1506] A little improvement when reading syntax quote formhttp://dev.clojure.org/jira/browse/CLJ-1506
Clojure<p>When reading syntax quote on keyword,string or number etc,it returns the form as result directly. Read it in:<br/>
<a href="https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/LispReader.java#L844-847">https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/LispReader.java#L844-847</a></p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java"><span class="code-keyword">else</span> <span class="code-keyword">if</span>(form <span class="code-keyword">instanceof</span> Keyword
|| form <span class="code-keyword">instanceof</span> <span class="code-object">Number</span>
|| form <span class="code-keyword">instanceof</span> <span class="code-object">Character</span>
|| form <span class="code-keyword">instanceof</span> <span class="code-object">String</span>)
ret = form;</pre>
</div></div>
<p>But missing check if it is a nil,regular pattern or boolean constants.<br/>
After patched:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java"><span class="code-keyword">else</span> <span class="code-keyword">if</span>(form == <span class="code-keyword">null</span>
|| form <span class="code-keyword">instanceof</span> Keyword
|| form <span class="code-keyword">instanceof</span> <span class="code-object">Number</span>
|| form <span class="code-keyword">instanceof</span> <span class="code-object">Character</span>
|| form <span class="code-keyword">instanceof</span> Pattern
|| form <span class="code-keyword">instanceof</span> <span class="code-object">Boolean</span>
|| form <span class="code-keyword">instanceof</span> <span class="code-object">String</span>)
ret = form;</pre>
</div></div>
<p>It's a little patch, i am not sure if it is worth a try.</p>Mac OSX 10.9.4
<br/>
java version &quot;1.7.0_17&quot;
<br/>
Java(TM) SE Runtime Environment (build 1.7.0_17-b02)
<br/>
Java HotSpot(TM) 64-Bit Server VM (build 23.7-b01, mixed mode)CLJ-1506A little improvement when reading syntax quote formEnhancementMinorOpenUnresolvedUnassigneddennis zhuangsyntax-quoteSat, 16 Aug 2014 08:28:08 -0500Sat, 30 Aug 2014 11:44:11 -0500Release 1.700Global RankPatchCode[CLJ-1504] Add :inline to most core predicateshttp://dev.clojure.org/jira/browse/CLJ-1504
Clojure<p>This will allow instance? predicates calls to be emitted using the instanceof JVM bytecode and will also allow tools like core.typed or tools.analyzer.jvm to infer the type of a var/local on a per branch basis without having to special-case all the core predicates.</p>CLJ-1504Add :inline to most core predicatesEnhancementMajorOpenUnresolvedUnassignedNicola MomettoFri, 15 Aug 2014 07:09:22 -0500Fri, 15 Aug 2014 13:42:05 -050000<p>Related ticket <a href="http://dev.clojure.org/jira/browse/CLJ-1227" title="Definline functions do not work as higher-order functions when AOT compiled"><del>CLJ-1227</del></a> and related quote from Alex:</p>
<blockquote>
<p>definline is considered to be an experimental feature and Rich would like to discourage its use as the hope is to remove it in the future. The desired replacement is something like common lisp compiler macros that could allow the compiler to detect special situations and optimize the result but leave behind a function invocation for the case where no special behavior is available.</p></blockquote><p>This patch uses "manual" :inline metadata on functions, it's used by many other core functions (like +,- et), not definline so Rich's comment doesn't apply.</p>Global RankPatchCode[CLJ-1502] Clojure Inspector navigation errorhttp://dev.clojure.org/jira/browse/CLJ-1502
Clojure<p>With Clojure 1.6.0 on some platforms (details below), if you create an object such as</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">(def nst (vec '((3 7 22) 99 (123 18 225 437))))</pre>
</div></div>
<p>and then you inspect the tree representing the object</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">(inspect-tree nst)</pre>
</div></div>
<p>Most of the navigation with the keyboard proceeds fine. However, when you point to an individual value - e.g. the 99 or the 437 - and press the right arrow key, there is an error</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">Exception in thread <span class="code-quote">"AWT-EventQueue-0"</span> java.lang.UnsupportedOperationException: count not supported on <span class="code-keyword">this</span> type: <span class="code-object">Long</span>
at clojure.lang.RT.countFrom(RT.java:556)
at clojure.lang.RT.count(RT.java:530)
at clojure.inspector$fn__6907.invoke(inspector.clj:40)
at clojure.lang.MultiFn.invoke(MultiFn.java:227)
at clojure.inspector$tree_model$fn__6929.invoke(inspector.clj:63)
at clojure.inspector.proxy$java.lang.<span class="code-object">Object</span>$TreeModel$775afa87.getChildCount(Unknown Source)
at javax.swing.plaf.basic.BasicTreeUI$Actions.traverse(BasicTreeUI.java:4395)
at javax.swing.plaf.basic.BasicTreeUI$Actions.actionPerformed(BasicTreeUI.java:4052)
at javax.swing.SwingUtilities.notifyAction(SwingUtilities.java:1662)
at javax.swing.JComponent.processKeyBinding(JComponent.java:2878)
at javax.swing.JComponent.processKeyBindings(JComponent.java:2925)
at javax.swing.JComponent.processKeyEvent(JComponent.java:2841)
at java.awt.Component.processEvent(Component.java:6282)
at java.awt.Container.processEvent(Container.java:2229)
at java.awt.Component.dispatchEventImpl(Component.java:4861)
at java.awt.Container.dispatchEventImpl(Container.java:2287)
at java.awt.Component.dispatchEvent(Component.java:4687)
at java.awt.KeyboardFocusManager.redispatchEvent(KeyboardFocusManager.java:1895)
at java.awt.DefaultKeyboardFocusManager.dispatchKeyEvent(DefaultKeyboardFocusManager.java:762)
at java.awt.DefaultKeyboardFocusManager.preDispatchKeyEvent(DefaultKeyboardFocusManager.java:1027)
at java.awt.DefaultKeyboardFocusManager.typeAheadAssertions(DefaultKeyboardFocusManager.java:899)
at java.awt.DefaultKeyboardFocusManager.dispatchEvent(DefaultKeyboardFocusManager.java:727)
at java.awt.Component.dispatchEventImpl(Component.java:4731)
at java.awt.Container.dispatchEventImpl(Container.java:2287)
at java.awt.Window.dispatchEventImpl(Window.java:2719)
at java.awt.Component.dispatchEvent(Component.java:4687)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:735)
at java.awt.EventQueue.access$200(EventQueue.java:103)
at java.awt.EventQueue$3.run(EventQueue.java:694)
at java.awt.EventQueue$3.run(EventQueue.java:692)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:87)
at java.awt.EventQueue$4.run(EventQueue.java:708)
at java.awt.EventQueue$4.run(EventQueue.java:706)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:705)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:242)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:161)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:150)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:146)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:138)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:91)</pre>
</div></div>
<p>Environments where this has been reproduced:<br/>
+ Windows 7 Enterprise, SP1, Oracle JDK 1.7.0_51, Clojure 1.6.0<br/>
+ Ubuntu Linux 14.04.1, Oracle JDK 1.7.0_65, Clojure 1.6.0</p>
<p>Environments where the same sequence of events does not cause an exception:<br/>
+ Mac OS X 10.8.5, Oracle JDK 1.7.0_51, Clojure 1.6.0</p>Windows 7 and 8, Java 7, Clojure replCLJ-1502Clojure Inspector navigation errorDefectMinorOpenUnresolvedUnassignedDan CampbellbuginspectornavigationTue, 12 Aug 2014 12:45:52 -0500Fri, 15 Aug 2014 18:40:04 -0500Release 1.601<p>Patch clj-1502-v1.patch avoids the exception in the situation reported. Tested manually on OS X, Linux, and Windows 7 versions mentioned in the patch comment. I suspect it is not worth the effort to write an automated test for this.</p><p>Thanks, Andy</p>
<ul class="alternate" type="square">
<li>DC</li>
</ul>
Global RankPatchCode[CLJ-1496] Added a new arity to 'ex-info' that only accepts a message. http://dev.clojure.org/jira/browse/CLJ-1496
Clojure<p>We often use 'ex-info' to throw a custom exception.But ex-info at least accepts two arguments: a string message and a data map.<br/>
In most cases，but we don't need to throw a exception that taken a data map.<br/>
So i think we can add a new arity to ex-info:</p>
<p> (ex-info "the exception message")</p>
<p>That created a ExceptionInfo instance carries empty data.</p>
<p>I am not sure it's useful for other people,but it's really useful for our developers.</p>
<p>The patch is attached.</p>
java version &quot;1.7.0_17&quot;
<br/>
Java(TM) SE Runtime Environment (build 1.7.0_17-b02)
<br/>
Java HotSpot(TM) 64-Bit Server VM (build 23.7-b01, mixed mode)
<br/>
<br/>
Mac OSX 10.9.4CLJ-1496Added a new arity to 'ex-info' that only accepts a message. EnhancementMinorOpenUnresolvedUnassigneddennis zhuangex-infoexceptionsFri, 8 Aug 2014 03:22:28 -0500Mon, 11 Aug 2014 07:28:40 -0500Release 1.700Global RankPatchCode[CLJ-1489] Implement var-symbolhttp://dev.clojure.org/jira/browse/CLJ-1489
Clojure<p>var-symbol provides the obvious complement operation to resolve. Where resolve maps from a symbol to a var by resolving it in the environment, var-symbol allows a user to recover the root binding symbol from a var if the var is named. If the var is not named, var-symbol returns nil.</p>
<p>This is related to <a href="http://dev.clojure.org/jira/browse/CLJ-1488" title="Implement Named over Vars">CLJ-1488</a> in that it handles the common case of symbolically manipulating Vars in terms of the Symbols they bind without requiring that users manually reconstruct the bound symbol. Futhermore this patch nicely handles the non-obvious implementation consequent case of an unnamed var.</p>
<p>Depends on <a href="http://dev.clojure.org/jira/browse/CLJ-1488" title="Implement Named over Vars">CLJ-1488</a></p>CLJ-1489Implement var-symbolEnhancementTrivialOpenUnresolvedUnassignedReid McKenzieSat, 2 Aug 2014 15:40:42 -0500Wed, 6 Aug 2014 14:30:15 -050001<p>Patch 0001-Implement-var-symbol.patch dated Aug 2 2014 does not apply cleanly. I haven't checked whether it used to apply cleanly before some commits made to Clojure master earlier today, but if it did, then those commits have made this patch become 'stale'.</p>
<p>See the section "Updating stale patches" at <a href="http://dev.clojure.org/display/community/Developing+Patches">http://dev.clojure.org/display/community/Developing+Patches</a> for suggestions on how to update patches.</p>Global Rank[CLJ-1486] Make fnil var-arghttp://dev.clojure.org/jira/browse/CLJ-1486
Clojure<p>Currently fnil is defined only for 1 to 3 args, this patch makes it var-arg</p>CLJ-1486Make fnil var-argEnhancementMinorOpenUnresolvedUnassignedNicola MomettoThu, 31 Jul 2014 17:36:56 -0500Thu, 18 Sep 2014 06:50:33 -050002Global RankPatchCode and Test[CLJ-1482] Replace a couple of (filter (complement ...) ...) usages with (remove ...)http://dev.clojure.org/jira/browse/CLJ-1482
Clojure<p>The title basically says it all - remove exists so we can express our intentions more clearly. </p>CLJ-1482Replace a couple of (filter (complement ...) ...) usages with (remove ...)EnhancementTrivialOpenUnresolvedUnassignedBozhidar BatsovenhancementSun, 27 Jul 2014 07:07:52 -0500Sun, 27 Jul 2014 07:07:52 -0500Release 1.600Global RankPatchCode[CLJ-1471] Option to print type infohttp://dev.clojure.org/jira/browse/CLJ-1471
Clojure<p>I've had an issue with defrecord-types being converted into ordinary maps somewhere, which was relatively hard to track down inside a deep structure since they are pprinted as the same thing by default.<br/>
The following code patches into the pprint dispatch and prints the type around values; it turned out to be quite useful, but feels hackish.<br/>
Maybe something like that would be useful to integrate into clojure.pprint directly (there are a number of cosmetic options already), i.e. into clojure.pprint/write-out.</p>
<p>Only printing <tt>(type)</tt> may not be enough in some cases; so an option to print all metadata would be nice.<br/>
Maybe something like <tt>:metadata nil</tt> as default, <tt>:metadata :type</tt> to print types (but also for non-IMetas, using <tt>(type)</tt> and <tt>:metadata true</tt> to print metadata for IMetas using <tt>(meta)</tt>.</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">(defn pprint-with-type
([object] (pprint object *out*))
([object writer]
; keep original dispatch.
; calling it directly will print only that object,
; but <span class="code-keyword">return</span> to our dispatch <span class="code-keyword">for</span> subobjects.
(let [dispatch clojure.pprint/*print-pprint-dispatch*]
(binding [clojure.pprint/*print-pprint-dispatch*
(fn [obj]
(<span class="code-keyword">if</span> (instance? clojure.lang.IMeta obj)
(<span class="code-keyword">do</span> (print <span class="code-quote">"^{:type "</span>)
(dispatch (type obj))
(print <span class="code-quote">"} "</span>)
(clojure.pprint/pprint-newline :fill)
(dispatch obj))
(<span class="code-keyword">do</span> (print <span class="code-quote">"(^:type "</span>)
(dispatch (type obj))
(print <span class="code-quote">" "</span>)
(clojure.pprint/pprint-newline :fill)
(dispatch obj)
(print <span class="code-quote">")"</span>))))]
(clojure.pprint/pprint object writer)))))</pre>
</div></div>CLJ-1471Option to print type infoEnhancementMinorOpenUnresolvedUnassignedPascal GermrothpprintMon, 21 Jul 2014 11:07:48 -0500Mon, 21 Jul 2014 11:07:48 -050000Global Rank[CLJ-1470] Make Atom and ARef easy to subclasshttp://dev.clojure.org/jira/browse/CLJ-1470
Clojure<p>Atom is currently defined as final and ARef.validate() is package-private. This makes it impossible to define a subclass of an Atom and difficult subclass ARef (if validate() needs to be called).</p>
<p>I propose removing the final modifier from Atom, making ARef.validate() protected and also making Atom.state protected (it is currently package-private).</p>
<p>I'm not sure if there is a specific reason why Atom is final - if this is for performance reasons or to prevent someone from doing strange things with Atom's, but I can see a use case for sub-classing it.</p>
<p>One use-case is to create reactive Atom that allows derefs to be tracked (as in reagent). I have some Clojure (not Clojurescript) code where I'm trying to play with this idea and I've had to copy the entire Atom class (because it's sealed) and place it in the clojure.lang package (because ARef.validate() is package-private): <a href="https://github.com/aaronc/freactive/blob/master/src/java/clojure/lang/ReactiveAtom.java">https://github.com/aaronc/freactive/blob/master/src/java/clojure/lang/ReactiveAtom.java</a>. In addition, I need to copy the defns for swap! and reset! into my own namespace. This seems a bit inconvenient.</p>CLJ-1470Make Atom and ARef easy to subclassEnhancementMinorOpenUnresolvedUnassignedAaron CraeliusSun, 20 Jul 2014 16:10:52 -0500Wed, 23 Jul 2014 00:55:10 -0500Release 1.602<p>related to <a href="http://dev.clojure.org/jira/browse/CLJ-803">http://dev.clojure.org/jira/browse/CLJ-803</a></p>Global RankPatchCode[CLJ-1469] Emit KeywordInvoke callsites only when keyword is not namespacedhttp://dev.clojure.org/jira/browse/CLJ-1469
Clojure<p>Summary: Don't emit KeywordLookup thunks and machinery for namespaced keyword access</p>
<p>Description: When the compiler sees a keyword at the beginning of a sexpr, (:foo x), it emits some machinery that takes into account that 'x' could be a defrecord with a defined 'foo' field. This exists to fast-path it into a field lookup. Here is the supporting code from the target defrecord: <a href="https://github.com/clojure/clojure/blob/master/src/clj/clojure/core_deftype.clj#L185-L198">https://github.com/clojure/clojure/blob/master/src/clj/clojure/core_deftype.clj#L185-L198</a> <br/>
The compiler currently emits the same machinery for (:foo/bar x), a namespaced keyword access, but defrecords don't have any fast path field access for that. This trivial patch turns that scenario into a normal invocation.</p>
<p>Here is the disassembly for (fn <span class="error">&#91;x&#93;</span> (:foo/bar x))<br/>
<a href="https://gist.github.com/anonymous/d94fc56fba4a1665f73f">https://gist.github.com/anonymous/d94fc56fba4a1665f73f</a></p>
<p>There are two static fields on the IFn also for every kw access. </p>
<p>With the trivial patch, it turns into a normal invoke. (emit the fn aka the namespaced keyword, then the args Aka the target, and call IFn invoke: kw.invoke(target))</p>CLJ-1469Emit KeywordInvoke callsites only when keyword is not namespacedEnhancementTrivialOpenUnresolvedUnassignedGhadi ShaybanFri, 18 Jul 2014 11:46:33 -0500Wed, 22 Oct 2014 14:14:25 -050012Global RankPatchCode[CLJ-1467] Implement Comparable in PersistentListhttp://dev.clojure.org/jira/browse/CLJ-1467
Clojure<p>PersistentVector implements Comparable already.</p>CLJ-1467Implement Comparable in PersistentListEnhancementMajorOpenUnresolvedUnassignedPascal GermrothcollectionsThu, 17 Jul 2014 13:20:29 -0500Fri, 14 Nov 2014 03:12:01 -060051<p>Patch for this issue; done with Jeroen van Dijk and Razvan Petruescu at a clojure meetup. Any feedback welcome; the learning for me here is not the fix, but learning how to deal with ant and jira etc.</p><p>Looks like you have navigated the steps for creating a patch in the desired format, and attaching it to a JIRA ticket, just fine. I see your name on the list of contributors, which is a precondition before a patch can be committed to Clojure or a contrib library.</p>
<p>You've gotten past what are actually the easier parts. There is still the issue of whether this ticket is even considered by the Clojure core team to be an enhancement worth making a change to Clojure. Take a look at the JIRA workflow here if you haven't seen it already and are curious: <a href="http://dev.clojure.org/display/community/JIRA+workflow">http://dev.clojure.org/display/community/JIRA+workflow</a></p>
<p>If you like Pascal think that this is a change you really want to see in Clojure, you may vote on this or any other JIRA ticket (except ones you create yourself &#8211; the creator is effectively the 0th voter for a ticket). Log in and click on the Vote link near the top right, and/or Watch to get email updates of changes.</p><p>Andy, thanks for the info. I was not aware of the JIRA workflow.</p>Global Rank[CLJ-1463] Providing own ClassLoader for eval is brokenhttp://dev.clojure.org/jira/browse/CLJ-1463
Clojure<p>clojure.lang.Compiler has a method with the signature</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java"><span class="code-keyword">public</span> <span class="code-keyword">static</span> <span class="code-object">Object</span> eval(<span class="code-object">Object</span> form, <span class="code-object">boolean</span> freshLoader)</pre>
</div></div>
<p>but the freshLoader argument is ignored since <a href="https://github.com/clojure/clojure/commit/2c2ed386ed0f6f875342721bdaace908e298c7f3">https://github.com/clojure/clojure/commit/2c2ed386ed0f6f875342721bdaace908e298c7f3</a></p>
<p>Is there a good reason this still needs to be "hotfixed" like this?</p>
<p>We would like to provide our own ClassLoader for eval to manage the lifecycle of the generated classes.</p>Clojure 1.6.0CLJ-1463Providing own ClassLoader for eval is brokenDefectMinorOpenUnresolvedUnassignedVolkert Oakley JurgenscompilerThu, 10 Jul 2014 18:12:14 -0500Thu, 10 Jul 2014 18:12:14 -0500Release 1.2Release 1.3Release 1.5Release 1.601Global Rank[CLJ-1462] cl-format throws ClassCastException: Writer cannot be cast to Future/IDerefhttp://dev.clojure.org/jira/browse/CLJ-1462
Clojure<p>Using <tt>&#126;I</tt> and <tt>&#126;_</tt> etc fails in many situations, the most trivial one being:</p>
<p>Clojure 1.6.0 and 1.5.1:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">user=&gt; (clojure.pprint/cl-format <span class="code-keyword">true</span> <span class="code-quote">"~I"</span>)
ClassCastException java.io.PrintWriter cannot be <span class="code-keyword">cast</span> to java.util.concurrent.Future clojure.core/deref-<span class="code-keyword">future</span> (core.clj:2180)
user=&gt; (clojure.pprint/cl-format nil <span class="code-quote">"~I"</span>)
ClassCastException java.io.StringWriter cannot be <span class="code-keyword">cast</span> to java.util.concurrent.Future clojure.core/deref-<span class="code-keyword">future</span> (core.clj:2180)
user=&gt; (clojure.pprint/cl-format nil <span class="code-quote">"~_"</span>)
ClassCastException java.io.StringWriter cannot be <span class="code-keyword">cast</span> to java.util.concurrent.Future clojure.core/deref-<span class="code-keyword">future</span> (core.clj:2180)</pre>
</div></div>
<p>Clojure 1.4.0</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">user=&gt; (clojure.pprint/cl-format <span class="code-keyword">true</span> <span class="code-quote">"~I"</span>)
ClassCastException java.io.OutputStreamWriter cannot be <span class="code-keyword">cast</span> to clojure.lang.IDeref clojure.core/deref (core.clj:2080)
user=&gt; (clojure.pprint/cl-format nil <span class="code-quote">"~I"</span>)
ClassCastException java.io.StringWriter cannot be <span class="code-keyword">cast</span> to clojure.lang.IDeref clojure.core/deref (core.clj:2080)
user=&gt; (clojure.pprint/cl-format nil <span class="code-quote">"~_"</span>)
ClassCastException java.io.StringWriter cannot be <span class="code-keyword">cast</span> to clojure.lang.IDeref clojure.core/deref (core.clj:2080)</pre>
</div></div>
<p>These work in other implementations, i.e. clisp, creating empty output in these trivial cases:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">&gt; (format t <span class="code-quote">"~I"</span>)
NIL
&gt; (format nil <span class="code-quote">"~I"</span>)
""
&gt; (format nil <span class="code-quote">"~_"</span>)
""</pre>
</div></div>CLJ-1462cl-format throws ClassCastException: Writer cannot be cast to Future/IDerefDefectMinorOpenUnresolvedUnassignedPascal GermrothprintMon, 7 Jul 2014 10:55:26 -0500Wed, 9 Jul 2014 18:37:24 -0500Release 1.4Release 1.5Release 1.601<p>The tilde-underscore sequence is for "conditional newline", according to the CLHS here: <a href="http://www.lispworks.com/documentation/lw51/CLHS/Body/22_cea.htm">http://www.lispworks.com/documentation/lw51/CLHS/Body/22_cea.htm</a></p>
<p>Tilde-capital-letter-I is for indent: <a href="http://www.lispworks.com/documentation/lw51/CLHS/Body/22_cec.htm">http://www.lispworks.com/documentation/lw51/CLHS/Body/22_cec.htm</a></p><p>Ah, didn't think to try that. It fails without cl-format as well:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">user=&gt; (clojure.pprint/pprint-newline :linear)
ClassCastException java.io.PrintWriter cannot be <span class="code-keyword">cast</span> to java.util.concurrent.Future clojure.core/deref-<span class="code-keyword">future</span> (core.clj:2180)
user=&gt; (clojure.pprint/pprint-indent :block 0)
ClassCastException java.io.PrintWriter cannot be <span class="code-keyword">cast</span> to java.util.concurrent.Future clojure.core/deref-<span class="code-keyword">future</span> (core.clj:2180)</pre>
</div></div>
<p>Manually creating a pretty writer does work though:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">user=&gt; (binding [*out* (clojure.pprint/get-pretty-writer *out*)] (clojure.pprint/pprint-newline :linear))
nil</pre>
</div></div>
<p>In the get-pretty-writer doc it says:</p>
<blockquote>
<p>Generally, it is unnecessary to call this function, since pprint,<br/>
write, and cl-format all call it if they need to.</p></blockquote>
<p>Which appears to not be true for cl-format, and it would be nice if it would be applied automatically for all functions that need a pretty writer.</p><p>More bad news!<br/>
Manually creating a pretty-writer doesn't do the trick either, because it is not being properly flushed:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">user=&gt; (binding [*out* (get-pretty-writer *out*)] (cl-format <span class="code-keyword">true</span> <span class="code-quote">"hello ~_world~%"</span>))
hello world
nil
user=&gt; (binding [*out* (get-pretty-writer *out*)] (cl-format <span class="code-keyword">true</span> <span class="code-quote">"hello ~_world"</span>))
hellonil
user=&gt; (binding [*out* (get-pretty-writer *out*)] (cl-format <span class="code-keyword">true</span> <span class="code-quote">"hello ~_world"</span>) (.ppflush *out*))
hello worldnil</pre>
</div></div>
<p>The <tt>~%</tt> inserts an unconditional newline like <tt>\n</tt>, which also works as expected.</p>
<p>Insert <tt>&#126;&#95;</tt> before and it only prints up to that one. But I've also managed to get it to abort at other <tt>&#126;&#95;</tt> s, maybe because other commands flushed it.</p>
<p>Manually flushing it, like the inexplicably private <tt>with-pretty-writer</tt> macro does works though.<br/>
I don't understand why <tt>get-pretty-writer</tt> is exposed but not the macro that is needed to use it properly. Also all functions using pretty-writer facilities should use with-pretty-writer, that's what it appears to be specifically designed for. Then there's no need to expose it (or get-pretty-writer).</p>Global Rank[CLJ-1459] records should support transienthttp://dev.clojure.org/jira/browse/CLJ-1459
Clojure<p>user=&gt; (defrecord R <span class="error">&#91;a&#93;</span>)<br/>
user.R<br/>
user=&gt; (transient (-&gt;R nil))<br/>
ClassCastException user.R cannot be cast to clojure.lang.IEditableCollection clojure.core/transient (core.clj:3060)</p>CLJ-1459records should support transientEnhancementMajorOpenUnresolvedUnassignedYongqian LidefrecordSat, 5 Jul 2014 20:13:26 -0500Sun, 6 Jul 2014 18:26:02 -050002Global Rank[CLJ-1455] Postcondition in defrecord: Compiler unable to resolve symbol %http://dev.clojure.org/jira/browse/CLJ-1455
Clojure<p>Clojure's postconditions<span class="error">&#91;1&#93;</span> are a splendiferous, notationally<br/>
idiot-proof way to scrutinize a function's return value without<br/>
inadvertently causing it to return something else.</p>
<p>Functions (implementing protocols) for a record type may be defined in<br/>
its defrecord or with extend-type. In functions defined in<br/>
extend-type, postconditions work as expected. Therefore, it is a<br/>
surprise that functions defined in defrecord cannot use<br/>
postconditions.</p>
<p>Actually it appears defrecord sees a pre/postcondition map as ordinary<br/>
code, so the postcondition runs at the beginning of the function (not<br/>
the end) and the symbol % (for return value) is not bound.</p>
<p>The code below shows a protocol and two record types that implement<br/>
it. Type "One" has an in-the-defrecord function definition where the<br/>
postcondition does not compile. Type "Two" uses extend-type and the<br/>
postcondition works as expected.</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<div class="error"><span class="error">Unable to find source-code formatter for language: clojure.</span> Available languages are: javascript, sql, xhtml, actionscript, none, html, xml, java</div><pre class="code-clojure">(defprotocol ITimesThree
(x3 [a]))
;; defrecord with functions inside cannot use postconditions.
(defrecord One
[]
ITimesThree
(x3 [a]
{:pre [(<span class="code-keyword">do</span> (println <span class="code-quote">"One x3 pre"</span>) 1)] ;; (works fine)
:post [(<span class="code-keyword">do</span> (println <span class="code-quote">"One x3 post, %="</span> %) 1)]
;; Unable to resolve symbol: % in <span class="code-keyword">this</span> context.
;; With % removed, it compiles but runs at start, not end.
}
(* 1 3)))
;; extend-type can add functions with postconditions to a record.
(defrecord Two
[])
(extend-type Two
ITimesThree
(x3 [a]
{:pre [(<span class="code-keyword">do</span> (println <span class="code-quote">"Two x3 pre"</span>) 1)] ;; (works fine)
:post [(<span class="code-keyword">do</span> (println <span class="code-quote">"Two x3 post, %="</span> %) 1)] ;; (works fine)
}
(* 2 3)))
(defn -main
<span class="code-quote">"Main"</span>
[]
(println (x3 (-&gt;One)))
(println (x3 (-&gt;Two))))</pre>
</div></div>
<p><span class="error">&#91;1&#93;</span> <a href="http://clojure.org/special_forms">http://clojure.org/special_forms</a>, in the fn section.</p>CLJ-1455Postcondition in defrecord: Compiler unable to resolve symbol %EnhancementMinorOpenUnresolvedUnassignedPhill WolfdefrecordSat, 28 Jun 2014 16:26:56 -0500Sun, 29 Jun 2014 23:39:07 -0500Release 1.611Global Rank[CLJ-1447] Make proxy work with protocols directly (like reify does)http://dev.clojure.org/jira/browse/CLJ-1447
Clojure<p>Currently Proxy only supports interfaces and abstract classes. While protocols are supported via the protocol's interface, this means that the method names must be java mangled. E.g. the method name for set-value! becomes set_value_BANG_. However, the only possible way to subclass abstract classes in Clojure is currently via gen-class (doesn't work from the REPL) or proxy. </p>CLJ-1447Make proxy work with protocols directly (like reify does)EnhancementMinorOpenUnresolvedUnassignedTimothy BaldridgeWed, 18 Jun 2014 07:44:20 -0500Wed, 18 Jun 2014 07:44:20 -050000Global Rank[CLJ-1446] (def v) with no init supplied destroys #'v metadatahttp://dev.clojure.org/jira/browse/CLJ-1446
Clojure<p>(def a) destroys #'a metadata, check this:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">(def ^:mykey a 1)
(meta #'a) ;; ok, :mykey is present
(let [v (def a)]
[(meta v) ;; NO :mykey present, metadata destroyed
(identical? v #'a) ;; <span class="code-keyword">true</span>, we are talking of the same <span class="code-keyword">var</span>
])
(meta #'a) ;; NO :mykey present</pre>
</div></div>
<p>If this is not a bug but a "feature", then we have at least two problems:</p>
<p>1- The def special form documentation doesn't state this behaviour at all, it needs to be clarified. With the current documentation it seems as doing a def with no init supplied will not make any side-effect at all, and this is not true for the var metadata.</p>
<p>2- defmulti uses this form to lookup the var and check if it already binds to a MultiFn, if that is the case then defmulti does nothing... but it really does something, defmulti will destroy the original var metadata in the (supposedly non-destructive) check. This is the involved defmulti fragment:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">(let [v# (def ~mm-name)]
(when-not (and (.hasRoot v#) (instance? clojure.lang.MultiFn (deref v#)))
...</pre>
</div></div>
CLJ-1446(def v) with no init supplied destroys #'v metadataDefectMajorOpenUnresolvedUnassignedNahuel GrecoFri, 13 Jun 2014 15:55:13 -0500Fri, 13 Jun 2014 19:35:27 -0500Release 1.601<p>I think this is mostly a dupe of <a href="http://dev.clojure.org/jira/browse/CLJ-1148" title="adds docstring support to defonce">CLJ-1148</a> but I'll leave it as it states the specific problem more precisely.</p><p>Alex Miller: It seems <a href="http://dev.clojure.org/jira/browse/CLJ-1148" title="adds docstring support to defonce">CLJ-1148</a> is an special case where this problem shows, but the patches in <a href="http://dev.clojure.org/jira/browse/CLJ-1148" title="adds docstring support to defonce">CLJ-1148</a> only fixes the issues for <tt>defonce</tt>, not generally for <tt>def</tt>, not for <tt>defmulti</tt> and not clarifies this behaviour in the <tt>def</tt> special form documentation. </p>Global Rank[CLJ-1445] pprint prints some metadata when *print-meta* bound to true, but not allhttp://dev.clojure.org/jira/browse/CLJ-1445
Clojure<p>Short example illustrating the behavior:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">user=&gt; *clojure-version*
{:major 1, :minor 6, :incremental 0, :qualifier nil}
user=&gt; (def f1 '(defn foo [^<span class="code-object">Integer</span> x] ^{:bar 8} (inc x)))
#'user/f1
;; pr shows all metadata, as expected
user=&gt; (binding [*print-meta* <span class="code-keyword">true</span>] (pr f1))
^{:line 2, :column 10} (defn foo [^<span class="code-object">Integer</span> x] ^{:bar 8, :line 2, :column 33} (inc x))nil
;; pprint shows some metadata, but not all
user=&gt; (binding [*print-meta* <span class="code-keyword">true</span>] (clojure.pprint/pprint f1))
(defn foo [^<span class="code-object">Integer</span> x] (inc x))
nil</pre>
</div></div>
<p>I have not dug into the details yet, but it appears that this may be because pprint uses pr to show symbols, but not to show collections. Thus pprint shows metadata on symbols, but not collections.</p>
<p>It would be nice if pprint could instead show all metadata, as pr does, when <b>print-meta</b> is bound to true.</p>CLJ-1445pprint prints some metadata when *print-meta* bound to true, but not allDefectMinorOpenUnresolvedUnassignedAndy FingerhutFri, 13 Jun 2014 11:02:45 -0500Fri, 13 Jun 2014 12:26:47 -0500Release 1.632<p>Attached file clj-1445-workaround-v1.clj is a function that pprints with more metadata than clojure.pprint does. As noted in the comments, it may not show metadata <b>on</b> other metadata. Please update with an enhanced version if you create one.</p><p>Attached file clj-1445-workaround-v2.clj supersedes the earlier one, which I will delete.</p>
<p>The included function pprint-meta appears to be a correct way to pprint values with all metadata, even if the metadata maps themselves have metadata on them.</p>Global Rank[CLJ-1444] Fix unquote splicing for empty seqshttp://dev.clojure.org/jira/browse/CLJ-1444
Clojure<p>Current behaviour:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">user=&gt; `(~@())
nil
user=&gt; `[~@()]
[]</pre>
</div></div>
<p>Expected behaviour:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">user=&gt; `(~@())
()
user=&gt; `[~@()]
[]</pre>
</div></div>CLJ-1444Fix unquote splicing for empty seqsDefectMinorOpenUnresolvedUnassignedNicola Momettoreadersyntax-quoteWed, 11 Jun 2014 16:06:49 -0500Wed, 12 Nov 2014 10:07:56 -060002<p>Patch 0001-Fix-unquote-splicing-for-empty-seqs.patch dated Jun 11 2014 no longer applies cleanly to latest Clojure master due to some changes committed earlier today. I haven't checked whether this patch is straightforward to update.</p><p>Updated patch to apply to HEAD</p><p>This patch requires the patch at <a href="http://dev.clojure.org/jira/browse/CLJ-1586">http://dev.clojure.org/jira/browse/CLJ-1586</a> to be applied first otherwise some compile-time metdata might get lost.</p>Global RankPatchCode and Test[CLJ-1443] reduce docstring partly incorrect with reducers.http://dev.clojure.org/jira/browse/CLJ-1443
Clojure<p>The docstring for reduce includes this: "If val is not supplied, returns the result of applying f to the first 2 items in coll". This is true if coll is a sequence, but not if it is a reducer. For example:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">user=&gt; (-&gt;&gt; (range 0 10 2) (reduce (fn[x y] (+ x y))))
20
user=&gt; (-&gt;&gt; (range 0 10 2) (r/map #(/ % 2)) (reduce (fn[x y] (+ x y))))
ArityException Wrong number of args (0)</pre>
</div></div>
<p>The docstring should be updated to make it clear that reducers (used without an initial seed value) require the reducing function to support a 0 arity overload returning the identity value for the reduction operation.</p>CLJ-1443reduce docstring partly incorrect with reducers.DefectMinorOpenUnresolvedUnassignedGreg ChapmandocstringreducersTue, 10 Jun 2014 13:16:43 -0500Tue, 10 Jun 2014 13:16:43 -0500Release 1.600Global Rank[CLJ-1442] Tag gensym sourced symbols with metadatahttp://dev.clojure.org/jira/browse/CLJ-1442
Clojure<p>For static analysis tools derived from TANAL it is frequently useful to determine whether a symbol is user defined or the result of code generation. As tools analyzer depends on the Clojure core for evaluation and symbol generation a user wishing to annotate generated symbols must currently provide a binding replacing clojure.core/gensym with a snippet equivalent to the following patch. Such overloading is not appropriate for TANAL, TE* or user code as it is a redefinition of clojure.core behavior which should be standard rather than subjected to users with crowbars.</p>CLJ-1442Tag gensym sourced symbols with metadataEnhancementTrivialOpenUnresolvedUnassignedReid McKenzieMon, 9 Jun 2014 14:06:02 -0500Mon, 11 Aug 2014 07:26:40 -050023<p>This could eventually help with filtering out def'd symbols like 't131045 coming from reify in CLJS. I've been seeing this behavior with core.async namespaces in an autodoc-cljs proof-of-concept, which could eventually target tools.analyzer.</p><p>Re the patch, why not call the Symbol constructor that takes meta instead of with-meta? For performance, it might also be useful to use the same constant map as well.</p><p>Because the compiler will emit the meta map as a static field the patch as-is will share the same map instance between all annotated symbols. Calling the metadata constructor is reasonable, I'll update the patch.</p><p>So the metadata constructor of Symbol is private, see <a href="https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/Symbol.java#L100">https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/Symbol.java#L100</a>. Without changing this directly constructing symbols with metadata is not possible from the core. If you're worried about escaping the var indirection cost of adding metadata via with-meta inlining with-meta is an option, however then we're building two symbols for no good reason. Exposing the currently private metadata constructor is probably the right fix, abet its own ticket.</p><p>From the comments above it appears that this is not planned to be a final version of this patch, but FYI some automated scripts I have found that patch 0001-Annotate-generated-symbols-with-metadata.patch dated Jun 9 2014 applies cleanly to the latest Clojure master as of Jul 1 2014, but Clojure fails to build.</p><p>Thanks Andy, I'll rework and test it in the morning</p><p>Because of the work that clojure.lang.Symbol/intern does, exposing and using the metadata constructor directly makes no sense. The updated patch directly invokes clojure.lang.Symbol/withMeta rather than indirecting through clojure.core/with-meta and taking the performance hit of calling through a Var. Builds cleanly on my system.</p><p>Reid, although JIRA can handle multiple attachments with the same name, it can be a bit confusing for people, and for some scripts I have for determining which patches apply and test cleanly. Would you mind renaming one of your patches?</p><p>3rd and final cut at this patch.</p>Global RankPatchCode[CLJ-1441] Provide docs on how to reference imports that conflict with default ns class importshttp://dev.clojure.org/jira/browse/CLJ-1441
Clojure<p>This is related to <a href="http://dev.clojure.org/jira/browse/CLJ-1440" title="Unable to exclude clojure.lang.Compiler using :refer-clojure"><del>CLJ-1440</del></a>; a name clash on class "Compiler" between clojure.lang and another package.</p>
<p>The documentation does not address how to handle this cleanly; specifically, <tt>refer</tt> would appear to allow a way to exclude clojure.lang.Compiler, but does not.</p>CLJ-1441Provide docs on how to reference imports that conflict with default ns class importsEnhancementMinorOpenUnresolvedUnassignedHoward Lewis ShipdocumentationSat, 7 Jun 2014 18:04:00 -0500Sat, 7 Jun 2014 19:57:17 -0500Release 1.601<p><tt>refer</tt> is all about symbols that refer to Var. refer's docstring seems pretty clear on that to me.</p>
<p>Your conflict is on symbols that refer to a Class, which is the domain of <tt>import</tt> and has no exclusion facilities. The set of default imports is defined in RT.DEFAULT_IMPORTS and includes clojure.lang.Compiler along with everything in java.lang.*.</p>
<p>You can always fully-qualify any class you want to use in your ns, so that is one workaround available. Another is what Nicola suggested in <a href="http://dev.clojure.org/jira/browse/CLJ-1440" title="Unable to exclude clojure.lang.Compiler using :refer-clojure"><del>CLJ-1440</del></a> - post-modify the ns after load.</p>
<p>Either <tt>ns</tt> or <tt>import</tt> could theoretically document more explicitly the list of auto-imports and recommend a solution to this problem. I'm not sure whether this is worth doing or would be accepted given the infrequency of the use case and availability of workarounds.</p>
<p>I tweaked <a href="http://clojure.org/namespaces">http://clojure.org/namespaces</a> to mention this.</p>Global Rank[CLJ-1438] bit-* functions don't check for overflowhttp://dev.clojure.org/jira/browse/CLJ-1438
Clojure<p>The bit* functions, in contrast to the other numerical functions, don't appear to check for overflow, i.e. <tt>(bit-test 13 200000)</tt> returns <tt>true</tt>.</p>
<p>It would be nice if the behaviour would fit the other numerical operators, i.e. throw on overflow and provide a variant that doesn't, and one that works with arbitrary precision, also not currently supported:<br/>
<tt>(bit-test (bigint 13) 20000)</tt>, <tt>(bit-test (biginteger 13) 20000)</tt> throw IllegalArgumentException.</p>CLJ-1438bit-* functions don't check for overflowEnhancementMinorOpenUnresolvedUnassignedPascal GermrothcheckargsmathThu, 5 Jun 2014 13:06:44 -0500Tue, 24 Feb 2015 11:52:06 -0600Release 1.601Global Rank[CLJ-1436] Deref throws an unhelpful error message when used on something not dereferencablehttp://dev.clojure.org/jira/browse/CLJ-1436
Clojure<p>Consider the following code:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">(def x 1)
(def y (ref 2))
(+ @x y)</pre>
</div></div>
<p>Clojure throws a ClassCastException on cast to Future. This is a very unhelpful error message; why a Future, why not Ref, Atom etc. It would be nice if this failed more gracefully.</p>CLJ-1436Deref throws an unhelpful error message when used on something not dereferencableEnhancementMinorOpenUnresolvedUnassignedPhillip LorderrormsgsnewbieTue, 3 Jun 2014 02:18:28 -0500Sun, 28 Dec 2014 11:06:25 -060031<p>Attached a patch with better error messages for deref. The above example now throws:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">IllegalArgumentException class java.lang.<span class="code-object">Long</span> is not derefable clojure.core/deref (core.clj:2211)</pre>
</div></div>
<p>and e.g.</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">(deref (delay 1) 500 :foo)</pre>
</div></div>
<p>throws</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">IllegalArgumentException class clojure.lang.Delay is not derefable with a timeout clojure.core/deref (core.clj:2222)</pre>
</div></div><p>Patch file clj-1436-patch-2014-09-16.diff updates the deref function so that it checks whether its arg is a future before sending it to deref-future. It also updates the deref function to provide clearer error messages. If the arg is not a future, and does not implement IDeref, the patched version of deref throws an IllegalArgumentException with a message that the arg cannot be dereferenced because it is not a ref/future/etc.</p><p>Oops, I had this page open from yesterday and didn't see the patch submitted by Tobias. His has everything mine does, so I'll withdraw mine.</p><p>One suggestion: the error message might sound better as "IllegalArgumentException cannot dereference clojure.lang.Delay; not a future or reference type".</p><p>Tobias' patch does not contain the tests I had in mine, so I'm re-submitting just the tests as tests-patch.diff. If you install the tests patch without installing the deref patch, the tests will fail with the error message "Wrong exception type when passing non-IDeref/non-future to deref/@". Applying the deref patch as well will allow the tests to pass.</p><p>This patch does not seem to consider performance implications of adding this check and its impact on inlining.</p>Global RankPatchCode and Test[CLJ-1435] 'numerator and 'denominator fail to handle integral values (i.e. N/1)http://dev.clojure.org/jira/browse/CLJ-1435
Clojure<p>Because ratio values reduce to lowest terms and, for integral values where the lowest term is N/1, are auto-converted to BigInts (and formerly Longs), the current behavior of <tt>clojure.core/numerator</tt> and <tt>clojure.core/denominator</tt> yield unexpected results.</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">user=&gt; (numerator 1/3)
1
user=&gt; (numerator (+ 1/3 2/3))
ClassCastException clojure.lang.BigInt cannot be <span class="code-keyword">cast</span> to clojure.lang.Ratio clojure.core/numerator (core.clj:3306)
user=&gt; (denominator 1/3)
3
user=&gt; (denominator (+ 1/3 2/3))
ClassCastException clojure.lang.BigInt cannot be <span class="code-keyword">cast</span> to clojure.lang.Ratio clojure.core/denominator (core.clj:3314)
user=&gt;</pre>
</div></div>
<p>The auto-conversion to Longs is not really the problem in my mind. I'd like to see <tt>numerator</tt> return the original value when presented with a BigInt and <tt>denominator</tt> always return 1 when presented with a BigInt. It seems reasonable to request the same for Longs.</p>
<p>If desired, I'd be happy to produce a patch.</p>CLJ-1435'numerator and 'denominator fail to handle integral values (i.e. N/1)DefectMajorOpenUnresolvedUnassignedAaron BrooksFri, 30 May 2014 16:31:29 -0500Fri, 30 May 2014 20:05:48 -0500Release 1.614<p>I don't know the official stance on this ticket, but will add some notes.</p>
<p>Aaron, numerator and denominator are pretty clearly documented to work on Ratio types only.</p>
<p>It is pretty easy to write my-numerator and my-denominator that work exactly as you wish, checking for the type of arg and using numerator, denominator for Ratio types, and doing whatever you think is correct for other numeric types.</p><p>I'm aware that they are documented as such. Part of my point is that you can be working entirely with Ratio types and, via arithmetic operations between them, sometimes wind up with a non-Ratio number unexpectedly.</p>
<p>Also consider:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">user=&gt; (numerator 2/1)
ClassCastException java.lang.<span class="code-object">Long</span> cannot be <span class="code-keyword">cast</span> to clojure.lang.Ratio clojure.core/numerator (core.clj:3238)</pre>
</div></div>
<p>You're then left either implementing a try/catch correction or always checking the type before using <tt>numerator</tt> or <tt>denominator</tt> which is a loss in performance.</p>
<p>The patch I have in mind is creating a protocol, extended to Ratio, BigInt and Long which calls the appropriate method (Ratios) or returns either the given number or 1 (numerator/denominator) for the integral types. I expect this to maintain the current level of performance in the cases where it works and behave properly in the cases currently not handled.</p>Global Rank[CLJ-1434] The doc string for `trampoline` suggests that it applies to mutual recursion in general. It doesn't: it applies to mutual *tail* recursion only. http://dev.clojure.org/jira/browse/CLJ-1434
Clojure<p>The doc-string for `trampoline` starts "trampoline can be used to convert algorithms requiring mutual<br/>
recursion without stack consumption. ". This is inaccurate: `trampoline` applies only to mutual <b>tail</b> recursion. </p>
<p>Replace this with "trampoline can be used to convert algorithms employing mutual <b>tail</b> recursion into a form that does not consume stack". </p>Any. CLJ-1434The doc string for `trampoline` suggests that it applies to mutual recursion in general. It doesn't: it applies to mutual *tail* recursion only. TaskTrivialOpenUnresolvedUnassignedColin Hastiedocstringpatch,Thu, 29 May 2014 08:38:33 -0500Thu, 29 May 2014 08:38:33 -0500Release 1.600Global Rank[CLJ-1433] proxy-super calls generally use reflectionhttp://dev.clojure.org/jira/browse/CLJ-1433
Clojure<p>For example:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">user=&gt; (proxy [java.util.BitSet] []
(flip [bitIndex]
(proxy-<span class="code-keyword">super</span> flip bitIndex)))
Reflection warning, NO_SOURCE_PATH:73:5 - call to method flip can't be resolved (target class is unknown).</pre>
</div></div>
<p>I believe this issue might be fixed by simply adding type-hint metadata to the 'this symbol emitted by the proxy macro. I have not tried this change, but this macro seems to indicate it should work:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">(defmacro proxy-<span class="code-keyword">super</span>-cls [cls meth &amp; args]
(let [thissym (with-meta (gensym) {:tag cls})]
`(let [~thissym ~'<span class="code-keyword">this</span>]
(proxy-call-with-<span class="code-keyword">super</span> (fn [] (. ~thissym ~meth ~@args)) ~thissym ~(name meth))
)))
;;;;;;;;;;;;;;;;;;;;;;
user=&gt; (proxy [java.util.BitSet] []
(flip [bitIndex]
(proxy-<span class="code-keyword">super</span>-cls java.util.BitSet flip bitIndex)))
#&lt;BitSet$ff19274a {}&gt;</pre>
</div></div>
CLJ-1433proxy-super calls generally use reflectionDefectMinorOpenUnresolvedUnassignedGreg ChapmantypehintsWed, 28 May 2014 19:52:04 -0500Wed, 28 May 2014 19:52:04 -0500Release 1.600Global Rank[CLJ-1432] NullPointerException on function with primitive result declarationhttp://dev.clojure.org/jira/browse/CLJ-1432
Clojure<p>The following minimal example shows the error:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">(defn f ^<span class="code-object">double</span> [])
(f)
=&gt; NullPointerException</pre>
</div></div>
<p>When decompiling the function `f` I found the following return expression:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java"><span class="code-keyword">return</span> <span class="code-keyword">null</span>.doubleValue();</pre>
</div></div>
<p>This happened in a Java interop scenario where the called Java method had no return value but was in the return position of the primitive Clojure function.<br/>
The compiler should check for `null` on compilation.</p>
<p>Another example - calling a method with void return as the last expression fails in a similar way:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">(defn f ^<span class="code-object">double</span> [^SomeClassToAvoidRuntimeReflection obj, x, y]
(.someMethod obj, x, y))
(f obj, x, y)
=&gt; NullPointerException</pre>
</div></div>CLJ-1432NullPointerException on function with primitive result declarationEnhancementMinorOpenUnresolvedUnassignedGunnar VölkelprimitivestypehintsMon, 26 May 2014 10:51:39 -0500Fri, 30 May 2014 08:35:40 -0500Release 1.601<p>What do you expect to happen in this case? You declared a function as returning a double but didn't return one.</p><p>Since this is only the minimal example the error is relatively easy to spot.<br/>
Consider the following small example with Java interop:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">(defn f ^<span class="code-object">double</span> [^SomeClassToAvoidRuntimeReflection obj, x, y]
(.someMethod obj, x, y))
(f obj, x, y)
=&gt; NullPointerException</pre>
</div></div>
<p>In this example it is much harder to find the reason for the NPE because you'd first suspect `obj` to be `null`.</p>
<p>I expect a check in the compiler at the point where "return null.doubleValue();" is emitted, followed by an error message, e.g. "Primitive return value of type 'double' expected, but no value is returned.".</p><p>Your second example seems perfectly OK to me, compiler should not report any error and NPE check must be at runtime.</p><p>@Jozef: No, you are wrong. The compiler infers via reflection at compile time that the called method does not return a value and emits "return null.doubleValue()". So this can and should be reported as explicit error at compile time. I added a typehint to make it clear that there is no runtime reflection involved.<br/>
You would be right, if the compiler emitted something like "return somevar.doubleValue();" because then at compile time there is no knowledge about a possible "null" value.</p><p>Gunnar, in your example, is the method 'someMethod' declared to return void, or something else? Adding that info to your example might help clarify it.</p><p>Gunnar, the second example was ambiguous and strayed away the discussion. Anyway, whether returning wrong type is through the native method or not, it is a user error in the first place. Right now it is reported at runtime. For me this ticket should be a minor enhancement instead of defect.</p><p>Yes, the reason is a user error. But one that is harder to debug than necessary.<br/>
Also, it is clearly a defect since emitting 'null.doubleValue()' can not be considered as a valid compilation. </p>
<p>Andy, yes 'someMethod' is declared to return void. I'd edit the original ticket text to add the example and the java method return value information, but it seems jira does not let me.</p><p>I added the second example (with clarifying void comment) to the description. </p>Global Rank[CLJ-1431] Switch from MurmurHash3 to SipHash to prevent DoS collision attack (hash flooding)http://dev.clojure.org/jira/browse/CLJ-1431
Clojure<p>Clojure is using Murmur3 throughout:<br/>
<a href="https://github.com/clojure/clojure/commit/dff9600387b962f16fc78e6477e10e34651fd366">https://github.com/clojure/clojure/commit/dff9600387b962f16fc78e6477e10e34651fd366</a></p>
<p>DJB, Jean-Philippe Aumasson, and Martin Boßlet have shown that Murmur3 is not resilient against hash collision attacks:<br/>
<a href="http://www.ocert.org/advisories/ocert-2012-001.html">http://www.ocert.org/advisories/ocert-2012-001.html</a><br/>
<a href="https://131002.net/siphash/">https://131002.net/siphash/</a></p>
<p>"Hash-flooding DoS reloaded: attacks and defenses" talk by DJB, Jean-Philippe Aumasson, and Martin Boßlet<br/>
<a href="http://media.ccc.de/browse/congress/2012/29c3-5152-en-hashflooding_dos_reloaded_h264.html">http://media.ccc.de/browse/congress/2012/29c3-5152-en-hashflooding_dos_reloaded_h264.html</a></p>
<p>"Breaking Murmur: Hash-flooding DoS Reloaded"<br/>
<a href="http://emboss.github.io/blog/2012/12/14/breaking-murmur-hash-flooding-dos-reloaded/">http://emboss.github.io/blog/2012/12/14/breaking-murmur-hash-flooding-dos-reloaded/</a></p>
<p>Python, Ruby, JRuby, Haskell, Rust, Perl, Redis... have all switched to SipHash <br/>
<a href="https://en.wikipedia.org/wiki/SipHash">https://en.wikipedia.org/wiki/SipHash</a></p>
<p>Last year Google dropped CityHash from Guava and replaced it with SipHash<br/>
<a href="https://code.google.com/p/guava-libraries/issues/detail?id=1232">https://code.google.com/p/guava-libraries/issues/detail?id=1232</a></p>
<p>SipHash Guava Implementation<br/>
<a href="https://code.google.com/p/guava-libraries/source/browse/guava/src/com/google/common/hash/SipHashFunction.java">https://code.google.com/p/guava-libraries/source/browse/guava/src/com/google/common/hash/SipHashFunction.java</a></p>
<p>SipHash Java reference implementation<br/>
<a href="https://github.com/emboss/siphash-java/blob/master/src/main/java/com/github/emboss/siphash/SipHash.java">https://github.com/emboss/siphash-java/blob/master/src/main/java/com/github/emboss/siphash/SipHash.java</a></p>
CLJ-1431Switch from MurmurHash3 to SipHash to prevent DoS collision attack (hash flooding)EnhancementMajorOpenUnresolvedUnassignedJames ThorntonsecuritySun, 25 May 2014 22:12:53 -0500Mon, 26 May 2014 01:09:15 -0500Release 1.4Release 1.5Release 1.603<p>Thanks, we've talked about this issue and some possible things we could do, but didn't have a ticket for it yet.</p><p>While the Java 7 approach relied on (attempting) to properly seed hash maps with string hash codes, that was all dropped in Java 8, which addressed DoS collision hash attacks by instead improving the data structure to switch from linear collisions to a red/black tree (log-time) for collisions. It's possible a similar approach could work in Clojure as well.</p>
<p>One workaround that could be used now is to wrap map keys in a custom type that implements IHashEq and implements an alternate hash function.</p>Global Rank[CLJ-1428] restart-agent is ignored inside an fn passed to set-error-handler.http://dev.clojure.org/jira/browse/CLJ-1428
Clojure<p>If I pass a function containing start-agent to set-error-handler of an agent, if an exception occurs the restart-agent is ignored.<br/>
for example:</p>
<p>(def a (agent 0))</p>
<p>(set-error-handler! a (fn <span class="error">&#91;the-agent the-exception&#93;</span> (restart-agent the-agent)) ) </p>
<p>If I now issue : (send! a #(/ 1 0)), I still have a failed agent. It did not restart.</p>
<p>I know I can set the error-mode to the agent to :continue to have my agent up after a crash, but I wished I could fix the conditions that caused the exception in the first-place then restart the agent programmatically in the set-error-handler.</p>
<p>Maybe it is a known beahviour, but then it is not documented ?</p>Linux, jdk 1.7, emacs / ciderCLJ-1428restart-agent is ignored inside an fn passed to set-error-handler.DefectMinorOpenUnresolvedUnassignedRafik NACCACHEagentsMon, 19 May 2014 11:35:23 -0500Mon, 19 May 2014 11:36:43 -0500Release 1.600Global Rank[CLJ-1425] Defer literal map construction of syntax-quoted maps to allow for semantically valid unquote splicinghttp://dev.clojure.org/jira/browse/CLJ-1425
Clojure<p>At present one cannot unquote-splice into a map literal unless the map contains an even number of literal forms, even if one of them is a null unquote (~@[]).</p>
<p>E.g.: `{~@<span class="error">&#91;1 2&#93;</span>} ;=&gt; RuntimeException Map literal must contain an even number of forms clojure.lang.Util.runtimeException (Util.java:219)</p>
<p>However, within the context of a syntax-quote, it is not essential that the map literal be represented internally as a map since the syntax-quote emits code to build the map and not the map itself. The syntaxQuote method on SyntaxQuoteReader does not even operate the map, but rather a flattened sequence of interleaved keys and values.</p>
<p>With the aid of metadata and a LispReader-global Var, we can track that a collection of elements within a syntax quote will become a map, and emit the proper code forms from the SyntaxQuoteReader. There is a small edge case in metadata literals, but an with additional piece of metadata containing the proto-map we can still generate the appropriate (with-meta ...) form at syntax-quote emission time.</p>
<p>Importantly, none of the hand-waving involved ever escapes the reader, and the eval/compile environment is none the wiser.</p>
<p>This allows the following:</p>
<p>`{~@<span class="error">&#91;1 2&#93;</span>} ;=&gt; after eval: {1 2}<br/>
`^{~@<span class="error">&#91;:foo :bar&#93;</span>} sym ;=&gt; metadata of 'sym after eval: {:foo :bar}</p>
<p>But not:<br/>
`~{1} ;=&gt; RuntimeException ...<br/>
<br/>
Or:{1} ;=&gt; RuntimeException ...</p>
<p>And `{~@<span class="error">&#91;1&#93;</span>} has the same semantics as the currently required `{~@<span class="error">&#91;1&#93;</span> ~@[]}<br/>
;=&gt; IllegalArgumentException No value supplied for key: 1 clojure.lang.PersistentHashMap.create (PersistentHashMap.java:77)</p>
<p>The changes in my patch pass all existing tests and include an additional test for the newly-supported map unquote-splicing form.</p>AnyCLJ-1425Defer literal map construction of syntax-quoted maps to allow for semantically valid unquote splicingEnhancementMinorOpenUnresolvedUnassignedJon DistadreaderFri, 16 May 2014 09:45:31 -0500Wed, 15 Oct 2014 08:16:07 -0500Release 1.703<p>Modified from this morning- more tests, plus bugfix for the new cases caught.</p><p>Updated patch.</p>
<p>Now uses two distinct paths for adding metadata. Old version potentially stacked with-meta calls, which could result in lost keys.</p><p>It seems like this is a bad idea, it sort of makes sense from purely a macro writing perspective, but syntax quote is used outside of macros, in which case this just becomes a circumvention of the duplicate key checks that were added, I think some time around 1.3 maybe 1.4</p>
<p><a href="http://dev.clojure.org/display/design/Allow+duplicate+map+keys+and+set+elements">http://dev.clojure.org/display/design/Allow+duplicate+map+keys+and+set+elements</a></p><p>Actually, unquote-splicing already circumvents the duplicate key check because it expands to an (apply hash-map ...) call.</p>
<p>In Clojure 1.7.0-alpha2</p>
<p>user&gt; `{~@<span class="error">&#91;:foo :bar :foo :bar&#93;</span> ~@[]} <br/>
;=&gt; {:foo :bar}<br/>
user&gt; '`{~@<span class="error">&#91;:foo :bar :foo :bar&#93;</span> ~@[]}<br/>
;=&gt; (clojure.core/apply clojure.core/hash-map (clojure.core/seq (clojure.core/concat <span class="error">&#91;:foo :bar :foo :bar&#93;</span> [])))</p><p>yeah, sorry, I was confusing this implementation with a related issue that was closed. do you have a motivating example for this? I write a fair bit of clojure and have not found it to be an issue in practice, and I am leery of relaxing these sort of constraints. if we allow this behavior, then syntax quote can definitely never be pulled out of the reader(there may be other behavior that already makes this hard to impossible, I am not sure), effectively syntax quote would have to operate on data before it makes out of the reader, were as if maps used in syntax quote are "well formed" in may be possible to move syntax quote (a source of a lot of complexity in the reader) out of the reader and have it operate on data that has already been read in.</p>
<p>I am almost 100% sure making syntax quote a post reader macro is not a priority in any shape or form, but I just mention it as the sort of follow on thing that could have the door shut on it due to these kind of changes, I've general begun to think of basically anything related to syntax quote as adding syntax above beyond just data, which seems a negative.</p>
<p>So anyway, I don't feel much pain from this behavior and it seems like the "fix" could have some follow on consequences, so a solid motivating example would be good.</p>
<p>just to warn you away from spending time coming up with a motivating example, every feature I have railed against has been committed, so if you just ignore me there is a real chance you'll make it in <img class="emoticon" src="http://dev.clojure.org/jira/images/icons/emoticons/smile.gif" height="20" width="20" align="absmiddle" alt="" border="0"/> </p><p>To be honest, I had forgotten I submitted this. I suppose it boils down to prioritizing principles- do the literal semantics of a map take precedence over the conceptual semantics? At this point I'm against my former position and I think the literal semantics of the should take precedence, as they currently do. Especially since this is in the reader.</p>Global RankPatchCode and Test[CLJ-1423] Applying a var to an infinite arglist consumes all available memoryhttp://dev.clojure.org/jira/browse/CLJ-1423
Clojure<p>It is possible to apply a function to an infinite argument list: for example, (apply distinct? (repeat 1)) immediately returns false, after realizing just a few elements of the infinite sequence (repeat 1). However, (apply #'distinct? (repeat 1)) attempts to realize all of (repeat 1) into memory at once.</p>
<p>This happens because Var.applyTo delegates to AFn.applyToHelper to decide which arity of Var.invoke to dispatch to; but AFn doesn't expect infinite arglists (mostly those use RestFn). So it uses RT.seqToArray, which doesn't work well in this case.</p>
<p>Instead, Var.applyTo(args) can just dispatch to deref().applyTo(args), and let the function being stored figure out what to do with the arglist.</p>
<p>I've changed Var.applyTo to do this, and added a test (which fails before my patch is applied, and passes afterwards).</p>CLJ-1423Applying a var to an infinite arglist consumes all available memoryDefectMinorOpenUnresolvedUnassignedAlan MalloyThu, 15 May 2014 16:59:14 -0500Thu, 15 May 2014 16:59:14 -050044Global RankPatchCode and Test[CLJ-1422] Recur around try boxes primitiveshttp://dev.clojure.org/jira/browse/CLJ-1422
Clojure<p>Primitive function and recur variables can't pass through a (try) cleanly; they're boxed to Object instead. This causes reflection warnings for fns or loops that use primitive types.</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">user=&gt; (set! *warn-on-reflection* <span class="code-keyword">true</span>)
<span class="code-keyword">true</span>
user=&gt; (fn [] (loop [t 0] (recur t)))
#&lt;user$eval676$fn__677 user$eval676$fn__677@3d80023a&gt;
user=&gt; (fn [] (loop [t 0] (recur (<span class="code-keyword">try</span> t))))
NO_SOURCE_FILE:1 recur arg <span class="code-keyword">for</span> primitive local: t is not matching primitive, had: <span class="code-object">Object</span>, needed: <span class="code-object">long</span>
Auto-boxing loop arg: t
#&lt;user$eval680$fn__681 user$eval680$fn__681@5419323a&gt;
user=&gt; (fn [^<span class="code-object">long</span> x] (recur (<span class="code-keyword">try</span> x)))
NO_SOURCE_FILE:1 recur arg <span class="code-keyword">for</span> primitive local: x is not matching primitive, had: <span class="code-object">Object</span>, needed: <span class="code-object">long</span>
CompilerException java.lang.IllegalArgumentException: recur arg <span class="code-keyword">for</span> primitive local: x is not matching primitive, had: <span class="code-object">Object</span>, needed: <span class="code-object">long</span>, compiling:(NO_SOURCE_PATH:1:1)</pre>
</div></div>CLJ-1422Recur around try boxes primitivesEnhancementMinorOpenUnresolvedUnassignedKyle KingsburycompilerperformancetypehintsWed, 14 May 2014 20:32:20 -0500Mon, 28 Jul 2014 17:22:12 -0500Release 1.5Release 1.601<p>Without commenting on the most desirable behavior, the following code does not cause reflection warnings:</p>
<div class="preformatted panel" style="border-width: 1px;"><div class="preformattedContent panelContent">
<pre>user=&gt; (set! *warn-on-reflection* true)
true
user=&gt; (fn [] (loop [t 0] (recur (long (try t)))))
#&lt;user$eval673$fn__674 user$eval673$fn__674@4e56c411&gt;
</pre>
</div></div><p>Similar ticket <a href="http://dev.clojure.org/jira/browse/CLJ-701">http://dev.clojure.org/jira/browse/CLJ-701</a></p><p>try/catch in the compiler only implements Expr, not MaybePrimitiveExpr, looking at extending TryExpr with MaybePrimitiveExpr it seems simple enough, but it turns out recur analyzes it's arguments in the statement context, which causes (try ...) to essentially wrap itself in a function like ((fn [] (try ...))), at which point it is an invokeexpr which is much harder to add maybeprimitiveexpr too and it reduces to the same case as <a href="http://dev.clojure.org/jira/browse/CLJ-701" title="Compiler loses &#39;loop&#39;s return type in some cases">CLJ-701</a></p><p><a href="http://dev.clojure.org/jira/browse/CLJ-701">http://dev.clojure.org/jira/browse/CLJ-701</a> has a patch that I think solves this</p><p>Should I dupe this to <a href="http://dev.clojure.org/jira/browse/CLJ-701" title="Compiler loses &#39;loop&#39;s return type in some cases">CLJ-701</a>? </p><p>if you want the fixes for try out of the return context to be part of <a href="http://dev.clojure.org/jira/browse/CLJ-701" title="Compiler loses &#39;loop&#39;s return type in some cases">CLJ-701</a> then yes it is a dupe, if you are unsure or would prefer 701 to stay more focused (my patch may not be acceptable, or may be too large and doing too much) then no it wouldn't be a dupe. I sort of took it on myself to solve both in the patch on <a href="http://dev.clojure.org/jira/browse/CLJ-701" title="Compiler loses &#39;loop&#39;s return type in some cases">CLJ-701</a> because I came to <a href="http://dev.clojure.org/jira/browse/CLJ-701" title="Compiler loses &#39;loop&#39;s return type in some cases">CLJ-701</a> via Nicola's comment here, and the same compiler machinery can be used for both.</p>
<p>I think the status is pending on the status of <a href="http://dev.clojure.org/jira/browse/CLJ-701" title="Compiler loses &#39;loop&#39;s return type in some cases">CLJ-701</a>.</p>Global Rank[CLJ-1419] Report errors on missing param list or return type of methods in gen-class and gen-interfacehttp://dev.clojure.org/jira/browse/CLJ-1419
Clojure<p>The following are invalid and should produce errors when invoked on gen-class or gen-interface:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">(gen-<span class="code-keyword">interface</span> :name clj1419.IFail :methods [[myMethod java.lang.<span class="code-object">String</span>]]) ;; no params, <span class="code-keyword">throws</span> error
(gen-<span class="code-keyword">interface</span> :name clj1419.IFail :methods [[myMethod []]]) ;; no <span class="code-keyword">return</span> type
(gen-<span class="code-keyword">interface</span> :name clj1419.IFail :methods [[myMethod]]) ;; no params or <span class="code-keyword">return</span> type</pre>
</div></div>
<p>The first example throws an error. The second and third do not but will generate an invalid class, verify with:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">(.getMethods clj1419.IFail)
ClassNotFoundException java.lang. java.net.URLClassLoader$1.run (URLClassLoader.java:366)</pre>
</div></div>
<p>Add checks to prevent these errors.</p>CLJ-1419Report errors on missing param list or return type of methods in gen-class and gen-interfaceEnhancementTrivialOpenUnresolvedUnassignedNathan Zadokserrormsgsgen-classSat, 10 May 2014 13:31:35 -0500Mon, 12 May 2014 08:49:49 -0500Release 1.600<p>I've implemented both fixes, and attached them as patches.</p><p>I'd argue that the behaviour of asm-type is at fault here (it can output an invalid type name when passed a nil argument), so I prefer that fix over the purely symptomatic generate-interface fix.</p><p>Nathan, were you planning on submitting a signed Clojure Contributor's Agreement, or already have? Details here if you have not: <a href="http://clojure.org/contributing">http://clojure.org/contributing</a></p>
<p>Patches from non-contributors cannot be committed to Clojure.</p>
<p>Note: I cannot promise you that one of your patches will be accepted into Clojure if you sign a CA &#8211; only that it will not if you do not sign one.</p><p>Please add an example of how this happens and the current error.</p><p>Andy — Yep, I've read up on that. My CA will be underway to Rich soon. (filled in, signed, in an envelope, just need to await the arrival of those bloody international stamps…)</p>
<p>Alex Miller — Tahdah!</p>
<p>A demonstration of the issue, both attached and as a gist: <a href="https://gist.github.com/nathan7/3a7e3a09e458f1354cbb">https://gist.github.com/nathan7/3a7e3a09e458f1354cbb</a></p><p>and here's log of the compiler crash that results (also added to the gist now)</p><p>Whoops, both of my patches were rather broken due to a misunderstanding on my side.<br/>
I forgot entirely that asm-type takes a <b>symbol</b>, not a string.<br/>
Modifying asm-type was definitely a bad idea, that check just looks whether it should defer to prim-&gt;class.<br/>
Adding nil to prim-&gt;class would work (and I've attached my patch for that too), but it's starting to look rather inelegant compared to just patching gen-interface.<br/>
(on a side note: I'm having a lot of fun exploring the Clojure codebase! thanks for that, humans!)</p><p>My reading of the docstring of gen-interface is that method declarations must specify a parameter list and a valid return type. I would expect all of these to be invalid:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">(gen-<span class="code-keyword">interface</span> :name clj1419.IFail :methods [[fail nil]])
(gen-<span class="code-keyword">interface</span> :name clj1419.IFail :methods [[fail [] nil]])
(gen-<span class="code-keyword">interface</span> :name clj1419.IFail :methods [[fail []]])</pre>
</div></div>
<p>"nil" is not a valid type - you can use "void" for this purpose and this works fine:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">(gen-<span class="code-keyword">interface</span> :name clj1419.IFail :methods [[fail [] void]])</pre>
</div></div>
<p>If this ticket is (as the title states) a request to allow omitting the return type or using "nil" as a return type, then I think the answer is no. If the ticket is a request to improve the error reporting of the failure cases above, then I think we can consider that but it will be very low priority.</p><p>The code seems to suggest otherwise though, seeing the <b>explicit</b> extra branch for pclasses being nil.<br/>
As much as I like PL trivia, I haven't run into `void` in Clojure anywhere else yet, and I'm surprised to see it here.<br/>
Maintaining the principle of least surprise seems preferable to pedantry about whether nil is a type: (= "nil" (str (type (.methodReturningVoid obj)))</p><p>The two places to look for words to rely on are docstrings and the <a href="http://clojure.org/documentation">http://clojure.org/documentation</a> pages. Implementation details are just that.</p>
<p>"nil" is not a type. "void" is a documented type identifier indicating the absence of a return value - <a href="http://clojure.org/java_interop#Java%20Interop-Aliases">http://clojure.org/java_interop#Java%20Interop-Aliases</a></p><p>Okay. Better error-checking in asm-type then?</p><p>I have updated the title and description based on my understanding of what this ticket should be, which is enhanced error-checking on the method specs for gen-class and gen-interface. I'm not sure if that's in asm-type or somewhere earlier.</p>Global RankPatchCode[CLJ-1412] Add 2-arity version of `cycle` that takes the numer of times to "repeat" the collhttp://dev.clojure.org/jira/browse/CLJ-1412
Clojure<p>There are already similar arities for repeat/repeatedly and similar functions, this patch adds a 2-arity version of cycle that behaves like this:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">user&gt; (cycle 0 '(1 2))
()
user&gt; (cycle -1 '(1 2))
()
user&gt; (cycle 3 '(1 2))
(1 2 1 2 1 2)
user&gt; (cycle 1 '(1 2))
(1 2)</pre>
</div></div>CLJ-1412Add 2-arity version of `cycle` that takes the numer of times to "repeat" the collEnhancementMinorOpenUnresolvedUnassignedNicola MomettoMon, 28 Apr 2014 17:07:32 -0500Thu, 18 Sep 2014 06:50:17 -050002<p>Patch 0001-Add-2-arity-version-of-cycle-that-takes-the-number-o.patch dated Apr 28 2014 no longer applies cleanly to latest Clojure master due to some changes committed earlier today. This appears trivial to update, as it is likely only a couple of lines of diff context that have changed.</p><p>Updated patch to apply to HEAD</p>Global RankPatchCode[CLJ-1411] Special symbols can be shadowed inconsistentlyhttp://dev.clojure.org/jira/browse/CLJ-1411
Clojure<p>The compiler does not complain about let binding (or def-ing) special symbols, but the binding only works if not used at the beginning of a list:</p>
<p>These work:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">(let [<span class="code-keyword">try</span> :a]
<span class="code-keyword">try</span>)
=&gt; :a
(let [<span class="code-keyword">try</span> (constantly :a)]
(apply <span class="code-keyword">try</span> :b))
=&gt; :a</pre>
</div></div>
<p>This doesn't work:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">(let [<span class="code-keyword">try</span> (constantly :a)]
(<span class="code-keyword">try</span> :b))
=&gt; :b</pre>
</div></div>
<p>This is true for all special symbols, not just publicly exposed ones like try and new, but also internal ones like fn*.</p>
<p>I would expect consistent behaviour: either the compiler does not permit shadowing special symbols at all, or shadowing them works in all cases. </p>CLJ-1411Special symbols can be shadowed inconsistentlyDefectMinorOpenUnresolvedUnassignedVolkert Oakley JurgenscompilerMon, 28 Apr 2014 03:11:37 -0500Tue, 29 Apr 2014 05:58:36 -0500Release 1.603<p>I don't think that shadowing special symbols is a good idea, but probably having all the special symbols namespace qualified (clojure.core/import* is the only one ns-qualified atm) along with checking for the symbol in the locals env first and fallbacking to the special symbols map after that, would probably help in those scenarios</p><p>I think that shadowing special symbols is a bad idea. If that was possible, we'd have to change most macros in clojure.core to make them safe (i.e. explicitly add a namespace to each special symbol usage). And how would we handle special symbols that are not just implementation specific, like <em>try</em> and <em>new</em>? Every 3rd party macro that uses those might become unsafe.</p>
<p>My personal preference would be to prohibit the shadowing of special symbols.</p><p>That won't be the case since what I'm proposing includes making syntax-quote aware of the namespaced special symbols.<br/>
`def would expand to 'clojure.core/def for example.</p><p>That's true, but macros don't have to use the syntax quote. See for example the definition of <em>when</em>.</p>Global Rank[CLJ-1409] Add support for marking gen-class methods as nativehttp://dev.clojure.org/jira/browse/CLJ-1409
Clojure<p>As far as I know, there is no support for creating a Java instance in Clojure with native methods. Everything else needed exists, but there is no way to get the right annotation on the method right now (similar to static). </p>
<p>Here's an example (<a href="http://benchmarksgame.alioth.debian.org/u64q/program.php?test=pidigits&amp;lang=clojure&amp;id=4">http://benchmarksgame.alioth.debian.org/u64q/program.php?test=pidigits&amp;lang=clojure&amp;id=4</a>) from Alioth perf tests where ASM is being used directly to generate a class with native methods where gen-class would have been perfectly adequate with this enhancement. (Equivalent Java: <a href="http://benchmarksgame.alioth.debian.org/u64q/program.php?test=pidigits&amp;lang=java&amp;id=2">http://benchmarksgame.alioth.debian.org/u64q/program.php?test=pidigits&amp;lang=java&amp;id=2</a>).</p>
<p>Suggested implementation is to mark ^{:native true} on a method and omit the body.</p>CLJ-1409Add support for marking gen-class methods as nativeEnhancementMinorOpenUnresolvedUnassignedAlex Millergen-classinteropMon, 21 Apr 2014 15:42:29 -0500Mon, 21 Apr 2014 15:42:29 -0500Release 1.600Global Rank[CLJ-1407] Recur mismatch might cause multiple evaluationhttp://dev.clojure.org/jira/browse/CLJ-1407
Clojure<p>Since mismatching recurs cause the loop body to be re-analyzed, macroexpansion in the loop body might happen more than once, causing any side effects that happen during macroexpansion to be evaluated potentially multiple times</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">Clojure 1.7.0-master-SNAPSHOT
user=&gt; (defmacro x [] (println <span class="code-quote">"foo"</span>))
#'user/x
user=&gt; (fn [] (loop [y 1] (x) (recur (<span class="code-object">Integer</span>. 1))))
foo
foo
#&lt;user$eval6$fn__7 user$eval6$fn__7@71687585&gt;</pre>
</div></div>CLJ-1407Recur mismatch might cause multiple evaluationDefectMinorOpenUnresolvedUnassignedNicola MomettocompilermacroThu, 17 Apr 2014 17:30:33 -0500Thu, 17 Apr 2014 21:54:32 -050001<p>This is not a question about whether the behavior in the description is a bug or not, but rather a curiosity about how often people write macros that have side effects at macroexpansion time. I think the following in Clojure itself do, but there may be others:</p>
<ul>
<li>gen-class, and also ns because it uses gen-class</li>
<li>gen-interface, and also definterface because it uses gen-interface</li>
<li>clojure.core/compile-if (private) calls eval on its expr arg, but as used now doesn't cause macroexpansion-time side effects</li>
<li>doc seems to have one case that prints at macroexpansion time</li>
<li>I am not sure whether defprotocol or deftype have macroexpansion time side effects, or whether they are limited to run time</li>
</ul>
<p>Andy, I don't think there are that many macros that side-effect at macroexpansion time and I haven't discovered this bug in real code but while thinking about how loop locals invalidation was implemented in Compiler.java.</p>
<p>Because there are a really a small number of side-effecting macros, this is unlikely to cause problems in real code, so I changed the priority to minor.</p>Global Rank[CLJ-1406] Libs are blindly added into loaded-libs even if an error occurs during loadinghttp://dev.clojure.org/jira/browse/CLJ-1406
Clojure<p>Suppose you have a lib that causes some errors during loading, like the following:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">(ns broken-lib)
(} ; <span class="code-keyword">this</span> line will cause a reader error</pre>
</div></div>
<p>And then, if you <tt>require</tt> the lib, it would be added into <tt>loaded-libs</tt> in spite of the reader error, which makes <tt>require</tt> succeed silently after that.</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">user=&gt; (contains? (loaded-libs) 'broken-lib)
<span class="code-keyword">false</span>
user=&gt; (require 'broken-lib)
CompilerException java.lang.RuntimeException: Unmatched delimiter: }, compiling:(broken_lib.clj:3:3)
user=&gt; (contains? (loaded-libs) 'broken-lib)
<span class="code-keyword">true</span>
user=&gt; (require 'broken-lib)
nil
user=&gt;</pre>
</div></div>
<p><b>Cause:</b><br/>
The patch for <a href="http://dev.clojure.org/jira/browse/CLJ-1116" title="More REPL-friendly &#39;ns macro"><del>CLJ-1116</del></a> made the <tt>ns</tt> macro blindly add the lib being defined into <tt>loaded-libs</tt> even if an error occurs during loading.</p>
<p><b>Approach:</b><br/>
Modify <tt>clojure.core/load-lib</tt> so that it removes the lib from <tt>loaded-libs</tt> on error.</p>CLJ-1406Libs are blindly added into loaded-libs even if an error occurs during loadingDefectMajorOpenUnresolvedUnassignedOHTA ShogoThu, 17 Apr 2014 09:00:19 -0500Thu, 17 Apr 2014 09:21:32 -0500Release 1.5Release 1.601<p>This patch seems somewhat removed from the cause - is there some way to instead prevent the lib from being added to loaded-libs in the first place?</p><p>To do so, I think we need to revert <a href="http://dev.clojure.org/jira/browse/CLJ-1116" title="More REPL-friendly &#39;ns macro"><del>CLJ-1116</del></a>.</p>Global RankPatchCode[CLJ-1403] ns-resolve might throw ClassNotFoundException but should return nilhttp://dev.clojure.org/jira/browse/CLJ-1403
Clojure<p>The doc of ns-resolve states that in case the symbol cannot be resolved, it should return nil.</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">user=&gt; (doc ns-resolve)
-------------------------
clojure.core/ns-resolve
([ns sym] [ns env sym])
Returns the <span class="code-keyword">var</span> or <span class="code-object">Class</span> to which a symbol will be resolved in the
namespace (unless found in the environment), <span class="code-keyword">else</span> nil. Note that
<span class="code-keyword">if</span> the symbol is fully qualified, the <span class="code-keyword">var</span>/<span class="code-object">Class</span> to which it resolves
need not be present in the namespace.
nil</pre>
</div></div>
<p>However if the symbol contains dots and is not a resolvable Class, a ClassNotFoundException is thrown</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">user=&gt; (ns-resolve *ns* 'foo.bar)
ClassNotFoundException foo.bar java.net.URLClassLoader$1.run (URLClassLoader.java:372)
user=&gt; (pst *e)
ClassNotFoundException foo.bar
java.net.URLClassLoader$1.run (URLClassLoader.java:372)
java.net.URLClassLoader$1.run (URLClassLoader.java:361)
java.security.AccessController.doPrivileged (AccessController.java:-2)
java.net.URLClassLoader.findClass (URLClassLoader.java:360)
clojure.lang.DynamicClassLoader.findClass (DynamicClassLoader.java:61)
java.lang.<span class="code-object">ClassLoader</span>.loadClass (<span class="code-object">ClassLoader</span>.java:424)
java.lang.<span class="code-object">ClassLoader</span>.loadClass (<span class="code-object">ClassLoader</span>.java:357)
java.lang.<span class="code-object">Class</span>.forName0 (<span class="code-object">Class</span>.java:-2)
java.lang.<span class="code-object">Class</span>.forName (<span class="code-object">Class</span>.java:340)
clojure.lang.RT.classForName (RT.java:2065)
clojure.lang.<span class="code-object">Compiler</span>.maybeResolveIn (<span class="code-object">Compiler</span>.java:6963)
clojure.core/ns-resolve (core.clj:4026)
nil</pre>
</div></div>
<p>The attached patch makes ns-resolve return nil in that case instead of throwing an exception</p>CLJ-1403ns-resolve might throw ClassNotFoundException but should return nilDefectMinorOpenUnresolvedUnassignedNicola MomettoMon, 14 Apr 2014 13:57:14 -0500Thu, 2 Oct 2014 11:48:45 -050012<p>Can you include the (pst *e) ?</p><p>Added result of (pst *e) in the description</p><p>Nicola, the patch 0001-<a href="http://dev.clojure.org/jira/browse/CLJ-1403" title="ns-resolve might throw ClassNotFoundException but should return nil">CLJ-1403</a>-ns-resolve-returns-nil-if-class-is-not-foun.patch dated 31 Aug 2014 applies cleanly to latest Clojure master as of Oct 1 2014, but fails to compile with JDK8. I haven't checked whether it compiles cleanly with other JDK versions yet.</p><p>Updated the patch so that it compiles fine on JDK8</p>Global RankPatchCode and Test[CLJ-1402] sort-by calls keyfn more times than is necessaryhttp://dev.clojure.org/jira/browse/CLJ-1402
Clojure<p>clojure.core/sort-by evaluates keyfn for every pairwise comparison. This is wasteful when keyfn is expensive to compute.</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">user=&gt; (def keyfn-calls (atom 0))
#'user/keyfn-calls
user=&gt; (defn keyfn [x] (<span class="code-keyword">do</span> (swap! keyfn-calls inc) x))
#'user/keyfn
user=&gt; @keyfn-calls
0
user=&gt; (sort-by keyfn (repeatedly 10 rand))
(0.1647483850582695 0.2836687590331822 0.3222305842748623 0.3850390922996001 0.41965440953966326 0.4777580378736771 0.6051704988802923 0.659376178201709 0.8459820304223701 0.938863131161208)
user=&gt; @keyfn-calls
44</pre>
</div></div>CLJ-1402sort-by calls keyfn more times than is necessaryEnhancementMinorOpenUnresolvedUnassignedSteve KimperformanceFri, 11 Apr 2014 11:45:32 -0500Mon, 9 Feb 2015 15:03:49 -060023<p><a href="http://dev.clojure.org/jira/browse/CLJ-99" title="GC Issue 95: max-key and min-key evaluate k multiple times for arguments">CLJ-99</a> is a similar issue</p><p>Avoid using for before it's defined</p>Global RankPatchCode[CLJ-1398] Update URLs in javadoc.cljhttp://dev.clojure.org/jira/browse/CLJ-1398
Clojure<p>Three minor fixes/enhancements to javadoc.clj:</p>
<p>0001 corrects the URLs for apache commons javadoc (the ones used in javadoc.clj no longer resolve).<br/>
0002 adds javadoc lookup for guava and apache commons lang3.<br/>
0003 adds javadoc lookup for jdk8.</p>
<p>(Note: contributor agreement is in the mail)</p>CLJ-1398Update URLs in javadoc.cljEnhancementTrivialOpenUnresolvedUnassignedEli LindseyWed, 2 Apr 2014 12:25:54 -0500Fri, 9 May 2014 20:18:08 -0500Release 1.711<p>Eli, thanks for the patches. It appears that you are not currently on the list of Clojure contributors here: <a href="http://clojure.org/contributing">http://clojure.org/contributing</a></p>
<p>It is the policy of the Clojure team only to incorporate patches submitted by people who have signed and submitted a Clojure CA. Were you interested in doing that?</p><p>&gt; It is the policy of the Clojure team only to incorporate patches submitted by people who have signed and submitted a Clojure CA. Were you interested in doing that?</p>
<p>Yup! I mailed off the CA to Rich on Wednesday when this was filed; should be arriving shortly. <img class="emoticon" src="http://dev.clojure.org/jira/images/icons/emoticons/smile.gif" height="20" width="20" align="absmiddle" alt="" border="0"/></p><p>Just to note - Clojure CA went through and I'm listed on the contributors page now.</p>Global RankPatchCode[CLJ-1394] Print multi method dispatch values in the exception messages.http://dev.clojure.org/jira/browse/CLJ-1394
Clojure<p>The error messages of defmulti are at the moment not as helpful as they could be under certain circumstances. Calling this multi method with a lazy seq as it's dispatch argument raises the following exception:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">(defmulti test-multi identity)
(defmethod test-multi 1 [arg] <span class="code-keyword">true</span>)
(test-multi (map identity [:x]))
;=&gt; java.lang.IllegalArgumentException: No method in multimethod 'test-multi' <span class="code-keyword">for</span> dispatch value: clojure.lang.LazySeq@3c6f1187</pre>
</div></div>
<p>Sometimes it would be useful to actually see which values are in the lazy seq being dispatched on. A better error message could look like<br/>
this for example:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">(test-multi (map identity [:x]))
;=&gt; java.lang.IllegalArgumentException: No method in multimethod 'test-multi' <span class="code-keyword">for</span> dispatch value (:x) of class clojure.lang.LazySeq</pre>
</div></div>
<p>This patch addresses this issue by formatting the dispatch value via `pr-str` and printing the class before it is passed to the exception constructor. The same is also done for the methods in MultiFn.java that throw a dispatch value as part of their exception message.</p>CLJ-1394Print multi method dispatch values in the exception messages.EnhancementTrivialOpenUnresolvedUnassignedRoman ScherererrormsgsMon, 31 Mar 2014 15:55:24 -0500Tue, 1 Apr 2014 14:30:38 -050002<p>What if the value is infinite lazy-seq?</p><p>Nicola, I forgot those. But I think infinite sequences could be handled with:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">(set! *print-length* 10)</pre>
</div></div>
<p>I'll try it out and will update the patch later.</p>
<p>Any other edge cases in mind?</p>
<p>After having read "Controlling run-away trains, onions, and exercise<br/>
bikes" <span class="error">&#91;1&#93;</span> I now bind <b>print-length</b> and <b>print-size</b> when building<br/>
the error message. This helps when not being able to dispatch on this<br/>
for example:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">(test-multi (let [x (atom 0)] (reset! x {:deeper x})))</pre>
</div></div>
<p>However I'm not sure if this helps in the following case, where<br/>
dispatching would fail on an infinite seq.</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">(test-multi (iterate inc 0))</pre>
</div></div>
<p>The above doesn't terminate in Clojure 1.6.0, nor does it when binding<br/>
<b>print-length</b> like the attached patch does. </p>
<p><span class="error">&#91;1&#93;</span> <a href="http://blog.n01se.net/blog-n01se-net-p-85.html">http://blog.n01se.net/blog-n01se-net-p-85.html</a></p>Global RankPatchCode and Test[CLJ-1391] Allow logical operators on assert expressionshttp://dev.clojure.org/jira/browse/CLJ-1391
Clojure<p>With current code, it is not possible to express logical operators on some clojure.test assert expressions. For example, this will work:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">(is (thrown? Exception &lt;some-expression&gt;))</pre>
</div></div>
<p>however, here will fail:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">(is (not (thrown? Exception &lt;some-expression&gt;)))</pre>
</div></div>
<p>since '(thrown?)' is not an ordinary function, but looks like. This also adds confusion which is hard to explain to others unless '(is)' code was shown first.</p>
<p>Also, if the one would like to implement macro (e.g. 'is-not-thrown?') in form:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">(defmacro is-not-thrown? [e expr]
`(is (not ('thrown? ~e ~expr))))</pre>
</div></div>
<p>which could be even more confusing for a person not knowing how 'thrown?' is implemented.</p>CLJ-1391Allow logical operators on assert expressionsDefectMinorOpenUnresolvedUnassignedSanel Zukanclojure.testWed, 26 Mar 2014 07:46:40 -0500Wed, 26 Mar 2014 07:46:40 -0500Release 1.501Global Rank[CLJ-1389] Re-loading a namespace ignores metadata specified for the namespacehttp://dev.clojure.org/jira/browse/CLJ-1389
Clojure<p>Using the REPL I added some metadata to a namespace and reloaded it.</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">(ns io.aviso.rook-test5)</pre>
</div></div>
<p>to</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">(ns io.aviso.rook-test5
<span class="code-quote">"A testing namespace"</span>
{:inherted :namespace
:overridden :namespace})</pre>
</div></div>
<p>But requesting the meta data yields nil:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">(-&gt; 'io.aviso.rook-test5 find-ns meta)
=&gt; nil</pre>
</div></div>
<p>I have tested a few variations, such as putting the metadata on the symbol instead of providing an attribute map. In all cases, the metadata from before the load persists.</p>
<p>Using <tt>remove-ns</tt> before re-loading the namespace does the right thing ... the metadata shows up as expected.</p>CLJ-1389Re-loading a namespace ignores metadata specified for the namespaceDefectMinorOpenUnresolvedUnassignedHoward Lewis ShipmetadatanamespacereplThu, 20 Mar 2014 12:07:31 -0500Thu, 20 Mar 2014 13:44:54 -0500Release 1.512Global Rank[CLJ-1385] Docstrings for `conj!` and `assoc!` should suggest using the return value; effect not always in-placehttp://dev.clojure.org/jira/browse/CLJ-1385
Clojure<p>The docstrings of both `assoc!` and `conj!` say "Returns coll.", suggesting the transient edit happens always in-place, `coll` being the first argument.</p>
<p>However, the fact that the following example omits the key `8` in its result proves that in-place edits aren't always the case:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">(let [a (<span class="code-keyword">transient</span> {})]
(dotimes [x 9]
(assoc! a x :ok))
(persistent! a))
;;=&gt; {0 :ok, 1 :ok, 2 :ok, 3 :ok, 4 :ok, 5 :ok, 6 :ok, 7 :ok}</pre>
</div></div>
<p>Instead, programmers should be guided towards using constructs like `reduce` with transients:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">(persistent! (reduce #(assoc! %1 %2 :ok)
(<span class="code-keyword">transient</span> {})
(range 9)))
;;=&gt; {0 :ok, 1 :ok, 2 :ok, 3 :ok, 4 :ok, 5 :ok, 6 :ok, 7 :ok, 8 :ok}</pre>
</div></div>
<p>The easiest way to achieve this is by changing the docstrings of (at least) `conj!` and `assoc!` to not read "Returns coll." but instead tell that the change is destructive.</p>CLJ-1385Docstrings for `conj!` and `assoc!` should suggest using the return value; effect not always in-placeEnhancementMinorOpenUnresolvedUnassignedPyry JahkolacollectionsdocstringSun, 16 Mar 2014 04:02:29 -0500Wed, 6 Aug 2014 15:04:45 -0500Release 1.622<p>When modifying transient collections, it is required to use the collection returned from functions like assoc!. The ! here indicates its destructive nature. The transients page (<a href="http://clojure.org/transients">http://clojure.org/transients</a>) describes the calling pattern pretty explicitly: "You must capture and use the return value in the next call."</p>
<p>I do not agree that we should be guiding programmers away from using functions like assoc! &#8211; transients are used as a performance optimization and using assoc! or conj! in a loop is often the fastest version of that. However I do think it would be helpful to make the docstring more explicit.</p><p>Alex I think you must have misread the ticket &#8211; the OP is suggesting guiding toward using the return value of <tt>assoc!</tt>, not avoiding <tt>assoc!</tt> altogether.</p>
<p>And the docstring is not simply inexplicit, it's actually incorrect specifically in the case that the OP pointed out. <tt>conj!</tt> and <tt>assoc</tt> do not return <tt>coll</tt> at the point where array-maps transition to hash-maps, and the fact that they do otherwise is supposed to be an implementation detail as far as I understand it.</p><p>@Gary - you're right, I did misread that. </p>
<p><tt>assoc</tt> and <tt>conj</tt> both explicitly say "return a new collection" whereas <tt>assoc!</tt> and <tt>conj!</tt> say "Returns coll." I read that as "returns the modified collection" without regard to whether it's the identical instance, but I can read it your way too. </p>
<p>Would saying "Returns updated collection." transmit the right idea? Using "collection" instead of "coll" removes the concrete tie to the variable and "updated" hints more strongly that you should use the return value.</p><p>@Alex, that update makes it sound right to me, FWIW.</p><p>Yeah, I think that's better. Thanks Alex. I'd be happy to submit a patch for that but I'm assuming patches are too heavy for this kind of change?</p><p>Patches are exactly what has been done in the past for this kind of change, if it is in a doc string and not on the clojure.org web page.</p><p>Yup, patch desired.</p><p>Glad I asked.</p>
<p>Patch is attached that also updates the docstring for <tt>pop!</tt> which had the same issue, though arguably it's less important since afaik <tt>pop!</tt> does always return the identical collection (but I don't think this is part of the contract).</p><p>Patch <a href="http://dev.clojure.org/jira/browse/CLJ-1385" title="Docstrings for `conj!` and `assoc!` should suggest using the return value; effect not always in-place">CLJ-1385</a>-reword-docstrings-on-transient-update-funct.patch dated Apr 6 2014 no longer applies to latest Clojure master cleanly, due to some changes committed earlier today. I suspect it should be straightforward to update the patch to apply cleanly, given that they are doc string changes, but there may have been doc string changes committed to master, too.</p><p>Attached a new patch.</p>Global RankPatchCode[CLJ-1383] Should name throw on nil?http://dev.clojure.org/jira/browse/CLJ-1383
Clojure<p>The name function throws NullPointerException on nil. Since the name function is about obtaining the string form of a specific object it should not throw on nil. It should just return the nil object as the str fn does.</p>CLJ-1383Should name throw on nil?EnhancementMinorOpenUnresolvedJozef WagnerJohn ChijiokeFri, 14 Mar 2014 03:46:26 -0500Sat, 15 Mar 2014 03:29:37 -0500Release 1.600<p>added patch with test</p>Global RankPatchCode and Test[CLJ-1381] Improve support for extending protocols to primitive arrayshttp://dev.clojure.org/jira/browse/CLJ-1381
Clojure<p>It is possible to extend protocols to primitive arrays but specifying the class for the type is a little tricky:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">(defprotocol P (p [_]))
(extend-protocol P (<span class="code-object">Class</span>/forName <span class="code-quote">"[B"</span>) (p [_] <span class="code-quote">"bytes"</span>))
(p (<span class="code-object">byte</span>-array 0)) ;; =&gt; <span class="code-quote">"bytes"</span></pre>
</div></div>
<p>However, things go bad if you try to do more than one of these:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">(extend-protocol P
(<span class="code-object">Class</span>/forName <span class="code-quote">"[B"</span>) (p [_] <span class="code-quote">"bytes"</span>)
(<span class="code-object">Class</span>/forName <span class="code-quote">"[I"</span>) (p [_] <span class="code-quote">"ints"</span>))
CompilerException java.lang.UnsupportedOperationException: nth not supported on <span class="code-keyword">this</span> type: <span class="code-object">Character</span>, compiling:(NO_SOURCE_PATH:1:1)
clojure.lang.<span class="code-object">Compiler</span>.analyze (<span class="code-object">Compiler</span>.java:6380)
clojure.lang.<span class="code-object">Compiler</span>.analyze (<span class="code-object">Compiler</span>.java:6322)
clojure.lang.<span class="code-object">Compiler</span>$MapExpr.parse (<span class="code-object">Compiler</span>.java:2879)
clojure.lang.<span class="code-object">Compiler</span>.analyze (<span class="code-object">Compiler</span>.java:6369)
clojure.lang.<span class="code-object">Compiler</span>.analyze (<span class="code-object">Compiler</span>.java:6322)
clojure.lang.<span class="code-object">Compiler</span>$InvokeExpr.parse (<span class="code-object">Compiler</span>.java:3624)
clojure.lang.<span class="code-object">Compiler</span>.analyzeSeq (<span class="code-object">Compiler</span>.java:6562)
clojure.lang.<span class="code-object">Compiler</span>.analyze (<span class="code-object">Compiler</span>.java:6361)
clojure.lang.<span class="code-object">Compiler</span>.analyze (<span class="code-object">Compiler</span>.java:6322)
clojure.lang.<span class="code-object">Compiler</span>$BodyExpr$Parser.parse (<span class="code-object">Compiler</span>.java:5708)
clojure.lang.<span class="code-object">Compiler</span>$FnMethod.parse (<span class="code-object">Compiler</span>.java:5139)
clojure.lang.<span class="code-object">Compiler</span>$FnExpr.parse (<span class="code-object">Compiler</span>.java:3751)
Caused by:
UnsupportedOperationException nth not supported on <span class="code-keyword">this</span> type: <span class="code-object">Character</span>
clojure.lang.RT.nthFrom (RT.java:857)
clojure.lang.RT.nth (RT.java:807)
clojure.core/emit-hinted-impl/hint--5951/fn--5953 (core_deftype.clj:758)
clojure.core/map/fn--4207 (core.clj:2487)
clojure.lang.LazySeq.sval (LazySeq.java:42)
clojure.lang.LazySeq.seq (LazySeq.java:60)
clojure.lang.RT.seq (RT.java:484)
clojure.lang.RT.countFrom (RT.java:537)
clojure.lang.RT.count (RT.java:530)
clojure.lang.Cons.count (Cons.java:49)
clojure.lang.<span class="code-object">Compiler</span>.analyze (<span class="code-object">Compiler</span>.java:6352)
clojure.lang.<span class="code-object">Compiler</span>.analyze (<span class="code-object">Compiler</span>.java:6322)</pre>
</div></div>
<p>The code in {parse-impls} is seeing the second {(Class/forName "[I")} as a function, not as a new type. One workaround for this is to only extend the protocol to one type at a time.</p>
<p>It would be even better (moving into enhancement area) if there was a syntax here to specify primitive array types - we already have the syntax of {bytes, ints, longs}, etc for type hints and those seem perfectly good to me.</p>CLJ-1381Improve support for extending protocols to primitive arraysDefectMajorOpenUnresolvedUnassignedAlex MillerprotocolsThu, 13 Mar 2014 13:01:14 -0500Thu, 18 Sep 2014 18:08:57 -0500Release 1.5Release 1.623<p>It also breaks when extending only one array type:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">(extend-protocol P
<span class="code-object">String</span> (p [_] <span class="code-quote">"string"</span>)
(<span class="code-object">Class</span>/forName <span class="code-quote">"[B"</span>) (p [_] <span class="code-quote">"ints"</span>)
)
;=&gt; CompilerException java.lang.UnsupportedOperationException: nth not supported on <span class="code-keyword">this</span> type ...</pre>
</div></div>
<p>But changing the declaration order fixes it:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">(extend-protocol P
(<span class="code-object">Class</span>/forName <span class="code-quote">"[B"</span>) (p [_] <span class="code-quote">"ints"</span>)
<span class="code-object">String</span> (p [_] <span class="code-quote">"string"</span>)
)
;=&gt; OK</pre>
</div></div>Global Rank[CLJ-1380] Three-arg ExceptionInfo constructor permits nil datahttp://dev.clojure.org/jira/browse/CLJ-1380
Clojure<p>The argument check in the two-arg clojure.lang.ExceptionInfo constructor isn't present in the three-arg constructor so it's possible to create an ExceptionInfo with arbitrary (or nil) data.</p>
<p>E.g.:</p>
<div class="preformatted panel" style="border-width: 1px;"><div class="preformattedContent panelContent">
<pre>user=&gt; (clojure-version)
"1.5.1"
user=&gt; (ex-info "hi" nil)
IllegalArgumentException Additional data must be a persistent map: null clojure.lang.ExceptionInfo.&lt;init&gt; (ExceptionInfo.java:26)
user=&gt; (ex-info "hi" nil (Throwable.))
NullPointerException clojure.lang.ExceptionInfo.toString (ExceptionInfo.java:40)
</pre>
</div></div>CLJ-1380Three-arg ExceptionInfo constructor permits nil dataDefectMinorOpenUnresolvedUnassignedGordon SymeThu, 13 Mar 2014 10:45:50 -0500Mon, 27 Oct 2014 05:32:46 -0500Release 1.500<p>Sorry, didn't meant to classify as "major" and I don't have permissions to edit.</p><p>Patch + tests</p>
<p>I'm not at all familiar with the project so may have put tests in the wrong language and/or wrong place.</p>
<p>The ex-info-works test is a bit dorky but shows that both constructors are equivalent (and passes without the patch to ExceptionInfo).</p><p>No worries on the classification - I adjust most incoming tickets in some way or another. <img class="emoticon" src="http://dev.clojure.org/jira/images/icons/emoticons/smile.gif" height="20" width="20" align="absmiddle" alt="" border="0"/> </p>
<p>Thanks for the patch, however it cannot be considered unless you complete the Clojure Contributor's Agreement - <a href="http://clojure.org/contributing">http://clojure.org/contributing</a>. This is an important step in the process that keeps the Clojure codebase on a sound legal basis.</p>
<p>Someone else could develop a clean room patch implementation for this ticket later, but of course it would be ideal if you could become a contributor!</p><p>Hi Alex,</p>
<p>sure, that makes sense. I'll get the contributor's agreement in the post. It may take a while to arrive since I'm based in Europe.</p><p>I just checked <a href="http://clojure.org/contributing">http://clojure.org/contributing</a>, looks like my CCA made it through</p><p>Gordon, I do not know if your patch is of interest to the Clojure developers, so I can't comment on that aspect of this ticket.</p>
<p>Instructions for creating a patch in the expected format is given on the wiki page below. Your patch is not in the expected format.</p>
<p><a href="http://dev.clojure.org/display/community/Developing+Patches">http://dev.clojure.org/display/community/Developing+Patches</a></p><p>Whoops, sorry Andy.</p>
<p>I've rebased against master and added a correctly formatted patch.</p>Global RankPatchCode and Test[CLJ-1379] Quoting of :actual form is incorrect in clojure.test :pass type mapshttp://dev.clojure.org/jira/browse/CLJ-1379
Clojure<p>The function symbol is not correctly quoted in the construction of the :actual value in a :pass type map for clojure.test.</p>
<p>It currently produces <tt>(list = 1 1)</tt> instead of <tt>(list '= 1 1)</tt> for an <tt>(is (= 1 1))</tt> test.</p>
<p>I haven't been able to come up with a workaround for this.</p>All clojure versionsCLJ-1379Quoting of :actual form is incorrect in clojure.test :pass type mapsDefectMinorOpenUnresolvedUnassignedHugo DuncantestWed, 12 Mar 2014 13:52:54 -0500Wed, 12 Mar 2014 14:19:39 -050001Global RankPatchCode[CLJ-1376] Initialize internal maps to more efficient versionhttp://dev.clojure.org/jira/browse/CLJ-1376
Clojure<p>In reviewing some hashing stuff, I noticed that there are many places internal to Clojure that use maps initialized with PersistentHashMap.EMPTY. Many of these maps are likely to have a small number of entries such that a PersistentArrayMap might be more efficient.</p>
<p>These are the candidates:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">src/jvm/clojure/lang/ARef.java
19:<span class="code-keyword">private</span> <span class="code-keyword">volatile</span> IPersistentMap watches = PersistentHashMap.EMPTY;
src/jvm/clojure/lang/<span class="code-object">Compiler</span>.java
3009: IPersistentMap m = PersistentHashMap.EMPTY;
3819: KEYWORDS, PersistentHashMap.EMPTY,
3820: VARS, PersistentHashMap.EMPTY,
3964: IPersistentMap closes = PersistentHashMap.EMPTY;
3977: IPersistentMap keywords = PersistentHashMap.EMPTY;
3978: IPersistentMap vars = PersistentHashMap.EMPTY;
5121: ,CLEAR_SITES, PersistentHashMap.EMPTY
7259: KEYWORDS, PersistentHashMap.EMPTY,
7260: VARS, PersistentHashMap.EMPTY
7418: IPersistentMap opts = PersistentHashMap.EMPTY;
7475: IPersistentMap fmap = PersistentHashMap.EMPTY;
7522: KEYWORDS, PersistentHashMap.EMPTY,
7523: VARS, PersistentHashMap.EMPTY,
7912: ,CLEAR_SITES, PersistentHashMap.EMPTY
src/jvm/clojure/lang/LispReader.java
755: RT.map(GENSYM_ENV, PersistentHashMap.EMPTY));
src/jvm/clojure/lang/MultiFn.java
39: <span class="code-keyword">this</span>.methodTable = PersistentHashMap.EMPTY;
41: <span class="code-keyword">this</span>.preferTable = PersistentHashMap.EMPTY;
49: methodTable = methodCache = preferTable = PersistentHashMap.EMPTY;
src/jvm/clojure/lang/Var.java
48: <span class="code-keyword">final</span> <span class="code-keyword">static</span> Frame TOP = <span class="code-keyword">new</span> Frame(PersistentHashMap.EMPTY, <span class="code-keyword">null</span>);
175: setMeta(PersistentHashMap.EMPTY);
341: IPersistentMap ret = PersistentHashMap.EMPTY;</pre>
</div></div>
<p><b>Approach:</b> Two possible approaches - initialize to PersistentArrayMap.EMPTY or call RT.map(). The latter requires function invocation so is slightly slower, but has the benefit of localizing map construction into a single place.</p>CLJ-1376Initialize internal maps to more efficient versionEnhancementMajorOpenUnresolvedUnassignedAlex MillerperformanceTue, 11 Mar 2014 10:37:06 -0500Tue, 11 Mar 2014 10:37:06 -0500Release 1.621Global Rank[CLJ-1375] Remove Util.pcequiv() and stop pretending Java colls are equiv to Clojure collshttp://dev.clojure.org/jira/browse/CLJ-1375
Clojure<p>The Util.pcequiv() method</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java"><span class="code-keyword">static</span> <span class="code-keyword">public</span> <span class="code-object">boolean</span> pcequiv(<span class="code-object">Object</span> k1, <span class="code-object">Object</span> k2){
<span class="code-keyword">if</span>(k1 <span class="code-keyword">instanceof</span> IPersistentCollection)
<span class="code-keyword">return</span> ((IPersistentCollection)k1).equiv(k2);
<span class="code-keyword">return</span> ((IPersistentCollection)k2).equiv(k1);
}</pre>
</div></div>
<p>tries to get equiv semantics (cross-class number equality) for cases of mixed Clojure/Java collection comparison. However, this is not a sustainable direction and we would like to stop doing this. </p>
<p>Attached patch removes this and changes calling code to only call equiv when both collections are IPersistentCollection.</p>CLJ-1375Remove Util.pcequiv() and stop pretending Java colls are equiv to Clojure collsEnhancementMinorOpenUnresolvedUnassignedAlex MillercollectionsTue, 11 Mar 2014 10:29:32 -0500Tue, 11 Mar 2014 10:30:14 -0500Release 1.503Global RankPatchCode[CLJ-1371] divide(Object, Object) with (NaN, 0) does not return NaNhttp://dev.clojure.org/jira/browse/CLJ-1371
Clojure<p>user=&gt; (def x Double/NaN)<br/>
#'user/x<br/>
user=&gt; (/ x 0)</p>
<p>ArithmeticException Divide by zero clojure.lang.Numbers.divide (Numbers.java:156)<br/>
user=&gt; (/ Double/NaN 0)<br/>
Double/NaN</p>CLJ-1371divide(Object, Object) with (NaN, 0) does not return NaNDefectTrivialReopenedUnresolvedUnassignedYongqian LimathFri, 7 Mar 2014 02:36:11 -0600Fri, 7 Mar 2014 09:48:40 -060001<p>As per the Java Language Specification (<a href="http://docs.oracle.com/javase/specs/jls/se7/html/jls-4.html#jls-4.2.4">http://docs.oracle.com/javase/specs/jls/se7/html/jls-4.html#jls-4.2.4</a>), </p>
<p>"All numeric operations with NaN as an operand produce NaN as a result."</p><p>But in the first example it produces an ArithmeticException.</p><p>Ah, I see the question now.</p>
<p>Here we are dividing a double by a long. In the first case, this is parsed as divide(Object, long) which then calls divide(Object, Object), which throws ArithmeticException if the second arg is 0 (regardless of the first arg).</p>
<p>In the second case it's parsed as divide(double, long) which just relies on Java to properly upcast the primitive long to a double to do the divide. </p>
<p>Note that making this call with 2 doubles does return NaN:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">user=&gt; (def x <span class="code-object">Double</span>/NaN)
#'user/x
user=&gt; (/ x 0.0)
NaN</pre>
</div></div>
<p>or type hinting x to a double works as well:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">user=&gt; (def x <span class="code-object">Double</span>/NaN)
#'user/x
user=&gt; (/ ^<span class="code-object">double</span> x 0.0)
NaN</pre>
</div></div>
<p>I think one option to "fix" this behavior would be to add checks in divide(Object, Object) to check whether x is NaN and instead return NaN.</p>Global Rank[CLJ-1368] Document usage for case with non-readable constantshttp://dev.clojure.org/jira/browse/CLJ-1368
Clojure<h2><a name="Problem"></a>Problem</h2>
<p>It is pretty obscure how to get constant-time dispatch for e.g. Enums, even if user knows about case.</p>
<h2><a name="Proposal"></a>Proposal</h2>
<p>The possibility to dispatch to arbitrary constants with case, by wrapper macro, should be documented.</p>
<h3><a name="Wording"></a>Wording</h3>
<ul class="alternate" type="square">
<li>Should it warn against doing that with unstable values?</li>
<li>Should it mention anything else than java Enums?</li>
</ul>
<h3><a name="CaseTechniques"></a>Case Techniques </h3>
<p>Case is documented for accepting all readable forms as test-constants. However, it can also be made to use any compile-time-known constants as test-constants, by wrapping it in another macro.</p>
<p>Sometimes this is appropriate, e.g. when dispatching on a java Enum.<br/>
Other times, less so, e.g. when dispatching on objects whose hash changes when the vm is restarted (breaks AOT).</p>
<h3><a name="Implications"></a>Implications</h3>
<p>This technique is an application of a more general technique: Passing non-literals to a macro from another macro.<br/>
Are there other macros that have use cases like this?</p>
<h2><a name="References"></a>References</h2>
<p><a href="https://groups.google.com/d/topic/clojure/3yGjDO2YnjQ/discussion">https://groups.google.com/d/topic/clojure/3yGjDO2YnjQ/discussion</a></p>CLJ-1368Document usage for case with non-readable constantsEnhancementMinorReopenedUnresolvedUnassignedHerwig HochleitnerdocsinteropSun, 2 Mar 2014 10:34:59 -0600Sun, 2 Mar 2014 11:34:18 -060003<p><del>This is a duplicate of</del> <a href="http://dev.clojure.org/jira/browse/CLJ-1367">http://dev.clojure.org/jira/browse/CLJ-1367</a></p>
<p>Actually, it's an alternate solution</p>Global Rank[CLJ-1367] Allow case statement to compare java constantshttp://dev.clojure.org/jira/browse/CLJ-1367
Clojure<p>As raised on the mailing list: <a href="https://groups.google.com/forum/#!topic/clojure/3yGjDO2YnjQ">https://groups.google.com/forum/#!topic/clojure/3yGjDO2YnjQ</a></p>
<p>It's not possible to use java constants in a case statement. condp = could be used in this case but these are things which could be used in a java switch statement and so it's annoying to give up constant time dispatch. For example:</p>
<p>(case (.getActionMasked event)<br/>
MotionEvent/ACTION_POINTER_DOWN :down<br/>
MotionEvent/ACTION_UP :up<br/>
MotionEvent/ACTION_POINTER_UP :up<br/>
MotionEvent/ACTION_MOVE :move<br/>
MotionEvent/ACTION_CANCEL :cancel<br/>
MotionEvent/ACTION_OUTSIDE :outside<br/>
:none))</p>
<p>Doesn't work, but there is no reason this couldn't be resolved at compile time and dispatched in constant time.</p>CLJ-1367Allow case statement to compare java constantsEnhancementMinorOpenUnresolvedUnassignedAdam ClementsinteropSun, 2 Mar 2014 09:02:57 -0600Sun, 2 Mar 2014 11:33:53 -060023<p>Another solution for this problem: <a href="http://dev.clojure.org/jira/browse/CLJ-1368">http://dev.clojure.org/jira/browse/CLJ-1368</a></p>Global Rank[CLJ-1366] The empty map literal is read as a different map each timehttp://dev.clojure.org/jira/browse/CLJ-1366
Clojure<p>As reported here (<a href="https://groups.google.com/forum/?hl=en#!topic/clojure-dev/n83hlRFsfHg">https://groups.google.com/forum/?hl=en#!topic/clojure-dev/n83hlRFsfHg</a>), the empty map literal is read as a different map each time.</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">user=&gt; (identical? (read-string <span class="code-quote">"{}"</span>) (read-string <span class="code-quote">"{}"</span>))
<span class="code-keyword">false</span></pre>
</div></div>
<p>Making the reader return the same empty map when it reads an empty map is expected to improve some memory efficiency, and also lead to consistency with the way other collection literals are read in.</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">user=&gt; (identical? (read-string <span class="code-quote">"()"</span>) (read-string <span class="code-quote">"()"</span>))
<span class="code-keyword">true</span>
user=&gt; (identical? (read-string <span class="code-quote">"[]"</span>) (read-string <span class="code-quote">"[]"</span>))
<span class="code-keyword">true</span>
user=&gt; (identical? (read-string <span class="code-quote">"#{}"</span>) (read-string <span class="code-quote">"#{}"</span>))
<span class="code-keyword">true</span></pre>
</div></div>
<p><b>Cause:</b> LispReader calls RT.map() with an empty array when it reads an empty map, and RT.map() in turn makes a new map unless its argument given is null.</p>
<p><b>Approach:</b> make RT.map() return the same empty map when the argument is an empty array as well, not only when null</p>CLJ-1366The empty map literal is read as a different map each timeEnhancementMinorOpenUnresolvedUnassignedOHTA ShogomemoryreaderSat, 1 Mar 2014 00:02:52 -0600Sun, 2 Mar 2014 11:41:15 -0600Release 1.5Release 1.601<p>Sorry, the patch 0001-make-the-reader-return-the-same-empty-map-when-it-re.patch didn't work.</p>
<p>The updated patch 0002-make-the-reader-return-the-same-empty-map-when-it-re.patch works, but I'm afraid it'd be beyond the scope of this ticket since it modifies RT.map() behavior a bit.</p>Global RankPatchCode[CLJ-1364] Primitive VecSeq does not implement equals or hashing methodshttp://dev.clojure.org/jira/browse/CLJ-1364
Clojure<p>VecSeq (as produced by <tt>(seq (vector-of :int 1 2 3))</tt>) does not implements equals, hashCode, or hasheq and does not play with any other Clojure collections or sequences appropriately in this regard.</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">user=&gt; (def rs (range 3))
user=&gt; (def vs (seq (vector-of :<span class="code-object">int</span> 0 1 2)))
user=&gt; rs
(0 1 2)
user=&gt; vs
(0 1 2)
user=&gt; (.equals rs vs)
<span class="code-keyword">true</span>
user=&gt; (.equals vs rs) ;; expect: <span class="code-keyword">true</span>
<span class="code-keyword">false</span>
user=&gt; (.equiv rs vs)
<span class="code-keyword">true</span>
user=&gt; (.equiv vs rs)
<span class="code-keyword">true</span>
user=&gt; (.hashCode rs)
29824
user=&gt; (.hashCode vs) ;; expect to match (.hashCode rs)
2081327893
user=&gt; (<span class="code-object">System</span>/identityHashCode vs) ;; show that we're just getting <span class="code-object">Object</span> hashCode
2081327893
user=&gt; (.hasheq rs)
29824
user=&gt; (.hasheq vs) ;; expect same as (.hasheq rs) but not implemented at all
IllegalArgumentException No matching field found: hasheq <span class="code-keyword">for</span> class clojure.core.VecSeq clojure.lang.Reflector.getInstanceField (Reflector.java:271)</pre>
</div></div>CLJ-1364Primitive VecSeq does not implement equals or hashing methodsDefectMajorOpenUnresolvedUnassignedAlex MillercollectionsWed, 19 Feb 2014 09:48:53 -0600Wed, 19 Feb 2014 09:49:08 -0600Release 1.502Global Rank[CLJ-1360] clojure.string/split strips trailing delimitershttp://dev.clojure.org/jira/browse/CLJ-1360
Clojure<p>clojure.string/split and clojure.string/split-lines inherit the bizarre default behavior of java.lang.String#split(String,int) in stripping trailing consecutive delimiters:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">(clojure.string/split <span class="code-quote">"banana"</span> #<span class="code-quote">"an"</span>)
⇒ [<span class="code-quote">"b"</span> <span class="code-quote">"" "</span>a"]
(clojure.string/split <span class="code-quote">"banana"</span> #<span class="code-quote">"na"</span>)
⇒ [<span class="code-quote">"ba"</span>]
(clojure.string/split <span class="code-quote">"nanabanana"</span> #<span class="code-quote">"na"</span>)
⇒ [<span class="code-quote">"" "</span><span class="code-quote">" "</span>ba"]</pre>
</div></div>
<p>In the case of split-lines, processing a file line by line and rejoining results in truncation of trailing newlines in the file. In both cases, the behavior is surprising and cannot be inferred from the docstrings.</p>
<p>This behavior should either be fixed or documented.</p>CLJ-1360clojure.string/split strips trailing delimitersDefectMajorOpenUnresolvedUnassignedTim McCormackTue, 18 Feb 2014 10:33:41 -0600Tue, 18 Feb 2014 10:51:47 -060011<p>Probably documenting would be safer than changing the behavior at this point, given that some people may actually rely on the current behavior after testing, deploying, etc.</p>
<p>I don't currently have a suggestion for a modified doc string, but note that there are examples of this behavior and how one can use an extra "-1" limit argument at the end to get all split strings: <a href="http://clojuredocs.org/clojure_core/clojure.string/split">http://clojuredocs.org/clojure_core/clojure.string/split</a></p>Global Rank[CLJ-1358] doc macro does not expand special cases properlyhttp://dev.clojure.org/jira/browse/CLJ-1358
Clojure<p>The <tt>doc</tt> macro supports three special cases, mapping <tt>&amp;</tt> to <tt>fn</tt>, <tt>catch</tt> to <tt>try</tt>, and <tt>finally</tt> to <tt>try</tt>. However, the macro does not currently expand these cases - it executes them like a function instead. This is evident if you use the following at a REPL:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">user&gt; (macroexpand '(doc <span class="code-keyword">try</span>)) ;; ok
((<span class="code-keyword">var</span> clojure.repl/print-doc) ((<span class="code-keyword">var</span> clojure.repl/special-doc) (quote <span class="code-keyword">try</span>)))
user&gt; (macroexpand '(doc <span class="code-keyword">catch</span>)) ;; broken
;; -- unexpectedly prints <span class="code-keyword">try</span> doc -- ;;
nil
user&gt; (= (with-out-str (doc <span class="code-keyword">catch</span>)) (with-out-str (doc <span class="code-keyword">try</span>))) ;; broken, expect <span class="code-keyword">true</span>
;; -- unexpectedly prints <span class="code-keyword">try</span> doc -- ;;
<span class="code-keyword">false</span></pre>
</div></div>
<p><b>Workaround:</b> Call <tt>doc</tt> with the symbol to which the special case is mapped, <tt>fn</tt> or <tt>try</tt>.</p>
<p><b>Cause:</b> Incorrect quoting when handling special cases in <tt>doc</tt> macro</p>
<p><b>Solution:</b> Update special case quoting approach to match the other cases.</p>
<p><b>Patch:</b> <a href="http://dev.clojure.org/jira/browse/CLJ-1358" title="doc macro does not expand special cases properly">CLJ-1358</a>.patch</p>CLJ-1358doc macro does not expand special cases properlyDefectMinorOpenUnresolvedUnassignedChad TaylorreplMon, 17 Feb 2014 22:39:53 -0600Mon, 17 Feb 2014 22:42:17 -0600Release 1.600<p>Adding a patch with code and test.</p>Global RankPatchCode and Test[CLJ-1347] finalize won't work in reified objects - documenthttp://dev.clojure.org/jira/browse/CLJ-1347
Clojure<p>Finalize is called for reified objects even when they are still reachable. It gets called second time at proper time.</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">user=&gt; (def x (reify <span class="code-object">Object</span> (finalize [o] (println <span class="code-quote">"OH MY!"</span>))))
#'user/x
user=&gt; (<span class="code-object">System</span>/gc)
nil
OH MY!
user=&gt; x
#&lt;user$reify__1496 user$reify__1496@53fb35af&gt;
user=&gt; (<span class="code-object">System</span>/gc)
nil
user=&gt; (def x nil)
#'user/x
user=&gt; (<span class="code-object">System</span>/gc)
nilOH MY!</pre>
</div></div>
<p>Deftype seems to work fine</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">user=&gt; (deftype T [] <span class="code-object">Object</span> (finalize [o] (println <span class="code-quote">"great success"</span>)))
user.T
user=&gt; (def y (-&gt;T))
#'user/y
user=&gt; (<span class="code-object">System</span>/gc)
nil
user=&gt; (def y nil)
#'user/y
user=&gt; (<span class="code-object">System</span>/gc)
great success</pre>
</div></div>
java 7CLJ-1347finalize won't work in reified objects - documentEnhancementMinorOpenUnresolvedUnassignedJozef WagnerMon, 10 Feb 2014 06:56:35 -0600Sat, 1 Mar 2014 13:36:06 -0600Release 1.5Release 1.603<p>Just a note: the calls to System/gc don't necessarily cause finalizers to run on the first try - sometimes it took more than one for that to succeed for me. You'd think System/runFinalizers would do it but I had no luck at all with that.</p><p><tt>reify</tt> actually creates two objects &#8211; the first is created by <tt>reify*</tt>, and then <tt>reify</tt> immediately calls <tt>with-meta</tt> on it, creating a copy.</p>
<p>The docstring sort of describes this behavior: "reify always implements clojure.lang.IObj and transfers meta data of the form to the created object."</p><p>Oh, so finalizer is a no-no in reify. Should be mentioned in docs IMO.</p><p>Just for fun you could do something tricksy like:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">^::second-object
(reify <span class="code-object">Object</span>
(finalize [self]
(when (::second-object (meta self))
...)))</pre>
</div></div>
<p>(have not actually run this)</p><p>It looks like the class generated by <tt>reify</tt> always has a constructor that takes a metadata argument, so it doesn't seem out of the question to eliminate the extra object altogether.</p>
<p>I'll try to keep digging on this.</p>Global Rank[CLJ-1342] Byte comparison boxes both bytes and converts to longs to compare (which is slow)http://dev.clojure.org/jira/browse/CLJ-1342
Clojure<p>This came up in a much more complicated example but consider a case like this:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">(defn simple []
(let [b (<span class="code-object">byte</span>-array [(<span class="code-object">byte</span> 0)])
m (<span class="code-object">byte</span> 0)]
(= m (aget b 0))))</pre>
</div></div>
<p>In the compiled bytecode, both m and (aget b 0) are known to be bytes, but both are boxed using Byte.valueOf(), then cast using RT.uncheckedLongCast() and finally compared as longs:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">26: iload_2
27: invokestatic #69 <span class="code-comment">// Method java/lang/<span class="code-object">Byte</span>.valueOf:(B)Ljava/lang/<span class="code-object">Byte</span>;
</span> 30: checkcast #81 <span class="code-comment">// class java/lang/<span class="code-object">Number</span>
</span> 33: invokestatic #85 <span class="code-comment">// Method clojure/lang/RT.uncheckedLongCast:(Ljava/lang/<span class="code-object">Object</span>;)J</span></pre>
</div></div>
<p>In a tight loop manipulating and matching against byte arrays, this boxing is significant for performance. </p>
<p>Attached is a test that demonstrates the performance difference between the byte[] and long[] performance to get an idea of the difference.</p>CLJ-1342Byte comparison boxes both bytes and converts to longs to compare (which is slow)EnhancementMinorOpenUnresolvedUnassignedAlex MillercompilerThu, 6 Feb 2014 17:10:24 -0600Thu, 6 Feb 2014 21:39:45 -060012<p>The description states that Util.equiv() has a byte/byte comparison variant but it doesn't look like it actually exists.</p><p>By the way, tools.emitter.jvm uses i2l to cast the byte to a long instead of boxing &amp;&amp; unboxing to a long</p><p>Thanks Nicola - I must have confused it with the boolean/boolean version.</p>Global Rank[CLJ-1341] keyword function returns nil on bad inputhttp://dev.clojure.org/jira/browse/CLJ-1341
Clojure<p>The keyword function should throw an exception on bad input rather than return nil.</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">user=&gt; (keyword 5)
nil
user=&gt; (keyword [])
nil</pre>
</div></div>
<p><b>Cause:</b> The keyword function is defined as a cond with cases for keywords, symbols, and strings. There is no :else so all other cases return nil.</p>
<p><b>Proposal:</b> Add an :else branch and throw an exception in keyword.</p>
<p><b>Patch:</b> </p>
CLJ-1341keyword function returns nil on bad inputEnhancementMinorOpenUnresolvedUnassignedAlex MillercheckargserrormsgsWed, 5 Feb 2014 21:34:01 -0600Tue, 24 Feb 2015 10:30:04 -0600Release 1.503<p>The keyword function should throw an IllegalArgumentException on wrong argument type rather than return nil. For consistency, the two-argument case should throw an IllegalArgumentException if not both arguments are strings.</p>
<p>The find-keyword function should behave similarly to maintain the same signature.</p>
<p>Current behavior:</p>
<p>user=&gt; (keyword 5)<br/>
nil<br/>
user=&gt; (keyword [])<br/>
nil<br/>
user=&gt; (keyword 1 1)<br/>
java.lang.ClassCastException: java.lang.Long cannot be cast to java.lang.String</p>
<p>Cause: The keyword function is defined as a cond with cases for keywords, symbols, and strings. There is no :else so all other cases return nil. The same goes for find-keyword, which should behave in the same way. The two-argument case does throw an exception, but the message is not very helpful.</p>
<p>Proposal: I have added an :else branch to the cond that throws an IllegalArgumentException with a message that indicates the acceptable types and prints the actual argument. I made the same change to find-keyword. There are also simple tests.</p>
<p>Patch: keyword-1341-2014-02-12.patch</p>
<p>Note: This change does not check for all bad input, just the type. For instance, it is still possible to pass in a string with "illegal" keyword characters.</p><p>Hey Eric, thanks for the patch! The 1 arg change looks good. </p>
<p>On the 2 arg change I have a concern - I'm worried that we are adding new checks into a pretty hot code path (keyword creation). The 2 arg path is not a silent failure as you'll get a ClassCastException so I do not think adding these checks here is worth it. In the 1-arg case you've already fallen through the else, so there's no additional cost.</p><p>Understood. I'll remove the two-argument case.</p><p>The keyword function should throw an IllegalArgumentException on wrong argument type rather than return nil. The two-argument case already throws an exception.</p>
<p>The find-keyword function should behave similarly to maintain the same signature.</p>
<p>Current behavior:</p>
<p>user=&gt; (keyword 5)<br/>
nil<br/>
user=&gt; (keyword [])<br/>
nil<br/>
user=&gt; (keyword 1 1)<br/>
java.lang.ClassCastException: java.lang.Long cannot be cast to java.lang.String</p>
<p>Cause: The keyword function is defined as a cond with cases for keywords, symbols, and strings. There is no :else so all other cases return nil. The same goes for find-keyword, which should behave in the same way.</p>
<p>Proposal: I have added an :else branch to the cond that throws an IllegalArgumentException with a message that indicates the acceptable types and prints the actual argument. I made the same change to find-keyword. There are also simple tests.</p>
<p>Alternatives: Adding checks for the two-argument case was considered but it was feared that adding the extra overhead was not worth it since it already threw an exception. No significant overhead is added in the single-argument case since it will only affect erroneous input.</p>
<p>Patch: keyword-1341-2014-02-12.2.patch</p>
<p>Note: This change does not check for all bad input, just the type. For instance, it is still possible to pass in a string with "illegal" keyword characters.</p>Global RankPatchCode and Test[CLJ-1340] Emit unboxed cohercions from int/long to float/doublehttp://dev.clojure.org/jira/browse/CLJ-1340
Clojure<p>Currently when an int or long is used where a float or double is expected, boxed conversion happens instead of emitting <span class="error">&#91;IL&#93;</span>2<span class="error">&#91;FD&#93;</span> instructions.</p>CLJ-1340Emit unboxed cohercions from int/long to float/doubleEnhancementMinorOpenUnresolvedUnassignedChristophe GrandenhancementperformanceWed, 5 Feb 2014 17:37:53 -0600Wed, 5 Feb 2014 17:37:53 -0600Release 1.511Global RankPatchCode[CLJ-1337] defprotocol's docstring is out of datehttp://dev.clojure.org/jira/browse/CLJ-1337
Clojure<p>The docstring of defprotocol has an out-of-date description as follows:</p>
<blockquote>
<p>defprotocol is dynamic, has no special compile-time effect, and defines no new types or classes.</p></blockquote>
<p>Indeed, it used to have no compile-time effect. Today, however, it does generate a corresponding interface via gen-interface at compile time.</p>
<p>The patch just removes this description.</p>CLJ-1337defprotocol's docstring is out of dateDefectTrivialOpenUnresolvedUnassignedOHTA ShogodocstringTue, 4 Feb 2014 08:36:51 -0600Tue, 4 Feb 2014 08:36:51 -060001Global RankPatchCode[CLJ-1333] Documentation for "=" is misleading http://dev.clojure.org/jira/browse/CLJ-1333
Clojure<p>Document for clojure.core/= says it compares numbers in a type-independent manner. In reality the comparission is made in a type dependent manner. If the above statement was true then (= 1 1.0) would eval to true not false; </p>
<p>clojure.core/=<br/>
(<span class="error">&#91;x&#93;</span> <span class="error">&#91;x y&#93;</span> <span class="error">&#91;x y &amp; more&#93;</span>)<br/>
Equality. Returns true if x equals y, false if not. Same as<br/>
Java x.equals<img class="emoticon" src="http://dev.clojure.org/jira/images/icons/emoticons/thumbs_up.gif" height="19" width="19" align="absmiddle" alt="" border="0"/> except it also works for nil, and compares<br/>
numbers and collections in a type-independent manner. Clojure's immutable data<br/>
structures define equals() (and thus =) as a value, not an identity,<br/>
comparison.</p>
linux 2.6.32-431.el6.x86_64CLJ-1333Documentation for "=" is misleading EnhancementMinorOpenUnresolvedUnassignedGeorgedocsThu, 30 Jan 2014 06:59:34 -0600Fri, 14 Feb 2014 07:56:48 -0600Release 1.503<p>I think this is a little more complex than described.</p>
<p>= does compare things in a jvm type independent manner, but it does use what people have taken to calling "equality classes"</p>
<p>(= <span class="error">&#91;1 2&#93;</span> '(1 2))</p>
<p>(= {:a 1} (doto (java.util.HashMap.) (.put :a 1))) </p>
<p>etc.</p>
<p>now for numbers, it seems logical to me, to have floating point and precise numbers in distinct equality classes</p>
<p>in which case, 1.0 and 1 are in distinct equality classes, so not equal.</p><p>The docstring is definitely misleading for people unfamiliar with this sort of thing though. Numbers are probably the first thing that the words "type independent manner" bring to mind. A brief pointer to the <tt>==</tt> function might be useful.</p><p>I find == function to be confusing <br/>
For example <br/>
(== 1 1.0) =&gt; true<br/>
(== 1 1.0M) =&gt; false ; what is wrong with this comparison? </p>
<p>and doc says:<br/>
Returns non-nil if nums all have the equivalent value (type-independent)</p>
<p>@George - that last example (== 1 1.0M) is actually a bug that is fixed in 1.6 where it will return true.</p>Global Rank[CLJ-1332] Exceptions are not cached in lazy seqshttp://dev.clojure.org/jira/browse/CLJ-1332
Clojure<p>It is confusing that exceptions will only be thrown once when it is possible to iterate over a seq many times.</p>
<p>user=&gt; (def a (for <span class="error">&#91;i (reverse (range 2))&#93;</span> (/ 1 i)))<br/>
#'user/a<br/>
user=&gt; (println a)</p>
<p>ArithmeticException Divide by zero clojure.lang.Numbers.divide<br/>
(Numbers.java:156)<br/>
(user=&gt; (println a)<br/>
(1)<br/>
nil<br/>
user=&gt; (println a)<br/>
(1)<br/>
nil</p>CLJ-1332Exceptions are not cached in lazy seqsEnhancementMinorOpenUnresolvedUnassignedYongqian LiWed, 29 Jan 2014 23:29:45 -0600Thu, 13 Feb 2014 23:38:05 -060014<p>The cause of this is the <tt>lazy-seq</tt> macro which uses <tt>:once</tt> metadata to signal to the compiler that the thunk it creates will only be called once.</p>
<p>When the evaluation of a lazy seq throws an exception, trying to walk the seq again causes the function to be called a second time. Since its closed over values have likely been cleared by that point, you get different behavior.</p>
<p>Glancing at <tt>LazySeq.java</tt> made me pretty convinced you can't cache exceptions without adding an extra check somewhere in the standard codepath for lazy seq traversal.</p><p>Btw, I ran into this issue while trying to evaluate a lazy-seq in a future in order to do some processing concurrently in the background. Any suggestions for workarounds?</p>Global Rank[CLJ-1327] Clojure Primitives extend Serializable without serialVersionUIDhttp://dev.clojure.org/jira/browse/CLJ-1327
Clojure<p>Clojure keywords for instance are serializable but do not define a serialVersionUID.</p>LinuxCLJ-1327Clojure Primitives extend Serializable without serialVersionUIDDefectMinorOpenUnresolvedUnassignedKuldeepMon, 20 Jan 2014 05:37:21 -0600Mon, 20 Jan 2014 07:30:57 -0600Release 1.500Global Rank[CLJ-1326] Inconsistent reflection warnings when target is a literalhttp://dev.clojure.org/jira/browse/CLJ-1326
Clojure<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">user=&gt; (set! *warn-on-reflection* <span class="code-keyword">true</span>)
<span class="code-keyword">true</span>
user=&gt; (.get {} 0)
Reflection warning, NO_SOURCE_PATH:2:1 - call to get can't be resolved.
nil
user=&gt; (.get {1 1} 0)
nil
user=&gt; (.get ^:foo {1 1} 0)
Reflection warning, NO_SOURCE_PATH:4:1 - call to get can't be resolved.
nil
user=&gt; (.get {1 (inc 0)} 0)
Reflection warning, NO_SOURCE_PATH:5:1 - call to get can't be resolved.
nil</pre>
</div></div>
<p>Similar issues apply to other literals (vector literals, list literals)</p>CLJ-1326Inconsistent reflection warnings when target is a literalEnhancementTrivialOpenUnresolvedUnassignedNicola MomettoerrormsgsSun, 19 Jan 2014 09:02:02 -0600Wed, 5 Feb 2014 11:59:20 -060011Global Rank[CLJ-1324] Allow leading slashes in unqualified symbol nameshttp://dev.clojure.org/jira/browse/CLJ-1324
Clojure<p>The proposal is to allow the reader to accept symbol names with leading slashes.</p>
<p>Problem: Leading slashes are frequently useful, e.g. in mathematical operators like "/" or "/="</p>
<p>Currently, only "/" is allowed as a special case, and is used for the division operator in clojure.core</p>
<p>This could be extended to allow all symbols to have names starting with a leading slash.</p>
<p>There should be no ambiguity with namespace-qualified symbols:<br/>
1) In the case of a leading slash, a symbol should be interpreted as an unqualified symbol e.g. "/="<br/>
2) In the case of a slash anywhere except in leading position, it should considered as namespace qualified, e.g. "clojure.core/+"<br/>
3) In the case of multiple non-leading slashes, the first slash is the namespace separator, e.g. "clojure.core.matrix.operators//=" </p>
<p>Optionally, it also would be possible to allow multiple slashes after the leading slash in a name. This would allow symbols such as "/src/main/clojure" to become valid.</p>AllCLJ-1324Allow leading slashes in unqualified symbol namesEnhancementMinorOpenUnresolvedUnassignedMike AndersonreaderWed, 15 Jan 2014 10:01:04 -0600Sat, 2 Aug 2014 20:44:03 -0500Release 1.505<p>Attached patch to allow leading slashes in symbol names.</p>
<p>The patch changes the regexp pattern used to match symbols to accept characters after a slash in symbol names.</p>
<p>Tests pass, and the patch also adds a couple of new special cases to the symbol tests.</p><p>Paavo, a commit made to Clojure master earlier today causes your patch clj-1324-1.patch to no longer apply cleanly. I haven't investigated in detail, but it might be straightforward to update the patch so that it applies cleanly again.</p><p>Attached updated patch.</p><p>It would be less confusing if you could name the patches differently, or remove the older one.</p>Global RankPatchCode and Test[CLJ-1323] AsmReflector throws exceptions on JDK8http://dev.clojure.org/jira/browse/CLJ-1323
Clojure<p>After the commit of the updated ASM library for <a href="http://dev.clojure.org/jira/browse/CLJ-713" title="Upgrade ASM to a more current version"><del>CLJ-713</del></a>, Clojure builds and passes all tests except for one, compare-reflect-and-asm in reflect.clj.</p>
<p>This can be narrowed down somewhat to a difference in behavior of the following 2 forms evaluated with the latest Clojure and JDK8:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">;; The following two lines work with the latest (Jan 11 2014) Clojure 1.6.0-master-SNAPSHOT
;; <span class="code-keyword">if</span> run on JDK 6 or JDK 7, but <span class="code-keyword">throw</span> an exception with JDK 8.
(<span class="code-keyword">import</span> '[clojure.asm ClassReader ClassVisitor Type Opcodes])
(def r (ClassReader. <span class="code-quote">"java.lang.<span class="code-object">Object</span>"</span>))</pre>
</div></div>
<p>I am not certain, but from a bit of Google searching it appears that this may be a limitation of the ASM library version 4 &#8211; it throws exceptions when attempting to read class files produced by JDK 8, because of a newer classfile version number. Links that seem to support this conclusion:</p>
<p> <a href="http://mail-archive.ow2.org/asm/2013-02/msg00000.html">http://mail-archive.ow2.org/asm/2013-02/msg00000.html</a></p>
<p> <a href="http://forge.ow2.org/tracker/index.php?func=detail&amp;aid=316375&amp;group_id=23&amp;atid=350023">http://forge.ow2.org/tracker/index.php?func=detail&amp;aid=316375&amp;group_id=23&amp;atid=350023</a></p>
<p>A couple of alternatives are:</p>
<p>(1) update ASM again to one that supports JDK 8 class files</p>
<p>(2) disable the compare-reflect-and-asm test. Clojure itself does not use the AsmReflector for anything except this unit test. The Java reflector is the default one.</p>CLJ-1323AsmReflector throws exceptions on JDK8DefectMinorOpenUnresolvedUnassignedAndy FingerhutMon, 13 Jan 2014 01:23:32 -0600Sun, 23 Mar 2014 12:17:48 -0500Release 1.602<p>1) There is no released ASM that supports JDK 8 yet. ASM 5 will but it will not be final till JDK 8 is in the final stages of release.</p>
<p>2) Probably more likely.</p><p>As of now, both JDK8 and ASM5 are out.<br/>
I just tried compiling clojure on JDK8 with ASM5 and all compiles fine</p><p>How are you running this test?</p><p>I downloades ASM5, replaced the bundled ASM that comes with clojure with that one after changing che package name to "clojure.asm" and run `mvn install`, all the tests pass.</p><p>I was actually talking about the JDK 8 change - was curious about exactly what was being changed?</p><p>In particular, I'm assuming that you're not altering the build.xml to change the compilation -source or -target and running with JAVA_HOME / path set to JDK 8. </p>
<p>We don't have any plans to actually build Clojure with JDK 8 any time soon, so I'm not overly concerned about that. But it does appear that the embedded ASM 4 cannot read newer class files from JDK 8. Afaik, the only place that happens is in clojure.reflect.java in the AsmReflector, which is not the default reflector. The JavaReflector will properly reflect the Java 8 classes.</p>
<p>ASM 5 has only been out a couple days and already has at least one serious bug reported - I'd like that to see more use before we switch to it, so maybe this is a good target for the release after Clojure 1.6.</p><p>Patch to temporarily disable the failing test until we have an ASM that supports JDK 8.</p>Global Rank[CLJ-1321] Documentation improvement for clojure.walk, to note use of recursion that can easily blow the JVM stackhttp://dev.clojure.org/jira/browse/CLJ-1321
Clojure<p>prewalk and postwalk are use recursion in ways that will blow the stack for sufficiently deep nested structures.</p>
<p>I suggest that this be noted in various clojure.walk documentation strings since this kind of recursion/limit seems to be rare in Clojure, and hence will be unexpected.</p>
<p>(It'd be even better to remove the recursion/limit via something like zippers and iteration, but this issue is just a suggestion for improvement of the documentation.)</p>JVMCLJ-1321Documentation improvement for clojure.walk, to note use of recursion that can easily blow the JVM stackEnhancementMinorOpenUnresolvedUnassignedLee SpectordocumentationThu, 9 Jan 2014 18:30:28 -0600Thu, 9 Jan 2014 18:30:28 -0600Release 1.511Global Rank[CLJ-1319] array-map fails lazily if passed an odd number of argumentshttp://dev.clojure.org/jira/browse/CLJ-1319
Clojure<p>If called with an odd number of arguments, <tt>array-map</tt> does not throw an exception until the map is realized, when it throws the confusing <tt>ArrayIndexOutOfBoundsException</tt>.</p>
<p>Example, in 1.5.1 and 1.6.0-alpha3:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">user=&gt; (def m (array-map :a 1 :b))
#'user/m
user=&gt; (prn m)
ArrayIndexOutOfBoundsException 3
clojure.lang.PersistentArrayMap$Seq.first
(PersistentArrayMap.java:313)</pre>
</div></div>CLJ-1319array-map fails lazily if passed an odd number of argumentsEnhancementMinorOpenUnresolvedUnassignedStuart SierraerrormsgsWed, 8 Jan 2014 10:30:50 -0600Thu, 30 Jan 2014 19:55:47 -060001<p>PersistentArrayMap.createAsIfByAssoc could check length is even to catch this</p><p>A better error message would be nice... this is the best I could think of.</p>Global RankPatchCode and Test[CLJ-1317] clojure.zip/seq-zip returns spurious nils during traversalhttp://dev.clojure.org/jira/browse/CLJ-1317
Clojure<p>Problem reported by Lee Spector on the mailing list:</p>
<p><a href="https://groups.google.com/d/msg/clojure/8TL7IGmE7N0/u1xfgTOLDRgJ">https://groups.google.com/d/msg/clojure/8TL7IGmE7N0/u1xfgTOLDRgJ</a></p>
<p>Here's a quote from Lee's post describing the problem:</p>
<div class="preformatted panel" style="border-width: 1px;"><div class="preformattedContent panelContent">
<pre>Here's an illustration, stepping through '(() 0) with next and printing the node at each step:
(loop [z (zip/seq-zip '(() 0))]
(if (zip/end? z)
:done
(do (println (zip/node z))
(recur (zip/next z)))))
That produces:
(() 0)
()
nil
0
:done
I don't expect the nil to be there.
</pre>
</div></div>
<p>The underlying cause is that <tt>seq-zip</tt> passes <tt>identity</tt> as the <tt>children</tt> argument to <tt>zipper</tt>. Applied to <tt>()</tt>, this returns <tt>()</tt>, which is truthy, leading <tt>zipper</tt> to descend into a non-existent subtree.</p>
<p>One natural solution would be to use <tt>seq</tt> in place of <tt>identity</tt>:</p>
<div class="preformatted panel" style="border-width: 1px;"><div class="preformattedContent panelContent">
<pre>(defn seq-zip [root]
(zipper seq?
seq ;; changed
(fn [node children] (with-meta children (meta node)))
root))
</pre>
</div></div>
<p>With this change, no <tt>nil</tt> is produced in the example above. Patch with this change forthcoming.</p>CLJ-1317clojure.zip/seq-zip returns spurious nils during traversalDefectMinorOpenUnresolvedUnassignedMichał MarczykzipTue, 31 Dec 2013 17:42:57 -0600Wed, 5 Feb 2014 11:58:25 -060011<p>Note that the docstring of <tt>clojure.zip/zipper</tt> asks that the <tt>children</tt> argument return a seq of children. The rest of <tt>clojure.zip</tt>, however, expects <tt>nil</tt> to be returned when there are no children, as evidenced by this problem.</p>
<p>One could argue that this behaviour of the rest of <tt>clojure.zip</tt> should be fixed, but I think it makes sense and is convenient. Perhaps the docstring should be adjusted, though.</p>Global RankPatchCode[CLJ-1316] for doesn't support :let binding as its first seq-exprhttp://dev.clojure.org/jira/browse/CLJ-1316
Clojure<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">user&gt; (<span class="code-keyword">for</span> [y [2 3 4]
:let [x 1]]
[x y])
([1 2] [1 3] [1 4])
user&gt; (<span class="code-keyword">for</span> [:let [x 1]
y [2 3 4]]
[x y])
IllegalStateException Can't pop empty vector clojure.lang.PersistentVector.pop (PersistentVector.java:380)</pre>
</div></div>
<p><b>Cause:</b> </p>
<p><b>Solution:</b></p>
<p><b>Patch:</b><br/>
<b>Screened by:</b></p>jvm clojureCLJ-1316for doesn't support :let binding as its first seq-exprEnhancementMinorOpenUnresolvedUnassignedJay FieldsMon, 30 Dec 2013 09:28:37 -0600Sun, 28 Dec 2014 11:11:57 -0600Release 1.513<p>Related (perhaps identical?) ticket <a href="http://dev.clojure.org/jira/browse/CLJ-207" title="for macro does not allow :let clause in first position"><del>CLJ-207</del></a> was declined.</p><p>It does look like a duplicate. I find it surprising that this doesn't work, but it does work for doseq:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">main=&gt; (doseq [:let [x 1] y [2 3 4]] (println x y))
1 2
1 3
1 4
nil</pre>
</div></div>
<p>I think you'll keep getting this bug report as long as that inconsistency exists.</p>
<p>for completeness, I think it's worth mentioning that I can't simply change the ordering (like Alex's example above), due to the cost of the value I'm calculating. I only want it to occur once, and I have to use a separate 'let (as Rich recommended)</p>
<p>Brandon Bloom pointed out that one difference between <tt>for</tt> and <tt>doseq</tt> is that <tt>for</tt> is lazy, and so for an initial <tt>:let</tt> it's not clear whether it should be evaluated immediately or after the first item is requested. <tt>doseq</tt> doesn't have that ambiguity.</p><p>@Gary, I think that's a good question, but either choice would be better than the current inconsistency. If you made it lazy, I can't really think of a downside. Even if it wasn't lazy, that would match the current performance characteristics of code that's already wrapping the for in a let.</p>Global Rank[CLJ-1314] Correct placement of doc string for function bubble-max-keyhttp://dev.clojure.org/jira/browse/CLJ-1314
Clojure<p>It is private, defined with defn-, so perhaps the doc string is superfluous, but someone wrote one, and it is in the wrong place relative to the args:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">(defn- bubble-max-key [k coll]
"Move a maximal element of coll according to fn k (which returns a number)
to the front of coll."
(let [max (apply max-key k coll)]
(cons max (remove #(identical? max %) coll))))</pre>
</div></div>
<p>Found using a pre-release version of the Eastwood Clojure lint tool.</p>CLJ-1314Correct placement of doc string for function bubble-max-keyEnhancementTrivialOpenUnresolvedUnassignedAndy FingerhutdocstringMon, 23 Dec 2013 16:08:22 -0600Wed, 5 Feb 2014 11:57:22 -060002<p>Patch clj-1314-v1.diff simply corrects the location of the doc string for bubble-max-key.</p><p>Patch clj-1314-v2.diff is same as the previous clj-1314-v1.diff, except it leaves out some unintended changes.</p>Global RankPatchCode[CLJ-1311] gen-interface uses DynamicClassLoader when not compiling, gen-class doesn'thttp://dev.clojure.org/jira/browse/CLJ-1311
Clojure<p>The documentation for both gen-class and gen-interface says: "When not compiling, does nothing."</p>
<p>However, gen-interface does the right thing and uses DynamicClassLoader.defineClass when not compiling. This means e.g. that gen-interface works from the repl.</p>
<p>I don't see a reason why gen-class couldn't do the same. Obviously, the docstrings would need to be updated too.</p>CLJ-1311gen-interface uses DynamicClassLoader when not compiling, gen-class doesn'tEnhancementMinorOpenUnresolvedUnassignedJoel Kaasinendocstringgen-classinteropFri, 20 Dec 2013 03:10:54 -0600Wed, 5 Feb 2014 11:59:53 -0600Release 1.501Global Rank[CLJ-1309] Bindings after :as in list destructuring should throw errorhttp://dev.clojure.org/jira/browse/CLJ-1309
Clojure<p>If you try to define a vector binding with anything at all after an :as parameter, you do not get a compiler error, and the binding is silently swallowed:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">user&gt; ((fn [[:as y z]] y) [1 2])
[1 2]</pre>
</div></div>
<p>If you try to actually use the binding, there will be a compiler error (the compiler will complain that there's no binding for the symbol), but the actual error has already happened, and should be reported earlier.</p>CLJ-1309Bindings after :as in list destructuring should throw errorEnhancementMinorOpenUnresolvedUnassignedben wolfsonCompilererrormsgsThu, 19 Dec 2013 18:25:17 -0600Wed, 5 Feb 2014 12:00:16 -0600Release 1.4Release 1.501Global Rank[CLJ-1308] extend-type doesn't type-hint correctly as promised by the doc when the class is determined at run-timehttp://dev.clojure.org/jira/browse/CLJ-1308
Clojure<p>extend-type works with non-constant expressions as its type:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">(extend-type (class 1) proto (protof [<span class="code-keyword">this</span>]))</pre>
</div></div>
<p>However, in this case this will get tagged with `(class 1)`, which is clearly wrong; the doc explicitely states that the args will be proberly type-hinted: "<span class="error">&#91;..&#93;</span> Propagates the class as a type hint on the first argument of all fns."</p>
<p>I don't know if extend-type is not supposed to work with non-constant Classes, in which case it should be stated in the doc or if the current behaviour is wrong.</p>CLJ-1308extend-type doesn't type-hint correctly as promised by the doc when the class is determined at run-timeDefectMinorOpenUnresolvedUnassignedNicola MomettotypehintsSun, 15 Dec 2013 16:12:04 -0600Tue, 6 Jan 2015 16:37:42 -060013<p>Eastwood as of around version 0.2.1 (or maybe have to wait until not-yet-released 0.2.2) will warn about such incorrect tags, if the :wrong-tag linter is enabled &#8211; it is by default. The section of Eastwood's documentation on this linter has a subsection specifically on extend-type and extend-protocol, primarily written so Andy can have a place to refer to this later after he forgets the details again.</p>
<p><a href="https://github.com/jonase/eastwood#wrong-tag">https://github.com/jonase/eastwood#wrong-tag</a></p>
<p>(you have to scroll down a page or two to get to the subsection on extend-type / extend-protocol)</p>Global Rank[CLJ-1300] take-while with n<1 behaves like (repeat 1)http://dev.clojure.org/jira/browse/CLJ-1300
Clojure
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-none">user=&gt; (take-nth -1 [1 3 4])
; hangs
user=&gt; (take 5 (take-nth -1 [5 9 14]))
(1 1 1 1 1)</pre>
</div></div>
<p>I understand this behavior may be intentionally undefined,<br/>
but raising the issue on IRC didn't yield an answer on whether<br/>
this is a bug or grey area.</p>CLJ-1300take-while with n<1 behaves like (repeat 1)DefectMinorOpenUnresolvedUnassignedYaron PelegFri, 22 Nov 2013 14:01:50 -0600Fri, 22 Nov 2013 14:01:50 -0600Release 1.1Release 1.2Release 1.3Release 1.4Release 1.5Release 1.600Global Rank[CLJ-1296] locking expressions cause vars to be dereferenced, even if not executed, unless wrapped in lethttp://dev.clojure.org/jira/browse/CLJ-1296
Clojure<p>Description of one example with poor performance discovered by Michał Marczyk in the discussion thread linked below.</p>
<p>The difference between the compiled versions of:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">(defn foo [x]
(<span class="code-keyword">if</span> (&gt; x 0)
(inc x)
(locking o
(dec x))))</pre>
</div></div>
<p>and</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">(defn bar [x]
(<span class="code-keyword">if</span> (&gt; x 0)
(inc x)
(let [res (locking o
(dec x))]
res)))</pre>
</div></div>
<p>is quite significant. foo gets compiled to a single class, with invocations handled by a single invoke method; bar gets compiled to a class for bar + an extra class for an inner function which handles the (locking o (dec x)) part &#8211; probably very similar to the output for the version with the hand-coded locking-part (although I haven't really looked at that yet). The inner function is a closure, so calling it involves an allocation of a closure object; its ctor receives the closed-over locals as arguments and stores them in two fields (lockee and x). Then they get loaded from the fields in the body of the closure's invoke method etc. </p>
<p>Note: The summary line may be too narrow a description of the root cause, and simply the first example of a case where this issue was noticed and examined. Please make the summary and this description more accurate if you diagnose this issue.</p>
<p>See discussion thread on Clojure group here: <a href="https://groups.google.com/forum/#!topic/clojure/x86VygZYf4Y">https://groups.google.com/forum/#!topic/clojure/x86VygZYf4Y</a></p>CLJ-1296locking expressions cause vars to be dereferenced, even if not executed, unless wrapped in letEnhancementMinorOpenUnresolvedUnassignedAndy FingerhutperformanceSun, 17 Nov 2013 16:07:36 -0600Fri, 18 Apr 2014 02:17:05 -0500Release 1.512<p>maybe it is already clear to others, but this was not immediately clear to me:</p>
<p>the reason</p>
<div class="preformatted panel" style="border-width: 1px;"><div class="preformattedContent panelContent">
<pre>(defn bar [x]
(if (&gt; x 0)
(inc x)
(let [res (locking o
(dec x))]
res)))
</pre>
</div></div>
<p>generates a second class is locking is a macro that contains a try/finally form in it's expansion.</p>
<p>binding the result of a try/finally form to a result (as in the let) would require some real tricky code gen without adding the extra function, so of course the clojure compile adds the extra function.</p>Global Rank[CLJ-1292] print docstring should specify nil return valuehttp://dev.clojure.org/jira/browse/CLJ-1292
Clojure<p>The docstring for print does not mention its return value. The docstring should clarify whether print dependably returns nil or shouldn't be depended on to (lest, for example, something leak out as the inadvertent return value of print's caller).</p>CLJ-1292print docstring should specify nil return valueEnhancementTrivialOpenUnresolvedUnassignedPhill WolfdocstringprintFri, 1 Nov 2013 20:53:08 -0500Thu, 6 Nov 2014 19:46:37 -0600Release 1.601<p>Hi, I just add to docstring the mention to fact that it return nil</p>Global Rank[CLJ-1291] struct-map docstring incomplete, inconsistenthttp://dev.clojure.org/jira/browse/CLJ-1291
Clojure<p>The docstring for struct-map refers to "structure-basis" and "keyvals" while the parameters are "s" and "inits". The docstring says "keyvals can also contain keys not in the basis" but does not say what happens in that case.</p>CLJ-1291struct-map docstring incomplete, inconsistentEnhancementTrivialOpenUnresolvedUnassignedPhill WolfdocstringFri, 1 Nov 2013 20:23:02 -0500Wed, 5 Feb 2014 12:17:31 -0600Release 1.600Global Rank[CLJ-1286] Fix reader spec and regex to match code for keywords starting with digitshttp://dev.clojure.org/jira/browse/CLJ-1286
Clojure<p>The reader page at <a href="http://clojure.org/reader">http://clojure.org/reader</a> states that symbols (and keywords) cannot start with a number and the regex used in LispReader (and EdnReader) also has this intention. <a href="http://dev.clojure.org/jira/browse/CLJ-1252" title="Clojure reader (incorrectly) accepts keywords starting with a number "><del>CLJ-1252</del></a> addressed this by fixing the broken reader regex to match the spec. However, that broke some existing code so we rolled back the change. There is still a disconnect here and this ticket serves to decide what to do instead.</p>
<p>I presume that we are effectively deciding that keywords like :5 are ok to read. If so, we should alter the regex to more accurately capture that intent - right now it allows these purely by accident due to backtracking. A secondary question is whether the Clojure and EDN reader spec should also explicitly allow these as valid. My preference would be to have the reader and the spec match, so I would lobby to loosen the reader spec.</p>
<p>Related ticket: <a href="http://dev.clojure.org/jira/browse/CLJ-1527" title="Harmonize accepted / documented symbol and keyword syntax over various readers">CLJ-1527</a></p>CLJ-1286Fix reader spec and regex to match code for keywords starting with digitsDefectMinorOpenUnresolvedUnassignedAlex MillerreaderThu, 31 Oct 2013 21:44:01 -0500Wed, 10 Dec 2014 10:08:04 -060025<p>what about keywords like :1/1 or :1/a? Clojure currently accepts the latter but not the former.</p><p>There's more discussion of this problem (and symbol/keyword parsing in general) in the context of cljs.reader at <a href="http://dev.clojure.org/jira/browse/CLJS-677" title="cljs.reader doesn&#39;t support keywords starting with a digit">CLJS-677</a>.</p><p>Francis, can you double-check that ticket number? The one you mention (<a href="http://dev.clojure.org/jira/browse/CLJS-667" title="validate extend-type and extend-protocol shape">CLJS-667</a>) doesn't seem to have any discussion of this problem.</p><p>Sincere apologies, it's <a href="http://dev.clojure.org/jira/browse/CLJS-677" title="cljs.reader doesn&#39;t support keywords starting with a digit">CLJS-677</a>. (Original post corrected too.)</p><p>From a discussion in #clojure, it emerged that while :foo/1 is currently not allowed, ::1 is.</p>Global Rank[CLJ-1284] Clojure functions and reified objects should expose a public static field to identify their proper Clojure namehttp://dev.clojure.org/jira/browse/CLJ-1284
Clojure<p>There are several examples of frameworks that attempt to de-mangle a Java class name into a Clojure symbol (including namespace); this is useful for writing out an improved, Clojure-specific stack trace when reporting exceptions.</p>
<p>Existing libraries are based on regular expression matching and guesswork, and can occasionally give incorrect results, such as when a namespace or function name actually contains an underscore.</p>
<p>It would be helpful for authors of such frameworks if Clojure would expose a static final field on such classes with the proper name that should appear in the stack trace; libraries would then be able to use reflection to access the proper name of the field, without the current guesswork.</p>
<p>I would suggest CLOJURE_SOURCE_NAME as a reasonable name for such a field.</p>
<p>Other Clojure class constructs beyond functions, such as reified types and protocol implementations, would also benefit, though it is less obvious what exact string value would properly and unambiguously identify what purpose the class plays.</p>CLJ-1284Clojure functions and reified objects should expose a public static field to identify their proper Clojure nameEnhancementMinorOpenUnresolvedUnassignedHoward Lewis ShiperrormsgsThu, 24 Oct 2013 18:07:43 -0500Fri, 29 Aug 2014 16:42:05 -0500Release 1.513<p>FYI, there is a patch on the way in for 1.6 that contains a new demunge function in Compiler. However, the munged name is not always reversible so having the original around is a good idea.</p><p>The patch Alex is referring to is attached to <a href="http://dev.clojure.org/jira/browse/CLJ-1083" title="Incorrect ArityException message for function names containing -&gt;"><del>CLJ-1083</del></a>.</p><p>Howard, there seems to be some overlap in the intent between this ticket and <a href="http://dev.clojure.org/jira/browse/CLJ-1278" title="Identify Clojure namespace and function name in a compiled function&#39;s toString()">CLJ-1278</a>. I guess either of them could be done without the other, but wanted to check.</p><p>Here's an initial stab at adding this feature.</p>
<p>Some notes:</p>
<ul>
<li>This will tag emitted classes from <tt>deftype</tt> and <tt>fn</tt></li>
<li>This will handle <tt>fn}}s that are enclosed, but the output will be slightly different from the standard {{demunge</tt> function: only the initial <tt>$</tt> is transformed to a <tt>/</tt>.</li>
<li>Unfortunately, because the <tt>defn</tt> for type/record constructor occurs in a <tt>let</tt> form, the generated symbol doesn't match what it should be.</li>
<li>There is no exposed API to get the demunged symbol from the class. Perhaps <tt>demunge</tt> should check if the given name corresponds to a class with this field?</li>
</ul>
<p>I welcome any input on how this should really work. In particular, any ideas on how to best deal with {{defn}}s that are not top-level forms.</p><p>Patch <a href="http://dev.clojure.org/jira/browse/CLJ-1284" title="Clojure functions and reified objects should expose a public static field to identify their proper Clojure name">CLJ-1284</a>-store-demunged-names.patch dated Aug 20 2014 does not apply cleanly to latest master after some commits were made to Clojure on Aug 29, 2014. I have not checked whether it applied cleanly before that day, nor have I checked how easy or difficult it might be to update this patch.</p>Global Rank[CLJ-1283] Method clojure.lang.RT.lastModified(URL, String) fails if 'jar' protocol is not handled by JarURLConnector.http://dev.clojure.org/jira/browse/CLJ-1283
Clojure<p>Method <tt>clojure.lang.RT.lastModified(URL, String)</tt> throws a <tt>ClassCastException</tt> if it is called in environment, where 'jar' protocol is not handled by standard <tt>JarURLConnector</tt>. The provided patch just adds a type check for that case. I ran into this problem when I tried to add a Clojure REPL to existing Java application. </p>CLJ-1283Method clojure.lang.RT.lastModified(URL, String) fails if 'jar' protocol is not handled by JarURLConnector.DefectMinorOpenUnresolvedUnassignedTVThu, 24 Oct 2013 03:19:05 -0500Thu, 24 Oct 2013 08:44:21 -050000<p>Hi TV, thanks for the report! Just a note, that we can't accept your patch unless you have signed a Contributor's Agreement as per <a href="http://clojure.org/contributing">http://clojure.org/contributing</a>. </p>
<p>Just out of curiosity, is this an internal environment where you've customized the jar protocol or some kind of app server someone else would be likely to encounter? </p><p>It is an internal environment and so I set the priority to minor.</p>Global RankPatchCode[CLJ-1280] Create reusable exception that can carry file/line/col infohttp://dev.clojure.org/jira/browse/CLJ-1280
Clojure<p>This concept already exists in multiple places in Clojure - Compiler$CompilerException and the Exception classes buried in EdnReader and LispReader. It would also be useful in other places where IllegalArgument or other other exceptions are thrown.</p>
<p>For example, this protocol exception throws an IllegalArgumentException and could transmit the file, line, and column info at the location of the error but it seems weird to use any of the existing exceptions for this purpose.</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">(defprotocol Bar (m [<span class="code-keyword">this</span>]) (m [<span class="code-keyword">this</span> arg]))</pre>
</div></div>
CLJ-1280Create reusable exception that can carry file/line/col infoEnhancementMajorOpenUnresolvedUnassignedAlex MillerFri, 18 Oct 2013 11:07:45 -0500Fri, 18 Apr 2014 00:09:58 -050012<p>seems like ExceptionInfo can do this</p>Global Rank[CLJ-1279] Fix confusing macroexpand1 ArityException handlinghttp://dev.clojure.org/jira/browse/CLJ-1279
Clojure<p>macros can give very confusing error messages when they execute a form which generates an ArityException. clojure.lang.Compiler.macroexpand1 assumes that any ArityException comes from the call to the macro itself, which need not be the case. For instance:</p>
<p> user&gt; (do (defmacro f [] (assoc)) (f))<br/>
ArityException Wrong number of args (-2) passed to: core$assoc clojure.lang.Compiler.macroexpand1 (Compiler.java:6488)<br/>
user&gt; (use 'clojure.repl) (pst)<br/>
nil<br/>
ArityException Wrong number of args (-2) passed to: core$assoc<br/>
clojure.lang.Compiler.macroexpand1 (Compiler.java:6488)<br/>
clojure.lang.Compiler.macroexpand (Compiler.java:6544)<br/>
clojure.lang.Compiler.eval (Compiler.java:6618)<br/>
clojure.lang.Compiler.eval (Compiler.java:6624)<br/>
clojure.lang.Compiler.eval (Compiler.java:6597)<br/>
clojure.core/eval (core.clj:2864)<br/>
clojure.main/repl/read-eval-print-<del>6596/fn</del>-6599 (main.clj:260)<br/>
clojure.main/repl/read-eval-print--6596 (main.clj:260)<br/>
clojure.main/repl/fn--6605 (main.clj:278)<br/>
clojure.main/repl (main.clj:278)<br/>
clojure.tools.nrepl.middleware.interruptible-eval/evaluate/fn--1251 (interruptible_eval.clj:56)<br/>
clojure.core/apply (core.clj:617)<br/>
nil</p>
<p>Easy enough to see the source of the problem in this case, but because both the number of arguments actually passed is off by two, and the stacktrace element for the call to assoc has been dropped, this shortcut by macroexpand1 can get super confusing.</p>
<p>The attached patch corrects this behavior. E.g.</p>
<p> user=&gt; (do (defmacro f [] (assoc)) (f))<br/>
ArityException Wrong number of args (0) passed to: core$assoc clojure.lang.AFn.throwArity (AFn.java:437)<br/>
user=&gt; (use 'clojure.repl) (pst)<br/>
nil<br/>
ArityException Wrong number of args (0) passed to: core$assoc<br/>
user/f (NO_SOURCE_FILE:1)<br/>
clojure.lang.Var.invoke (Var.java:419)<br/>
clojure.lang.Var.applyTo (Var.java:532)<br/>
clojure.lang.Compiler.macroexpand1 (Compiler.java:6507)<br/>
clojure.lang.Compiler.macroexpand (Compiler.java:6580)<br/>
clojure.lang.Compiler.eval (Compiler.java:6654)<br/>
clojure.lang.Compiler.eval (Compiler.java:6660)<br/>
clojure.lang.Compiler.eval (Compiler.java:6633)<br/>
clojure.core/eval (core.clj:2864)<br/>
clojure.main/repl/read-eval-print-<del>6594/fn</del>-6597 (main.clj:260)<br/>
clojure.main/repl/read-eval-print--6594 (main.clj:260)<br/>
clojure.main/repl/fn--6603 (main.clj:278)<br/>
nil</p>CLJ-1279Fix confusing macroexpand1 ArityException handlingDefectMajorOpenUnresolvedUnassignedAlex CoventryCompilererrormsgsmacroWed, 16 Oct 2013 22:12:55 -0500Wed, 5 Feb 2014 12:25:20 -0600Release 1.632<p>Patch with test</p><p>Amended patch to deal more gracefully with unexpected stack trace structure.</p><p>Also see <a href="http://dev.clojure.org/jira/browse/CLJ-397" title="better error message when calling macros with arity"><del>CLJ-397</del></a> and <a href="http://dev.clojure.org/jira/browse/CLJ-383" title="different arrities of macro don&#39;t work in 1.2 (20100607 build)"><del>CLJ-383</del></a>. </p><p>Thanks, Alex. It would be easy enough to move most of the logic into ArityException, which would be a compromise between Stu's<span class="error">&#91;1&#93;</span> options 1 and 2. Is that worth doing?</p>
<p>Amending clojure.lang.AFn.throwArity to check whether "this" is a macro and adjust the arg count there accordingly might be the simplest way. I can see why Rich prefers all the logic to go into ArityException, but since ArityExceptions are used for things other than macros, I don't see a way to make an honest error message there without groveling the stack trace.</p>
<p><span class="error">&#91;1&#93;</span> <a href="http://dev.clojure.org/jira/browse/CLJ-397?focusedCommentId=24090&amp;page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-24090">http://dev.clojure.org/jira/browse/CLJ-397?focusedCommentId=24090&amp;page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-24090</a></p><p>I would have to take more time than I have to make an informed opinion but I can say that from a general point of view inspecting StackTraceElements does not seem like the right solution to (almost) any problem. <img class="emoticon" src="http://dev.clojure.org/jira/images/icons/emoticons/smile.gif" height="20" width="20" align="absmiddle" alt="" border="0"/> </p><p>This patch causes Var.setMacro to set instance attribute AFn.macrop to true, so that AFn.throwArity can reduce the number of arguments reported.</p>
<p>I'm not used to negotiating java class hierarchies, so it's possible there's a cleaner way. Since Var.fn() returns an IFn, I added macrop handling methods IFn.setMacro and IFn.isMacro. These then needed to be implemented in Ref and Keyword, as well as AFn (where I wanted them) because they implement the IFn interface but don't inherit from AFn.</p>
<p>The real drawback I see with this approach is the duplicated state, though: ^{:macro true} vs AFn.macrop==true.</p><p>I have not investigated the reason yet, but neither patch applies cleanly after the latest commits to Clojure master on Oct 25 2013. Given that what kinds of solution methods would be acceptable for this issue, it sounds like more thinking and code changes are probably needed anyway before worrying too much about that.</p>Global RankPatchCode and Test[CLJ-1278] Identify Clojure namespace and function name in a compiled function's toString()http://dev.clojure.org/jira/browse/CLJ-1278
Clojure<p>For debugging purposes, it would be useful to have Clojure-oriented toString() for functions.</p>
<div class="preformatted panel" style="border-width: 1px;"><div class="preformattedContent panelContent">
<pre>novate.core.processing.async/locate-destination(async.clj:231)
</pre>
</div></div>
<p>instead of:</p>
<div class="preformatted panel" style="border-width: 1px;"><div class="preformattedContent panelContent">
<pre>novate.core.processing.async$locate_destination@2690d691
</pre>
</div></div>
<p>This would remove the frustration of mentally de-mangling the function name from the Java class name.</p>
<p>This will have a relatively insignificant change to the generated code: An implementation of the toString() method. This will add a few dozen bytes to the size of a compiled Clojure function (for the additional bytecodes, and the constant string). </p>CLJ-1278Identify Clojure namespace and function name in a compiled function's toString()EnhancementMinorOpenUnresolvedUnassignedHoward Lewis ShiperrormsgsinteropThu, 10 Oct 2013 13:47:52 -0500Wed, 26 Nov 2014 16:14:51 -0600Release 1.591<p>Contains changes and updated tests. I don't have any details on if this affects compiler performance or generated code size in any significant or even measurable way.</p><p>Howard, sorry I do not have more useful comments on the changes you make in your patch. Right now I only have a couple of minor comments on its form. The preferred format for patches is that created using the instructions shown on this wiki page: <a href="http://dev.clojure.org/display/community/Developing+Patches">http://dev.clojure.org/display/community/Developing+Patches</a></p>
<p>Also, there are several parts of your patch that appear to only make changes in the whitespace of lines. It would be best to leave such changes out of a proposed patch.</p><p>Yes, I didn't notice the whitespace changes until after; I must have hit reformat at some point, despite my best efforts. I'll put together a new patch shortly.</p><p>Clean patch</p><p>FYI, it's been a year. The correct file is <a href="http://dev.clojure.org/jira/browse/CLJ-1278" title="Identify Clojure namespace and function name in a compiled function&#39;s toString()">CLJ-1278</a>-2.patch.</p><p>... hm, something's changed in recent times.</p>
<div class="preformatted panel" style="border-width: 1px;"><div class="preformattedContent panelContent">
<pre> [java] FAIL in (fn-toString) (fn.clj:83)
[java] nested functions
[java] expected: (= (simple-name (.toString (factory-function))) (str "clojure.test-clojure.fn/" "factory-function/fn"))
[java] actual: (not (= "clojure.test-clojure.fn/factory-function/fn__7565" "clojure.test-clojure.fn/factory-function/fn"))
[java]
[java] FAIL in (fn-toString) (fn.clj:83)
[java] nested functions
[java] expected: (= (simple-name (.toString (named-factory-function))) (str "clojure.test-clojure.fn/" "named-factory-function/a-function-name"))
[java] actual: (not (= "clojure.test-clojure.fn/named-factory-function/a-function-name__7568" "clojure.test-clojure.fn/named-factory-function/a-function-name"))
</pre>
</div></div>
<p>I'd be willing to update my patch if there's any indication that it will ever be picked up. It's been over a year since last update.</p><p>The change in behavior you are seeing is most likely due to a fix for ticket <a href="http://dev.clojure.org/jira/browse/CLJ-1330" title="Class name clash between top-level functions and defn&#39;ed ones"><del>CLJ-1330</del></a>.</p>
<p>And in case you were wondering, no, I am not the person who knows what tickets are of interest. I know that this one has gotten a fair number of votes, and by votes is one of the top ranked enhancement suggestions - look under "enhancements" on this report, or search for 1330: <a href="http://jafingerhut.github.io/clj-ticket-status/CLJ-top-tickets-by-weighted-vote.html">http://jafingerhut.github.io/clj-ticket-status/CLJ-top-tickets-by-weighted-vote.html</a></p>
<p>The features going into Clojure 1.7 are pretty well decided upon, and a fair number of other fixes and enhancements were delayed to 1.8. A longer than 1 year wait is not unusual, especially for enhancements.</p><p>Thanks for the info; don't want to come off as whiny but The Great Silence is off putting to someone who wants to help improve things. </p>
<p>I'll update my patch, and hope to see some motion for 1.8.</p><p>There are ~400 open tickets for Clojure. As a printing enhancement, this is generally considered lower priority than defects. Additionally, the proposal changes the compiler, bytecode generation code, and adds fields to generated objects, which has unassessed and potentially wide impacts. The combination of these things means it might be a while before we get around to looking at it. </p>
<p>Things that you could do to help:<br/>
1) Simplify the description. Someone coming to this ticket (screeners and ultimately Rich) want to look at the description and get the maximal understanding with the minimal effort. We have some guidelines on this at <a href="http://dev.clojure.org/display/community/Creating+Tickets">http://dev.clojure.org/display/community/Creating+Tickets</a> if you haven't seen it. For an enhancement, a short (1-2 sentence) description of the problem and an example I can run in the repl is best. Then a proposal (again, as short as possible). Examples: <a href="http://dev.clojure.org/jira/browse/CLJ-1529" title="Significantly improve compile time by reducing calls to Class.forName"><del>CLJ-1529</del></a>, <a href="http://dev.clojure.org/jira/browse/CLJ-1325" title="Report warnings if *unchecked-math* and boxing happens"><del>CLJ-1325</del></a>, <a href="http://dev.clojure.org/jira/browse/CLJ-1378" title="Hints don&#39;t work with #() form of function"><del>CLJ-1378</del></a>. For an enhancement like this, seeing (succinct) before/after versions where a user will see this is often the quickest way for a screener to understand the benefit.</p>
<p>2) Anticipate and remove blockers. As I mentioned above, you are changing the size of every function object. What is the impact on size and construction time? Providing data and/or a test harness saves a screener from doing this work. It's better to leave details in attachments or comments and refer to it in the description if it's lengthy.</p>
<p>3) Have others screen (per <a href="http://dev.clojure.org/display/community/Screening+Tickets">http://dev.clojure.org/display/community/Screening+Tickets</a> ) - while that is the job a screener (often me) will have to re-do, having more eyeballs on it early helps. Ask on #clojure for someone else to take a look, try it, etc. If there are open questions, leaving those in the description helps guide my work.</p>
<p>Alex, thanks for the advice. I'll follow through. Some of that data is already present, but I can make it more prominent.</p>
<p>I know that I'm overwhelmed by the number of issues (including enhancements and minor improvements) on the Tapestry issue list, so I'm understanding of problem space.</p>Global RankPatchCode and Test[CLJ-1275] print-dup's handling of metadata typehint is unreadable in some circumstanceshttp://dev.clojure.org/jira/browse/CLJ-1275
Clojure<p>With <b>print-dup</b> true, if an object being printed has a metadata map with only a :tag key, the printer renders it as "^value". This can cause an IllegalArgumentException if you try to read the printed string back in, in some circumstances. E.g.</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">user=&gt; (read-string (let [ge (with-meta (gensym) {:tag <span class="code-object">Object</span>})] (binding [*print-dup* <span class="code-keyword">true</span>] (pr-str ge))))
IllegalArgumentException Metadata must be Symbol,Keyword,<span class="code-object">String</span> or Map clojure.lang.LispReader$MetaReader.invoke (LispReader.java:732)</pre>
</div></div>
<p>This is causing problems with sleight/riddley's <span class="error">&#91;1&#93;</span> handling of the (case) macro, which drops a type-hint on a gensym it incorporates in the form it returns. When sleight tries to reserialize a macroexpanded (case) form from riddley, it fails as demonstrated above. E.g.</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">user=&gt; (read-string (binding [*print-dup* <span class="code-keyword">true</span>] (pr-str (macroexpand '(<span class="code-keyword">case</span> 1 1 1)))))
user=&gt; IllegalArgumentException Metadata must be Symbol,Keyword,<span class="code-object">String</span> or Map clojure.lang.LispReader$MetaReader.invoke (LispReader.java:732)</pre>
</div></div>
<p>The attached patch corrects this by making core_print.clj's print-meta always print out the full metadata map if <b>print-dup</b> is true. The patch also contains a test for this case.</p>
<p><span class="error">&#91;1&#93;</span> <a href="https://github.com/ztellman/sleight">https://github.com/ztellman/sleight</a> <a href="https://github.com/ztellman/riddley">https://github.com/ztellman/riddley</a></p>CLJ-1275print-dup's handling of metadata typehint is unreadable in some circumstancesDefectMinorOpenUnresolvedUnassignedAlex CoventrymetadataprintWed, 2 Oct 2013 22:22:21 -0500Fri, 29 Aug 2014 16:39:20 -0500Release 1.5Release 1.600<p>Corresponding bug on sleight: <a href="https://github.com/ztellman/sleight/issues/5">https://github.com/ztellman/sleight/issues/5</a></p><p>Patch 0001-Don-t-use-shorthand-for-typehints-when-print-dup.patch dated Oct 2 2013 no longer applied cleanly to latest master after some commits were made to Clojure on Aug 29, 2014. It did apply cleanly before that day.</p>
<p>I have not checked how easy or difficult it might be to update this patch.</p>Global RankPatchCode and Test[CLJ-1272] Agent thread executors do not use the global uncaught exception handlerhttp://dev.clojure.org/jira/browse/CLJ-1272
Clojure<p>If you use Thread.setDefaultUncaughtExceptionHandler to catch all application exceptions, and then throw an exception in a future, that exception will get swallowed up in deployment environments that don't watch stdout. It seems that the agent's executors ought to delegate to the global handler.</p>
<p>This issue bit us, in that we deploy and monitor our system only through its logs and metrics, and never actually saw that exceptions were being thrown in futures.</p>CLJ-1272Agent thread executors do not use the global uncaught exception handlerEnhancementMajorOpenUnresolvedUnassignedDavid GreenbergagentsTue, 1 Oct 2013 13:07:18 -0500Wed, 5 Feb 2014 12:25:02 -0600Release 1.500Global Rank[CLJ-1266] Better primitive support for floatshttp://dev.clojure.org/jira/browse/CLJ-1266
Clojure<p>Clojure offers optimized arithmetic functions for long, int and doubles but none for floats.<br/>
Plus converting from integers (ints or longs) to floating point numbers (float or double) doesn't use the specialized bytecode.<br/>
This patch adds float-add/subtract/multiply/divide and more efficient coversion from integers to floating points numbers.</p>CLJ-1266Better primitive support for floatsEnhancementMinorOpenUnresolvedUnassignedChristophe GrandperformanceThu, 26 Sep 2013 09:04:23 -0500Wed, 5 Feb 2014 17:40:27 -0600Release 1.510<p>I think it's unlikely the arithmetic float ops will be accepted.<br/>
However, the intrinsics changes could be useful - could you split those into a new ticket?</p><p>I attached a new patch with only intrinsics and more comprehensive primitive coercion. Is it the split you expected?</p><p>No, but totally my fault for saying the wrong words. <img class="emoticon" src="http://dev.clojure.org/jira/images/icons/emoticons/smile.gif" height="20" width="20" align="absmiddle" alt="" border="0"/></p>
<p>I think the changes in Compiler to get access to I2D, L2D, I2F, and L2F are potentially useful (most particularly L2D) - these would make sense in a new ticket. </p>
<p>The other changes in Intrinsics and Numbers to support float math are unlikely to be accepted.</p><p>Godd thing I had already split coercions in a sparate commit then <img class="emoticon" src="http://dev.clojure.org/jira/images/icons/emoticons/wink.gif" height="20" width="20" align="absmiddle" alt="" border="0"/></p>
<p>See <a href="http://dev.clojure.org/jira/browse/CLJ-1340">http://dev.clojure.org/jira/browse/CLJ-1340</a></p>
Global RankPatchCode[CLJ-1263] Allow static compilation of function invocationshttp://dev.clojure.org/jira/browse/CLJ-1263
Clojure<p>This proposal is to allow metadata on functions to prevent a fully dynamic var deref to be used whenever the function is called. </p>
<p>When the function is invoked, JVM "invokevirtual" instruction will be used, which is faster than the current implementation (var deref + IFn cast + invokinterface) and has less restrictions (no need to predefine interfaces to match the function parameters). The JVM is generally able to compile such invokevirtual instructions into extremely efficient code - effectively as fast as pure Java.</p>
<p>This is intended to pave the way to better support for statically compiled, high performance code. In particular, it allow:</p>
<ul class="alternate" type="square">
<li>Supporting arbitrary JVM primitives (float, int, byte, char etc.) as well as just double/long.</li>
<li>Supporting typed return values e.g. "String". This could eliminate many casts and type checks.</li>
<li>Supporting typed reference arguments (e.g. String).</li>
</ul>
<p>Suggested usage:</p>
<p>(defn ^:static foo ^int <span class="error">&#91;^String a ^String b&#93;</span><br/>
(+ (count a) (Integer/parseInt b)))</p>
<p>Existing code / semantics should not be affected</p>CLJ-1263Allow static compilation of function invocationsEnhancementMajorOpenUnresolvedUnassignedMike AndersoncompilerSat, 14 Sep 2013 23:31:10 -0500Thu, 7 Nov 2013 12:48:46 -060025<p>Very nice! That is what would really improve experience with certain tasks. I think it will also make possible to work with primitive arrays without the conversions?</p><p>Hi Alex - which aspect of "work with primitive arrays" are you referring to? This feature would certainly help with passing primitive arguments to/from functions that use primitive arrays. It would also potentially help avoid some casts of primitive array arguments themselves. I don't think it helps in any other way - perhaps a separate issue would be appropriate if there is another thing you are trying to do?</p><p>this issue is confusing, because there was/is a :static feature in clojure(which seems to be disabled in the compiler at the moment) and this proposal doesn't mention the existing work at all.</p>
<p>I also think this proposal is begging the question, there is no discussion of other possible solutions to the performance problem (whatever that is) that this is trying to solve.</p>
<p>the (var.deref()(IFn)).invoke(...) is pretty fundamental to the feel of clojure, in fact the existing :static keyword seems to be disabled in the compiler exactly because it complicates those semantics. so we should have a very clear proposal (not a wishlist) if we want to change that with some very clear wins.</p>
<p>maybe an optimizing clojure compiler would be a better approach.</p><p>Hi Kevin,</p>
<p>This is partly in response to this discussion on Clojure-Dev, where we discussed there are quite a lot of performance issues around the way that Clojure passes arguments currently:<br/>
<a href="https://groups.google.com/d/topic/clojure/H5P25eYKBj4/discussion">https://groups.google.com/d/topic/clojure/H5P25eYKBj4/discussion</a></p>
<p>Also I believe it reinstates the original intention of "^:static": I can't find where this is/was officially documented, but Arthur's answer in this SO question suggests that this was the case:<br/>
<a href="http://stackoverflow.com/questions/7552632/what-does-static-do-in-clojure">http://stackoverflow.com/questions/7552632/what-does-static-do-in-clojure</a></p>
<p>I think the proposal is relatively clear: it's probably the minimal change required to get static/direct (i.e. not via an indirect var reference / IFn) function invocations without affecting any of the semantics of current code.</p>
<p>This is sufficiently important for me that it's preventing me from shifting some performance-critical code to Clojure (even with primitive type hints). e.g. here's a simple case with a small primitive function:</p>
<p>(defn ^long foo <span class="error">&#91;^long x&#93;</span><br/>
(inc x))</p>
<p>(c/quick-bench (dotimes <span class="error">&#91;i 100&#93;</span> (foo i))) ;; c = criterium<br/>
=&gt; Execution time mean : 194.334293 ns</p>
<p>(c/quick-bench (dotimes <span class="error">&#91;i 100&#93;</span> (inc i)))<br/>
=&gt; Execution time mean : 71.539048 ns</p>
<p>i.e. the indirect function invocation is costing us nearly 170% overhead. In Java the equivalent functions perform identically: the overhead is zero because with static function invocation the JVM JIT is able to eliminate all the function call overhead.</p>
<p>In the long term, I agree that a proper optimising compiler would be the best way forward (perhaps Clojure 2.0/CinC can give us this?) but in the meantime I think this is a pragmatic way to improve performance with minimal impact on existing code. Even with an optimising compiler, I think we' would need some way to specifiy the "optimised" semantics rather than the indirect var deref behaviour, and "^:static" seems like a reasonable way to do so (unless anyone has a better idea?)</p>
<p>have you looked at the definition of int and how it uses :inline/definline to avoid the call overhead?</p><p>Good point Kevin - :inline and definline seem like a good approach in many cases (although it's marked as "experimental" - does that mean we can't rely on it to work in future releases?).</p>
<p>This proposal is still somewhat different: the inline solutions and its variants are effectively doing macro expansion to generate code without a function call on the Clojure side. The approach in this proposal would still emit a function call in bytecode, but do so in a way that the JVM can subsequently inline and optimise much more efficiently. Both have their uses, I think?</p>
<p>Commented edited Nov 7 2013 by Andy Fingerhut: Regarding definline marked as experimental, it has been so marked since Clojure 1.0's release, and the plan is to keep it marked that way in the pending Clojure 1.6 release. See discussion thread on <a href="http://dev.clojure.org/jira/browse/CLJ-1281" title="Clojure 1.6 - reconsider what is &quot;alpha&quot; in core"><del>CLJ-1281</del></a>. No plans to remove it that I am aware of.</p><p>my point is your benchmark above is not a comparison of clojure's current deref + cast + invoke vs. invokevirtual, inc is being inlined in to a static method call there</p><p>I've been noodling around this, and it is entirely possible to generate and invoke code in clojure right now without paying the extra deref() cost:</p>
<div class="preformatted panel" style="border-width: 1px;"><div class="preformattedContent panelContent">
<pre> (defn ^long fib [^long n]
(case n
0 0
1 1
(+ (fib (dec n))
(fib (dec (dec n))))))
</pre>
</div></div>
<p>can be written as </p>
<div class="preformatted panel" style="border-width: 1px;"><div class="preformattedContent panelContent">
<pre>(declare TheR1798)
(definterface I1797
(^long fib_Invoke_1 [^long n]))
(deftype R1798 []
I1797
(^long fib_Invoke_1
[this1799 ^long n]
(case n
0 0
1 1
(+ (.fib_Invoke_1 this1799 (dec n))
(.fib_Invoke_1 this1799 (dec (dec n)))))))
(def TheR1798 (new R1798))
(defn ^long fib [^long n]
(.fib_Invoke_1 TheR1798 n)))
</pre>
</div></div>
<p>now the recursive calls are invokeinterfaces, and the resulting function seems to have mean execution time about 5 times smaller using criterium to bench mark</p>
<p>it is entirely possible to write a macro that translates one in to other, and the weird names in the above are because I have a little proof of concept that does that.</p>
<p>the body of the bytecode for the regular fib function first shown looks something like:</p>
<div class="preformatted panel" style="border-width: 1px;"><div class="preformattedContent panelContent">
<pre> public final java.lang.Object invokePrim(long);
Code:
0: lload_1
1: lstore_3
2: lload_3
3: l2i
4: tableswitch { // 0 to 1
0: 28
1: 40
default: 52
}
28: lconst_0
29: lload_3
30: lcmp
31: ifne 52
34: getstatic #33 // Field const__1:Ljava/lang/Object;
37: goto 94
40: lconst_1
41: lload_3
42: lcmp
43: ifne 52
46: getstatic #37 // Field const__3:Ljava/lang/Object;
49: goto 94
52: getstatic #57 // Field const__5:Lclojure/lang/Var;
55: invokevirtual #70 // Method clojure/lang/Var.getRawRoot:()Ljava/lang/Object;
58: checkcast #6 // class clojure/lang/IFn$LO
61: lload_1
62: invokestatic #75 // Method clojure/lang/Numbers.dec:(J)J
65: invokeinterface #77, 3 // InterfaceMethod clojure/lang/IFn$LO.invokePrim:(J)Ljava/lang/Object;
70: getstatic #57 // Field const__5:Lclojure/lang/Var;
73: invokevirtual #70 // Method clojure/lang/Var.getRawRoot:()Ljava/lang/Object;
76: checkcast #6 // class clojure/lang/IFn$LO
79: lload_1
80: invokestatic #75 // Method clojure/lang/Numbers.dec:(J)J
83: invokestatic #75 // Method clojure/lang/Numbers.dec:(J)J
86: invokeinterface #77, 3 // InterfaceMethod clojure/lang/IFn$LO.invokePrim:(J)Ljava/lang/Object;
91: invokestatic #81 // Method clojure/lang/Numbers.add:(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Number;
94: areturn
LineNumberTable:
line 243: 0
line 244: 2
line 247: 52
line 247: 52
line 247: 61
line 248: 70
line 248: 79
line 248: 79
LocalVariableTable:
Start Length Slot Name Signature
2 92 3 G__301 J
0 94 0 this Ljava/lang/Object;
0 94 1 n J
public java.lang.Object invoke(java.lang.Object);
Code:
0: aload_0
1: aload_1
2: checkcast #89 // class java/lang/Number
5: invokestatic #93 // Method clojure/lang/RT.longCast:(Ljava/lang/Object;)J
8: invokeinterface #77, 3 // InterfaceMethod clojure/lang/IFn$LO.invokePrim:(J)Ljava/lang/Object;
13: areturn
</pre>
</div></div>
<p>the body of the "optimized" version looks like:</p>
<div class="preformatted panel" style="border-width: 1px;"><div class="preformattedContent panelContent">
<pre> public long fib_Invoke_1(long);
Code:
0: lload_1
1: lstore_3
2: lload_3
3: l2i
4: tableswitch { // 0 to 1
0: 28
1: 38
default: 48
}
28: lconst_0
29: lload_3
30: lcmp
31: ifne 48
34: lconst_0
35: goto 80
38: lconst_1
39: lload_3
40: lcmp
41: ifne 48
44: lconst_1
45: goto 80
48: aload_0
49: checkcast #6 // class com/thelastcitadel/kernel/I2364
52: lload_1
53: invokestatic #53 // Method clojure/lang/Numbers.dec:(J)J
56: invokeinterface #55, 3 // InterfaceMethod com/thelastcitadel/kernel/I2364.fib_Invoke_1:(J)J
61: aload_0
62: checkcast #6 // class com/thelastcitadel/kernel/I2364
65: lload_1
66: invokestatic #53 // Method clojure/lang/Numbers.dec:(J)J
69: invokestatic #53 // Method clojure/lang/Numbers.dec:(J)J
72: invokeinterface #55, 3 // InterfaceMethod com/thelastcitadel/kernel/I2364.fib_Invoke_1:(J)J
77: invokestatic #59 // Method clojure/lang/Numbers.add:(JJ)J
80: lreturn
LineNumberTable:
line 251: 0
line 251: 2
line 251: 48
line 251: 48
line 251: 52
line 251: 61
line 251: 65
line 251: 65
LocalVariableTable:
Start Length Slot Name Signature
2 78 3 G__2363 J
0 80 0 this Lcom/thelastcitadel/kernel/R2365;
0 80 1 n J
</pre>
</div></div>
<p>so the calls are not invokevirtual (due to the way clojure compiles stuff, you cannot type anything inside a record as being that record's type), but the interface is unique and only has one instance, so I think the jvm's class hierarchy analysis makes short work of that.</p>
<p>if I have time I may try and complete my macro and release it as a library, but given tools.analyzer.jvm someone should be able to do better than my little proof of concept very quickly.</p><p>I don't know if my editing of Mike Anderson's Nov 5 2013 comment is notified to people watching this ticket, so adding a new comment so those interested in definline's experimental status can know to go back and re-read it.</p>Global Rank[CLJ-1257] Suppress warnings when clojure.core symbols are explicitly replaced with "use" or "refer"http://dev.clojure.org/jira/browse/CLJ-1257
Clojure<p>Problem: Libraries that provide DSLs (such as core.matrix) often replace or extend functions in core (such as "+", "==", "zero?"), since it is desirable to use the best / most idiomatic names.</p>
<p>Currently importing such libraries with "use" causes unwanted warnings like "WARNING: + already refers to: #'clojure.core/+ in namespace: test.blank, being replaced by: #'clojure.core.matrix/+". </p>
<p>Avoiding these warnings requires extra user effort and boilerplate code, which is frustrating for users since they have already explicitly asked for the full library to be imported into the current namespace (i.e. via "use" or ":refer :all").</p>
<p>Proposed solution is to introduce a new var <b>warn-on-replace</b> similar to <b>warn-on-reflection</b> which allows this warning to be controlled.</p>CLJ-1257Suppress warnings when clojure.core symbols are explicitly replaced with "use" or "refer"EnhancementMinorOpenUnresolvedUnassignedMike AndersonnamespaceFri, 6 Sep 2013 22:33:49 -0500Fri, 29 Aug 2014 19:00:41 -0500Release 1.501<p>Basic patch and test attached.</p><p>I have no idea whether this idea will be vetted or not, but if it is, I have some comments on the proposed patch.</p>
<p>The new symbol warn-on-replace should have doc and metadata on it. See add-doc-and-meta for warn-on-reflection in core.clj for an example to copy and edit.</p>
<p>You check WARN_ON_REFLECTION before issuing the warning in Namespace.java, instead of WARN_ON_REPLACE.</p>
<p>Possible typo in the test description in ns_libs.clj: Maybe "symbol in clojure.core" instead of "symbol is clojure.core"?</p>
<p>If someone <b>wants</b> warnings from :use statements in ns forms, it seems the only way to do that with patch clj-1257.diff would be to do (set! <b>warn-on-replace</b> true) in a file <b>before</b> the ns form. That would not work well with the current version of tools.namespace, which assumes that if there is an ns form, it is the first form in the file. One can argue that tools.namespace should not make such an assumption, but it does right now.</p>
<p>Perhaps there should be a command line option clojure.compile.warn-on-replace like there is for clojure.compile.warn-on-reflection (search for warn-on-replace in Compile.java)?</p><p>Thanks Andy for the feedback! I'll post an updated patch shortly.</p>
<p>It occurs to me that we should probably implement a more general approach to warnings in Clojure. Adding new vars and command line options for each warning doesn't seem like a good long-term strategy. I think that's beyond the scope of this patch though. <img class="emoticon" src="http://dev.clojure.org/jira/images/icons/emoticons/smile.gif" height="20" width="20" align="absmiddle" alt="" border="0"/></p><p>Actually, there is something called compiler-options (search for the variations compiler-options, COMPILER_OPTIONS, and compiler_options for all related occurrences) that is a map where each key/value pair is a different option. That might be preferable for warn-on-replace, if it is in fact desired.</p><p>Updated patch attached. </p>
<p>Compiler-options looks like it may indeed be a better place for this, if that is the preferred strategy for controlling warnings. But I'll wait for more feedback / confirmation on the approach before making that change.</p><p>Is (:refer-clojure :exclude <span class="error">&#91;+ = zero?&#93;</span>) a valid workaround? Or are you really concerned with the consumers of the library?</p><p>I'm mainly concerned with consumers of the library. </p>
<p>So while (:refer-clojure :exclude <span class="error">&#91;+ = zero?&#93;</span>) is possible as a temporary workaround, it's very inconvenient for users. We should really fix this in Clojure itself. Users have enough trouble with ns forms already without adding to their woes <img class="emoticon" src="http://dev.clojure.org/jira/images/icons/emoticons/smile.gif" height="20" width="20" align="absmiddle" alt="" border="0"/></p>
<p>As an alternative solution: I personally wouldn't mind it if the library author could add some metadata to symbols (e.g. "^:replace-symbol") to signal that a library function is intended to replace something in core. That's a slightly different approach (and I think a bit trickier to implement) but it should also work.</p><p>Example issue reported by a user because of this:</p>
<p><a href="https://github.com/mikera/vectorz-clj/issues/23">https://github.com/mikera/vectorz-clj/issues/23</a></p><p>As before, I can't comment on whether there is interest in this ticket or these patches, but I can say that all patches dated Sep 7 2013 and earlier no longer applied cleanly to latest master after some commits were made to Clojure on Aug 29, 2014. They did apply cleanly before that day.</p>
<p>I have not checked how easy or difficult it might be to update this patch.</p><p>I'm happy to update the patch, just need feedback on which approach / solution to this problem is preferred.</p>
<p>I'd really like to see this in 1.7!</p>Global RankPatchCode[CLJ-1256] Support type-hinted overrides of function parametershttp://dev.clojure.org/jira/browse/CLJ-1256
Clojure<p>Problem: in many cases, the Clojure compiler has enough information about the type of a function argument to statically emit maximally efficient code on the JVM (i.e. without instance? checks, type casts or other forms of dynamic polymorphic dispatch). We are currently unable to do so in Clojure, which pushes developers with strong performance requirements to use some unidiomatic or convoluted workarounds.</p>
<p>Proposal is simply to allow functions to take type-hinted overloads of function arguments, e.g.</p>
<p>(defn foo<br/>
(<span class="error">&#91;^double x&#93;</span> (Math/floor x))<br/>
(<span class="error">&#91;^float x&#93;</span> (Math/floor (double x)))<br/>
(<span class="error">&#91;^String s&#93;</span> (count s)))</p>
<p>An "Object" version of the code with the correct arity will always be emitted, which will maintain compatibility with the IFn interface and ensure that the function can still be used in dynamic / interactive contexts. If the "Object" version is not explicitly provided, then it will be generated to use instance? checks that subsequently delegate to the appropriate typed version of the function (or throw an InvalidArgumentException if no match is found).</p>
<p>Matching rules would be the same as Java.</p>
<p>This will be backwards compatible with all existing uses of defn. In particular, it should extend / enhance / supercede the existing handling of primitive functions.</p>
<p>In the future, this technique might be used alongside core.typed to ensure that the most efficient function version is chosen based on type inference.</p>CLJ-1256Support type-hinted overrides of function parametersEnhancementMajorOpenUnresolvedUnassignedMike AndersoncompilerinteroptypehintsFri, 6 Sep 2013 21:37:59 -0500Mon, 9 Sep 2013 13:44:02 -050022Global Rank[CLJ-1243] Cannot resolve public generic method from package-private base classhttp://dev.clojure.org/jira/browse/CLJ-1243
Clojure<p>The Clojure compiler cannot resolve a public generic method inherited from a package-private base class.</p>
<p>Instructions to reproduce:</p>
<ul>
<li>In package P1
<ul>
<li>Define a package-private class A with generic type parameters</li>
<li>Define a public method M in A using generic types in either its arguments or return value</li>
<li>Define a public class B which extends A</li>
</ul>
</li>
<li>In package P2
<ul>
<li>Construct an instance of B</li>
<li>Invoke B.M()</li>
</ul>
</li>
</ul>
<p>This is valid in Java. In Clojure, invoking B.M produces a reflection warning, followed by the error "java.lang.IllegalArgumentException: Can't call public method of non-public class." No amount of type-hinting prevents the warning or the error.</p>
<p>Attachment clj-1243-demo1.tar.gz contains sample code and script to demonstrate the problem.</p>
<p>Examples of Java projects which use public methods in package-private classes:</p>
<ul>
<li><a href="http://netty.io/">Netty</a> 4
<ul>
<li>See <a href="https://github.com/netty/netty/blob/ca0018279754557576bb2ecc17d209c2b6874609/transport/src/main/java/io/netty/bootstrap/AbstractBootstrap.java#L152">AbstractBootstrap.java</a> and <a href="https://github.com/netty/netty/issues/1780">issue #1780</a> and Clojure ticket <a href="http://dev.clojure.org/jira/browse/CLJ-1183" title="java interop - cannot call a final method on non-public superclass "><del>CLJ-1183</del></a></li>
</ul>
</li>
<li><a href="https://github.com/jfager/functional-critbit">jfager/functional-critbit</a>
<ul>
<li>See <a href="https://github.com/jfager/functional-critbit/blob/abb927d7e93ad21eaf75da339c27220f2cfdc222/src/main/java/io/prelink/critbit/AbstractCritBitTree.java#L305">AbstractCritBitTree.java</a></li>
<li>Example: <tt>(.get (io.prelink.critbit.CritBitTree. (org.ardverk.collection.DefaultKeyAnalyzer.)) nil)</tt></li>
</ul>
</li>
</ul>
CLJ-1243Cannot resolve public generic method from package-private base classDefectMinorOpenUnresolvedUnassignedStuart SierrainteropThu, 1 Aug 2013 13:34:21 -0500Sat, 21 Feb 2015 09:28:30 -0600Release 1.3Release 1.4Release 1.511<p>It is also not possible to call the method reflectively from <b>Java</b>.</p>
<p>This may be a bug in Java reflection: <a href="http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4283544">JDK-4283544</a></p>
<p>But <b>why</b> does it only happen on generic methods?</p><p>According to Rich Hickey, the presence of bridge methods is unspecified and inconsistent across JDK versions.</p>
<p>A possible solution is to use ASM to examine the bytecode of third-party Java classes, instead of the reflection API. That way the Clojure compiler would have access to the same information as the Java compiler.</p><p><a href="http://dev.clojure.org/jira/browse/CLJ-1183" title="java interop - cannot call a final method on non-public superclass "><del>CLJ-1183</del></a> was closed as a duplicate of this one. Mentioning it here in case anyone working on this ticket wants to follow the link to it and read discussion or test cases described there.</p><p>The current work around I use is to define a new Java class, add a static method that does what I need, and call that from Clojure.</p><p>Also, I'm seeing this issue in 1.6 and 1.7(alpha5) but the issue mentions only up to 1.5 .</p>Global Rank[CLJ-1242] get/= on sorted collections when types don't match result in a ClassCastExceptionhttp://dev.clojure.org/jira/browse/CLJ-1242
Clojure<p>user=&gt; (= (sorted-set 1) #{:a})<br/>
ClassCastException java.lang.Long cannot be cast to clojure.lang.Keyword clojure.lang.Keyword.compareTo (Keyword.java:109)</p>
<p>but</p>
<p>user=&gt; (= (sorted-set 1) :a)<br/>
false</p>
<p>also</p>
<p>user=&gt; (get (sorted-set 1) :a 2)<br/>
ClassCastException java.lang.Long cannot be cast to clojure.lang.Keyword clojure.lang.Keyword.compareTo (Keyword.java:109)</p>CLJ-1242get/= on sorted collections when types don't match result in a ClassCastExceptionDefectMinorOpenUnresolvedUnassignedNicola MomettoWed, 31 Jul 2013 07:33:31 -0500Wed, 31 Jul 2013 20:26:21 -0500Release 1.5Release 1.622<p>PersistentVector also has the same problem.</p>
<p>user=&gt; (compare <span class="error">&#91;1&#93;</span> <span class="error">&#91;:a&#93;</span>)<br/>
java.lang.ClassCastException: clojure.lang.Keyword cannot be cast to java.lang.Number</p>
<p>The cause of this problem is that Util.compare() casts the second argument <br/>
to Number without checking its type when the first argument is a Number.</p><p>Umm, my brain was not working right.<br/>
Util.compare() should raise an Exception when the arguments' type are different.</p>Global RankPatchCode and Test[CLJ-1240] Clarify limits of clojure.walk/macroexpand-all in docstringhttp://dev.clojure.org/jira/browse/CLJ-1240
Clojure<p>The <tt>clojure.walk/macroexpand-all</tt> function appears to be a general recursive macroexpansion, but it is not because it doesn't understand special forms such as <tt>let</tt>.</p>
<p><b>Current patch:</b> 0001-<a href="http://dev.clojure.org/jira/browse/CLJ-1240" title="Clarify limits of clojure.walk/macroexpand-all in docstring">CLJ-1240</a>-Note-limits-of-clojure.walk-macroexpand-all.patch</p>
<p>The modified docstring in this patch notes that <tt>clojure.walk/macroexpand-all</tt> is not identical to macroexpansion by the Clojure compiler and should be used for development only.</p>CLJ-1240Clarify limits of clojure.walk/macroexpand-all in docstringEnhancementTrivialOpenUnresolvedStuart SierraStuart SierrawalkMon, 29 Jul 2013 14:16:08 -0500Tue, 3 Sep 2013 09:58:13 -050000Global RankPatchCode[CLJ-1239] faster, more flexible dispatch for clojure.walkhttp://dev.clojure.org/jira/browse/CLJ-1239
Clojure<p>The conditional dispatch in clojure.walk is slow and not open to extension. Prior to <a href="http://dev.clojure.org/jira/browse/CLJ-1105" title="clojure.walk should support records"><del>CLJ-1105</del></a> it did not support records.</p>
<p><b>Approach:</b> Reimplement clojure.walk using protocols. The public API does not change. Users can extend the <tt>walk</tt> protocol to other types (for example, Java collections) if desired. As in <a href="http://dev.clojure.org/jira/browse/CLJ-1105" title="clojure.walk should support records"><del>CLJ-1105</del></a>, this version of clojure.walk supports records.</p>
<p><b>Patch:</b> 0002-<a href="http://dev.clojure.org/jira/browse/CLJ-1239" title="faster, more flexible dispatch for clojure.walk">CLJ-1239</a>-protocol-dispatch-for-clojure.walk.patch</p>
<p><b>Performance:</b> My tests indicate this is 1.5x-2x the speed of the original clojure.walk. See <a href="https://github.com/stuartsierra/clojure.walk2">https://github.com/stuartsierra/clojure.walk2</a> for benchmarks.</p>
<p><b>Risks:</b> This approach carries some risk of breaking user code that relied on type-specific behavior of the old clojure.walk. When running the full Clojure test suite, I discovered (and fixed) some breakages that did not show up in clojure.walk's unit tests. See, for example, <a href="https://github.com/stuartsierra/clojure.walk2/commit/730eb756dcc424aa535d0872bd626079955c3892">commit 730eb75 in clojure.walk2</a></p>CLJ-1239faster, more flexible dispatch for clojure.walkEnhancementMinorOpenUnresolvedStuart SierraStuart SierrawalkMon, 29 Jul 2013 13:35:08 -0500Thu, 27 Feb 2014 17:17:18 -060064<p>It looks, as it is now, that walking the tree and replacing forms doesn't preserve original meta-data contained in data structures.</p><p>Patch 0001-<a href="http://dev.clojure.org/jira/browse/CLJ-1239" title="faster, more flexible dispatch for clojure.walk">CLJ-1239</a>-protocol-dispatch-for-clojure.walk.patch no longer applies cleanly to latest Clojure master since the patch for <a href="http://dev.clojure.org/jira/browse/CLJ-1105" title="clojure.walk should support records"><del>CLJ-1105</del></a> was committed on Nov 22, 2013. From the description, it appears the intent was either that patch or this one, not both, so I am not sure what should happen with this patch, or even this ticket.</p><p>This patch and ticket are still candidates for future release.</p><p>Added new patch that applies on latest master after <a href="http://dev.clojure.org/jira/browse/CLJ-1105" title="clojure.walk should support records"><del>CLJ-1105</del></a>.</p><p>The way this patch behaves can be surprising compared to regular maps:</p>
<div class="preformatted panel" style="border-width: 1px;"><div class="preformattedContent panelContent">
<pre>(clojure.walk/prewalk-replace {[:a 1] nil} {:a 1, :b 2})
;=&gt; {:b 2}
(defrecord Foo [a b])
(clojure.walk/prewalk-replace {[:a 1] nil} (map-&gt;Foo {:a 1, :b 2}))
;=&gt; #user.Foo{:a 1, :b 2}
</pre>
</div></div>
<p>Note how the <tt><span class="error">&#91;:a 1&#93;</span></tt> entry is removed from the map, but not from the record.</p>
<p>Here's an implementation that doesn't suffer from that problem, though it does scary class name munging instead: <a href="https://github.com/LonoCloud/synthread/blob/a315f861e04fd33ba5398adf6b5e75579d18ce4c/src/lonocloud/synthread/impl.clj#L66">https://github.com/LonoCloud/synthread/blob/a315f861e04fd33ba5398adf6b5e75579d18ce4c/src/lonocloud/synthread/impl.clj#L66</a> </p>
<p>Perhaps we could add to the defrecord abstraction to support well the kind of things that synthread code is doing clumsily, and then <tt>walk</tt> could take advantage of that.</p><p>@Chouser, can you file a new ticket related to this? It's hard to manage work on something from comments on a closed ticket.</p><p>@Chouser - Never mind! I was thinking this was the change that went into 1.6. Carry on. <img class="emoticon" src="http://dev.clojure.org/jira/images/icons/emoticons/smile.gif" height="20" width="20" align="absmiddle" alt="" border="0"/></p><p>Alex, for what it matters clojure-1.6.0 after <a href="http://dev.clojure.org/jira/browse/CLJ-1105" title="clojure.walk should support records"><del>CLJ-1105</del></a> exibits the same behaviour as described by Chouser for this patch</p>Global RankPatchCode[CLJ-1237] reduce gives a SO for pathological seqshttp://dev.clojure.org/jira/browse/CLJ-1237
Clojure<p><tt>reduce</tt> gives a <tt>StackOverflowError</tt> on long sequences that contain many transitions between chunked and unchunked:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">(-&gt;&gt; (repeat 50000 (cons :x [:y]))
(apply concat)
(reduce (constantly nil)))
;; <span class="code-keyword">throws</span> StackOverflowError</pre>
</div></div>
<p>Such a sequence is well behaved under most other sequence operations, and its underlying structure can even be masked such that <tt>reduce</tt> succeeds:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">(-&gt;&gt; (repeat 50000 (cons :x [:y]))
(apply concat)
(take 10000000)
(reduce (constantly nil)))
;; =&gt; nil</pre>
</div></div>
<p>I don't think Clojure developers normally worry about mixing chunked and unchunked seqs, so the existence of such a sequence is not at all unreasonable (and indeed this happened to me at work and was very difficult to debug).</p>
<p>It seems obvious what causes this given the implementation of reduce &#8211; it bounces back and forth between the chunked impl and the unchunked impl, consuming more and more stack as it goes. Without proper tail call optimization, it's not obvious to me what a good fix would be.</p>
<h2><a name="Presumedbadsolutions"></a>Presumed bad solutions</h2>
<h3><a name="Degradetonaiveimplafterfirstchunk"></a>Degrade to naive impl after first chunk</h3>
<p>In the <tt>IChunkedSeq</tt> implementation, instead of calling <tt>internal-reduce</tt> when the<br/>
sequence stops being chunked, it could have an (inlined?) unoptimized implementation,<br/>
ensuring that no further stack space is taken up. This retains the behavior that a<br/>
generic seq with a chunked tail will still run in an optimized fashion, but a seq with<br/>
two chunked portions would only be optimized the first time.</p>
<h3><a name="Useclojure.core%2Ftrampoline"></a>Use clojure.core/trampoline</h3>
<p>This would presumably work, but requires wrapping the normal return values from all<br/>
implementations of <tt>internal-reduce</tt>.</p>
<h2><a name="ProposedSolution"></a>Proposed Solution</h2>
<p>(attached as <a href="http://dev.clojure.org/jira/browse/CLJ-1237" title="reduce gives a SO for pathological seqs">CLJ-1237</a>c.patch)</p>
<p>Similar to using <tt>trampoline</tt>, but create a special type (<tt>Unreduced</tt>) that signals<br/>
an implementation change. The two implementation-change points in <tt>internal-reduce</tt><br/>
(in the <tt>IChunkedSeq</tt> impl and the <tt>Object</tt> impl) are converted to return an instance<br/>
of <tt>Unreduced</tt> instead of a direct call to <tt>internal-reduce</tt>.</p>
<p>Then <tt>seq-reduce</tt> is converted to check for instances of <tt>Unreduced</tt> before returning,<br/>
and recurs if it finds one.</p>
<h3><a name="Pros"></a>Pros</h3>
<ul class="alternate" type="square">
<li>Only requires one additional check in most cases</li>
<li>Reduces stack usage for existing heterogeneous reductions that weren't extreme enough to crash</li>
<li>Should be compatible with 3rd-party implementations of <tt>internal-reduce</tt>, which can still use the old style (direct recursive calls to <tt>internal-reduce</tt>) or the optimized style if desired.</li>
</ul>
<h3><a name="Cons"></a>Cons</h3>
<ul class="alternate" type="square">
<li><tt>internal-reduce</tt> is slightly more complicated</li>
<li>There's an extra check at the end of <tt>seq-reduce</tt> &#8211; is that a performance worry?</li>
</ul>
1.5.1CLJ-1237reduce gives a SO for pathological seqsDefectMajorOpenUnresolvedUnassignedGary FredericksSat, 27 Jul 2013 17:31:21 -0500Sun, 25 Aug 2013 16:39:06 -0500Release 1.524<p>Added patch.</p>Global RankPatchCode and Test[CLJ-1231] fn and letfn don't support hinting the function's return typehttp://dev.clojure.org/jira/browse/CLJ-1231
Clojure<p>You can add type hints to the argument vector(s) of `defn` to declare the return type of a function like so (with <b>warn-on-reflection</b> being true):</p>
<div class="preformatted panel" style="border-width: 1px;"><div class="preformattedContent panelContent">
<pre>user&gt; (defn foo ^String [s] s)
#'user/foo
user&gt; (.substring (foo "hallo") 1 2)
"a"
</pre>
</div></div>
<p>But sadly, the same doesn't work with `fn` and `letfn`:</p>
<div class="preformatted panel" style="border-width: 1px;"><div class="preformattedContent panelContent">
<pre>user&gt; (.substring ((fn ^String [s] s) "hallo") 1 2)
Reflection warning, NO_SOURCE_PATH:1:1 - call to substring can't be resolved.
"a"
user&gt; (letfn [(foo ^String [s] s)]
(.substring (foo "hallo") 1 2))
Reflection warning, NO_SOURCE_PATH:2:7 - call to substring can't be resolved.
"a"
</pre>
</div></div>
<p>I don't see why this feature is available to `defn` but not to `fn` and `letfn`. I even consider it a kind of defect, because anything else including :pre/:post are also supported by the latter two, so the support for hinting the return type should be there simply because of analogy.</p>CLJ-1231fn and letfn don't support hinting the function's return typeDefectMinorOpenUnresolvedUnassignedTassilo HorntypehintsWed, 17 Jul 2013 07:04:13 -0500Tue, 3 Sep 2013 08:43:07 -0500Release 1.510Global Rank[CLJ-1230] print-table displays tables incorrectly when one of the cells is a string that has newlineshttp://dev.clojure.org/jira/browse/CLJ-1230
Clojure<p>When using print-table to print an ASCII table to stdout, the table display breaks if any of the values is a string with any new lines in it. For example:</p>
<div class="preformatted panel" style="border-width: 1px;"><div class="preformattedContent panelContent">
<pre>user=&gt; (print-table [{:a "test" :b "test\ntest2"}])
| :a | :b |
|------+------------|
| test | test
test2 |
nil
</pre>
</div></div>
<p>I would expect the output to look something like this:</p>
<div class="preformatted panel" style="border-width: 1px;"><div class="preformattedContent panelContent">
<pre>user=&gt; (print-table [{:a "test" :b "test\ntest2"}])
| :a | :b |
|------+------------|
| test | test +
| | test2 |
nil
</pre>
</div></div>
<p>The + symbol on the right border means that the row continues over multiple lines. This is similar to how the PostgreSQL psql tool displays table with multi-line rows:</p>
<div class="preformatted panel" style="border-width: 1px;"><div class="preformattedContent panelContent">
<pre>user=# select 'test' col1, E'test\ntest2\ntest3' col2;
col1 | col2
------+-------
test | test +
| test2+
| test3
(1 row)
Time: 0.776 ms
</pre>
</div></div>Mac OS X, Clojure 1.5.1
<br/>
CLJ-1230print-table displays tables incorrectly when one of the cells is a string that has newlinesEnhancementMinorOpenUnresolvedUnassignedBen BoothprintTue, 9 Jul 2013 14:02:29 -0500Fri, 31 Jan 2014 09:10:47 -0600Release 1.500<p>JIRA destroyed my formatting, and looks like I can't edit it to fix it. Here is what I meant to say:</p>
<p>When using print-table to print an ASCII table to stdout, the table display breaks if any of the values is a string with any new lines in it. For example:</p>
<div class="preformatted panel" style="border-width: 1px;"><div class="preformattedContent panelContent">
<pre>user=&gt; (print-table [{:a "test" :b "test\ntest2"}])
| :a | :b |
|------+------------|
| test | test
test2 |
</pre>
</div></div>
<p>I would expect the output to look something like this:</p>
<div class="preformatted panel" style="border-width: 1px;"><div class="preformattedContent panelContent">
<pre>user=&gt; (print-table [{:a "test" :b "test\ntest2"}])
| :a | :b |
|------+------------|
| test | test +
| | test2 |
</pre>
</div></div>
<p>The + symbol on the right border means that the row continues over multiple lines. This is similar to how the PostgreSQL psql tool displays table with multi-line rows:</p>
<div class="preformatted panel" style="border-width: 1px;"><div class="preformattedContent panelContent">
<pre>labtrack=# select 'test' col1, E'test\ntest2' col2;
col1 | col2
------+-------
test | test +
| test2
(1 row)
</pre>
</div></div><p>I have no direct knowledge of this, but my guess would be that the Clojure team would consider this an enhancement request rather than a defect.</p>
<p>You are likely to get what you want faster either by writing your own version of print-table that works as you wish, or see whether these projects already behave as desired, or the authors are willing to enhance them: <a href="https://github.com/cldwalker/table">https://github.com/cldwalker/table</a> or <a href="https://github.com/joegallo/doric">https://github.com/joegallo/doric</a></p>Global Rank[CLJ-1229] count silently overflows for sequences with more than Integer/MAX_VALUE elementshttp://dev.clojure.org/jira/browse/CLJ-1229
Clojure<p>Found by John Jacobsen: <a href="https://mail.google.com/mail/?shva=1#label/clojure/13fbba0c3e4ba6b7">https://mail.google.com/mail/?shva=1#label/clojure/13fbba0c3e4ba6b7</a></p>
<p>user&gt; (time (count (range (*' 1000 1000 1000 3))))<br/>
"Elapsed time: 375225.663 msecs"<br/>
-1294967296</p>CLJ-1229count silently overflows for sequences with more than Integer/MAX_VALUE elementsDefectMinorOpenUnresolvedUnassignedAndy FingerhutmathTue, 9 Jul 2013 01:36:03 -0500Tue, 3 Sep 2013 08:44:25 -0500Release 1.512<p>Patch clj-1229-count-overflow-patch-v1.txt dated Jul 8 2013 modifies count to throw an ArithmeticException for sequences with more than Integer/MAX_VALUE elements.</p>
<p>Performance experiments with this expression show no significant time differences before and after the change. I verified with -XX:+PrintCompilation, and only paid attention to timing results after no further JIT compilation was performed when executing the expression:</p>
<p>(defn foo <span class="error">&#91;n m&#93;</span> (doall (for <span class="error">&#91;i (range n)&#93;</span> (count (range m)))))<br/>
(time (foo 100 1000000))</p>
<p>No tests are added. A test verifying that an exception is thrown for such a long sequence would be prohibitively slow.</p><p>I think a better strategy might be to convert all count-like functions from int to long. int overflow exceptions aren't a particularly nice result, especially since they probably won't get picked up in tests for the reasons Andy mentioned.</p>
<p>That buys us a quite a few years more future proofing...</p><p>Mike, unless I am missing something, that would require changing the method count() in the Counted interface to return a long, and that in turn requires little changes throughout the code base wherever Counted is used. It could be done, of course, but it is not a small change.</p><p>I agree that Mike's approach is nicer overall, but think Andy's patch is an immediate improvement over what we have now, and could be implemented until someone takes the time to correctly make all the detailed changes Mike is suggesting.</p><p>FWIW I did apply the patch, build, and test manually:</p>
<p>user=&gt; (count (range (* 1000 1000 1000 3))) <br/>
ArithmeticException integer overflow clojure.lang.RT.countFrom (RT.java:549)<br/>
user=&gt; </p>
<p>Perhaps of interest, Java's Collection.size() returns Integer.MAX_VALUE if the size of the collection &gt; MAX_VALUE. I can't say that either that behavior or overflow is particularly helpful in practice of course. <img class="emoticon" src="http://dev.clojure.org/jira/images/icons/emoticons/smile.gif" height="20" width="20" align="absmiddle" alt="" border="0"/></p>Global RankPatchCode[CLJ-1226] set! of a deftype field using field-access syntax causes ClassCastExceptionhttp://dev.clojure.org/jira/browse/CLJ-1226
Clojure<p>Clojure 1.6.0-master-SNAPSHOT</p>
<p>user=&gt; (defprotocol p (f <span class="error">&#91;_&#93;</span>))<br/>
p<br/>
user=&gt; (deftype t <span class="error">&#91;^:unsynchronized-mutable x&#93;</span> p (f <span class="error">&#91;_&#93;</span> (set! (.x _) 1)))<br/>
user.t<br/>
user=&gt; (f (t. 1))<br/>
ClassCastException user.t cannot be cast to compile__stub.user.t user.t (NO_SOURCE_FILE:1</p>
<p>After patch:<br/>
Clojure 1.6.0-master-SNAPSHOT<br/>
user=&gt; (defprotocol p (f <span class="error">&#91;_&#93;</span>))<br/>
p<br/>
user=&gt; (deftype t <span class="error">&#91;^:unsynchronized-mutable x&#93;</span> p (f <span class="error">&#91;_&#93;</span> (set! (.x _) 1)))<br/>
user.t<br/>
user=&gt; (f (t. 1))<br/>
1</p>CLJ-1226set! of a deftype field using field-access syntax causes ClassCastExceptionDefectMajorOpenUnresolvedUnassignedNicola MomettocompilerdeftypeinteropWed, 26 Jun 2013 19:21:01 -0500Sun, 31 Aug 2014 10:36:53 -0500Release 1.700<p>This patch offers a better workaround for <a href="http://dev.clojure.org/jira/browse/CLJ-1075" title="deftype: compiler error on set! for mutable field"><del>CLJ-1075</del></a>, making it possible to write<br/>
(deftype foo <span class="error">&#91;^:unsynchronized-mutable x&#93;</span> MutableX (set-x <span class="error">&#91;this v&#93;</span> (try (set! (.x this) v)) v))</p>Global RankPatchCode and Test[CLJ-1223] Improve App Engine Support by Providing an Option to Use the App Engine ThreadMangerhttp://dev.clojure.org/jira/browse/CLJ-1223
Clojure<p>Clojure support for App Engine can be improved now that App Engine supports sockets and threads.</p>
<p>Sockets<br/>
<a href="https://developers.google.com/appengine/docs/java/sockets/overview">https://developers.google.com/appengine/docs/java/sockets/overview</a></p>
<p>Threads<br/>
<a href="https://developers.google.com/appengine/docs/java/javadoc/com/google/appengine/api/ThreadManager">https://developers.google.com/appengine/docs/java/javadoc/com/google/appengine/api/ThreadManager</a></p>
<p>The new sockets API uses java.net.Socket so it should just work without much/any modification to core. The Sockets API is an important addition because it enables you to connect to Compute Engine servers from App Engine without having to use the HTTP client.</p>
<p>Presently Clojure's agents and futures do not work on App Engine, but the new ThreadManager API now allows you to execute short-lived threads; however, you must use the ThreadManger API to create threads &#8211; "you cannot invoke new Thread() yourself or use the default thread factory" and "each request is limited to 50 concurrent request threads" &#8211; so adding support for threads will require a build option and some modifications. </p>
<p>Supporting agents on App Engine could be done by adding a Clojure build option for App Engine that includes the App Engine JDK dependency and injects the App Engine TreadManager factory into jvm/clojure/lang/Agent.java .</p>
<p>Google App Engine SDK for Java<br/>
<a href="https://developers.google.com/appengine/downloads#Google_App_Engine_SDK_for_Java">https://developers.google.com/appengine/downloads#Google_App_Engine_SDK_for_Java</a></p>
<p>See also <a href="https://developers.google.com/appengine/docs/java/runtime#The_Sandbox">https://developers.google.com/appengine/docs/java/runtime#The_Sandbox</a> ...</p>
<p>A Java application can create a new thread, but there are some restrictions on how to do it. These threads can't "outlive" the request that creates them. (On a backend server, an application can spawn a background thread, a thread that can "outlive" the request that creates it.)</p>
<p>An application can...</p>
<p>Implement java.lang.Runnable; and<br/>
Create a thread factory by calling com.google.appengine.api.ThreadManager.currentRequestThreadFactory()<br/>
call the factory's newRequestThread method, passing in the Runnable, newRequestThread(runnable)<br/>
or use the factory object returned by com.google.appengine.api.ThreadManager.currentRequestThreadFactory() with an ExecutorService (e.g., callExecutors.newCachedThreadPool(factory)).</p>
<p>However, you must use one of the methods on ThreadManager to create your threads. You cannot invoke new Thread() yourself or use the default thread factory.</p>
<p>An application can perform operations against the current thread, such as thread.interrupt().</p>
<p>Each request is limited to 50 concurrent request threads.</p>
<p>App Engine JRE Whitelist:<br/>
<a href="https://developers.google.com/appengine/docs/java/jrewhitelist">https://developers.google.com/appengine/docs/java/jrewhitelist</a></p>
<p>From the current App Engine Magic README (<a href="https://github.com/gcv/appengine-magic">https://github.com/gcv/appengine-magic</a>)...</p>
<p>"Google App Engine maintains a whitelist of permitted classes in Java's standard library. Other classes will cause your application to fail to deploy. Examples include threads and sockets. If you use those in your application, it will not work. This means that you cannot use Clojure's agents or futures. In addition, if one of your dependencies uses those, your application will also not work. For example, clojure.java.io (and its fore-runner, duck-streams from clojure-contrib), uses java.net.Socket, a forbidden class."</p>
Google App EngineCLJ-1223Improve App Engine Support by Providing an Option to Use the App Engine ThreadMangerEnhancementMinorOpenUnresolvedUnassignedJames ThorntonSat, 22 Jun 2013 22:44:55 -0500Tue, 3 Sep 2013 08:47:30 -0500Release 1.510Global Rank[CLJ-1221] Should repackage jsr166 and include known version with Clojurehttp://dev.clojure.org/jira/browse/CLJ-1221
Clojure<p>Clojure 1.5 reducers work with either the JDK version of forkjoin (JDK 1.7+) or with an external jsr166 jar. This causes complexity for users and complexity in the build to deal with the two options.</p>
<p>jsr166 code is public domain and it is common for other projects to repackage the handful of files and ship it with the project (similar to what we do with asm). This would allow us just use a known existing version of jsr166 across all jdks and we could get rid of the custom build wrangling we introduced in Clojure 1.5.</p>
<p>jsr166y is compatible with JDK 1.6+ and is the version that (for example) Scala currently repackages. That's the best choice for JDK 1.6 and 1.7. In JDK 1.8, the best choice will (temporarily) be the built-in version in java.util.concurrent which tracks jsr166e but then as soon as there are updates will become jsr166e. Many fork/join fixes are ported to both y and e right now.</p>
<p>Some choices here for JDK 1.8:</p>
<ul class="alternate" type="square">
<li>go for maximal compatibility just use repackaged jsr166y regardless of JDK (simplest)</li>
<li>check for jdk version # and use java.util.concurrent instead</li>
<li>check for jdk version # and repackage jsr166e and use it instead</li>
</ul>
<p>Not sure yet which of these is best choice right now.</p>CLJ-1221Should repackage jsr166 and include known version with ClojureEnhancementMajorOpenUnresolvedAlex MillerAlex MillerreducersThu, 20 Jun 2013 14:55:14 -0500Tue, 3 Sep 2013 09:00:25 -0500Release 1.503Global Rank[CLJ-1218] mapcat is too eagerhttp://dev.clojure.org/jira/browse/CLJ-1218
Clojure<p>The following expression prints <tt>1234</tt> and returns <tt>1</tt>:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">(first (mapcat #(<span class="code-keyword">do</span> (print %) [%]) '(1 2 3 4 5 6 7)))</pre>
</div></div>
<p>The reason is that <tt>(apply concat args)</tt> is not maximally lazy in its arguments, and indeed will realize the first four before returning the first item. This in turn is essentially unavoidable for a variadic <tt>concat</tt>.</p>
<p>This could either be fixed just in <tt>mapcat</tt>, or by adding a new function (to <tt>clojure.core</tt>?) that is a non-variadic equivalent to <tt>concat</tt>, and reimplementing <tt>mapcat</tt> with it:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">(defn join
<span class="code-quote">"Lazily concatenates a sequence-of-sequences into a flat sequence."</span>
[s]
(lazy-seq (when-let [[x &amp; xs] (seq s)] (concat x (join xs)))))</pre>
</div></div>CLJ-1218mapcat is too eagerEnhancementMinorOpenUnresolvedUnassignedGary FrederickslazySun, 16 Jun 2013 22:10:34 -0500Wed, 5 Feb 2014 13:35:11 -0600Release 1.533<p>I realized that <tt>concat</tt> could actually be made lazier without changing its semantics, if it had a single <tt><span class="error">&#91;&amp; args&#93;</span></tt> clause that was then implemented similarly to <tt>join</tt> above.</p><p>I lost several hours understanding this issue last month <span class="error">&#91;1, 2&#93;</span> before seeing this ticket in Jira today... +1.</p>
<p><span class="error">&#91;1&#93;</span> <a href="http://eigenhombre.com/2013/07/13/updating-the-genome-decoder-resulting-consequences/">http://eigenhombre.com/2013/07/13/updating-the-genome-decoder-resulting-consequences/</a></p>
<p><span class="error">&#91;2&#93;</span> <a href="http://clojurian.blogspot.com/2012/11/beware-of-mapcat.html">http://clojurian.blogspot.com/2012/11/beware-of-mapcat.html</a></p><p>Updated <tt>join</tt> code to be actually valid.</p>Global Rank[CLJ-1217] for consumes sequence argument more eagerly than necessaryhttp://dev.clojure.org/jira/browse/CLJ-1217
Clojure<p>In a call like (do (for <span class="error">&#91;x (do (println &quot;realized&quot;) nil)&#93;</span> x) nil), no elements of the for comprehension are ever requested, and so it is not actually necessary to evaluate the inner do-block. However, this expression causes "realized" to be printed, because the first sequence-expression in for is evaluated even if no items are ever requested from the output lazy-seq.</p>
<p>It's not documented whether this is intended or unintentional, but I was surprised by this behavior, and a brief unscientific survey on #clojure suggests that other users, even "old hands" who've been using clojure for years, don't expect this either.</p>
<p>I've attached a patch that wraps the problematic expression in a lazy-seq call. This is not quite ideal, because it means that the first iteration is "lazied" twice, as in ((fn step <span class="error">&#91;s&#93;</span> (lazy-seq ...)) (lazy-seq xs)), but a change to make this not happen would be much broader in scope, and this seemed the least dangerous.</p>CLJ-1217for consumes sequence argument more eagerly than necessaryEnhancementMinorOpenUnresolvedUnassignedAlan MalloylazyFri, 14 Jun 2013 14:35:23 -0500Wed, 5 Feb 2014 12:38:50 -060001Global RankPatchCode[CLJ-1216] Evaling ((fn [do] do) 1) returns nil while ((fn [do] do do) 1) returns 1http://dev.clojure.org/jira/browse/CLJ-1216
Clojure<p>user=&gt; ((fn <span class="error">&#91;do&#93;</span> do) 1)<br/>
nil</p>
<p>user=&gt; ((fn <span class="error">&#91;do&#93;</span> (do do)) 1)<br/>
1</p>
<p>user=&gt; ((fn [] do))<br/>
nil</p>
<p>user=&gt; ((fn [] do do))<br/>
CompilerException java.lang.RuntimeException: Unable to resolve symbol: do in this context, compiling:(NO_SOURCE_PATH:0:0) </p>CLJ-1216Evaling ((fn [do] do) 1) returns nil while ((fn [do] do do) 1) returns 1DefectMinorOpenUnresolvedUnassignedNicola MomettocompilerSun, 9 Jun 2013 16:29:14 -0500Tue, 3 Sep 2013 09:07:23 -050000<p>This patch creates a DoExpr class and makes DoExpr.Parser the DO special form parser.</p>
<p>DoExpr.Parser simply removes the 'do' symbol and delegates to BodyExpr, that was previously done by BodyExpr incorrectly.</p>Global RankPatchCode and Test[CLJ-1212] Silent truncation/downcasting of primitive type on reflection call to overloaded method (Math/abs)http://dev.clojure.org/jira/browse/CLJ-1212
Clojure<p>I realise relying on reflection when calling these kinds of methods isn't a great idea performance-wise, but it shouldn't lead to incorrect or dangerous behaviour.</p>
<p>Here it seems to trigger a silent downcast of the input longs, giving a truncated integer output:</p>
<p>user&gt; (defn f <span class="error">&#91;a b&#93;</span> (Math/abs (- a b)))<br/>
Reflection warning, NO_SOURCE_PATH:1:15 - call to abs can't be resolved.<br/>
#'user/f<br/>
user&gt; (f 1000000000000 2000000000000)<br/>
727379968<br/>
user&gt; (class (f 1000000000000 2000000000000))<br/>
java.lang.Integer<br/>
user&gt; (defn f <span class="error">&#91;^long a ^long b&#93;</span> (Math/abs (- a b)))<br/>
#'user/f<br/>
user&gt; (f 1000000000000 2000000000000)<br/>
1000000000000<br/>
user&gt; (class (f 1000000000000 2000000000000))<br/>
java.lang.Long</p>Clojure 1.5.1
<br/>
OpenJDK Runtime Environment (IcedTea6 1.12.5) (6b27-1.12.5-0ubuntu0.12.04.1)CLJ-1212Silent truncation/downcasting of primitive type on reflection call to overloaded method (Math/abs)DefectMajorOpenUnresolvedUnassignedMatthew WillsonprimitivestypehintsTue, 28 May 2013 12:47:26 -0500Wed, 5 Feb 2014 12:40:28 -0600Release 1.500<p>For an even simpler way to replicate the issue:</p>
<p>user&gt; (#(Math/abs %) 1000000000000)<br/>
Reflection warning, NO_SOURCE_PATH:1:3 - call to abs can't be resolved.<br/>
727379968</p><p>I was able to reproduce the behavior you see with these Java 6 JVMs on Ubuntu 12.04.2:</p>
<p>java version "1.6.0_27"<br/>
OpenJDK Runtime Environment (IcedTea6 1.12.5) (6b27-1.12.5-0ubuntu0.12.04.1)<br/>
OpenJDK 64-Bit Server VM (build 20.0-b12, mixed mode)</p>
<p>java version "1.6.0_45"<br/>
Java(TM) SE Runtime Environment (build 1.6.0_45-b06)<br/>
Java HotSpot(TM) 64-Bit Server VM (build 20.45-b01, mixed mode)</p>
<p>However, I tried two Java 7 JVMs, and it gave the following behavior which looks closer to what you would hope for. I do not know what is the precise difference between Java 6 and Java 7 that leads to this behavior difference, but this is some evidence that this has something to do with Java 6 vs. Java 7.</p>
<p>user=&gt; (set! <b>warn-on-reflection</b> true)<br/>
true<br/>
user=&gt; (defn f <span class="error">&#91;a b&#93;</span> (Math/abs (- a b)))<br/>
Reflection warning, NO_SOURCE_PATH:1:15 - call to abs can't be resolved.<br/>
#'user/f<br/>
user=&gt; (f 1000000000000 2000000000000)<br/>
1000000000000<br/>
user=&gt; (class (f 1000000000000 2000000000000))<br/>
java.lang.Long</p>
<p>Above behavior observed with Clojure 1.5.1 on these JVMs:</p>
<p>Ubuntu 12.04.2 plus this JVM:<br/>
java version "1.7.0_21"<br/>
Java(TM) SE Runtime Environment (build 1.7.0_21-b11)<br/>
Java HotSpot(TM) 64-Bit Server VM (build 23.21-b01, mixed mode)</p>
<p>Mac OS X 10.8.3 plus this JVM:<br/>
java version "1.7.0_15"<br/>
Java(TM) SE Runtime Environment (build 1.7.0_15-b03)<br/>
Java HotSpot(TM) 64-Bit Server VM (build 23.7-b01, mixed mode)</p><p>Ah, interesting.<br/>
Maybe it's a difference in the way the reflection API works in java 7?</p>
<p>Here's the bytecode generated incase anyone's curious:</p>
<p>public java.lang.Object invoke(java.lang.Object);<br/>
Code:<br/>
0: ldc #14; //String java.lang.Math<br/>
2: invokestatic #20; //Method java/lang/Class.forName:(Ljava/lang/String;)Ljava/lang/Class;<br/>
5: ldc #22; //String abs<br/>
7: iconst_1<br/>
8: anewarray #24; //class java/lang/Object<br/>
11: dup<br/>
12: iconst_0<br/>
13: aload_1<br/>
14: aconst_null<br/>
15: astore_1<br/>
16: aastore<br/>
17: invokestatic #30; //Method clojure/lang/Reflector.invokeStaticMethod:(Ljava/lang/Class;Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/Object;<br/>
20: areturn</p><p>Just an idea (and maybe this is what's happening under java 7?) but given it's a static method and all available overloaded variants are presumably known at compile time, perhaps it could generate code along the lines of:</p>
<p>(cond<br/>
(instance? Long x) (Math/abs (long x))<br/>
(instance? Integer x) (Math/abs (int x))<br/>
;; ...<br/>
)</p><p>In Reflector.java method invokeStaticMethod(Class c, String methodName, Object[] args) there is a call to getMethods() followed by a call to invokeMatchingMethod(). getMethods() returns the 4 java.lang.Math/abs methods in different orders on Java 6 and 7, causing invokeMatchingMethod() to pick a different one on the two JVMs:</p>
<p>java version "1.6.0_39"<br/>
Java(TM) SE Runtime Environment (build 1.6.0_39-b04)<br/>
Java HotSpot(TM) 64-Bit Server VM (build 20.14-b01, mixed mode)</p>
<p>user=&gt; (pprint (seq (clojure.lang.Reflector/getMethods java.lang.Math 1 "abs" true)))<br/>
(#&lt;Method public static int java.lang.Math.abs(int)&gt;<br/>
#&lt;Method public static long java.lang.Math.abs(long)&gt;<br/>
#&lt;Method public static float java.lang.Math.abs(float)&gt;<br/>
#&lt;Method public static double java.lang.Math.abs(double)&gt;)<br/>
nil</p>
<p>java version "1.7.0_21"<br/>
Java(TM) SE Runtime Environment (build 1.7.0_21-b11)<br/>
Java HotSpot(TM) 64-Bit Server VM (build 23.21-b01, mixed mode)</p>
<p>user=&gt; (pprint (seq (clojure.lang.Reflector/getMethods java.lang.Math 1 "abs" true)))<br/>
(#&lt;Method public static double java.lang.Math.abs(double)&gt;<br/>
#&lt;Method public static float java.lang.Math.abs(float)&gt;<br/>
#&lt;Method public static long java.lang.Math.abs(long)&gt;<br/>
#&lt;Method public static int java.lang.Math.abs(int)&gt;)<br/>
nil</p>
<p>That might be a sign of undesirable behavior in invokeMatchingMethod() that is too dependent upon the order of methods given to it.</p>
<p>As you mention, type hinting is good for avoiding the significant performance hit of reflection.</p>Global Rank[CLJ-1207] Importing a class that does not exist fails to report the name of the class that did not existhttp://dev.clojure.org/jira/browse/CLJ-1207
Clojure<p>Pop quiz: What Java class is missing from the classpath?</p>
<div class="preformatted panel" style="border-width: 1px;"><div class="preformattedContent panelContent">
<pre>java.lang.NoClassDefFoundError: Could not initialize class com.annadaletech.nexus.util.logging__init
at java.lang.Class.forName0 (Class.java:-2)
java.lang.Class.forName (Class.java:264)
clojure.lang.RT.loadClassForName (RT.java:2098)
clojure.lang.RT.load (RT.java:430)
clojure.lang.RT.load (RT.java:411)
clojure.core$load$fn__5018.invoke (core.clj:5530)
clojure.core$load.doInvoke (core.clj:5529)
clojure.lang.RestFn.invoke (RestFn.java:408)
clojure.core$load_one.invoke (core.clj:5336)
clojure.core$load_lib$fn__4967.invoke (core.clj:5375)
clojure.core$load_lib.doInvoke (core.clj:5374)
clojure.lang.RestFn.applyTo (RestFn.java:142)
clojure.core$apply.invoke (core.clj:619)
clojure.core$load_libs.doInvoke (core.clj:5413)
clojure.lang.RestFn.applyTo (RestFn.java:137)
clojure.core$apply.invoke (core.clj:619)
clojure.core$require.doInvoke (core.clj:5496)
clojure.lang.RestFn.invoke (RestFn.java:512)
novate.console.app$eval1736$loading__4910__auto____1737.invoke (app.clj:1)
novate.console.app$eval1736.invoke (app.clj:1)
clojure.lang.Compiler.eval (Compiler.java:6619)
clojure.lang.Compiler.eval (Compiler.java:6608)
clojure.lang.Compiler.load (Compiler.java:7064)
user$eval1732.invoke (NO_SOURCE_FILE:1)
clojure.lang.Compiler.eval (Compiler.java:6619)
clojure.lang.Compiler.eval (Compiler.java:6582)
clojure.core$eval.invoke (core.clj:2852)
clojure.main$repl$read_eval_print__6588$fn__6591.invoke (main.clj:259)
clojure.main$repl$read_eval_print__6588.invoke (main.clj:259)
clojure.main$repl$fn__6597.invoke (main.clj:277)
clojure.main$repl.doInvoke (main.clj:277)
clojure.lang.RestFn.invoke (RestFn.java:1096)
clojure.tools.nrepl.middleware.interruptible_eval$evaluate$fn__584.invoke (interruptible_eval.clj:56)
clojure.lang.AFn.applyToHelper (AFn.java:159)
clojure.lang.AFn.applyTo (AFn.java:151)
clojure.core$apply.invoke (core.clj:617)
clojure.core$with_bindings_STAR_.doInvoke (core.clj:1788)
clojure.lang.RestFn.invoke (RestFn.java:425)
clojure.tools.nrepl.middleware.interruptible_eval$evaluate.invoke (interruptible_eval.clj:41)
clojure.tools.nrepl.middleware.interruptible_eval$interruptible_eval$fn__625$fn__628.invoke (interruptible_eval.clj:171)
clojure.core$comp$fn__4154.invoke (core.clj:2330)
clojure.tools.nrepl.middleware.interruptible_eval$run_next$fn__618.invoke (interruptible_eval.clj:138)
clojure.lang.AFn.run (AFn.java:24)
java.util.concurrent.ThreadPoolExecutor.runWorker (ThreadPoolExecutor.java:1110)
java.util.concurrent.ThreadPoolExecutor$Worker.run (ThreadPoolExecutor.java:603)
java.lang.Thread.run (Thread.java:722)
</pre>
</div></div>
<p>If you guess "com.annadaletech.nexus.util.logging__init" you are wrong!</p>
<p>Wait, I'll give you a hint:</p>
<div class="preformatted panel" style="border-width: 1px;"><div class="preformattedContent panelContent">
<pre>(ns com.annadaletech.nexus.util.logging
(:use [clojure.string :only [trim-newline]]
[clojure.pprint :only [code-dispatch pprint with-pprint-dispatch *print-right-margin*]])
(:import [java.io StringWriter]
[org.slf4j MDC MarkerFactory Marker LoggerFactory]
[java.util.concurrent.locks ReentrantLock]))
</pre>
</div></div>
<p>Oh, sorry, did that not help?</p>
<p>The correct answer is "org.slf4j.MDC". </p>
<p>Having that information in the stack trace would have saved me nearly an hour. I think it is worth the effort to get that reported correctly.</p>1.5.1, OS XCLJ-1207Importing a class that does not exist fails to report the name of the class that did not existDefectMinorOpenUnresolvedUnassignedHoward Lewis ShiperrormsgsMon, 29 Apr 2013 17:36:32 -0500Wed, 5 Feb 2014 12:41:34 -0600Release 1.512<p>When I try this on a fresh project, I get this error:<br/>
"ClassNotFoundException org.slf4j.MDC<br/>
java.net.URLClassLoader$1.run (URLClassLoader.java:202)<br/>
java.security.AccessController.doPrivileged (AccessController.java:-2)"</p>
<p>Howard, could you give us a project.clj or better yet a github repository that recreates this issue?</p><p>I'll see what I can do. Probably be next week. Thanks for looking at this.</p><p>This reminds me of an issue with `lein run` that resulted from it trying to figure out whether you wanted to run a namespace or a java class:</p>
<p><a href="https://github.com/technomancy/leiningen/issues/1182">https://github.com/technomancy/leiningen/issues/1182</a></p>Global RankWaiting Onhlewisship[CLJ-1206] 'eval' of closures or fns with runtime metadata within a call expr yields "No matching ctor found" exceptionshttp://dev.clojure.org/jira/browse/CLJ-1206
Clojure<p>I ran into some issues with 'eval' when writing compilation strategies for Graph. It seems these may have been known for some time <span class="error">&#91;1&#93;</span>, but I couldn't find a ticket for them, so here we are.</p>
<p>Clojure docs <span class="error">&#91;2&#93;</span> say "If the operator is not a special form or macro, the call is considered a function call. Both the operator and the operands (if any) are evaluated, from left to right," and "Any object other than those discussed above will evaluate to itself." While bare fns do seem to evaluate to themselves in all cases, when in a call expression, the evaluation of the operator fails on fn objects that are closures or have run-time metadata applied:</p>
<p>;; raw non-closures are fine<br/>
user&gt; (eval (fn <span class="error">&#91;x&#93;</span> (inc x))) <br/>
#&lt;user$eval30559$fn_<em>30560 user$eval30559$fn</em>_30560@354ee11c&gt;</p>
<p>;; raw closures are fine<br/>
user&gt; (eval (let <span class="error">&#91;y 1&#93;</span> (fn <span class="error">&#91;x&#93;</span> (+ x y))))<br/>
#&lt;user$eval30511$fn_<em>30512 user$eval30511$fn</em>_30512@3bac3a34&gt;</p>
<p>;; non-closures in exprs are fine<br/>
user&gt; (eval `(~(fn <span class="error">&#91;x&#93;</span> (inc x)) 1))<br/>
2</p>
<p>;; but closures in exprs cause an error<br/>
user&gt; (eval `(~(let <span class="error">&#91;y 1&#93;</span> (fn <span class="error">&#91;x&#93;</span> (+ x y))) 1))<br/>
IllegalArgumentException No matching ctor found for class user$eval30535$fn__30536 clojure.lang.Reflector.invokeConstructor (Reflector.java:163)</p>
<p>;; as do fns with metadata in exprs<br/>
user&gt; (eval `(~(with-meta (fn <span class="error">&#91;x&#93;</span> (inc x)) {:x 1}) 1))<br/>
IllegalArgumentException No matching ctor found for class clojure.lang.AFunction$1 clojure.lang.Reflector.invokeConstructor (Reflector.java:163)</p>
<p><span class="error">&#91;1&#93;</span> <a href="http://stackoverflow.com/a/11287181">http://stackoverflow.com/a/11287181</a><br/>
<span class="error">&#91;2&#93;</span> <a href="http://clojure.org/evaluation">http://clojure.org/evaluation</a></p>CLJ-1206'eval' of closures or fns with runtime metadata within a call expr yields "No matching ctor found" exceptionsDefectMinorOpenUnresolvedUnassignedJason WolfeSun, 28 Apr 2013 18:27:49 -0500Sun, 28 Apr 2013 18:27:49 -0500Release 1.502Global Rank[CLJ-1201] There should also be writing in clojure.ednhttp://dev.clojure.org/jira/browse/CLJ-1201
Clojure<p>In clojure.edn I see only "read" and "read-string".</p>
<p>For symmetry I expect "write" and "write-string" to be nearby. At first it could be just alias for "pr" and "pr-str", but in furure they may limited version of "pr" which only produces valid input for clojure.edn/read.</p>CLJ-1201There should also be writing in clojure.ednEnhancementMinorOpenUnresolvedUnassignedVitaly ShukelaednMon, 15 Apr 2013 08:20:01 -0500Thu, 23 May 2013 17:56:23 -0500Release 1.533<p>Related clojure-dev message: <a href="https://groups.google.com/forum/?fromgroups#!topic/clojure-dev/fLJWh9A3OuA">https://groups.google.com/forum/?fromgroups#!topic/clojure-dev/fLJWh9A3OuA</a></p>
<p>and enhancement proposal wiki page: <a href="http://dev.clojure.org/display/design/Representing+EDN">http://dev.clojure.org/display/design/Representing+EDN</a></p>Global Rank[CLJ-1199] Record values are not 'eval'uated, unlike values of PersistentMap:http://dev.clojure.org/jira/browse/CLJ-1199
Clojure<p>I'm not sure if this is by design, but it caught me off guard. </p>
<p>user&gt; (defrecord A <span class="error">&#91;x&#93;</span>)<br/>
user.A</p>
<p>user&gt; (eval (hash-map :x `long))<br/>
{:x #&lt;core$long clojure.core$long@5de54eb7&gt;}<br/>
user&gt; (eval (-&gt;A `long))<br/>
#user.A{:x clojure.core/long}<br/>
user&gt; (eval (map-&gt;A (hash-map :x `long)))<br/>
#user.A{:x clojure.core/long}</p>
<p>and in case it matters, here's a simplified version of the real use case where this came up, with no eval &#8211; just a macro:</p>
<p>user&gt; (defmacro munge-meta1 <span class="error">&#91;x&#93;</span> (assoc x :schema (-&gt;A (:schema (meta x)))))<br/>
#'user/munge-meta1<br/>
user&gt; (munge-meta1 ^{:schema long} {})<br/>
{:schema #user.A{:x long}}</p>
<p>user&gt; (defmacro munge-meta2 <span class="error">&#91;x&#93;</span> (assoc x :schema (hash-map :x (:schema (meta x)))))<br/>
#'user/munge-meta2<br/>
user&gt; (munge-meta2 ^{:schema long} {})<br/>
{:schema {:x #&lt;core$long clojure.core$long@5de54eb7&gt;}}</p>
<p>This seems to be fixed by moving the record creation post-evaluation, so it's not a big deal, just surprising (plus I haven't yet convinced myself that this will always work if the user's schema itself contains record-creating forms, although it seems to work OK):</p>
<p>user&gt; (defmacro munge-meta1 <span class="error">&#91;x&#93;</span> (assoc x :schema `(-&gt;A ~(:schema (meta x)))))<br/>
#'user/munge-meta1<br/>
user&gt; (munge-meta1 ^{:schema long} {})<br/>
{:schema #user.A{:x #&lt;core$long clojure.core$long@5de54eb7&gt;}}</p>
<p>I brought this up on the mailing list here:</p>
<p><a href="https://groups.google.com/forum/?fromgroups=#!topic/clojure-dev/UgD35E1RQTo">https://groups.google.com/forum/?fromgroups=#!topic/clojure-dev/UgD35E1RQTo</a></p>CLJ-1199Record values are not 'eval'uated, unlike values of PersistentMap:DefectMinorOpenUnresolvedUnassignedJason WolfeSat, 13 Apr 2013 00:29:58 -0500Sat, 13 Apr 2013 00:29:58 -0500Release 1.500Global Rank[CLJ-1198] Apply metadata to primitive fns causes them to lose their primitive-nesshttp://dev.clojure.org/jira/browse/CLJ-1198
Clojure<p>user&gt; (def f (fn <span class="error">&#91;^long x&#93;</span> x))<br/>
#'user/f<br/>
user&gt; (.invokePrim (with-meta f {}) 1)<br/>
IllegalArgumentException No matching method found: invokePrim for class clojure.lang.AFunction$1 clojure.lang.Reflector.invokeMatchingMethod (Reflector.java:53)<br/>
user&gt; (contains? (ancestors (class f)) clojure.lang.IFn$LO)<br/>
true<br/>
user&gt; (contains? (ancestors (class (with-meta f {}))) clojure.lang.IFn$LO)<br/>
false</p>
<p>We're working on libraries that use metadata on functions to track information about their arguments (schemata, etc), and this currently blocks us from fully supporting primitive fns. </p>CLJ-1198Apply metadata to primitive fns causes them to lose their primitive-nessDefectMinorOpenUnresolvedUnassignedJason WolfeSat, 13 Apr 2013 00:27:45 -0500Sat, 13 Apr 2013 00:27:45 -0500Release 1.500Global Rank[CLJ-1189] Map-destructuring :or fumble needs compiler warninghttp://dev.clojure.org/jira/browse/CLJ-1189
Clojure<p>Here is a map-destructuring blunder that I wish the compiler warned about: </p>
<p>(defn server<br/>
[{servlet ::servlet<br/>
type ::type<br/>
:or {::type :jetty}<br/>
:as service-map}]</p>
<p>It would be splendid to get a warning that :or keys that are not symbols being bound have no effect. </p>
<p>The incomplete code snippet above comes from Pedestal.service 0.1.0. </p>
<p>Here is a complete one-line example with the coding error: </p>
<p>user&gt; (defn picnic <span class="error">&#91;{botulism :botulism :or {:botulism 6}}&#93;</span> botulism) <br/>
#'user/picnic <br/>
user&gt; (picnic {}) <br/>
nil <br/>
user&gt; ;; I intended 6. </p>CLJ-1189Map-destructuring :or fumble needs compiler warningDefectMinorOpenUnresolvedUnassignedPhill WolferrormsgsSun, 31 Mar 2013 08:02:44 -0500Tue, 3 Sep 2013 09:35:06 -0500Release 1.511<p>Should this be a warning or an exception? I don't know of any similar example of the compiler giving a warning, so I would expect the latter.</p><p>Added a patch that throws an exception when :or is not a map or its keys are not symbols. Also some tests.</p>Global RankPatchCode and Test[CLJ-1181] clojure.pprint/code-dispatch breaks on certain types of anonymous functionshttp://dev.clojure.org/jira/browse/CLJ-1181
Clojure<div class="preformatted panel" style="border-width: 1px;"><div class="preformattedContent panelContent">
<pre>(with-out-str
(with-pprint-dispatch code-dispatch
(pp/pprint (read-string "(fn* [x] x)"))))
</pre>
</div></div>
<p>breaks because the format string here: <a href="https://github.com/clojure/clojure/blob/master/src/clj/clojure/pprint/dispatch.clj#L378">https://github.com/clojure/clojure/blob/master/src/clj/clojure/pprint/dispatch.clj#L378</a> expects a sequence. In the case of (fn* <span class="error">&#91;x&#93;</span> x) it is passed a symbol.</p>CLJ-1181clojure.pprint/code-dispatch breaks on certain types of anonymous functionsDefectMinorOpenUnresolvedUnassignedDevin WaltersprintSun, 10 Mar 2013 16:40:11 -0500Wed, 5 Feb 2014 12:43:23 -0600Release 1.512<p>I think the main "issue" here resides within the undocumented functionality of fn*. (fn* <span class="error">&#91;x&#93;</span> x) is a semantically working function, but (fn <span class="error">&#91;x&#93;</span> x) expands into (fn* (<span class="error">&#91;x&#93;</span> x)). Anonymous function literals expand into (fn* <span class="error">&#91;gensyms&#93;</span> (...)), and as such, it also accepts expressions like (fn* <span class="error">&#91;x&#93;</span> x). Should pprint pretty print expressions which has used fn* directly, or should it "just" ignore it?</p>Global Rank[CLJ-1180] defprotocol doesn't resolve tag classnameshttp://dev.clojure.org/jira/browse/CLJ-1180
Clojure<p>defprotocol doesn't resolve tag classnames, this results in exceptions being thrown when the declared protocol uses as a tag an imported class that is not imported in the namespace that uses it.</p>
<p>user=&gt; (import 'clojure.lang.ISeq)<br/>
clojure.lang.ISeq<br/>
user=&gt; (defprotocol p (^ISeq f <span class="error">&#91;_&#93;</span>))<br/>
p<br/>
user=&gt; (ns x)<br/>
nil<br/>
x=&gt; (defn x <span class="error">&#91;y&#93;</span> (let <span class="error">&#91;z (user/f y)&#93;</span> (inc z)))<br/>
CompilerException java.lang.IllegalArgumentException: Unable to resolve classname: ISeq, compiling:(NO_SOURCE_PATH:4:33) </p>CLJ-1180defprotocol doesn't resolve tag classnamesDefectMajorOpenUnresolvedUnassignedNicola MomettoprotocolsSun, 10 Mar 2013 14:15:31 -0500Wed, 5 Feb 2014 12:42:35 -0600Release 1.5Release 1.600<p>Similer to <a href="http://dev.clojure.org/jira/browse/CLJ-1232" title="Functions with non-qualified return type hints force import of hinted classes when called from other namespace">CLJ-1232</a>.</p>Global RankPatchCode and Test[CLJ-1172] Cross-linking between clojure.lang.Compiler and clojure.lang.RThttp://dev.clojure.org/jira/browse/CLJ-1172
Clojure<p>This is my code (an example):</p>
<div class="preformatted panel" style="border-width: 1px;"><div class="preformattedContent panelContent">
<pre>import clojure.lang.Compiler;
import clojure.lang.RT;
import clojure.lang.Var;
Compiler.load("(+ 5 %)");
Var foo = RT.var("bar", "foo");
Object result = foo.invoke(10);
assert result.toString().equals("15");
</pre>
</div></div>
<p>This is what I'm getting:</p>
<div class="preformatted panel" style="border-width: 1px;"><div class="preformattedContent panelContent">
<pre>ava.lang.ExceptionInInitializerError
at clojure.lang.Compiler.&lt;clinit&gt;(Compiler.java:47)
at foo.main(Main.java:75)
Caused by: java.lang.NullPointerException
at clojure.lang.RT.baseLoader(RT.java:2043)
at clojure.lang.RT.load(RT.java:417)
at clojure.lang.RT.load(RT.java:411)
at clojure.lang.RT.doInit(RT.java:447)
at clojure.lang.RT.&lt;clinit&gt;(RT.java:329)
... 36 more
</pre>
</div></div>
<p>The same code worked just fine with version 1.4. Looks like <tt>Compiler</tt> is using <tt>RT</tt> and <tt>RT</tt> is using <tt>Compiler</tt>, both statically.</p>version 1.5.0-RC17CLJ-1172Cross-linking between clojure.lang.Compiler and clojure.lang.RTDefectMinorReopenedUnresolvedUnassignedYegor BugayenkoThu, 28 Feb 2013 06:30:50 -0600Fri, 21 Jun 2013 10:36:56 -0500Release 1.502<p>I cross-posted this question to SO: <a href="http://stackoverflow.com/questions/15207596">http://stackoverflow.com/questions/15207596</a></p><p>calling <tt>RT.init()</tt> before <tt>Compiler.load()</tt> solves the problem</p><p>Yegor, do you consider it OK to close this ticket as not being a problem, or at least one with a reasonable workaround?</p><p>Yes, of course. Let's close it.</p><p>Ticket submitter agrees that this is not an issue, or that there is a reasonable workaround.</p><p>This issue came up again on the Clojure group. <a href="https://groups.google.com/forum/?hl=en_US&amp;fromgroups=#!topic/clojure/2xdLNMb9yyQ">https://groups.google.com/forum/?hl=en_US&amp;fromgroups=#!topic/clojure/2xdLNMb9yyQ</a></p>
<p>I did some testing, and the issue did not exist in Clojure 1.5.0-RC3 and before, and it has existed since 1.5.0-RC4. There was only one commit between those two points:</p>
<p> <a href="https://github.com/clojure/clojure/commit/9b80a552fdabeabdd93951a625b55ae49c2f8d83">https://github.com/clojure/clojure/commit/9b80a552fdabeabdd93951a625b55ae49c2f8d83</a></p>
<p>Maybe this new behavior is an intended consequence of that change. I don't know. In any case, it seems like perhaps the "No need to call RT.init() anymore" message might be outdated?</p><p>Reopening since it came up again, and there is some more info known about the issue. I'll let someone who knows more about the issue decide whether to close it.</p><p>Doing this RT.load("clojure/core"); at the top works avoids the message from RT.init()</p><p>It seems like <tt>RT.load("clojure/core")</tt> does not hide the message anymore - at least not from 1.5.1.</p>Global Rank[CLJ-1167] repl value of *file* is "NO_SOURCE_PATH", of *source-path* is "NO_SOURCE_FILE"http://dev.clojure.org/jira/browse/CLJ-1167
ClojureCLJ-1167repl value of *file* is "NO_SOURCE_PATH", of *source-path* is "NO_SOURCE_FILE"DefectTrivialOpenUnresolvedUnassignedBrian MarickreplTue, 19 Feb 2013 16:22:10 -0600Tue, 3 Sep 2013 09:59:26 -0500Release 1.501<p>Forgot to mention: I think it's intended to be the other way around, given the names.</p>Global Rank[CLJ-1162] Error Message when calling deref on a non-IDeref is unhelpfulhttp://dev.clojure.org/jira/browse/CLJ-1162
Clojure<p>If you just type "@1" is the repl, on previous versions you'll get an error that Long cannot be cast to IDeref. In 1.5, the error message is that it cannot be cast to java.util.concurrent.Future. This is because it assumes that anything that isn't an IDeref is automatically a Future. The deref method should generate a custom error stating that the type you've passed in is neither an IDeref nor a Future. </p>Found this on ubuntu, lein 2, Clojure 1.5 snapshot, but it&#39;s obvious from inspectionCLJ-1162Error Message when calling deref on a non-IDeref is unhelpfulEnhancementMinorOpenUnresolvedUnassignedJulian BircherrormsgsTue, 12 Feb 2013 03:01:23 -0600Tue, 3 Sep 2013 10:01:19 -0500Release 1.512<p>Attached a patch that implements the old behavior (can't cast to IDeref), which strikes me as good enough considering the support for j.u.c.Future seems rather an edge case (being that clojure's futures are themselves IDeref).</p>
<p>The weirdest thing I did was to use clojure.core/cast to unconditionally throw a ClassCastException. Let me know if that's weird and I'll do something different.</p>Global RankPatchCode[CLJ-1159] clojure.java.io/delete-file doesn't return the status of the deletion(true/false)http://dev.clojure.org/jira/browse/CLJ-1159
Clojure<p>initially reported it here(somehow):<br/>
<a href="https://groups.google.com/d/msg/clojure/T9Kvr0IL0kg/wcKBfR9w_1sJ">https://groups.google.com/d/msg/clojure/T9Kvr0IL0kg/wcKBfR9w_1sJ</a></p>
<p>Basically clojure.java.io/delete-file doesn't ever return false (even when silently is true, it returns the value of silently), it's due to how it's implemented - but it's obvious from the code, so I'll stop here.</p>
<p>Thanks.</p>
<p>PS: this is what I'm using as my current workaround:<br/>
(defn delete-file<br/>
"<br/>
an implementation that returns the true/false status<br/>
which clojure.java.io/delete-file doesn't do(tested in 1.5.0-RC14)<br/>
"<br/>
[f &amp; <span class="error">&#91;silently&#93;</span>]<br/>
(let <span class="error">&#91;ret (.delete (clojure.java.io/file f))&#93;</span><br/>
(cond (or ret silently)<br/>
ret<br/>
:else<br/>
(throw (java.io.IOException. (str "Couldn't delete " f)))<br/>
)<br/>
)<br/>
)</p>
<p>I'm sure you guys can find a better way, but as a clojure newbie(really!) that's what I have.</p>anyCLJ-1159clojure.java.io/delete-file doesn't return the status of the deletion(true/false)DefectMinorOpenUnresolvedUnassignedAtKaaZerrormsgsioSun, 10 Feb 2013 13:55:52 -0600Tue, 3 Sep 2013 10:01:05 -0500Release 1.501<p>I kinda just realized it affects all versions since and including 1.2, because it appears that its implementation was the same since then.</p>
<p>If it's not meant to return the result of the delete, maybe it should specifically return nil and/or the doc say something?</p><p>As noted in a thread on the Clojure ML, you can pass a known value in the second argument position to detect a delete that failed:</p>
<p><tt>(clojure.java.io/delete-file some-file :not-deleted)</tt></p>
<p>This returns true on success and :not-deleted on failure.</p>
<p>However the docstring could be better worded to make that intention clear. Perhaps:</p>
<p><tt>Delete file f. Return true if it succeeds. If silently is nil or false, raise an exception if it fails, else return the value of silently.</tt><br/>
<tt>This allows you to detect whether the delete succeeded without catching an exception by passing a non-true truthy value as the second argument.</tt></p>Global Rank[CLJ-1151] Minor Code Cleanup in core.reducers: use required walk, drop this for collhttp://dev.clojure.org/jira/browse/CLJ-1151
Clojure<p>First, core.reducers requires clojure.walk :as walk, but does not use the alias. <br/>
Second, the two arity implementation of coll-reduce in function reducer uses 'this', whereas similar implementations in that file use 'coll'. AFAICT it makes no difference to use 'coll' (all tests pass, no change in performance) and it is more in line with the rest of the code.</p>
<p>The two things seem small enough to be put into one cleanup case.</p>CLJ-1151Minor Code Cleanup in core.reducers: use required walk, drop this for collEnhancementTrivialOpenUnresolvedUnassignedStefan KamphausenMon, 21 Jan 2013 16:43:30 -0600Tue, 3 Sep 2013 16:09:03 -0500Release 1.500<p>your patch is wrong. If you want to replace this with coll, you have to allso call xf on f1.</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">(clojure.core.protocols/coll-reduce <span class="code-keyword">this</span> f1 (f1))</pre>
</div></div>
<p>becomes</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">(clojure.core.protocols/coll-reduce coll (xf f1) (f1))</pre>
</div></div><p>Scary, that the test suite did not detect that.</p><p>Is it straightforward to add a test that would have detected that?</p><p>I will happily look into that. It may take a few days, before I'll find the time, though.</p>Global RankPatchCode[CLJ-1147] Threading macro (->) does not permit inline function declarationshttp://dev.clojure.org/jira/browse/CLJ-1147
Clojure<p>(-&gt; <span class="error">&#91;1 2 3&#93;</span> (fn <span class="error">&#91;args&#93;</span> apply + args))</p>
<p>CompilerException java.lang.Exception: Unsupported binding form: 1, compiling:(NO_SOURCE_PATH:1:13)</p>
<p>The expression is expanded to:</p>
<p>(fn <span class="error">&#91;1 2 3&#93;</span> <span class="error">&#91;args&#93;</span> apply + args)</p>
<p>If this is intended behaviour then at the least the compiler error message is confusing. It would be preferable if the -&gt; macro checked for (fn..) before treating a form as a sequence and injecting the argument.</p>CLJ-1147Threading macro (->) does not permit inline function declarationsDefectMinorOpenUnresolvedUnassignedStephen NelsonMon, 14 Jan 2013 21:17:51 -0600Sun, 26 May 2013 14:21:55 -0500Release 1.501<p>Note that this works as you might have hoped:</p>
<p>(-&gt; <span class="error">&#91;1 2 3&#93;</span> ((fn <span class="error">&#91;args&#93;</span> (apply + args))))</p>
<p>because it expands into:</p>
<p>((fn <span class="error">&#91;args&#93;</span> (apply + args)) <span class="error">&#91;1 2 3&#93;</span>)</p>
<p>Your suggestion that -&gt; check for (fn ...) before treating it as a sequence and injecting the argument leaves open the question: Why only (fn ...) should be treated specially? Why not (let ...), (for ...), (doseq ...), etc? And if you go that far, how do you decide what should be allowed and what not?</p><p>I agree with Andy, that it's not realistic suggestion to check for fn,let,etc. Perhaps a doc fix would help here but I'm not sure if we just want to call out (fn ...). I'd recommend closing this unless Stephen speaks up.</p><p>I'm happy with Andy's synopsis of the problem, and it's reasonable not to change the behaviour of the threading macro specifically for (fn..).</p>
<p>However, this is a mistake that I'm sure many others make/have made and it's hard to diagnose what is going wrong without dumping interpreted form &#8211; hardly a reasonable expectation for a novice user.</p>
<p>Before closing this issue, I'd like to see improved failure reporting, such as causing the threading macro to throw a compile error or warning if passed a raw (unwrapped) function declaration (are there legitimate use cases this would affect?).</p><p>Throwing an error on (-&gt; <span class="error">&#91;1 2 3&#93;</span> (fn ...)) would certainly affect any perverse individual using a local redefinition of 'fn.</p>
<p>I think the best that can be done here is a mention in the docstring.</p>Global Rank[CLJ-1146] Symbol name starting with digits to defn throws "Unmatched delimiter )"http://dev.clojure.org/jira/browse/CLJ-1146
Clojure<p>When trying to use an invalid symbol name when defining a function, the error message thrown is a confusing and wrong one. The error message is "RuntimeException Unmatched delimiter: ) clojure.lang.Util.runtimeException (Util.java:219)", which unfortunately is the only message seen in nrepled emacs.</p>
<p>$ java -jar clojure-1.5.0-RC2.jar<br/>
Clojure 1.5.0-RC2<br/>
user=&gt; (defn 45fn [] nil)<br/>
NumberFormatException Invalid number: 45fn clojure.lang.LispReader.readNumber (LispReader.java:255)<br/>
[]<br/>
nil<br/>
RuntimeException Unmatched delimiter: ) clojure.lang.Util.runtimeException (Util.java:219)</p>
<p>Expected:<br/>
When trying to (defn or (def a thing with a non valid symbol name, the last thrown error message should be one stating that the given symbol name is not a valid one.</p>$java -jar clojure-1.5.0-RC2.jar
<br/>
<br/>
$java -version
<br/>
java version &quot;1.6.0_37&quot;
<br/>
Java(TM) SE Runtime Environment (build 1.6.0_37-b06-434-10M3909)
<br/>
Java HotSpot(TM) 64-Bit Server VM (build 20.12-b01-434, mixed mode)
<br/>
Mac OS X:
<br/>
System Version: Mac OS X 10.6.8 (10K549)
<br/>
Kernel Version: Darwin 10.8.0
<br/>
CLJ-1146Symbol name starting with digits to defn throws "Unmatched delimiter )"EnhancementTrivialOpenUnresolvedUnassignedLinus EricssonerrormsgsreaderSun, 13 Jan 2013 15:41:03 -0600Fri, 18 Apr 2014 02:27:41 -0500Release 1.501<p>this is an artifact of how streams and repls work.</p>
<p>when you type (defn 45fn [] nil) and hit enter, the inputstream flushes and "(defn 45fn [] nil)" is made available to the reader, the reader reads up to 45fn, throws an error back to the main repl loop, which prints out the error, then calls read, which still has the unread parts available to it "[] nil)"</p>
<p>changing this behavior would require significant changes to clojure's repl.</p>
<p>checkout <a href="https://github.com/trptcolin/reply">https://github.com/trptcolin/reply</a> instead </p>Global Rank[CLJ-1142] Incorrect divide-by-zero error with floating point numbershttp://dev.clojure.org/jira/browse/CLJ-1142
Clojure<p>The unary call for clojure.core// treats a dividend of 0.0 differently than the binary call, likely due to inlining.</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">(/ 0.0) ;; java.lang.ArithmeticException: Divide by zero
(/ 1 0.0) ;;= Infinity
(/ 1 (identity 0.0)) ;; java.lang.ArithmeticException: Divide by zero</pre>
</div></div>CLJ-1142Incorrect divide-by-zero error with floating point numbersDefectMinorOpenUnresolvedUnassignedTim McCormackmathTue, 8 Jan 2013 16:00:00 -0600Wed, 5 Feb 2014 12:44:56 -0600Release 1.401<p>The relevant code seems to be this in clojure.lang.Numbers/divide:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java"><span class="code-keyword">if</span>(yops.isZero((<span class="code-object">Number</span>)y))
<span class="code-keyword">throw</span> <span class="code-keyword">new</span> ArithmeticException(<span class="code-quote">"Divide by zero"</span>);</pre>
</div></div>
<p>Making Numbers/divide be more restrictive than double arithmetic seems like a bug; explicitly throwing an ArithmeticException instead of letting the JVM figure it just seems like more work than necessary.</p>Global Rank[CLJ-1141] Allow pre and post-conditions in defprotocol and deftype macroshttp://dev.clojure.org/jira/browse/CLJ-1141
Clojure<p>The fn special form and the defn macro allow pre- and post-conditions. It would be nice if one could use that conditions also in method declarations of the defprotocol and deftype macro.</p>
<p>Currently I use the extend function as workaround where one can specify the methods using a map of keyword-name and fn special form.</p>Dos not matter.CLJ-1141Allow pre and post-conditions in defprotocol and deftype macrosEnhancementMinorOpenUnresolvedUnassignedAlexander KieldeftypeprotocolsWed, 2 Jan 2013 05:08:13 -0600Wed, 4 Sep 2013 12:28:25 -0500Release 1.425<p>Using <tt>:pre</tt> and <tt>:post</tt>, IMO, isn't a good idea. Handling assertions is a two part game. The mechanism needs to account for both detection and reaction, and the latter is missing.</p>
<p>This isn't a perfect work-around, as it's a little verbose, but using <a href="https://github.com/MichaelDrogalis/dire">Dire</a> might work better than using extend. In addition, you get the "reaction" functionality that's missing from <tt>:pre</tt> and <tt>:post</tt></p>
<p>Example for protocol preconditions: <a href="https://gist.github.com/4471276">https://gist.github.com/4471276</a></p><p>@Michael I read your <a href="https://gist.github.com/4471276">gist</a> and the README of <a href="https://github.com/MichaelDrogalis/dire">Dire</a>. I think the supervision concept of Erlang has it's places but I don't like it for pre- and post-conditions. For me, such conditions have two proposes: </p>
<ol>
<li>they should document the code and</li>
<li>they should fail fast to detect failures early.</li>
</ol>
<p>To support my first point, your pre- and post-conditions are just lexical too far away from the actual function definition. For the second point: I think in the case of violations the program should just crash. One could maybe wrap some part of the program with one of your exception supervisors handling an AssertionError. But I don't think that handling pre- and post-condition violations for individual functions is a good thing.</p><p>@Alexander Indeed, your points are correct. Dire is meant to be exactly what you described. Lexically removed from application logic, and opportunity to recover from crashing. That was my best shot at aiding your needs quickly, anyway. <img class="emoticon" src="http://dev.clojure.org/jira/images/icons/emoticons/smile.gif" height="20" width="20" align="absmiddle" alt="" border="0"/></p>Global Rank[CLJ-1138] data-reader returning nil causes exceptionhttp://dev.clojure.org/jira/browse/CLJ-1138
Clojure<p>If a data-reader returns nil, the reader throws java.lang.RuntimeException: No dispatch macro... The error message implies that there is no dispatch macro for whatever the first character of the tag happens to be.</p>
<p>Here's a simple example:</p>
<p> (binding <span class="error">&#91;*data-readers* {'f/ignore (constantly nil)}&#93;</span> (read-string "#f/ignore 42 10"))</p>
<p>RuntimeException No dispatch macro for: f clojure.lang.Util.runtimeException (Util.java:219)</p>clojure 1.5 beta2, Mac OS X 10.8.2, java version &quot;1.6.0_37&quot;CLJ-1138data-reader returning nil causes exceptionDefectMinorOpenUnresolvedUnassignedSteve MinerreaderSat, 22 Dec 2012 08:41:18 -0600Thu, 14 Feb 2013 15:06:47 -0600Release 1.4Release 1.512<p>clj-1138-allow-data-reader-to-return-nil-instead-of-throwing.patch allows a data-reader to return nil instead of throwing. Does sanity check that possible tag or record isJavaIdentifierStart(). Gives better error message for special characters that might actually be dispatch macros (rather than assuming it's a tagged literal).</p><p>clj-1138-data-reader-return-nil-for-no-op.patch allows a data-reader returning nil to be treated as a no-op by the reader (like #_). nil is not normally a useful value (actually it causes an exception in Clojure 1.4 through 1.5 beta2) for a data-reader to return. With this patch, one could get something like a conditional feature reader using data-readers.</p><p>clj-1138-allow-data-reader-to-return-nil-instead-of-throwing.patch is the first patch to consider. It merely allows nil as a value from a data-reader and returns nil as the final value. I think it does what was originally intended for dispatch macros, and gives a better error message in many cases (mostly typos).</p>
<p>The second patch, clj-1138-data-reader-return-nil-for-no-op.patch, depends on the other being applied first. It takes an extra step to treat a nil value returned from a data-reader as a no-op for the reader (like #_).</p><p>It turns out that you can work around the original problem by having your data-reader return '(quote nil) instead of plain nil. That expression conveniently evaluates to nil so you can get a nil if necessary. This also works after applying the patches so there's still a way to return nil if you really want it.</p>
<p> (binding <span class="error">&#91;*data-readers* {'x/nil (constantly '(quote nil))}&#93;</span> (read-string "#x/nil 42"))<br/>
;=&gt; (quote nil)</p><p>Patch clj-1138-allow-data-reader-to-return-nil-instead-of-throwing.patch dated Dec 22 2012 still applies cleanly to latest master if you use the following command:</p>
<p>% git am --keep-cr -s --ignore-whitespace &lt; clj-1138-allow-data-reader-to-return-nil-instead-of-throwing.patch</p>
<p>Without the --ignore-whitespace option, the patch fails only because some whitespace was changed in Clojure master recently.</p><p>OK, now with latest master (1.5.0-RC15 at this time), patch clj-1138-allow-data-reader-to-return-nil-instead-of-throwing.patch no longer applies cleanly, not even using --ignore-whitespace in the 'git am' command given above. Steve, if you could see what needs to be updated, that would be great. Using the patch command as suggested in the "Updating stale patches" section of <a href="http://dev.clojure.org/display/design/JIRA+workflow">http://dev.clojure.org/display/design/JIRA+workflow</a> wasn't enough, so it should probably be carefully examined by hand to see what needs updating.</p><p>I removed my patches. Things have changes recently with the LispReader and new EdnReader.</p>Global Rank[CLJ-1136] Type hinting for array classes does not work in binding formshttp://dev.clojure.org/jira/browse/CLJ-1136
Clojure<p>Type hints don't work as expected in binding forms. </p>
<p>The following form results in a reflection warning:</p>
<p> (let [^{:tag (Class/forName "<span class="error">&#91;Ljava.lang.Object;&quot;)} a (make-array Object 2)&#93;</span><br/>
(aget a 0))</p>
<p>However, hinting does appear to work correctly on vars:</p>
<p> (def ^{:tag (Class/forName "[Ljava.lang.Object;")} a (make-array Object 2))<br/>
(aget a 0) ;; no reflection warning</p>replicated on OpenJDK 7u9 on Ubuntu 12.04, and Hotspot 1.6.0_37 on OSX LionCLJ-1136Type hinting for array classes does not work in binding formsDefectMajorOpenUnresolvedUnassignedLuke VanderHartinteroptypehintsThu, 20 Dec 2012 14:59:58 -0600Tue, 3 Sep 2013 10:02:25 -0500Release 1.4Release 1.500<p>It's a little more insidious than type hinting: the compiler doesn't evaluate metadata in the binding vec.</p>
<p>This doesn't throw the necessary exception...</p>
<p>(let <span class="error">&#91;^{:foo (Class/forName &quot;not real&quot;)} bar 42&#93;</span><br/>
bar)</p>
<p>neither this...</p>
<p>(let <span class="error">&#91;^{gyorgy ligeti} a 42&#93;</span><br/>
a)</p>
<p>Gyorgy Ligeti never resolves.</p>
<p>These two equivalent examples don't reflect: <br/>
(let <span class="error">&#91;^objects a (make-array Object 2)&#93;</span><br/>
(aget a 0))</p>
<p>(let <span class="error">&#91;a ^objects (make-array Object 2)&#93;</span><br/>
(aget a 0))</p>
<p>On only the left-hand side of a local binding, metadata on a symbol is not analyzed or evaluated.</p>Global Rank[CLJ-1133] Certain actions on mutable fields in deftype lead to very strange error messageshttp://dev.clojure.org/jira/browse/CLJ-1133
Clojure<p>Consider the following code:</p>
<p>(definterface Test<br/>
(^void fail []))</p>
<p>(deftype TestImpl<br/>
<span class="error">&#91;^{:unsynchronized-mutable true :tag int} x&#93;</span><br/>
Test<br/>
(fail <span class="error">&#91;this&#93;</span><br/>
(set! x (dec x))))</p>
<p>Its compilation fails with the following message:<br/>
CompilerException java.lang.VerifyError: (class: test/TestImpl, method: fail signature: ()V) Expecting to find integer on stack, compiling<img class="emoticon" src="http://dev.clojure.org/jira/images/icons/emoticons/sad.gif" height="20" width="20" align="absmiddle" alt="" border="0"/>.../test.clj:27) </p>
<p>The following code works:</p>
<p>(definterface Test<br/>
(^void fail []))</p>
<p>(deftype TestImpl<br/>
<span class="error">&#91;^{:unsynchronized-mutable true :tag int} x&#93;</span><br/>
Test<br/>
(fail <span class="error">&#91;this&#93;</span><br/>
(set! x (int (dec x)))))</p>
<p>The only change here is that I have wrapped (dec x) form into (int) call.</p>
<p>I understand that in fact the former code should not work anyway (or at least should not work as I have expected) because (dec) is defined as a call to clojure.lang.Numbers.dec(), which is overloaded for double, long and Object only (in fact, changing :tag int to :tag long in the first example allows the program to compile). However, the error message is completely uninformative and misleading; it also looks like that it is a consequence of compiler error. It is also not a problem of this concrete example; I found this error in more complex interface method implementation where (set!) call was right in the middle of its body.</p>
<p>I'm using Clojure 1.4.0 and have experienced this problem on Archlinux x86_64 and Windows 7 x86_64.</p>
<p>Full stack trace of the error, in case it would be helpful:</p>
<p>java.lang.VerifyError: (class: test/TestImpl, method: fail signature: ()V) Expecting to find integer on stack, compiling<img class="emoticon" src="http://dev.clojure.org/jira/images/icons/emoticons/sad.gif" height="20" width="20" align="absmiddle" alt="" border="0"/>.../test.clj:27)<br/>
at clojure.lang.Compiler.analyzeSeq(Compiler.java:6462)<br/>
at clojure.lang.Compiler.analyze(Compiler.java:6262)<br/>
at clojure.lang.Compiler.analyze(Compiler.java:6223)<br/>
at clojure.lang.Compiler$BodyExpr$Parser.parse(Compiler.java:5618)<br/>
at clojure.lang.Compiler$FnMethod.parse(Compiler.java:5054)<br/>
at clojure.lang.Compiler$FnExpr.parse(Compiler.java:3674)<br/>
at clojure.lang.Compiler.analyzeSeq(Compiler.java:6453)<br/>
at clojure.lang.Compiler.analyze(Compiler.java:6262)<br/>
at clojure.lang.Compiler.analyzeSeq(Compiler.java:6443)<br/>
at clojure.lang.Compiler.analyze(Compiler.java:6262)<br/>
at clojure.lang.Compiler.access$100(Compiler.java:37)<br/>
at clojure.lang.Compiler$DefExpr$Parser.parse(Compiler.java:518)<br/>
at clojure.lang.Compiler.analyzeSeq(Compiler.java:6455)<br/>
at clojure.lang.Compiler.analyze(Compiler.java:6262)<br/>
at clojure.lang.Compiler.analyzeSeq(Compiler.java:6443)<br/>
at clojure.lang.Compiler.analyze(Compiler.java:6262)<br/>
at clojure.lang.Compiler.analyze(Compiler.java:6223)<br/>
at clojure.lang.Compiler$BodyExpr$Parser.parse(Compiler.java:5618)<br/>
at clojure.lang.Compiler$LetExpr$Parser.parse(Compiler.java:5919)<br/>
at clojure.lang.Compiler.analyzeSeq(Compiler.java:6455)<br/>
at clojure.lang.Compiler.analyze(Compiler.java:6262)<br/>
at clojure.lang.Compiler.analyze(Compiler.java:6223)<br/>
at clojure.lang.Compiler$BodyExpr$Parser.parse(Compiler.java:5618)<br/>
at clojure.lang.Compiler$FnMethod.parse(Compiler.java:5054)<br/>
at clojure.lang.Compiler$FnExpr.parse(Compiler.java:3674)<br/>
at clojure.lang.Compiler.analyzeSeq(Compiler.java:6453)<br/>
at clojure.lang.Compiler.analyze(Compiler.java:6262)<br/>
at clojure.lang.Compiler.eval(Compiler.java:6508)<br/>
at clojure.lang.Compiler.load(Compiler.java:6952)<br/>
at clojure.lang.Compiler.loadFile(Compiler.java:6912)<br/>
at clojure.lang.RT$3.invoke(RT.java:307)<br/>
at test$eval3224.invoke(NO_SOURCE_FILE:43)<br/>
at clojure.lang.Compiler.eval(Compiler.java:6511)<br/>
at clojure.lang.Compiler.eval(Compiler.java:6477)<br/>
at clojure.core$eval.invoke(core.clj:2797)<br/>
at clojure.main$repl$read_eval_print__6405.invoke(main.clj:245)<br/>
at clojure.main$repl$fn__6410.invoke(main.clj:266)<br/>
at clojure.main$repl.doInvoke(main.clj:266)<br/>
at clojure.lang.RestFn.invoke(RestFn.java:421)<br/>
at clojure.main$repl_opt.invoke(main.clj:332)<br/>
at clojure.main$main.doInvoke(main.clj:428)<br/>
at clojure.lang.RestFn.invoke(RestFn.java:397)<br/>
at clojure.lang.Var.invoke(Var.java:411)<br/>
at clojure.lang.AFn.applyToHelper(AFn.java:159)<br/>
at clojure.lang.Var.applyTo(Var.java:532)<br/>
at clojure.main.main(main.java:37)<br/>
Caused by: java.lang.VerifyError: (class: test/TestImpl, method: fail signature: ()V) Expecting to find integer on stack<br/>
at java.lang.Class.forName0(Native Method)<br/>
at java.lang.Class.forName(Class.java:264)<br/>
at clojure.lang.RT.classForName(RT.java:2039)<br/>
at clojure.lang.Compiler$HostExpr.maybeClass(Compiler.java:957)<br/>
at clojure.lang.Compiler$HostExpr.access$400(Compiler.java:736)<br/>
at clojure.lang.Compiler$NewExpr$Parser.parse(Compiler.java:2473)<br/>
at clojure.lang.Compiler.analyzeSeq(Compiler.java:6455)<br/>
... 45 more</p>Archlinux x86_64, Windows 7 x86_64CLJ-1133Certain actions on mutable fields in deftype lead to very strange error messagesDefectMinorOpenUnresolvedUnassignedVladimir MatveevdeftypeTue, 18 Dec 2012 13:48:31 -0600Tue, 3 Sep 2013 10:11:06 -0500Release 1.400<p>Shouldn't have set major priority; but I cannot edit issue again <img class="emoticon" src="http://dev.clojure.org/jira/images/icons/emoticons/sad.gif" height="20" width="20" align="absmiddle" alt="" border="0"/></p><p>Reduced priority to minor, since ticket creator could not do so themselves.</p>Global Rank[CLJ-1131] Importing a non-existent class causes an exception that does not fully identify the source filehttp://dev.clojure.org/jira/browse/CLJ-1131
Clojure<p>I'm in the process of stripping out some OSGi support, and I missed one import.</p>
<p>The exception identifies "init.clj", but I'd prefer to see the full path there, as I have a few different "init.clj" files in my overall project.</p>
<div class="preformatted panel" style="border-width: 1px;"><div class="preformattedContent panelContent">
<pre>:core-services:compileClojure
Reflection warning, com/annadaletech/nexus/services/registry.clj:37 - call to unregisterAll can't be resolved.
Reflection warning, com/annadaletech/nexus/services/registry.clj:131 - call to getConfiguration can't be resolved.
Reflection warning, com/annadaletech/nexus/services/registry.clj:150 - call to getConfiguration can't be resolved.
Exception in thread "main" java.lang.ClassNotFoundException: org.osgi.framework.ServiceRegistration, compiling:(init.clj:1)
at clojure.lang.Compiler$InvokeExpr.eval(Compiler.java:3387)
at clojure.lang.Compiler.compile1(Compiler.java:7035)
at clojure.lang.Compiler.compile1(Compiler.java:7025)
at clojure.lang.Compiler.compile(Compiler.java:7097)
at clojure.lang.RT.compile(RT.java:387)
at clojure.lang.RT.load(RT.java:427)
at clojure.lang.RT.load(RT.java:400)
at clojure.core$load$fn__4890.invoke(core.clj:5415)
at clojure.core$load.doInvoke(core.clj:5414)
at clojure.lang.RestFn.invoke(RestFn.java:408)
at clojure.core$load_one.invoke(core.clj:5227)
at clojure.core$compile$fn__4895.invoke(core.clj:5426)
at clojure.core$compile.invoke(core.clj:5425)
at clojuresque.tasks.compile$main$fn__64.invoke(compile.clj:23)
at clojuresque.cli$with_command_line_STAR_.invoke(cli.clj:92)
at clojuresque.tasks.compile$main.doInvoke(compile.clj:6)
at clojure.lang.RestFn.applyTo(RestFn.java:137)
at clojure.core$apply.invoke(core.clj:601)
at clojure.lang.Var.invoke(Var.java:419)
at clojuresque.Driver.main(Driver.java:39)
Caused by: java.lang.ClassNotFoundException: org.osgi.framework.ServiceRegistration
</pre>
</div></div>CLJ-1131Importing a non-existent class causes an exception that does not fully identify the source fileDefectMinorOpenUnresolvedUnassignedHoward Lewis ShiperrormsgsMon, 17 Dec 2012 18:13:02 -0600Tue, 3 Sep 2013 10:04:06 -0500Release 1.400<p>While it's reasonable to want this for your case, having long path names in a stacktrace could be inconvenient for others. I'd recommend posting your desired change on the dev list - <a href="https://groups.google.com/forum/?fromgroups#!forum/clojure-dev">https://groups.google.com/forum/?fromgroups#!forum/clojure-dev</a> . If they're ok with it, then I'd recommend submitting a patch.</p>Global Rank[CLJ-1128] Improve merge-withhttp://dev.clojure.org/jira/browse/CLJ-1128
Clojure<p>Set a first map as an initial value for reduce to<br/>
avoid merge-entry (series of contains? calls and etc) call on the first map.</p>CLJ-1128Improve merge-withEnhancementMinorOpenUnresolvedUnassignedEdward TsechThu, 13 Dec 2012 13:29:35 -0600Thu, 13 Dec 2012 17:41:39 -060002<p>Tests pass.</p><p>Edward, your patch replaces the expression (or m1 {}) with m1. It was changed from m1 to (or m1 {}) in a commit on Oct 16, 2008 with descriptive text "improved nil handling in merge, merge-with", so I am pretty sure it would be best to leave it as (or m1 {}). I believe the intent is to allow all but one of the map arguments to merge-with be nil, and everything will still work.</p>
<p>The rest of the patch for avoiding one merge call seems sound to me.</p>
<p>Your change would be even better at preserving any metadata on the first non-nil map in the list, if instead of calling with the first map, it called it with the first non-nil item of the list, and then the rest of the list after that.</p><p>I figured out that `reduce1` did pass a head of the list for me. <img class="emoticon" src="http://dev.clojure.org/jira/images/icons/emoticons/smile.gif" height="20" width="20" align="absmiddle" alt="" border="0"/> (<a href="https://github.com/clojure/clojure/blob/master/src/clj/clojure/core.clj#L887">https://github.com/clojure/clojure/blob/master/src/clj/clojure/core.clj#L887</a>)<br/>
But case with first nil argument is still valid. Correct me, please, if i'm wrong.</p>
<p>I'm not sure about `(or m1 {})`. I don't see any problems which can happen. Probably behaviour of functions which are used internally was changed since 2008.</p>
<p>(contains? nil :a) ;=&gt; false<br/>
(assoc nil :a 1) ;=&gt; {:a 1}<br/>
(get nil :a) ;=&gt; nil</p>
<p>I could write some tests for that.</p>Global RankPatchCode[CLJ-1120] Introduce ex-message and ex-cause to abstract away the platform in dealing with ExceptionInfohttp://dev.clojure.org/jira/browse/CLJ-1120
Clojure<p>As described in the title. See <a href="http://dev.clojure.org/jira/browse/CLJS-429" title="Data Conveying Exception: ex-data and ex-info"><del>CLJS-429</del></a>.</p>CLJ-1120Introduce ex-message and ex-cause to abstract away the platform in dealing with ExceptionInfoEnhancementMinorOpenUnresolvedMichał MarczykMichał MarczykThu, 6 Dec 2012 06:19:15 -0600Fri, 21 Dec 2012 23:03:36 -060020<p>The attached patch implements ex-message and ex-cause to work on arbitrary Throwables.</p>Global RankPatchCode[CLJ-1119] inconsistent behavior of lazy-seq w/ macro & closure on excptionshttp://dev.clojure.org/jira/browse/CLJ-1119
Clojure<p>lazy-seq seems to evaluate inconsistently when body includes a macro and throws and exception. 1st evalutation throws the exceptions, subsequent ones return empty sequence.</p>
<p>demo code:</p>
<p>(defn gen-lazy []<br/>
(let [coll <span class="error">&#91;1 2 3&#93;</span>]<br/>
(lazy-seq<br/>
(when-let <span class="error">&#91;s (seq coll)&#93;</span><br/>
(throw (Exception.))))))</p>
<p>(def lazy (gen-lazy))</p>
<p>(try<br/>
(println "lazy:" lazy)<br/>
(catch Exception ex<br/>
(println ex)))</p>
<p>(try<br/>
(println "lazy, again:" lazy)<br/>
(catch Exception ex<br/>
(println ex)))</p>
<p>It should throw an exception both times but only does on 1st. Generally speaking an expression shouldn't evaluate to different things depending on whether it's been evaluated before.</p>
<p>When removing the closure ...</p>
<p>(defn gen-lazy []<br/>
(lazy-seq<br/>
(when-let [s (seq <span class="error">&#91;1 2 3&#93;</span>)]<br/>
(throw (Exception.)))))</p>
<p>... or removing the when-let macro ...</p>
<p>(defn gen-lazy []<br/>
(let [coll <span class="error">&#91;1 2 3&#93;</span>]<br/>
(lazy-seq<br/>
(seq coll)<br/>
(throw (Exception.)))))</p>
<p>It works i.e. consistently throws the exception, so seems to be some interaction between the closure and the macro at work here. This particular combination is used in the 'map' function.</p>
<p>See also: <a href="https://groups.google.com/forum/?fromgroups=#!topic/clojure/Z3EiBUQ7Inc">https://groups.google.com/forum/?fromgroups=#!topic/clojure/Z3EiBUQ7Inc</a></p>CLJ-1119inconsistent behavior of lazy-seq w/ macro & closure on excptionsDefectMinorOpenUnresolvedUnassignedHankMon, 3 Dec 2012 03:00:15 -0600Thu, 8 Aug 2013 03:20:35 -0500Release 1.402<p>N.B. The primary use case I have for this, in case it matters, is interrupting the evaluation of a 'map' expression in which the mapped fn is slow to evaluate (throwing an InterruptedException), because I am not interested in its result any more. Then later I re-evaluate it because I am interested in the result after all, however with above bug the lazy sequence terminates instead of recommencing where it left off.</p>
<p>(UPDATE: This use case is similar to the kind of ersatz continuations that Jetty does (RetryRequest runtime exception) or even Clojure itself when barging STM transactions with the RetryEx exception.)</p><p>Related to <a href="http://dev.clojure.org/jira/browse/CLJ-457" title="lazy recursive definition giving incorrect results">CLJ-457</a> according to Christophe. His patch fixes this,too.</p><p>Sorry Christophe's patch doesn't work for me here. It avoids evaluating the LazySeq a second time by prematurely throwing an exception. However a LazySeq might evaluate properly the second time around b/c the situation causing the exception was transient. As per comment above an evaluation might get interrupted, throwing InterruptedException the first time around but not the second time.</p>
<p>Also the observation with the closure and macro need explanation IMHO.</p><p>further insight: 'delay' exhibits the same behavior and is a more simple case to examine. the macro suspicion is a red herring: as demoed below it is actually the closed over variable magically turns to nil, the when-let macro simply turned that into a nil for the whole expression.</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">(def delayed
(let [a <span class="code-keyword">true</span>]
(delay
(print <span class="code-quote">"a="</span> a)
(<span class="code-keyword">throw</span> (Exception.)))))
(<span class="code-keyword">try</span>
(print <span class="code-quote">"delayed 1:"</span>)
(force delayed)
(<span class="code-keyword">catch</span> Exception ex (println ex)))
(<span class="code-keyword">try</span>
(print <span class="code-quote">"delayed 2:"</span>)
(force delayed)
(<span class="code-keyword">catch</span> Exception ex (println ex)))</pre>
</div></div>
<p>prints:</p>
<p>delayed 1:a= true#&lt;Exception java.lang.Exception&gt;<br/>
delayed 2:a= nil#&lt;Exception java.lang.Exception&gt;</p><p>The above leads to dodgy outcomes such as: The following expression leads to an Exception on 1st evaluation and to "w00t!" on subsequent ones.</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">(def delayed
(let [a <span class="code-keyword">true</span>]
(delay
(<span class="code-keyword">if</span> a
(<span class="code-keyword">throw</span> (Exception.))
<span class="code-quote">"w00t!"</span>))))</pre>
</div></div>
<p>Try it like this:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">(<span class="code-keyword">try</span>
(print <span class="code-quote">"delayed 1:"</span> )
(println (force delayed))
(<span class="code-keyword">catch</span> Exception ex (println ex)))
(<span class="code-keyword">try</span>
(print <span class="code-quote">"delayed 2:"</span>)
(println (force delayed))
(<span class="code-keyword">catch</span> Exception ex (println ex)))</pre>
</div></div>
<p>Results in:<br/>
delayed 1:#&lt;Exception java.lang.Exception&gt;<br/>
delayed 2:w00t!</p>
<p>This code shows that the problem is tied to the :once flag as suspected.</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">(def test-once
(let [a <span class="code-keyword">true</span>]
(^{:once <span class="code-keyword">true</span>} fn* foo []
(println <span class="code-quote">"a="</span> a)
(<span class="code-keyword">throw</span> (Exception.)))))</pre>
</div></div>
<p>Invoking the fn twice will show 'a' turning from 'true' to 'nil', try it like this:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">(<span class="code-keyword">try</span>
(print <span class="code-quote">"test-once 1:"</span>)
(test-once)
(<span class="code-keyword">catch</span> Exception ex (println ex)))
(<span class="code-keyword">try</span>
(print <span class="code-quote">"test-once 2:"</span>)
(test-once)
(<span class="code-keyword">catch</span> Exception ex (println ex)))</pre>
</div></div>
<p>Results in:<br/>
test-once 1:a= true<br/>
#&lt;Exception java.lang.Exception&gt;<br/>
test-once 2:a= nil<br/>
#&lt;Exception java.lang.Exception&gt;</p>
<p>That doesn't happen when the ^{:once true} is removed. Now one could argue that above fn is invoked twice, which is exactly what one is not supposed to do when decorated with the :once flag, but I argue that an unsuccessful call doesn't count as invocation towards the :once flag. The delay and lazy-seq macros agree with me there as the resulting objects are not considered realized (as per realized? function) if the evaluation of the body throws an exception, and realization/evaluation of the body is therefore repeated on re-evaluation of the delay/lazy-seq.</p>
<p>Try this using <div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">(realized? delayed)</pre>
</div></div> after the first evaluation in the code above. In the implementation this can be seen e.g. <a href="https://github.com/clojure/clojure/blob/d0c380d9809fd242bec688c7134e900f0bbedcac/src/jvm/clojure/lang/Delay.java#L33">here for clojure.lang.Delay</a> (similarly for LazySeq), the body-fn is set to null (meaning realized) after the invocation returns <b>successfully</b> only.</p>
<p>The :once flag affects <a href="https://github.com/clojure/clojure/blob/d0c380d9809fd242bec688c7134e900f0bbedcac/src/jvm/clojure/lang/Compiler.java#L4701">this part of the compiler only</a>. Some field is set to nil there in the course of a function invocation, for the good reason of letting the garbage compiler collect objects, however this should to be done after the function successfully completes only. Can this be changed?</p><p>A workaround for the case of the 'map' function as described in the 1st comment, works as this: The original map function, if you take out the cases for several colls, the performance enhancements for chunked seqs and forcing the coll argument to a seq, looks like this:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">(defn map [f s]
(lazy-seq
(cons (f (first s)) (map f (<span class="code-keyword">rest</span> s)))))</pre>
</div></div>
<p>In my workaround I evaluate f <b>twice</b>:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">(defn map [f s]
(lazy-seq
(f (first s))
(cons (f (first s)) (map f (<span class="code-keyword">rest</span> s)))))</pre>
</div></div>
<p>Because the downstream functions that are slow to evaluate are all of the deref kind that cache their result (more lazy-seqs, delays, futures, promises), the InterruptedException can only happen during the 1st evaluation, while the tail call optimization that sets closed-over variables to nil (it pays to read this here: <a href="http://clojure.org/lazy">http://clojure.org/lazy</a>) only happens on the second call. The first still creates an fn that captures the head of the sequence 's', however this is not being held onto as it is not returned.</p>
<p>I use this special version of map (and other, similarly rewritten functions based on lazy-seq such as iterate) when I want interruptible, restartable seq evaluations.</p><p>Instead of above hack, implementing map and all other combinators using a lazy Y-combinator, and removing the :once meta-data tag in the lazy-seq definition fixes things properly. Since the compiler sort-of-hack that clears closed-over variables that's triggered by the :once meta-data tag is basically only for cases of recursion that can be implemented using the Y-combinator, that won't be needed anymore either.</p><p>Re the Delay reference above, this is covered (and addressed) in <a href="http://dev.clojure.org/jira/browse/CLJ-1175" title="NPE in clojure.lang.Delay/deref"><del>CLJ-1175</del></a> which is waiting for a final screen.</p>Global Rank[CLJ-1115] multi arity intohttp://dev.clojure.org/jira/browse/CLJ-1115
Clojure<p>Any reason why into isn't multi arity?</p>
<p>(into to &amp; froms) =&gt; (reduce into to froms)</p>
<p>(into #{} <span class="error">&#91;3 3 4&#93;</span> <span class="error">&#91;2 1&#93;</span> <span class="error">&#91;&quot;a&quot;&#93;</span>) looks better than (reduce into #{} [<span class="error">&#91;3 3 4&#93;</span> <span class="error">&#91;2 1&#93;</span> <span class="error">&#91;&quot;a&quot;&#93;</span>])</p>CLJ-1115multi arity intoEnhancementTrivialOpenUnresolvedUnassignedYongqian LiSun, 25 Nov 2012 07:50:56 -0600Wed, 6 Aug 2014 14:12:02 -050012<p>Seems to be a valid enhancement. I can't see any issues we'd have with it. Vetted. </p><p>Added patch &amp; test. This patch retains the old performance characteristics of into in the case that there is only one collection argument. For example: (into [] <span class="error">&#91;1 2 3&#93;</span>) . </p>
<p>Since the multi-arity version will be slightly slower, I opted to provide it as a second body instead of unifying both into a single body. If someone has a problem with this, I can rewrite the patch. At least this way, into won't get slower. </p><p>This is a good example of an idea for an enhancement I haven't approved, and thus is not yet vetted.</p><p>What's the plan for this bug?</p><p>@Yongqian This ticket is one of several hundred open enhancements right now. It is hard to predict when it will be considered. Voting (or encouraging others to vote) on an issue will raise it's priority. The list at <a href="http://dev.clojure.org/display/community/Screening+Tickets">http://dev.clojure.org/display/community/Screening+Tickets</a> indicates how we prioritize triage.</p><p>Patch multi-arity-into.diff dated Nov 29 2012 no longer applied cleanly to latest Clojure master due to commits made earlier today. Those changes add another arity to the function clojure.core/into, so the multi-arity generalization of into seems unlikely to be compatible with those changes.</p>Global RankPatchCode and Test[CLJ-1113] `reductions` reducerhttp://dev.clojure.org/jira/browse/CLJ-1113
Clojure<p>It would be nice to have a reducers implementation of the core `reductions` function.</p>
<p>Initial implementation attempt included. This version requires an initial reduction value parameter (vs using (f)) and includes that initial value in the final reduction. I'm not certain either of these decisions is optimal, but results in a function which most closely mimics `clojure.core/reductions`.</p>CLJ-1113`reductions` reducerEnhancementMinorOpenUnresolvedUnassignedMarshall T. VandegriftreducersFri, 23 Nov 2012 08:22:37 -0600Wed, 3 Sep 2014 20:12:21 -0500Release 1.500<p>Patch reductions-reducer.diff dated Nov 23 2012 no longer applies cleanly to latest master after some commits were made to Clojure on Sep 3, 2014.</p>
<p>I have not checked whether this patch is straightforward to update, nor do I know if there is interest in an updated patch, or whether transducers are the preferred way to go over reducers, and thus all reducers-related tickets will be closed. See the section "Updating stale patches" at <a href="http://dev.clojure.org/display/community/Developing+Patches">http://dev.clojure.org/display/community/Developing+Patches</a> for suggestions on how to update patches.</p>Global RankPatchCode and Test[CLJ-1112] Var *loading-verbosely* should initialize from a JVM system propertyhttp://dev.clojure.org/jira/browse/CLJ-1112
Clojure<p>I often find myself adding :verbose to a (require) or (use) clause of my (ns) in order to debug problems (especially macros, or bad namespace declarations). It would be very nice if I could define a JVM system property (say -Dclojure.load-verbosely=true) to default <b>loading-verbosely</b> to true for a REPL session, or as part of a build. </p>
<p>Sometimes I just like to see that namespaces load as a measure of progress, when starting an application, or when running a set of tests.</p>CLJ-1112Var *loading-verbosely* should initialize from a JVM system propertyEnhancementMinorOpenUnresolvedUnassignedHoward Lewis ShipWed, 21 Nov 2012 13:19:20 -0600Tue, 3 Sep 2013 10:18:28 -0500Release 1.411<p>This patch implements the suggested feature.</p>
<p>The new system property is called <tt>clojure.core.loading-verbosely</tt> in analogy to the existing <tt>clojure.compile.warn-on-reflection</tt>.</p>Global RankPatchCode[CLJ-1108] Allow to specify an Executor instance to be used with future-callhttp://dev.clojure.org/jira/browse/CLJ-1108
Clojure<p>This adds an arity to future-call that expects a java.util.concurrent/ExecutorService instance to be used instead of clojure.lang.Agent/soloExecutor. </p>CLJ-1108Allow to specify an Executor instance to be used with future-callEnhancementMajorOpenUnresolvedUnassignedMax PenetSun, 18 Nov 2012 06:32:18 -0600Thu, 27 Dec 2012 02:25:43 -060001<p>Rich Hickey committed a change on Dec 21, 2012 to the future-call function that made the patch bac37b91230d8e4ab3a1e6042a6e8c4b7e9cbf53.patch dated Nov 18 2012 no longer apply cleanly.</p>
<p>clj-1108-enhance-future-call-patch-v2.txt dated Dec 26 2012 is identical to that earlier patch, except it has been updated to apply cleanly to the latest master.</p>
<p>It would be best if Max Penet, author of the earlier patch, could verify I've merged his patch to the latest Clojure master correctly.</p><p>It's verified, it applies correctly to the latest master 00978c76edfe4796bd6ebff3a82182e235211ed0 .</p>
<p>Thanks Andy. </p>Global RankPatchCode[CLJ-1103] Make conj assoc dissoc and transient versions handle args similarlyhttp://dev.clojure.org/jira/browse/CLJ-1103
Clojure<p>Examples that work as expected:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">Clojure 1.7.0-master-SNAPSHOT
user=&gt; (dissoc {})
{}
user=&gt; (disj #{})
#{}
user=&gt; (conj {})
{}
user=&gt; (conj [])
[]</pre>
</div></div>
<p>Examples that do not work as desired, but are changed by the proposed patch:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">user=&gt; (assoc {})
ArityException Wrong number of args (1) passed to: core/assoc clojure.lang.AFn.throwArity (AFn.java:429)
user=&gt; (assoc! (<span class="code-keyword">transient</span> {}))
ArityException Wrong number of args (1) passed to: core/assoc! clojure.lang.AFn.throwArity (AFn.java:429)
user=&gt; (dissoc! (<span class="code-keyword">transient</span> {}))
ArityException Wrong number of args (1) passed to: core/dissoc! clojure.lang.AFn.throwArity (AFn.java:429)</pre>
</div></div>
<p>I looked through the rest of the code for similar cases, and found that there were some other differences between them in how different numbers of arguments were handled, such as:</p>
<p>+ conj handles an arbitrary number of arguments, but conj! does not.<br/>
+ assoc checks for a final key with no value specified (<a href="http://dev.clojure.org/jira/browse/CLJ-1052" title="assoc should throw exception if missing val for last key"><del>CLJ-1052</del></a>), but assoc! did not.</p>
<p>History/discussion: A discussion came up in the Clojure Google group about conj giving an error when taking only a coll as an argument, as opposed to disj which works for this case:</p>
<p><a href="https://groups.google.com/forum/?fromgroups=#!topic/clojure/Z9mFxsTYTqQ">https://groups.google.com/forum/?fromgroups=#!topic/clojure/Z9mFxsTYTqQ</a></p>CLJ-1103Make conj assoc dissoc and transient versions handle args similarlyEnhancementMinorOpenUnresolvedUnassignedAndy FingerhutSun, 4 Nov 2012 18:00:32 -0600Fri, 29 Aug 2014 18:04:43 -0500Release 1.4Release 1.5Release 1.663<p>clj-1103-make-conj-assoc-dissoc-handle-args-similarly-v1.txt dated Nov 4 2012 makes conj conj! assoc assoc! dissoc dissoc! handle args similarly to each other.</p><p>I too ran into this and started an additional discussion here: <a href="https://groups.google.com/d/topic/clojure-dev/wL5hllfhw4M/discussion">https://groups.google.com/d/topic/clojure-dev/wL5hllfhw4M/discussion</a></p>
<p>In particular, I don't buy the argument that (into coll xs) is sufficient, since into implies conj and there isn't an terse and idiomatic way to write (into map (parition 2 keyvals))</p>
<p>So +1 from me</p><p>Patch clj-1103-2.diff is identical to the previous patch clj-1103-make-conj-assoc-dissoc-handle-args-similarly-v1.txt except it applies cleanly to latest master. The only changes were some changed context lines in a test file.</p><p>Patch clj-1103-3.diff is identical to the patch clj-1103-2.diff, except it applies cleanly to latest master. The only changes were some doc strings for assoc! and dissoc! in the context lines of the patch.</p><p>Patch clj-1103-4.diff is identical to the previous clj-1103-3.diff, except it updates some context lines so that it applies cleanly to latest Clojure master as of today.</p><p>Can someone update the description with some code examples? Or drop them here at least?</p><p>What do you mean code examples?</p>
<p>These currently work as expected:<br/>
(dissoc {})<br/>
(disj #{})</p>
<p>The following fail with arity errors:<br/>
(assoc {})<br/>
(conj {})</p>
<p>Similarly for the transient ! versions.</p>
<p>This is annoying if you ever try to do (apply assoc m keyvals)... it works at first glance, but then one day, bamn! Runtime error because you tried to give it an empty sequence of keyvals.</p>
<p>Patch clj-1103-5.diff dated Aug 6 2014 applies cleanly to latest Clojure master as of today, whereas the previous patch did not. Rich added 1-arg version of conj to 1.7.0-alpha1, so that change no longer is part of this patch.</p><p>Patch clj-1103-6.diff dated Aug 29 2014 is identical to the former patch clj-1103-5.diff (which will be deleted), except it applies cleanly to the latest Clojure master.</p>Global RankPatchCode and Test[CLJ-1097] node-seq for clojure.ziphttp://dev.clojure.org/jira/browse/CLJ-1097
Clojure<p>Many times it's easier to get to a zipper node via (first (filter pred ...)) instead of manually walking the tree via next/up/down. Other times it's easier to process certain nodes via filter &amp; map instead of again, walking the tree. This patch provides a single function called node-seq that uses zip/next to generate a lazy-seq of nodes. Tests provide two examples.</p>
CLJ-1097node-seq for clojure.zipEnhancementMinorOpenUnresolvedUnassignedTimothy BaldridgezipMon, 29 Oct 2012 21:37:18 -0500Tue, 3 Sep 2013 10:20:45 -0500Release 1.500Global RankPatchCode and Test[CLJ-1095] Allow map-indexed to accept multiple collections (a la map)http://dev.clojure.org/jira/browse/CLJ-1095
Clojure<p>Bring external interface of map-indexed in line with map. Existing usages of map-indexed unchanged both in implementation and interface.</p>
<div class="code panel" style="border-width: 1px;"><div class="codeHeader panelHeader" style="border-bottom-width: 1px;"><b>examples</b></div><div class="codeContent panelContent">
<pre class="code-java">(map vector (range 10 20) (range 30 35)) ;=&gt; ([10 30] [11 31] [12 32] [13 33] [14 34])
(map-indexed vector (range 10 20) (range 30 35)) ;=&gt; ([0 10 30] [1 11 31] [2 12 32] [3 13 33] [4 14 34])</pre>
</div></div>
<p>The attached patch is not necessarily the best implementation (I haven't benchmarked it or tried any alternatives yet) but hopefully enough to start a conversation about whether this is an addition that is warranted. I know I wished for this behavior a few weeks ago though I ended up finding another way.</p>
<p>(I haven't sent my CA yet, but I have it signed and ready to send in the next few days)</p>CLJ-1095Allow map-indexed to accept multiple collections (a la map)EnhancementTrivialOpenUnresolvedUnassignedBo JeanesThu, 25 Oct 2012 16:30:01 -0500Thu, 8 Nov 2012 14:58:13 -060001<p>Can you add a test for the improved functionality?</p><p>You bet. I tried to before submitting this but found no existing tests for map-indexed to expand upon. Given that, I decided to just start the conversation first. If you think this is a good addition, I'll find a place to stick the tests and add a new patch file.</p><p>Add two unit tests for <tt>map-indexed</tt>. One tests old behavior (single collection) and the second tests mapping across 3 collections. </p>
<p>There were no existing tests for <tt>map-indexed</tt> that I could see to expand upon (using <tt>git grep map-indexed src/clojure</tt>)</p>Global RankPatchCode and Test[CLJ-1088] repl/source could support protocol functionshttp://dev.clojure.org/jira/browse/CLJ-1088
Clojure<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">user=&gt; (source clojure.core.protocols/coll-reduce)
Source not found</pre>
</div></div>
<p>But since the protocol fn's var's metadata points to the protocol var, and the protocol var knows the file and line where it was defined, it would be trivial to improve 'source' to look like this:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">user=&gt; (source clojure.core.protocols/coll-reduce)
(defprotocol CollReduce
"Protocol <span class="code-keyword">for</span> collection types that can implement reduce faster than
first/next recursion. Called by clojure.core/reduce. Baseline
implementation defined in terms of Iterable."
(coll-reduce [coll f] [coll f val]))</pre>
</div></div>CLJ-1088repl/source could support protocol functionsEnhancementTrivialOpenUnresolvedUnassignedChouserreplSun, 21 Oct 2012 09:53:35 -0500Fri, 31 Jan 2014 18:25:25 -0600Release 1.501<p>Add one-line patch to clojure.repl/source so that it will find the protocol definition for a given protocol function.</p><p>Patch 0001-Add-support-for-protocol-fns-to-repl-source.-<a href="http://dev.clojure.org/jira/browse/CLJ-1088" title="repl/source could support protocol functions">CLJ-1088</a>.patch no longer applies cleanly as of commits made to Clojure master on Jan 31 2014, probably due to the patch for <a href="http://dev.clojure.org/jira/browse/CLJ-1176" title="clojure.repl/source fails when *read-eval* bound to :unknown"><del>CLJ-1176</del></a>. I have not investigated how easy or difficult it would be to update.</p>Global RankPatchCode[CLJ-1087] clojure.data/diff uses set union on key seqshttp://dev.clojure.org/jira/browse/CLJ-1087
Clojure<p><tt>clojure.data/diff</tt>, on line 118, defines:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">java.util.Map
(diff-similar [a b]
(diff-associative a b (set/union (keys a) (keys b))))</pre>
</div></div>
<p>Since <tt>keys</tt> returns a key seq, this seems like an error. <tt>clojure.set/union</tt> has strange and inconsistent behavior with regard to non-sets, and in this case the two key seqs are concatenated. Based on a cursory benchmark, it seems that this bug <img class="emoticon" src="http://dev.clojure.org/jira/images/icons/emoticons/help_16.gif" height="16" width="16" align="absmiddle" alt="" border="0"/> is a slight performance gain when the maps have no common keys, and a significant performance loss when the maps have the same keys. The results are still correct because of the merging reduce in <tt>diff-associative</tt>.</p>
<p>The patch is easy (just call set on each key seq).</p>CLJ-1087clojure.data/diff uses set union on key seqsEnhancementMinorOpenUnresolvedUnassignedTom JackcheckargsperformanceMon, 15 Oct 2012 03:59:52 -0500Tue, 24 Feb 2015 11:57:58 -060001<p>clj-1087-diff-perf-enhance-patch-v1.txt dated Oct 15 2012 implements Tom's suggested performance enhancement, although not exactly in the way he suggested. It does calculate the union of the two key sequences.</p>Global RankPatchCode[CLJ-1081] REPL binding not working that works with with-bindingshttp://dev.clojure.org/jira/browse/CLJ-1081
Clojure<p>This works as expected:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">java -jar clojure-1.4.0.jar -e <span class="code-quote">"(<span class="code-keyword">do</span> (require 'clojure.repl) (.setDynamic #'clojure.repl/print-doc) (with-bindings {#'clojure.repl/print-doc str} (eval '(clojure.repl/doc println))))"</span></pre>
</div></div>
<p>Output:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java"><span class="code-quote">"{:ns #&lt;Namespace clojure.core&gt;, :name println, :arglists ([&amp; more]), :added \"</span>1.0\<span class="code-quote">", :<span class="code-keyword">static</span> <span class="code-keyword">true</span>, :doc \"</span>Same as print followed by (newline)\<span class="code-quote">", :line 3325, :file \"</span>clojure/core.clj\<span class="code-quote">"}"</span></pre>
</div></div>
<p>But the same thing does not work in the REPL:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">java -jar clojure-1.4.0.jar -e <span class="code-quote">"(<span class="code-keyword">do</span> (require 'clojure.repl) (.setDynamic #'clojure.repl/print-doc) (clojure.main/repl :init (fn [] {#'clojure.repl/print-doc str}))))"</span>
Output <span class="code-keyword">for</span> Output of {{(doc println)}}:</pre>
</div></div>
<p>user=&gt; (doc println)<br/>
-------------------------<br/>
clojure.core/println<br/>
(<span class="error">&#91;&amp; more&#93;</span>)<br/>
Same as print followed by (newline)<br/>
nil<br/>
user=&gt;</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java"></pre>
</div></div>CLJ-1081REPL binding not working that works with with-bindingsDefectMinorOpenUnresolvedUnassignedSteven DevijverreplSun, 30 Sep 2012 15:21:42 -0500Wed, 5 Feb 2014 12:47:01 -0600Release 1.401<p>Found a work-around:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">java -jar clojure-1.4.0.jar -e <span class="code-quote">"(<span class="code-keyword">do</span> (require 'clojure.repl) (.setDynamic #'clojure.repl/print-doc) (with-bindings {#'clojure.repl/print-doc str} (clojure.main/repl)))))"</span></pre>
</div></div>
<p>I'm still not sure whether the method above using :init should or should not work.</p>Global Rank[CLJ-1080] Eliminate many uses of reflection in Clojure codehttp://dev.clojure.org/jira/browse/CLJ-1080
Clojure<p>There are dozens of uses of reflection in Clojure code that can be eliminated by adding suitable type hints. This patch adds the necessary type hints for most of those.</p>CLJ-1080Eliminate many uses of reflection in Clojure codeEnhancementMinorOpenUnresolvedUnassignedAndy FingerhutperformancetypehintsSun, 30 Sep 2012 11:36:18 -0500Thu, 10 Oct 2013 00:23:06 -0500Release 1.4Release 1.503<p>Patch clj-1080-eliminate-many-reflection-warnings-patch-v1.txt dated Sep 30 2012 adds type hints to eliminate many uses of reflection in Clojure core code.</p><p>clj-1080-eliminate-many-reflection-warnings-patch-v2.txt dated Nov 14 2012 is identical to the previous patch (to be removed soon), except it applies cleanly to latest master.</p><p>clj-1080-eliminate-many-reflection-warnings-patch-v3.txt dated Feb 7 2013 is identical to the previous patch (to be removed soon), except it applies cleanly to latest master. One type hint in the patch was added due to a different change, and was no longer needed in the patch.</p><p>Patch clj-1080-v4.txt eliminates many, but not all, uses of reflection. To avoid overlap with <a href="http://dev.clojure.org/jira/browse/CLJ-1259" title="Speed up pprint">CLJ-1259</a>, it does not touch pprint or any of the files loaded from pprint.clj. See <a href="http://dev.clojure.org/jira/browse/CLJ-1259" title="Speed up pprint">CLJ-1259</a> for those.</p><p>Patch clj-1080-v5.txt eliminates many, but not all, uses of reflection. It does not touch pprint or any of the files loaded from pprint.clj &#8211; see <a href="http://dev.clojure.org/jira/browse/CLJ-1259" title="Speed up pprint">CLJ-1259</a> for those. Similarly see <a href="http://dev.clojure.org/jira/browse/CLJ-1277" title="Speed up printing of time instants by adding type hints">CLJ-1277</a> for elimination of reflection in instant.clj</p>Global RankPatchCode[CLJ-1079] Don't squash explicit :line and :column metadata in the MetaReaderhttp://dev.clojure.org/jira/browse/CLJ-1079
Clojure<p>I have been experimenting with using <a href="https://github.com/lynaghk/cljx">cljx</a> to produce Clojure and ClojureScript source from a single file. This has gone well so far, with the exception that, due to the way the source transformation works, all of the linebreaks and other formatting is gone from the output. There is an option to include the original <tt>:line</tt> metadata in the output though, like so:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">;;This file autogenerated from
;;
;; src/cljx/com/foo/hosty.cljx
;;
^{:line 1} (ns com.foo.hosty)
^{:line 3} (defn ^{:clj <span class="code-keyword">true</span>} system-hash [x] ^{:line 5} (<span class="code-object">System</span>/identityHashCode x))</pre>
</div></div>
<p>(Hopefully, such hackery won't be necessary in the future with <a href="https://github.com/cgrand/sjacket">sjacket</a> or something like it...)</p>
<p>Unfortunately, when read in using a <tt>LineNumberingPushbackReader</tt>, code like this has its <tt>:line</tt> metadata squashed by the line numbers coming from that. A REPL-friendly example would be:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">=&gt; (meta (read (clojure.lang.LineNumberingPushbackReader.
(java.io.StringReader. <span class="code-quote">"^{:line 66} ()"</span>))))
{:line 1}
=&gt; (meta (read (java.io.PushbackReader.
(java.io.StringReader. <span class="code-quote">"^{:line 66} ()"</span>))))
{:line 66}</pre>
</div></div>
<p>The latter seems more correct to me (and is equivalent to <tt>read-string</tt>).</p>CLJ-1079Don't squash explicit :line and :column metadata in the MetaReaderDefectMajorOpenUnresolvedUnassignedChas EmerickreaderSat, 29 Sep 2012 17:12:45 -0500Tue, 3 Sep 2013 11:34:08 -0500Release 1.4Release 1.522<p>{{<a href="http://dev.clojure.org/jira/browse/CLJ-1097" title="node-seq for clojure.zip">CLJ-1097</a>.diff}} contains a fix for this issue, as well as a separate commit that eliminates a series of casts in order to improve readability in the area.</p><p>Chas, your patch doesn't apply cleanly to latest Clojure master as of Oct 5 2012. I'm not sure, but I think some recent commits to Clojure on Oct 4 2012 caused that. I also take it as evidence of your awesomeness that you can write patches for tickets that haven't been filed yet <img class="emoticon" src="http://dev.clojure.org/jira/images/icons/emoticons/smile.gif" height="20" width="20" align="absmiddle" alt="" border="0"/></p><p>"patches for tickets that haven't been filed yet?"</p>
<p>Anyway, tweaking up this patch is a small price to pay for having column meta. New {{<a href="http://dev.clojure.org/jira/browse/CLJ-1097" title="node-seq for clojure.zip">CLJ-1097</a>.diff}} patch attached, applies clean on master as of now. Otherwise same contents as in the original patch, except:</p>
<ul>
<li>the same dynamic is also applied to <tt>:column</tt> metadata, now that it's available</li>
<li>the changes have been rebased into a single commit (including the elimination of the casts in <tt>MetaReader</tt>, which were becoming so numerous that the code was less readable than most</li>
</ul>
<p>"patches for tickets that haven't been filed yet?"</p>
<p>He was referring to the fact that you uploaded "<a href="http://dev.clojure.org/jira/browse/CLJ-1097" title="node-seq for clojure.zip">CLJ-1097</a>.diff" while the ticket is #1079 </p><p>Oh, hah! Twice now, even! One more data point recommending my having slight dyslexia or somesuch. :-P</p>
<p>I've replaced the attached patch with one that is named properly to avoid any later confusion.</p><p>Refreshed patch to apply cleanly to master after the recent <a href="https://github.com/clojure/clojure/commit/65b5f73a9be30669116fcddb6ced9e60680532e5">off by one patch for <tt>:column</tt> metadata</a>.</p><p>This feels backwards to me. If a special purpose tool wants to convey information via metadata, why does it use names that collide with those used by LispReader?</p><p>The information being conveyed is the same <tt>:line</tt> and <tt>:column</tt> metadata conveyed by <tt>LispReader</tt> — in fact, that's where it comes from in the first place.</p>
<p>Kibit (and cljx) is essentially an out-of-band source transformation tool. Given an input like this:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">(ns com.foo.hosty)
(defn ^:clj system-hash
[x]
(<span class="code-object">System</span>/identityHashCode x))
(defn ^:cljs system-hash
[x]
(goog/getUid x))</pre>
</div></div>
<p>…it produces two files, a <tt>.clj</tt> for Clojure, and a <tt>.cljs</tt> for ClojureScript. (The first code listing in the ticket description is the former.)</p>
<p>However, because there's no way to transform Clojure code/data without losing formatting, anything that depends on line/column numbers (stack traces, stepping debuggers) is significantly degraded. If <tt>LispReader</tt> were to defer to <tt>:line</tt> and <tt>:column</tt> metadata already available on the loaded forms (there when the two generated files are spit out with <tt>&#42;print-meta&#42;</tt> on), this would not be the case.</p><p>clj-1079-patch-v2.txt dated Feb 7 2013 is identical to Chas's <a href="http://dev.clojure.org/jira/browse/CLJ-1079" title="Don&#39;t squash explicit :line and :column metadata in the MetaReader">CLJ-1079</a>.diff dated Oct 7 2012, except it applies cleanly to latest master. I believe the only difference is that some white space in the context lines is updated.</p><p>Sorry for the noise. I've removed clj-1079-patch-v2.txt mentioned in the previous comment, because I learned that <a href="http://dev.clojure.org/jira/browse/CLJ-1079" title="Don&#39;t squash explicit :line and :column metadata in the MetaReader">CLJ-1079</a>.diff dated Oct 7 2012 applies cleanly to latest master and passes all tests if you use this command to apply it.</p>
<p>% git am --keep-cr -s --ignore-whitespace &lt; <a href="http://dev.clojure.org/jira/browse/CLJ-1079" title="Don&#39;t squash explicit :line and :column metadata in the MetaReader">CLJ-1079</a>.diff</p>
<p>I will update the JIRA workflow page instructions for applying patches to mention this, too, because there are multiple patches that fail without --ignore-whitespace, but apply cleanly with that option. That will eliminate the need to update patches merely for whitespace changes.</p>Global RankPatchCode and Test[CLJ-1078] Add queue and queue? to clojure.corehttp://dev.clojure.org/jira/browse/CLJ-1078
Clojure<p>Add <tt>queue</tt> function to create queues from collections and <tt>queue?</tt> predicate to check queueness.</p>
<p><b>Patch:</b> clj-1048-add-queue-functions.diff </p>CLJ-1078Add queue and queue? to clojure.coreEnhancementMinorOpenUnresolvedUnassignedTimothy Baldridgedata-structuresqueueWed, 26 Sep 2012 23:38:59 -0500Sun, 28 Dec 2014 11:14:33 -0600Release 1.5105<p>Timothy, I tried applying both of these Sep 26, 2012 patches to latest Clojure master as of that date. I had to apply 0001-make-PersistentQueue-ctor-public.patch by hand since it failed to apply using git or patch. It built fine, but failed to pass several of the Clojure tests. Have you looked into those test failures to see if you can find the cause and fix them? I tested on Ubuntu 11.10 with Oracle JDK 1.6 and 1.7, and saw similar failures with both.</p><p>Fixed the patch. Tests pass, created the patch, applied it to a different copy of the source and the tests still pass. So this new patch should be good to go.</p><p>Timothy, I'm not sure how you are getting successful results when applying this patch. Can you try the steps below and see what happens for you? I get errors trying to apply the patch with latest Clojure master as of Oct 26, 2012. Also please use the steps on the JIRA workflow page to create a git format patch (<a href="http://dev.clojure.org/display/design/JIRA+workflow">http://dev.clojure.org/display/design/JIRA+workflow</a> under "Development" heading).</p>
<p>% git clone git://github.com/clojure/clojure.git<br/>
% cd clojure<br/>
% patch -p1 &lt; queues.patch<br/>
patching file src/clj/clojure/core.clj<br/>
patching file src/jvm/clojure/lang/PersistentQueue.java<br/>
Hunk #1 FAILED at 32.<br/>
1 out of 1 hunk FAILED &#8211; saving rejects to file src/jvm/clojure/lang/PersistentQueue.java.rej<br/>
patching file test/clojure/test_clojure/data_structures.clj<br/>
Hunk #1 succeeded at 123 with fuzz 2.<br/>
Hunk #2 succeeded at 861 with fuzz 2.<br/>
Hunk #3 FAILED at 872.<br/>
1 out of 3 hunks FAILED &#8211; saving rejects to file test/clojure/test_clojure/data_structures.clj.rej<br/>
patching file test/clojure/test_clojure/java_interop.clj</p><p>I was using git apply. I tried the method you show above, and now I'm seeing the same issues you show above. </p><p>Just so you know, the preferred way to create and apply patches are the "git format-patch master --stdout &gt; patch.txt" to create a patch (after doing the branching commands described on the JIRA workflow page to create a branch for your changes), and the "git am --keep-cr -s &lt; patch.txt" to apply a patch. If a patch was created that way and applies cleanly with that command, then you are definitely good to go.</p>
<p>The "patch -p1 &lt; patch.txt" command is just a secondary method sometimes used to try to apply patches that aren't in the format produced above, or have errors when applying using that method.</p><p>Just so you know, the preferred way to create and apply patches are the "git format-patch master --stdout &gt; patch.txt" to create a patch (after doing the branching commands described on the JIRA workflow page to create a branch for your changes), and the "git am --keep-cr -s &lt; patch.txt" to apply a patch. If a patch was created that way and applies cleanly with that command, then you are definitely good to go.</p>
<p>The "patch -p1 &lt; patch.txt" command is just a secondary method sometimes used to try to apply patches that aren't in the format produced above, or have errors when applying using that method.</p><p>added patch</p><p>That one applies cleanly and passes all tests. It should show up on the next list of prescreened patches. Thanks.</p><p>we don't use the queue* convention elsewhere, e.g. vec and vector. I think queue should take a collection like vec and set. (queue <span class="error">&#91;1 2 3&#93;</span>) could be made to 'adopt' the collection as front.</p><p>Patch queue.patch dated Oct 26 2012 no longer applies cleanly after recent <a href="http://dev.clojure.org/jira/browse/CLJ-1000" title="Performance drop in PersistentHashMap.valAt(...) in v.1.4 -- Util.hasheq(...) ?"><del>CLJ-1000</del></a> commits, but only because of one line of changed patch context. It still applies cleanly with "patch -p1 &lt; queue.patch". Not bothering to update the stale patch given Rich's comments suggesting more substantive changes.</p><p>See also <a href="http://dev.clojure.org/jira/browse/CLJ-976" title="Implement reader literal and print support for PersistentQueue data structure">CLJ-976</a> (tagged literal support for PersistentQueue)</p><p>Don't want to step on Timothy B's toes here, but it looks straightforward to adopt his patch to implement Rich's suggestion. I'd offer to give it a whack if nobody else wants the ticket now.</p><p>Discussion initiated on clojure-dev: <a href="https://groups.google.com/forum/?fromgroups#!topic/clojure-dev/2BOqHm24Vc4">https://groups.google.com/forum/?fromgroups#!topic/clojure-dev/2BOqHm24Vc4</a></p><p>This patch (if accepted) supersedes Timothy Baldridge's patch; it implements "queue" and "queue?" (but not "queue*"); "queue" accepts a collection rather than being a variadic function, as per Rich's suggestion.</p><p>The patch clj-1048-queue-takes-collections.diff applied cleanly to latest Clojure master as of Jan 23 2014, but not on Jan 30 2014. There were several commits made to Clojure during that week involving updating the hash functions that conflict in some way with this patch. I have not checked to see how easy or difficult it might be to update the patch.</p><p>Hi Andy, I updated the patch and removed my previous version. The new one should apply cleanly and pass all tests.</p><p>Updated ticket title.</p><p>Hi John... Can you condense these changes into a single commit? Please also remove the comments above queue* in java_interop.clj. Thanks...</p><p>Hi Alex, the updated patch removes that comment and rebases all three commits into c9f77dd. Let me know if you need anything else. Thanks!</p><p>A tiny remark - I think the docstrings should end with a dot.</p>Global RankPatchCode and Test[CLJ-1077] thread-bound? returns true (implying set! should succeed) even for non-binding threadhttp://dev.clojure.org/jira/browse/CLJ-1077
Clojure<p>thread-bound? returns true for a non-binding thread, this result (according to the docstring) implies that set! should succeed. However, thread-bound? does not check that any binding that might exist was created by the current thread, and calling set! fails with an exception when it is called from a non-binding thread, even though thread-bound? returns true.</p>
<p>thread-bound? should return false if there is a binding, and that binding was not established by the current thread.</p>
<p>Here is an example REPL session where a thread establishes a binding, those bindings are conveyed to a second thread, the second thread checks thread-bound? to see if it can set the binding, thread-bound? returns true indicating that the binding can be set, the second thread tries to set the binding, and the second thread gets an IllegalStateException:</p>
<div class="preformatted panel" style="border-width: 1px;"><div class="preformattedContent panelContent">
<pre> Clojure 1.5.1
user=&gt; (def ^:dynamic *set-me* nil)
#'user/*set-me*
user=&gt; (defn try-to-set [] (binding [*set-me* 1] (doall (pcalls #(if (thread-bound? #'*set-me*) (set! *set-me* (inc *set-me*)))))))
#'user/try-to-set
user=&gt; (try-to-set)
IllegalStateException Can't set!: *set-me* from non-binding thread clojure.lang.Var.set (Var.java:230)
user=&gt;
</pre>
</div></div>CLJ-1077thread-bound? returns true (implying set! should succeed) even for non-binding threadDefectMajorOpenUnresolvedUnassignedPaul StadigWed, 26 Sep 2012 13:51:28 -0500Tue, 20 Aug 2013 07:55:04 -050030<p>I have attached a patch that changes clojure.lang.Var and clojure.core/thread-bound? to only return true if a Var is set!-able.</p><p>REPL example?</p><p>Sure thing, Alex &#8211; here's a repl example I just ran this morning.</p>
<div class="preformatted panel" style="border-width: 1px;"><div class="preformattedContent panelContent">
<pre>; nREPL 0.1.7
user&gt; (def ^:dynamic *set-me* nil)
#'user/*set-me*
user&gt; (defn try-to-set [] (binding [*set-me* 1] (doall (pcalls #(if (thread-bound? #'*set-me*) (set! *set-me* (inc *set-me*)))))))
#'user/try-to-set
user&gt; (try-to-set)
IllegalStateException Can't set!: *set-me* from non-binding thread clojure.lang.Var.set (Var.java:230)
user&gt;</pre>
</div></div>Global RankPatchCode[CLJ-1063] Missing dissoc-inhttp://dev.clojure.org/jira/browse/CLJ-1063
Clojure<p>There is no clojure.core/dissoc-in although there is an assoc-in.<br/>
It is correct that dissoc-in can be build with update-in and dissoc but this is an argument against assoc-in as well.<br/>
When a shortcut for assoc-in is provided, there should also be one for dissoc-in for consistency reasons.<br/>
Implementation is analogical to assoc-in.</p>CLJ-1063Missing dissoc-inEnhancementMinorOpenUnresolvedUnassignedGunnar VölkelFri, 7 Sep 2012 05:20:59 -0500Fri, 26 Jul 2013 15:10:18 -0500Release 1.412<p>Patch clj-1063-add-dissoc-in-patch-v2.txt dated Sep 13 2012 supersedes 001-dissoc-in.diff dated Sep 7 2012. It fixes a typo (missing final " in doc string), and adds a test case for the new function.</p><p>Thanks for the fix Andy</p><p>This proposed dissoc-in should be compared with the one in clojure.core.incubator which I just happened across. I see they look different, but haven't examined to see if there are any behavior differences.</p>
<p><a href="https://github.com/clojure/core.incubator/blob/master/src/main/clojure/clojure/core/incubator.clj">https://github.com/clojure/core.incubator/blob/master/src/main/clojure/clojure/core/incubator.clj</a></p><p>dissoc-in in clojure.core.incubator recursively removes empty maps</p>
<p>user=&gt; (clojure.core.incubator/dissoc-in {:a {:b {:c 1}}} <span class="error">&#91;:a :b :c&#93;</span>)<br/>
{}</p>
<p>while the one in this patch doesn't (as I would expect)</p>
<p>user=&gt; (dissoc-in {:a {:b {:c 1}}} <span class="error">&#91;:a :b :c&#93;</span>)<br/>
{:a {:b {}}}</p><p>Please do this work in the incubator.</p>Global RankPatchCode and Test[CLJ-1060] 'list*' returns not a listhttp://dev.clojure.org/jira/browse/CLJ-1060
Clojure<p>Function 'list*' returns sequence, but not a list.<br/>
It is a bit confusing.</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">user=&gt; (list? (list* 1 '(2 3)))
<span class="code-keyword">false</span></pre>
</div></div>CLJ-1060'list*' returns not a listDefectTrivialOpenUnresolvedUnassignedAndrei ZhlobichMon, 3 Sep 2012 06:32:23 -0500Thu, 26 Feb 2015 15:11:06 -0600Release 1.403<p>should the docstring for list* change to say it returns a seq?</p><p>Is there a reason why we can't have list* actually return a list? The cost of creating a list vs a cons is negligible.</p><p>The question is what to do with the one-argument case of list*, because in cases like: (list* {:a 1 :b 2}) it doesn't return IPersistentList as well. I propose just applying 'list'.</p>
<p>I added patch 'list-star-fix.diff' (dated 04/Jan/2013) with Cons implementing IPersistentList and doing (apply list args) in one-argument case of list*. To be able to use 'apply' in list* I had to declare it before the definition of list* in the source code. The apply itself also uses list*, but luckily not the one-argument version of list*, so it should be safe... The patch also contains simple unit tests.</p>
<p>Discussion is also here: <a href="https://groups.google.com/forum/#!topic/clojure/co8lcKymfi8">https://groups.google.com/forum/#!topic/clojure/co8lcKymfi8</a></p><p>(apply list args) would make (list* (range)) hang, where currently it returns a partially-realized lazy seq. Also, even for non-lazy seqs &#8211; possibly lists themselves &#8211; it would always build a new list from scratch, right?</p>
<p>Also, if I'm reading the patch correctly, it would make 2+-ary list&#42; overloads and cons return lists &#8211; that is, IPersistentList instances &#8211; always (Conses would now be lists), but repeatedly calling next on such a list might eventually produce a non-list. The only way around that would be to make all seqs into IPersistentLists &#8211; that doesn't seem desirable at first glance...?</p>
<p>On a side note, for the case where the final "args" argument is in fact a list, we already have a "prepend many items" function, namely conj. list&#42; currently acts as the vararg variant of cons (in line with Lisp tradition); I'm actually quite happy with that.</p><p>I'm in favour of the "list" -&gt; "seq" tweak to the docstring though, assuming impl remains unchanged.</p><p>Yep, these are all valid points, thanks! I see this as a question whether the list* function is a list constructor or not. If yes (and it would be possible to implement it in a satisfactory way), it should probably return a list.</p>
<p>We could avoid building a new list by sth like:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">(<span class="code-keyword">if</span> (list? args)
args
(apply list args))</pre>
</div></div>
<p>(btw, 'vec' also creates a new vector even when the argument itself is a vector)</p>
<p>The contract of next seems to be to return a seq, not a list - its docstring reads: <em>"Returns a seq of the items after the first. Calls seq on its argument. If there are no more items, returns nil."</em></p>
<p>Btw, in some Lisp/Scheme impls I checked, cons seems to be a list as well. E.g. in CLisp (and similar in Guile and Racket):</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">&gt; (listp (cons 2 '()))
T
&gt; (listp (list* 1 2 '()))
T</pre>
</div></div><p>I bump into this every once in a while and it bothers my pedantic side.</p>
<p>I think it's too late to change the implementation of `list*`. There's a risk of breaking existing code (dealing with lazy-seqs, etc.) It would be good to change the doc string to say it returns a seq, not a list. </p>
<p>But the real issue is the name of the function implies that it will return a list. You could deprecate `list*` (but keep it forever for backwards compatibility.) A better name for the same implementation might be `seq*`.</p>Global RankPatchCode and Test[CLJ-1059] PersistentQueue doesn't implement java.util.List, causing nontransitive equalityhttp://dev.clojure.org/jira/browse/CLJ-1059
Clojure<p>PersistentQueue implements Sequential but doesn't implement java.util.List. Lists form an equality partition, as do Sequentials. This means that you can end up with nontransitive equality:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">(def q (conj clojure.lang.PersistentQueue/EMPTY 1 2 3))
;=&gt; #user/q
(def al (doto (java.util.ArrayList.) (.add 1) (.add 2) (.add 3)))
;=&gt; #user/al
(def v [1 2 3])
;=&gt; #user/v
(= al v)
;=&gt; <span class="code-keyword">true</span>
(= v q)
;=&gt; <span class="code-keyword">true</span>
(not= al q)
;=&gt; <span class="code-keyword">true</span></pre>
</div></div>
<p>This happens because PersistentQueue is a Sequential but not a List, ArrayList is a List but not a Sequential, and PersistentVector is both.</p>CLJ-1059PersistentQueue doesn't implement java.util.List, causing nontransitive equalityDefectMajorOpenUnresolvedPhilip PotterPhilip PotterqueueMon, 3 Sep 2012 04:23:59 -0500Mon, 11 Aug 2014 01:37:06 -0500Release 1.413<p>Whoops, according to <a href="http://dev.clojure.org/display/design/JIRA+workflow">http://dev.clojure.org/display/design/JIRA+workflow</a> I should have emailed clojure-dev before filing this ticket. Here is the discussion:</p>
<p><a href="https://groups.google.com/d/topic/clojure-dev/ME3-Ke-RbNk/discussion">https://groups.google.com/d/topic/clojure-dev/ME3-Ke-RbNk/discussion</a></p><p>Attached 001-make-PersistentQueue-implement-List.diff, 15/Sep/12</p>
<p>Note that this patch has a minor conflict with the one I added to <a href="http://dev.clojure.org/jira/browse/CLJ-1070" title="PersistentQueue&#39;s hash function does not match its equality"><del>CLJ-1070</del></a>, because both add an extra interface to PersistentQueue - List in this case, IHashEq in <a href="http://dev.clojure.org/jira/browse/CLJ-1070" title="PersistentQueue&#39;s hash function does not match its equality"><del>CLJ-1070</del></a>.</p><p>Philip, patch looks pretty good &#8211; thanks for doing this. A couple notes:</p>
<p>This is only my opinion, but I prefer imports be listed without wildcards, even if it means an extra couple lines at the top of a .java file.</p>
<p>I noticed the "List stuff" code is a copy of what's in ASeq and EmptyList. I suppose this is copied because EmptyList and PersistentQueue extend Obj and therefore can't extend ASeq. Is this the only reason? It seems a shame to duplicate these method definitions, but I don't know of a better solution, do you?</p>
<p>It would also be nice if the test check a couple of the List methods you've implemented.</p><p>oh, also "git am" refused to apply the patch, but I'm not sure why. "patch -p 1" worked perfectly.</p><p>did you use the --keep-cr option to git am?</p>
<p>I struggled to know whether I should be adding CRs or not to line endings, because the files I was editing weren't consistent in their usage. If you open them in emacs, half the lines have ^M at the end.</p><p>Will submit another patch, with the import changed. I'll have a think about the list implementation and see what ideas I can come up with.</p><p>Attached 002-make-PersistentQueue-implement-Asequential.diff</p>
<p>This patch is an alternative to 001-make-PersistentQueue-implement-List.diff</p>
<p>So I took on board what you said about ASeq, but it didn't feel right making PersistentQueue directly implement ISeq, somehow.</p>
<p>So I split ASeq into two parts &#8211; ASequential, which implements j.u.{Collection,List} and manages List-equality and hashcodes; and ASeq, which... doesn't seem to be doing much anymore, to be honest.</p>
<p>As a bonus, this patch fixes <a href="http://dev.clojure.org/jira/browse/CLJ-1070" title="PersistentQueue&#39;s hash function does not match its equality"><del>CLJ-1070</del></a> too, so I went and added the tests from that ticket in to demonstrate this fact. It also tidies up PersistentQueue by removing all equals/hashcCode stuff and all Collection stuff.</p>
<p>(It turns out that because ASeq was already implementing Obj, the fact that PersistentQueue was implementing Obj was no barrier to using it.)</p>
<p>Would appreciate comments on this approach, and how it differs from the previous patch here and the patch on <a href="http://dev.clojure.org/jira/browse/CLJ-1070" title="PersistentQueue&#39;s hash function does not match its equality"><del>CLJ-1070</del></a>.</p><p>Looking at EmptyList's implementation of List, it is a duplicate of the others, but it shouldn't be. I think its implementation of indexOf is the biggest culprit - it should just be 'return -1;' but it has a great big for loop! But this is beyond the scope of this ticket, so I won't patch that here.</p><p>Philip, now that the patch for <a href="http://dev.clojure.org/jira/browse/CLJ-1070" title="PersistentQueue&#39;s hash function does not match its equality"><del>CLJ-1070</del></a> has been applied, these patches no longer apply cleanly. Would you be willing to update them? If so, please remove the obsolete patches.</p><p>Andy, thanks so much for your efforts to make people aware of these things. I will indeed submit new patches, hopefully later this week.</p><p>Replaced existing patches with new ones which apply cleanly to master.</p>
<p>There are two patches:</p>
<p>001-clj-1059-make-persistentqueue-implement-list.diff</p>
<p>This fixes equality by making PersistentQueue implement List directly. I also took the opportunity to remove the wildcard import and to add tests for the List methods, as compared with the previous version of the patch.</p>
<p>002-clj-1059-asequential.diff</p>
<p>This fixes equality by creating a new abstract class ASequential, and making PersistentQueue extend this.</p>
<p>My preferred solution is still the ASequential patch, but I'm leaving both here for comparison.</p><p>Vetting. </p><p>Philip, this time I think it was patches that were committed for <a href="http://dev.clojure.org/jira/browse/CLJ-1000" title="Performance drop in PersistentHashMap.valAt(...) in v.1.4 -- Util.hasheq(...) ?"><del>CLJ-1000</del></a> that make your patch 002-clj-1059-asequential.diff not apply cleanly. I often fix up stale patches where the change is straightforward and mechanical, but in this case you are moving some methods that <a href="http://dev.clojure.org/jira/browse/CLJ-1000" title="Performance drop in PersistentHashMap.valAt(...) in v.1.4 -- Util.hasheq(...) ?"><del>CLJ-1000</del></a>'s patch changed the implementation of, so it would be best if someone figured out a way to update this patch in a way that doesn't clobber the <a href="http://dev.clojure.org/jira/browse/CLJ-1000" title="Performance drop in PersistentHashMap.valAt(...) in v.1.4 -- Util.hasheq(...) ?"><del>CLJ-1000</del></a> changes.</p><p>Thanks Andy. Submitted a new patch, 002-clj-1059-asequential-rebased-to-cached-hasheq.diff, which supersedes 002-clj-1059-asequential.diff.</p>
<p>The patch 001-clj-1059-make-persistentqueue-implement-list.diff still applies cleanly, and is still an alternative to 002-clj-1059-asequential-rebased-to-cached-hasheq.diff.</p><p>With the commits to Clojure master made in the week leading up to Jan 30 2014, particularly changes to hasheq, patch 002-clj-1059-asequential-rebased-to-cached-hasheq.diff no longer applies cleanly.</p>
<p>Patch 001-clj-1059-make-persistentqueue-implement-list.diff still does.</p><p>This issue was run into again and a duplicate ticket <a href="http://dev.clojure.org/jira/browse/CLJ-1374" title="Make PersistentQueue implement List"><del>CLJ-1374</del></a> created &#8211; later closed as a duplicate of this one. Just wanted to record that this issue is being hit by others besides those originally reporting it.</p><p>One or more commits made to Clojure master between Aug 1 2014 and Aug 10 2014 conflict with the patch 001-clj-1059-make-persistentqueue-implement-list.diff, and it no longer applies cleanly.</p>Global RankPatchCode and Test[CLJ-1057] Var's .setDynamic does not set :dynamic in metadatahttp://dev.clojure.org/jira/browse/CLJ-1057
Clojure<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">((juxt (comp :dynamic meta) #(.isDynamic %)) #'*agent*)</pre>
</div></div>CLJ-1057Var's .setDynamic does not set :dynamic in metadataDefectTrivialOpenUnresolvedUnassignedBrandon BloomSun, 2 Sep 2012 13:06:21 -0500Mon, 3 Dec 2012 09:10:16 -060000<p>This is actually an enhancement as no where in the clojure code is provision made for syncing var's metadata and dynamic state. .isDynamic is the authoritative source, and the calling of .setDynamic is configured by the compiler. If you'd like to see this change, please, feel free to bring it up on clojure-dev for a discussion.</p>Global Rank[CLJ-1047] Simplify the process of requiring fj in clojure.core.reducershttp://dev.clojure.org/jira/browse/CLJ-1047
Clojure<p>this patch removes compile-if in favor of import-if, removing code duplication</p>CLJ-1047Simplify the process of requiring fj in clojure.core.reducersEnhancementMinorOpenUnresolvedUnassignedNicola MomettoreducersTue, 21 Aug 2012 18:27:01 -0500Tue, 3 Sep 2013 12:17:53 -050000Global RankPatchCode[CLJ-1046] Drop-while as a reducerhttp://dev.clojure.org/jira/browse/CLJ-1046
Clojure<p>Implement drop-while as a reducer. Follows the same atom-based strategy as drop and take.</p>
<p>Does not depend on any of my other reducer patches, but there will probably be some minor merge conflicts unless it is merged after <a href="http://dev.clojure.org/jira/browse/CLJ-1045" title="Generalize/refactor implementation of PersistentVector/coll-fold">CLJ-1045</a>, and before <a href="http://dev.clojure.org/jira/browse/CLJ-992" title="`iterate` reducer">CLJ-992</a> and <a href="http://dev.clojure.org/jira/browse/CLJ-993" title="`range` reducer">CLJ-993</a>.</p>CLJ-1046Drop-while as a reducerEnhancementMajorOpenUnresolvedUnassignedAlan MalloyreducersSat, 18 Aug 2012 19:11:59 -0500Wed, 3 Sep 2014 20:11:31 -050003<p>Patch drop-while-reducer.patch dated Aug 18 2012 no longer applies cleanly to latest master after some commits were made to Clojure on Sep 3, 2014.</p>
<p>I have not checked whether this patch is straightforward to update, nor do I know if there is interest in an updated patch, or whether transducers are the preferred way to go over reducers, and thus all reducers-related tickets will be closed. See the section "Updating stale patches" at <a href="http://dev.clojure.org/display/community/Developing+Patches">http://dev.clojure.org/display/community/Developing+Patches</a> for suggestions on how to update patches.</p>Global RankPatchCode and Test[CLJ-1045] Generalize/refactor implementation of PersistentVector/coll-foldhttp://dev.clojure.org/jira/browse/CLJ-1045
Clojure<p>Vector currently contains a specialized implementation of the folding algorithm "split the collection in half until the pieces are small enough". The attached commit lifts out the general strategy so that it can be reused by other collection types amenable to splitting.</p>
<p><a href="http://dev.clojure.org/jira/browse/CLJ-993" title="`range` reducer">CLJ-993</a> depends on this patch, as it uses the new fold-by-halves function.</p>CLJ-1045Generalize/refactor implementation of PersistentVector/coll-foldEnhancementMajorOpenUnresolvedUnassignedAlan MalloyreducersSat, 18 Aug 2012 19:06:24 -0500Tue, 3 Sep 2013 12:18:18 -050003<p>clj-1045-fold-by-halves-patch-v2.txt dated Jan 25 2013 is identical to fold-by-halves.patch dated Aug 18 2012, except it updates one line of context changed by a recent commit to Clojure master.</p>Global RankPatchCode[CLJ-1044] Enable refering to ->type inside deftypehttp://dev.clojure.org/jira/browse/CLJ-1044
Clojure<p>Inside a defrecord body it's possible to refer to -&gt;type-ctor but that is not possible inside deftype.</p>
<p>This patch adds an implicit declare, as done in defrecord making it possible to use the -&gt;type-ctor inside deftype methods</p>CLJ-1044Enable refering to ->type inside deftypeEnhancementTrivialOpenUnresolvedUnassignedNicola MomettodeftypeSat, 18 Aug 2012 08:02:50 -0500Sun, 31 Aug 2014 10:39:41 -050000<p>Seems valid. Vetting. </p>Global RankPatchCode[CLJ-1043] Unordered literals does not preserve left-to-right evaluation of argumentshttp://dev.clojure.org/jira/browse/CLJ-1043
Clojure<p>Given: (defn f <span class="error">&#91;x&#93;</span> (println x) x)</p>
<p>#{(f 2) (f 1)}</p>
<p>Prints:</p>
<p>1<br/>
2</p>
<p>But expected would be:</p>
<p>2<br/>
1</p>
<p>This issue is related to <a href="http://dev.clojure.org/jira/browse/CLJS-288" title="Compilation of unordered collections ">CLJS-288</a></p>CLJ-1043Unordered literals does not preserve left-to-right evaluation of argumentsDefectMinorOpenUnresolvedUnassignedBrandon BloomThu, 16 Aug 2012 21:25:31 -0500Sun, 23 Sep 2012 19:38:35 -0500Release 1.401<p>I have the same question as David Nolen for <a href="http://dev.clojure.org/jira/browse/CLJS-288" title="Compilation of unordered collections ">CLJS-288</a>: Is this a bug, or just behavior you didn't expect?</p>
<p>It seems that vectors preserve the order of evaluation, so if you really want