[CLJ-827] unsigned-bit-shift-right Created: 09/Aug/11 Updated: 24/May/13 |
|
| Status: | Open |
| Project: | Clojure |
| Component/s: | None |
| Affects Version/s: | None |
| Fix Version/s: | Release 1.6 |
| Type: | Enhancement | Priority: | Major |
| Reporter: | Joe Gallo | Assignee: | Unassigned |
| Resolution: | Unresolved | Votes: | 12 |
| Labels: | None | ||
| Attachments: |
|
| Patch: | Code |
| Approval: | Screened |
| Description |
|
Add a clojure equivalent of >>>. A simple version of this is implemented here (https://github.com/joegallo/clojure/tree/unsigned-bit-shift-right), and just follows the example set by shift-right. The downside of this implementation is that it treats all integer types as longs, and shifts them accordingly, which yields different results than you would get in java. A previous version of this did not have the same problem, when BitOps was its own thing. I'm not sure if this limitation is acceptable and appropriate, or needs to be worked around (my inclination is the latter). |
| Comments |
| Comment by Joe Gallo [ 11/Nov/11 12:58 PM ] |
|
I just realized (with the asssistance of Paul Stadig) that just doing only longs is probably sufficient, as you can get the integer version if you really want it: > (int (bit-and Integer/MAX_VALUE (unsigned-bit-shift-right -5 1))) Of course, that's less efficient than just doing it directly with java, but it's enough that I think my concern from the previous comment is addressed. |
| Comment by Tim McCormack [ 16/Jan/12 6:01 PM ] |
|
I have attached "0001-CLJ-827-Add-bit-shift-right-logical.patch", which implements a logical bit-shift-right using the same JVM bytecode as >>>. The patch mimics the implementations of << and >>. |
| Comment by Stuart Halloway [ 02/Feb/13 5:09 PM ] |
|
For context, this feature appears to be needed for Clojure-in-Clojure data structures: https://groups.google.com/d/msg/clojure-dev/iAwH7CLSFzE/6wzDH4RS1YQJ |
| Comment by Michał Marczyk [ 08/Feb/13 5:31 AM ] |
|
Just wanted to note that I've introduced this operation to ClojureScript when implementing PersistentHashMap. The name over there is bit-shift-right-zero-fill. Would it be alright for Clojure to use that name? Failing that, ClojureScript would probably have to change to match. |
| Comment by Gabriel Horner [ 24/May/13 2:23 PM ] |
|
I've added clj-827-unsigned-bit-shift-right-with-tests.patch which builds off of Tim's patch and adds tests. I also renamed the new fn to unsigned-bit-shift-right after chatting with Rich. @Michal - This may mean you need to rename the cljs fn. After this lands on master, I can open a ticket with a patch if you'd like. |
[CLJ-322] Enhance AOT compilation process to emit classfiles only for explicitly-specified namespaces Created: 29/Apr/10 Updated: 24/May/13 |
|
| Status: | In Progress |
| Project: | Clojure |
| Component/s: | None |
| Affects Version/s: | None |
| Fix Version/s: | Release 1.6 |
| Type: | Enhancement | Priority: | Major |
| Reporter: | Chas Emerick | Assignee: | Unassigned |
| Resolution: | Unresolved | Votes: | 12 |
| Labels: | None | ||
| Attachments: |
|
| Patch: | Code and Test |
| Approval: | Incomplete |
| Waiting On: | Chas Emerick |
| Description |
|
Summary: still needs decision on implementation approach. This was originally/erroneously reported by Howard Lewis Ship in the clojure-contrib assembla: My build file specifies the namespaces to AOT compile but if I include another namespace (even from a JAR dependency) that is not AOT compiled, the other namespace will be compiled as well. In my case, I was using clojure-contrib's clojure.contrib.str-utils2 namespace, and I got a bunch of clojure/contrib/str_utils2 classes in my output directory. I think that the AOT compiler should NOT precompile any namespaces that are transitively reached, only namespaces in the set specified by the command line are appropriate. As currently coded, you will frequently find unwanted third-party dependencies in your output JARs; further, if multiple parties depend on the same JARs, this could cause bloating and duplication in the eventual runtime classpath. Having the option of shipping either all AOT-compiled classfiles or mixed source/AOT depending upon one's distribution requirements would make that phase of work with a clojure codebase significantly easier and less error-prone. The only question in my mind is what the default should be. We're all used to the current behaviour, but I'd guess that any nontrivial project where the form of the distributable matters (i.e. the source/AOT mix), providing as much control as possible by default makes the most sense. Given the tooling that most people are using, it's trivial (and common practice, IIUC) to provide a comprehensive list of namespaces one wishes to compile, so making that the default shouldn't be a hurdle to anyone. If an escape hatch is desired, a --transitive switch to clojure.lang.Compile could be added. |
| Comments |
| Comment by Assembla Importer [ 28/Sep/10 12:18 AM ] |
|
Converted from http://www.assembla.com/spaces/clojure/tickets/322 |
| Comment by Assembla Importer [ 28/Sep/10 12:18 AM ] |
|
hlship said: I'd like to reinforce this. I've been doing research on Clojure build tools for an upcoming talk and all of them (Maven, Leiningen, Gradle) have the same problem: the AOT compile extends from the desired namespaces (such as one containing a :gen-class) to every reached namespace. This is going to cause a real ugliness when application A uses libraries B and C that both depend on library D (such as clojure-contrib) and B and C are thus both bloated with duplicate, unwanted AOT compiled classes from the library D. |
| Comment by Assembla Importer [ 28/Sep/10 12:18 AM ] |
|
cemerick said: This behaviour is an implementation detail of Clojure's AOT compilation process, and is orthogonal to any particular build tooling. I am working on a patch that would provide a mechanism for such tooling to disable this default behaviour. |
| Comment by Assembla Importer [ 28/Sep/10 12:18 AM ] |
|
cemerick said: A first cut of a change to address this issue is here (caution, work in progress!): http://github.com/cemerick/clojure/commit/6f14e0790c0d283a7e44056adf1bb3f36bb16e0e This makes available a new recognized system property, clojure.compiler.transitive, which defaults to true. When set/bound to false (i.e. -Dclojure.compiler.transitive=false when using clojure.lang.Compile), only the first loaded file (either the ns named in the call to compile or each of the namespaces named as arguments to clojure.lang.Compile) will have classfiles written to disk. This means that this compilation invocation: java -cp <your classpath> -Dclojure.compiler.transitive=false clojure.lang.Compile com.bar com.baz
will generate classfiles only for com.bar and com.baz, but not for any of the namespaces or other files they load, require, or use. The only shortcoming of this WIP patch is that classfiles are still generated for proxy and gen-class classes defined outside of the explicitly-named namespaces. What I thought was a solution for this ended up breaking the loading of generated interfaces (as produced by defprotocol, etc). I'll take a second look at this before the end of the week, but wanted to get this out there so as to get any comments people might have. |
| Comment by Assembla Importer [ 28/Sep/10 12:18 AM ] |
|
technomancy said: Looks good, but I'm having trouble getting it to work. I tried compiling from master of Chas's fork on github, but I still got the all the .class files generated with -Dclojure.compiler.transitive=false. It could be a quirk of the way I'm using ant to fork off processes though. Is it possible to set it using System/setProperty, or must it be given as a property on the command-line? |
| Comment by Assembla Importer [ 28/Sep/10 12:18 AM ] |
|
cemerick said: Bah, that's just bad documentation. :-/ The system property is only provided by clojure.lang.Compile; the value of it drives the binding of clojure.core/transitive-compile, which has a root binding of true. You should be able to configure the transitivity the same way you configure compile-path (system prop to clojure.lang.Compile or a direct binding when at the REPL, etc). If not, ping me in irc or elsewhere. |
| Comment by Assembla Importer [ 28/Sep/10 12:18 AM ] |
|
meikelbrandmeyer said: I think, excluding parts 'load'ed is a little strong. I have some namespaces which load several parts from different files, but which belong to the same namespace. The most prominent example of such a case is clojure.core itself. I'm find with stopping require and use, but load is a bit too much, I'd say. |
| Comment by Assembla Importer [ 28/Sep/10 12:18 AM ] |
|
technomancy said: Chas: Thanks; will give that a go. Meikel: Do people actually use load outside of clojure.core? I thought it was only used there because clojure.core is a "special" namespace where you want more vars to be available than can reasonably fit in a single file. Splitting up a namespace into several files is quite unadvisable otherwise. |
| Comment by Assembla Importer [ 28/Sep/10 12:18 AM ] |
|
technomancy said: I can confirm that this works for me modulo the proxy/gen-class issue that Chas mentioned. I would love to see this in Clojure 1.2; it would really clean up a lot of build-related issues. |
| Comment by Assembla Importer [ 28/Sep/10 12:18 AM ] |
|
meikelbrandmeyer said: I used it several times and this is the first time, I hear that it is unadvisable to do so. Even with a lower number of Vars in the namespace (c.c is here certainly exceptional) and might be of use to split several "sections" of code which belong to the same namespace but have different functionality. Whether to use a big comment in the source to indicate the section or split things into subfiles is a matter of taste. But it's a perfectly reasonable thing todo. Another use case, where I use this (and c.c.lazy-xml, IIRC) is to conditionally load code depending on whether a dependency is available or not. Eg. vimclojure uses c.c.pprint and c.c.stacktrace/clj-stacktrace transparently depending on their availability. There are perfectly legal uses of load. I don't see any "unadvisable" here. |
| Comment by Assembla Importer [ 28/Sep/10 12:18 AM ] |
|
cemerick said: Thanks, Meikel; I had forgotten about that use case, as I don't use load directly myself at all. I probably wouldn't say it's inadvisable, just mostly unnecessary. In any case, that's a good catch. It complicates things a bit, but we'll see what happens. I'm going to take another whack at resolving the proxy/gen-class case and narrowing the impact of nontransitivity to use and require later tonight. I agree wholeheartedly that this should be in 1.2, assuming the technical bits work out. This has been an irritant for quite a long time. I actually believe that nontransitivity should be the default – no one wants or expects to have classfiles show up for dependencies show up when a project is AOT-compiled. I think the only negative impact would be whoever still fiddles with compilation at the REPL, and doesn't use maven or lein – and even then, it's just a matter of binding another var. |
| Comment by Assembla Importer [ 28/Sep/10 12:18 AM ] |
|
meikelbrandmeyer said: Then the var should be added to the default bindings in the clojure.main repl. Then it's set!-able like the other vars ��� warn-on-reflection and friends. |
| Comment by Assembla Importer [ 28/Sep/10 12:18 AM ] |
|
cemerick said: This is looking pretty good (still WIP): http://github.com/cemerick/clojure/commit/fedfb022ecef420a932b3d69c182ec7a8e5960a6 Thank you again for mentioning load, Meikel: it was very helpful in resolving the proxy/gen-class issue as well. Just a single data point: the jar produced by the medium-sized project I've been using for testing the changes has shrunk from 1.8MB to less than 1MB. That's not the only reason this is a good change, but it's certainly a nice side-effect. |
| Comment by Assembla Importer [ 28/Sep/10 12:18 AM ] |
|
cemerick said: [file:aIWFiWHeGr35ImeJe5cbLA] |
| Comment by Assembla Importer [ 28/Sep/10 12:18 AM ] |
|
cemerick said: [file:aI7Eu-HeGr35ImeJe5cbLA] |
| Comment by Assembla Importer [ 28/Sep/10 12:18 AM ] |
|
cemerick said: Patched attached. The The user impact of changing the default would be:
|
| Comment by Assembla Importer [ 28/Sep/10 12:18 AM ] |
|
hlship said: Just had a brain-storm: How about an option to support transitive compilation, but only if the Clojure source file being compiled as a file: URL (i.e., its a local file on the file system, not a file stored in a JAR). That would make it easier to use compilation on the local project without transitively compiling imported libraries, such as clojure-contrib. So transitive-compile should be a keyword, not a boolean, with values :all (for 1.1 behavior), :none (to compile only the exact specified namespaces) or :local (to compile transitively, but only for local files, not source files from JARs). |
| Comment by Assembla Importer [ 28/Sep/10 12:18 AM ] |
|
cemerick said: (Crossposted to the clojure-dev list) I thought about this some, and I don't think that's a good idea, at least for now. I'm uncomfortable with semantics changing depending upon where code is being loaded from – which, depending upon a tool's implementation, might be undefined. E.g. if the com.foo.bar ns is available in source form in one directory, but as classes from a jar, and classpaths aren't being constructed in a stable fashion, then the results of compilation will change. If we decide that special treatment depending upon the source of code is warranted in the future, that's a fairly straightforward thing to do w.r.t. the API – we could have :all and :local as you suggest, with nil representing :none. |
| Comment by Assembla Importer [ 28/Sep/10 12:18 AM ] |
|
stu said: Rich is not comfortable enough with the implementation complexity of this patch (e.g. the guard clause for proxies and gen-class) to slide this in as a minor fix under the wire for 1.2. Better to live with the pain we know a little longer than ship something we don't have enough experience with to be confident. |
| Comment by Chas Emerick [ 19/Nov/10 9:28 PM ] |
|
Updated patch to cleanly apply to HEAD and address issues raised by screening done by Cosmin Stejerean. Also includes proper tests. Note: this patch's tests require the fix for |
| Comment by Stuart Halloway [ 29/Nov/10 7:18 AM ] |
|
the "-resolved" patch resolves a conflict in main.clj |
| Comment by Stuart Halloway [ 29/Nov/10 7:25 AM ] |
|
Several questions:
|
| Comment by Stuart Sierra [ 10/Dec/10 3:34 PM ] |
|
An alternative approach: patch write-classes-1.diff.gz From my forked branch What this patch does:
This approach was prompted by the following observations:
|
| Comment by Chas Emerick [ 10/Dec/10 4:04 PM ] |
|
S. Halloway: My apologies, I didn't know you had commented. I thought that, having assigned this issue to myself, I'd be notified of updates. FWIW, I aim to review your comments and SS' approach over the weekend. |
| Comment by Chas Emerick [ 16/Dec/10 7:36 AM ] |
|
S. Halloway: 1. Certainly shouldn't happen. AFAIK, others have screened the patch, presumably with a successful build. |
| Comment by Chas Emerick [ 16/Dec/10 9:00 AM ] |
|
I think S. Sierra's approach is fundamentally superior what I offered. I have two suggestions: one slight perspective change (which implies no change in the actual implementation), and an idea for an even simpler approach (at least from a user perspective), in that order. While interop is the driving requirement behind AOT, I absolutely do not want to have to keep an updated enumeration of all of the classes resulting from each and every defrecord et al. usages in my pom.xml/project.clj (and I wouldn't wish the task of ferreting those usages and their resulting classnames on any build tool author). Right now, *compile-write-classes* is documented to be a set of classname strings, but could just as easily be any other function. *compile-write-classes* should be documented to accept any predicate function (renamed to e.g. *compile-write-class?*?). There's no reason why it shouldn't be bound to, e.g. #(re-matches #"foo\.bar\.[\w_]+$" %) if I know that all my records are defined in the foo.bar namespace. To go along with that, I think some package/classname-globbing utilities along with corresponding options to clojure.lang.Compile would be most welcome. Classname munging rules are not exactly obvious, and it'd be good to make things a little easier for users in this regard. Another alternativeIf there's a closed set of forms that generate classes that one might reasonably be interested in having in a build result (outside of use cases for pervasive AOT), then why not have a simple option that only those forms utilize? gen-class and gen-interface already do this, but reusing the all-or-nothing *compile-files* binding; if they keyed off of a binding that implied a diminished scope (e.g. *compile-interop-forms* – which would be true if *compile-files* were true), then they'd do exactly what we wanted. Extending this approach to deftype (and therefore defrecord) should be straightforward. An implementation of this would probably be somewhat more complicated than S. Sierra's patch, though not as complex as my original stab at the problem (i.e. no *load-level*). On the plus side: 1. No additional configuration for users or implementation work for build tool authors, aside from the addition of the boolean diminished-scope AOT option I can see wanting to further restrict AOT to specific classnames in certain circumstances, in which case the above and S. Sierra's patch might be complimentary. |
| Comment by Stuart Sierra [ 16/Dec/10 11:49 AM ] |
|
I like the idea of *compile-interop-forms*. But is it always possible to determine what an "interop form" is? I think it is, I'm just not sure. |
| Comment by Allen Rohner [ 09/Oct/11 12:50 PM ] |
|
I'm also in favor of compile-interop-forms. As far as determining, how about sticking metadata on the var? (defmacro ^{:interop-form true} deftype ...) |
| Comment by Stuart Sierra [ 21/Oct/11 8:38 AM ] |
|
Summary and design discussion on wiki at http://dev.clojure.org/display/design/Transitive+AOT+Compilation |
| Comment by Stuart Sierra [ 29/Nov/11 6:54 PM ] |
|
New attachment compile-interop-1.patch has new approach: Add a third possible value for *compile-files*. True and false keep their original meanings, but :interop causes only interop-related forms to be written out as .class files. "Interop forms" are gen-class, gen-interface, deftype, defrecord, defprotocol, and definterface. Pros:
Cons:
|
| Comment by Stuart Sierra [ 02/Dec/11 8:12 AM ] |
|
Just realized my patch doesn't solve the transitive compilation problem. If library A loads library B, then compiling interop forms in A will also emit interop .class files in B. |
| Comment by Paudi Moriarty [ 01/Jan/13 3:55 AM ] |
|
It's disappointing to see an important issue like this still unresolved after 2.5 years. This is a real pain for us. We have a large closed source project where shipping source is not an option. This forces us to manage the AOT'ing of dependencies due to the hard dependency on protocol interfaces introduced by transitive AOT compilation (see https://groups.google.com/forum/?fromgroups=#!topic/clojure-dev/r3A1JOIiwVU). |
| Comment by Andy Fingerhut [ 01/Jan/13 4:27 PM ] |
|
Paul, do you have a suggestion for which of the approaches described in comments here, or on the wiki page http://dev.clojure.org/display/design/Transitive+AOT+Compilation would be preferable solution for you? Or perhaps even a patch that implements your preferred approach? |
| Comment by Howard Lewis Ship [ 04/Jan/13 4:18 PM ] |
|
Andy, I'm now consulting with Paudi's organization, so I think I can speak for him (I'm now the default buildmeister). I like Stuart's :interop idea, but that is somewhat orthogonal to our needs. I return to what I would like; compilation would compile specific namespaces; dependencies of those namespaces would not be compiled. To be honest, I'm still a little hung up on the interop forms: especially defprotocol and friends; from a cursory glance, it appears that todays AOT compilation will compile the protocol into a Java class, then compile the namespace that references the protocol with the assumption that the protocol's Java class is available. When we use build rules to only package our namespace's class files into the output JAR, the code fails with a NoClassDefFoundError because the protocol really needs to be recompiled, at runtime compilation, into an in-memory Java class. Obviously, supporting this correctly will be a challenge; the compiled bytecode for our namespace would ideally: I can imagine any number of ways to juggle things to make this work, so I won't suggest a specific implementation. In the meantime, our workaround is to create a "stub" module as part of our build; it simply requires in the necessary namespaces (for example, org.clojure:core.cache); this forces an AOT compile of the dependencies and we have a special rule to package such dependencies in the stub module's output JAR. This may not be a scalable problem, and it is expensive to identify what 3rd party dependencies require this treatment. |
| Comment by Stuart Halloway [ 24/May/13 1:25 PM ] |
|
I am marking this incomplete because there does not yet seem to be plurality, much less consensus or unanimity, on approach. Personally I am in favor of a solution based on a predicate that gets handed the class name and compiled bits, and then can choose whether to write the class. Pretty close to Stuart Sierra's compile-write-classes. Might be possible to flow more information than classname to the predicate. |
[CLJ-1016] Global scope overrides lexical scope for classes (Clojure assumes no classes in default package / Clojure cannot handle yFiles JARs in classpath) Created: 21/Jun/12 Updated: 24/May/13 |
|
| Status: | Open |
| Project: | Clojure |
| Component/s: | None |
| Affects Version/s: | Release 1.5 |
| Fix Version/s: | None |
| Type: | Defect | Priority: | Major |
| Reporter: | Edward Z. Yang | Assignee: | Unassigned |
| Resolution: | Unresolved | Votes: | 0 |
| Labels: | None | ||
| Attachments: |
|
| Description |
|
The most visible symptom of this bug is having a class named 'w' (default package) in your classpath (such classes are produced by Java obfuscation tools such as yFiles) and then attempting to load Clojure's core class. For example: java -cp hotspotapi.jar:clojure-1.4.0-slim.jar clojure.main (where hotspotapi.jar is a stereotypical example of an obfuscated JAR) results in: Exception in thread "main" java.lang.ExceptionInInitializerError To understand what is going on, consider this simple test: import java.io.StringReader; import clojure.lang.Compiler; public class Test { It should be clear that 'mumble' in the dot operator is referencing the locally defined mumble. However, if we define a class named 'mumble' in the default package, Clojure picks that one up instead. To forestall any objections: yes, we know that placing classes in the default package is extremely poor form. Point of the matter is, the Java ecosystem is extremely diverse and there are a lot of JARs people may not have control over. While one might argue, "Don't put classes in the default namespace", point of the matter is, Clojure is wrong here, and these situations arise in practice, through no fault of the implementer. |
| Comments |
| Comment by Edward Z. Yang [ 21/Jun/12 11:01 AM ] |
|
Here is a workaround patch which makes this error less likely to occur. |
| Comment by Andy Fingerhut [ 27/Aug/12 7:37 PM ] |
|
Edward, it is Rich Hickey's policy only to consider for inclusion in Clojure patches written by people who have signed a Contributor Agreement: http://clojure.org/contributing Were you interested in becoming a contributor? |
| Comment by Edward Z. Yang [ 27/Aug/12 9:24 PM ] |
|
Sure, although the patch attached is emphatically not the one you want to actually applying, since it only band-aids the problem. |
| Comment by Andy Fingerhut [ 24/May/13 1:21 PM ] |
|
I am not sure, but this ticket may be related to CLJ-1171. At least, there the issue was a global name not being shadowed by a local name bound with let. That seems similar to this issue. |
[CLJ-1074] Read/print round-trip for +/-Infinity and NaN Created: 21/Sep/12 Updated: 24/May/13 |
|
| Status: | Open |
| Project: | Clojure |
| Component/s: | None |
| Affects Version/s: | Release 1.4 |
| Fix Version/s: | None |
| Type: | Defect | Priority: | Minor |
| Reporter: | Colin Jones | Assignee: | Unassigned |
| Resolution: | Unresolved | Votes: | 2 |
| Labels: | patch | ||
| Attachments: |
|
| Patch: | Code and Test |
| Description |
|
A few float-related forms (namely, Double/POSITIVE_INFINITY, Double/NEGATIVE_INFINITY, Double/NaN) are not eval-able after a round-trip via (read-string (binding [*print-dup* true] (pr-str f))
The two options I see are to provide print-method implementations for these and their Float cousins, or to make Infinity, -Infinity, +Infinity, and NaN readable values. Since it sounds like edn may want to provide a spec for these values (see https://groups.google.com/d/topic/clojure-dev/LeJpOhHxESs/discussion and https://github.com/edn-format/edn/issues/2), I think making these values directly readable as already printed is preferable. Something like Double/POSITIVE_INFINITY seems too low-level from edn's perspective, as it would refer to a Java class and constant. I'm attaching a patch implementing reader support for Infinity, -Infinity, +Infinity, and NaN. |
| Comments |
| Comment by Timothy Baldridge [ 03/Dec/12 11:34 AM ] |
|
Please bring this up on clojure-dev. We'll be able to vet this ticket after that. |
| Comment by Colin Jones [ 03/Dec/12 1:18 PM ] |
|
Should I respond to my original clojure-dev post about this (linked in the issue description above), or start a new one? |
| Comment by Andy Fingerhut [ 24/May/13 1:11 PM ] |
|
Patch clj-1074-read-infinity-and-nan-patch-v2.txt dated May 24 2013 is identical to 0001-Read-Infinity-and-NaN.patch dated Sep 21 2012, except it applies cleanly to latest master. The older patch conflicts with a recent commit made for |
[CLJ-669] clojure.java.io/do-copy: use java.nio for Files Created: 01/Nov/10 Updated: 24/May/13 |
|
| Status: | Open |
| Project: | Clojure |
| Component/s: | None |
| Affects Version/s: | Release 1.3 |
| Fix Version/s: | Release 1.6 |
| Type: | Enhancement | Priority: | Minor |
| Reporter: | Jürgen Hötzel | Assignee: | Unassigned |
| Resolution: | Unresolved | Votes: | 0 |
| Labels: | None | ||
| Attachments: |
|
| Patch: | Code |
| Description |
|
NIO Channels reduce CPU/Disk load when copying Files (by using CPU-Load goes from 100% to 0% on my system when copying large files, because no userspace-copying is involved: Patch: http://github.com/juergenhoetzel/clojure/commit/2b5ab103cbcfe6c49236ac6966c032d3c922233d |
| Comments |
| Comment by Jürgen Hötzel [ 27/Nov/10 5:05 AM ] |
|
Patch instead of linking to github |
| Comment by Andy Fingerhut [ 24/May/13 12:45 PM ] |
|
Patch clj-669-use-java.nio-in-do-copy-for-files-patch-v2.txt dated May 24 2013 is identical to patch 0001-use-java.nio-in-do-copy-method-for-Files.patch dated Nov 27 2010 except it applies cleanly to latest master. The older patch conflicts with a recent commit for |
[CLJ-1107] 'get' should throw exception on non-Associative argument Created: 13/Nov/12 Updated: 24/May/13 |
|
| Status: | Open |
| Project: | Clojure |
| Component/s: | None |
| Affects Version/s: | None |
| Fix Version/s: | None |
| Type: | Enhancement | Priority: | Minor |
| Reporter: | Stuart Sierra | Assignee: | Stuart Sierra |
| Resolution: | Unresolved | Votes: | 1 |
| Labels: | None | ||
| Attachments: |
|
| Patch: | Code and Test |
| Description |
|
The implementation of clojure.core/get returns null if its argument is not a valid associative collection. However, calling 'get' on something which is neither nil nor an Associative collection is almost certainly a bug, and should be indicated by an exception. This behavior can obscure common programmer errors such as: (def a (atom {:a 1 :b 2})
(:foo a) ; forgot to deref a
;;=> nil
Attached patch 0001 throws an IllegalArgumentException as the fall-through case of RT.getFrom. |
| Comments |
| Comment by Andy Fingerhut [ 24/May/13 12:31 PM ] |
|
Patch clj-1107-throw-on-get-for-unsupported-types-patch-v2.txt dated May 24 2013 is identical to 0001-CLJ-1107-Throw-exception-for-get-called-on-unsupport.patch dated Nov 13 2012, except it applies cleanly to latest master. A recent commit for |
[CLJ-850] Hinting the arg vector of a primitive-taking fn with a non-primitive type results in AbstractMethodError when invoked Created: 09/Oct/11 Updated: 24/May/13 |
|
| Status: | Open |
| Project: | Clojure |
| Component/s: | None |
| Affects Version/s: | Release 1.3 |
| Fix Version/s: | Release 1.6 |
| Type: | Defect | Priority: | Major |
| Reporter: | Alexander Taggart | Assignee: | Stuart Halloway |
| Resolution: | Unresolved | Votes: | 2 |
| Labels: | None | ||
| Attachments: |
|
| Patch: | Code and Test |
| Approval: | Screened |
| Description |
|
Summary: The CLJ-850-conform-to-invokePrim.diff patch is constructed per Rich's feedback, and appears good to me [Stu]. See the following examples: user=> (defn f1 ^String [^String s] s) #'user/f1 user=> (f1 "foo") "foo" user=> (defn f2 ^long [^String s ^long i] i) #'user/f2 user=> (f2 "foo" 1) 1 user=> (defn f3 ^String [^String s ^long i] s) #'user/f3 user=> (f3 "foo" 1) AbstractMethodError user$f3.invokePrim(Ljava/lang/Object;J)Ljava/lang/Object; user/eval8 (NO_SOURCE_FILE:6) |
| Comments |
| Comment by Ben Smith-Mannschott [ 15/Oct/11 11:54 AM ] |
|
CLJ-850-test.patch added. |
| Comment by Ben Smith-Mannschott [ 16/Oct/11 7:32 AM ] |
|
XXX this is where I got myself confused. The invokePrim overload it's trying to invoke is the correct one. But, that apparently is no the one that's being generated. Sorry for the noise. |
| Comment by Ben Smith-Mannschott [ 16/Oct/11 10:17 AM ] |
|
|
| Comment by Ben Smith-Mannschott [ 18/Oct/11 12:29 AM ] |
|
There are two things going on here. I'm not sure which is the error. It looks like the return type of the generated invokePrim method is too specific. It's generated as returning String, though the IFn$LO interface specifies returning Object. The caller attempts to call invokePrim returning Object, which is what the interface IFn$LO specifies, but this doesn't work because methodSL doesn't actually implement that method. Instead it implements an overload returning String.
(defn methodSL ^String [^long i] (str i)) <<1>> public final java.lang.String invokePrim(long); <<1>>
Code:
0: getstatic #25;
//Field const__0:Lclojure/lang/Var;
3: invokevirtual #34;
//Method clojure/lang/Var.getRawRoot:()Ljava/lang/Object;
6: checkcast #36;
//class clojure/lang/IFn
9: lload_1
10: invokestatic #42;
//Method clojure/lang/Numbers.num:(J)Ljava/lang/Number;
13: invokeinterface #46, 2;
//InterfaceMethod clojure/lang/IFn.invoke:(Ljava/lang/Object;)Ljava/lang/Object;
18: checkcast #48;
//class java/lang/String
21: areturn
public java.lang.Object invoke(java.lang.Object);
Code:
0: aload_0
1: aload_1
2: checkcast #54;
//class java/lang/Number
5: invokestatic #58;
//Method clojure/lang/RT.longCast:(Ljava/lang/Object;)J
<<2>> 8: invokeinterface #60, 3;
//InterfaceMethod clojure/lang/IFn$LO.invokePrim:(J)Ljava/lang/String;
13: areturn
(defn callSL ^String [] (methodSL 42)) public java.lang.Object invoke();
Code:
0: getstatic #25;
//Field const__0:Lclojure/lang/Var;
3: invokevirtual #43;
//Method clojure/lang/Var.getRawRoot:()Ljava/lang/Object;
6: checkcast #45;
//class clojure/lang/IFn$LO
9: ldc2_w #26;
//long 42l
<<3>> 12: invokeinterface #49, 3;
//InterfaceMethod clojure/lang/IFn$LO.invokePrim:(J)Ljava/lang/Object;
17: areturn
|
| Comment by Ben Smith-Mannschott [ 18/Oct/11 1:40 AM ] |
|
Given P is some primitive type, O is type Object, and R some subclass of Object: When Clojure generates a R invokePrim(P x), it also generates a Object invoke(Object x), which delegates to R invokePrim(P x). R invokePrim(P x) overloads, but does not override the method of the corresponding Fn$PO interface. If Clojure were to generate an additional O invokePrim(P x) which delegates to R invokePrim(P x), it would satisfy the requirements of the Fn$PO interface, and should fix this issue. |
| Comment by Ben Smith-Mannschott [ 18/Oct/11 2:54 PM ] |
|
CLJ-850.patch fixes the issue. I consider this patch to be pretty hackish and hope that there's a cleaner way of addressing CLJ-850. This is the first time I've tried to understand (much less change) the Clojure compiler, so don't expect genius. |
| Comment by Ben Smith-Mannschott [ 19/Oct/11 5:06 AM ] |
|
The patch lies slightly:
It turns out that what I'm actually doing is generating a R invokePrim(P x) which is a copy of O invokePrim(P x), instead of delgating to O invokePrim(P x). This works, but the resulting class file would be smaller if the patch actually did what it says it does. |
| Comment by Andy Fingerhut [ 28/Feb/12 12:49 AM ] |
|
clj-850-type-hinted-fn-abstractmethoderror-patch2.txt is identical to Ben's two patches combined into one, with the small modification that the new tests are added to metadata.clj instead of creating a new test file. The patch applies cleanly to latest master as of Feb 27, 2012. One of the new tests does fail without the change to the compiler, and succeeds with it. I can't vouch for the correctness of the change myself, not knowing enough about the compiler internals to judge. |
| Comment by Andy Fingerhut [ 23/Mar/12 7:50 PM ] |
|
Same comments as made on Feb 27, 2012, except the patch clj-850-type-hinted-fn-abstractmethoderror-patch3.txt applies cleanly to latest master as of Mar 23, 2012. Updated because previous patch (now removed) no longer applied cleanly. git patches often fail to apply if context lines near changes are modified. |
| Comment by Rich Hickey [ 13/Apr/12 9:35 AM ] |
|
We don't support sigs taking prims and returning anything other than prim or Object. Overloading on return value only is a bad idea (and forbidden in Java). The return type of the generated method should be Object, and the String return hint should be used only as a hint. |
| Comment by Andy Fingerhut [ 01/Nov/12 7:22 PM ] |
|
clj-850-type-hinted-fn-abstractmethoderror-patch4.txt dated Nov 1 2012 is same as Ben Smith-Mannschott's CLJ-850.patch and CLJ-850-test.patch, except it has been combined into one patch and does not create a new test source file. |
| Comment by Mike Anderson [ 09/Dec/12 3:42 PM ] |
|
+10 for solving this issue: it keeps biting me in 1.4 and wouuld love to see in 1.5 I'm not familiar with the Clojure compiler internals, but looking at the approach, shouldn't we produce a primitive method with a different name (since Java doesn't support overloading on return types as Rich correctly points out). Also I think there should be 4 methods: R invokePrimExact(P x) - the actual method, used when compiler can infer I think this solves all the important cases? |
| Comment by Rich Hickey [ 19/Dec/12 8:03 AM ] |
|
Still no patch incorporating my feedback, afaict. Pushing to next release. |
| Comment by Ghadi Shayban [ 19/Dec/12 3:41 PM ] |
|
Does this new patch address the issue and concerns? (This incorporates Ben's tests from the previous patch, wasn't sure how to attribute him on that hunk) CLJ-850-conform-to-invokePrim.diff |
| Comment by Andy Fingerhut [ 21/Dec/12 10:53 PM ] |
|
Presumptuously changing state from Incomplete back to Vetted after Ghadi Shayban added the patch CLJ-850-conform-to-invokePrim.diff dated Dec 19 2012 after the status was changed to Incomplete. |
[CLJ-1193] bigint, biginteger throw on double values outside of long range Created: 07/Apr/13 Updated: 24/May/13 |
|
| Status: | Open |
| Project: | Clojure |
| Component/s: | None |
| Affects Version/s: | None |
| Fix Version/s: | Release 1.6 |
| Type: | Defect | Priority: | Minor |
| Reporter: | Andy Fingerhut | Assignee: | Unassigned |
| Resolution: | Unresolved | Votes: | 0 |
| Labels: | None | ||
| Attachments: |
|
| Patch: | Code and Test |
| Approval: | Screened |
| Description |
|
This works fine: user> (bigint (* 0.99 Long/MAX_VALUE)) but this and any other Float or Double values outside the range of a user> (bigint (* 1.01 Long/MAX_VALUE)) Similarly for biginteger |
| Comments |
| Comment by Andy Fingerhut [ 07/Apr/13 4:38 PM ] |
|
Patch clj-1197-make-bigint-work-on-all-doubles-v1.txt dated Apr 7 2013 changes bigint and biginteger so that they return the correct value for all float and double values, and no longer throw an exception. |
| Comment by Gabriel Horner [ 17/May/13 10:52 AM ] |
|
Looks good. Tests pass and the failing example now converts correctly |
[CLJ-1125] Clojure can leak memory when used in a servlet container Created: 11/Dec/12 Updated: 24/May/13 |
|
| Status: | Open |
| Project: | Clojure |
| Component/s: | None |
| Affects Version/s: | None |
| Fix Version/s: | Release 1.6 |
| Type: | Defect | Priority: | Major |
| Reporter: | Toby Crawley | Assignee: | Stuart Halloway |
| Resolution: | Unresolved | Votes: | 8 |
| Labels: | None | ||
| Attachments: |
|
| Patch: | Code |
| Approval: | Incomplete |
| Description |
|
When used within a servlet container The issue comes from threads living beyond the lifetime of a I've attached a patch that does the following:
There is still the opportunity for memory leaks if agents or futures This patch has a small performance impact: its use of a try/finally Providing an automated test for this patch is difficult - I've tested The above is a condensation of: I'm happy to provide whatever feedback/work is needed to get this |
| Comments |
| Comment by Colin Jones [ 13/May/13 7:30 PM ] |
|
This patch works great for me to avoid OOM/PermGen crashes from classloaders being retained [mine is a non-servlet use case]. |
| Comment by Stuart Halloway [ 24/May/13 9:43 AM ] |
|
Does Tomcat create warnings for Clojure, as described e.g. here? If so, does this patch make the warnings go away? |
| Comment by Toby Crawley [ 24/May/13 9:56 AM ] |
|
Stu: that's a good question. I'll take a look at Tomcat this afternoon. |
| Comment by Stuart Halloway [ 24/May/13 10:04 AM ] |
|
The code that calls transaction.remove() seems unncessarily subtle. There are two exits from the method, and only one is protected by the finally block. If the "outer" case was a top-level if, the logic would be more clear, and only the "outer" case would need try/finally, which might reduce the performance penalty in the case of deeply nested dosyncs. Did your transaction overhead of 4-6 microseconds test only one level of dosync, or many? |
| Comment by Stuart Halloway [ 24/May/13 10:13 AM ] |
|
Because the unwind code calls remove at the top (as opposed to set(null)), the code should now be safe for use with Clojure-defined ThreadLocal subclasses. Therefore, Var's use of an initialValue should be irrelevant to this patch, and it should be possible to fix this bug with a patch half the size of the current patch, touching only LockingTransaction.runInTransaction and Var.popThreadBindings. |
[CLJ-1083] Incorrect ArityException message for function names containing -> Created: 09/Oct/12 Updated: 24/May/13 |
|
| Status: | Open |
| Project: | Clojure |
| Component/s: | None |
| Affects Version/s: | Release 1.2, Release 1.3, Release 1.4, Release 1.5 |
| Fix Version/s: | Release 1.6 |
| Type: | Defect | Priority: | Minor |
| Reporter: | Alex Nixon | Assignee: | Unassigned |
| Resolution: | Unresolved | Votes: | 2 |
| Labels: | None | ||
| Attachments: |
|
| Patch: | Code |
| Approval: | Incomplete |
| Description |
|
user=> (defn a->b []) Note that the reported function name in the stack trace is "user$a", where it should be "user$a->b" (or some mangled variant thereof?) See discussion here: https://groups.google.com/d/msg/clojure/PVNoLclhhB0/_NWqyE0cPAUJ |
| Comments |
| Comment by Timothy Baldridge [ 26/Nov/12 10:27 AM ] |
|
Fix for this defect. |
| Comment by Timothy Baldridge [ 26/Nov/12 10:30 AM ] |
|
The throwArity now attempts to locate and call clojure.main/demunge. If it finds the function it invokes it and uses the returned string in the error. Otherwise it just throws the actual class name. This results in the following behaviour: user=> (defn a->b []) |
| Comment by Stuart Halloway [ 24/May/13 11:35 AM ] |
|
Timothy: Why the empty catch block? I don't see anything in the try block whose failure we would want to ignore. |
[CLJ-1171] Compiler macro for clojure.core/instance? disregards lexical shadows on class names Created: 27/Feb/13 Updated: 24/May/13 |
|
| Status: | Open |
| Project: | Clojure |
| Component/s: | None |
| Affects Version/s: | None |
| Fix Version/s: | Release 1.6 |
| Type: | Defect | Priority: | Major |
| Reporter: | Herwig Hochleitner | Assignee: | Stuart Halloway |
| Resolution: | Unresolved | Votes: | 0 |
| Labels: | None | ||
| Attachments: |
|
| Patch: | Code and Test |
| Approval: | Screened |
| Description |
SummaryThe compiler tries to emit jvm native instanceof expressions for direct clojure.core/instance? calls. Patches[Stu] All three patches should be applied IMO.
DataTest caseuser=> (let [Long String] (instance? Long "abc")) false ;; expected true as in user=> (let [Long String] (apply instance? [Long "abc"])) true Culprit methodList Discussionhttps://groups.google.com/d/topic/clojure/mf25OlFRpa8/discussion TangentThis was discovered because the same compiler macro also omits the arity check implicit in the default definition. This could also conveniently be fixed when touching that method: user=> (instance? String) false ;; expected user=> (apply instance? [String]) ArityException Wrong number of args (1) passed to: core$instance-QMARK- clojure.lang.AFn.throwArity (AFn.java:437)
|
| Comments |
| Comment by Herwig Hochleitner [ 27/Feb/13 8:11 PM ] |
|
Attached patches test and fix issue + tangent |
| Comment by Herwig Hochleitner [ 04/Mar/13 3:51 PM ] |
|
Note: Patch 0003 just adds the arity check, hence is optional, but if it's omitted from the patchset, the corresponding test from patch 0001 will fail. |
| Comment by Stuart Halloway [ 29/Mar/13 7:31 AM ] |
|
Summarizing the decisions in these patches:
It is possible (although unlikely) that existing code relies on the current eccentric behavior of instance?. I think it would be fair to categorize programs relying on this behavior as buggy, but that is easy for me to say. |
[CLJ-1161] sources jar has bad versions.properties resource Created: 11/Feb/13 Updated: 24/May/13 |
|
| Status: | Open |
| Project: | Clojure |
| Component/s: | None |
| Affects Version/s: | Release 1.4, Release 1.5 |
| Fix Version/s: | Release 1.5, Release 1.6 |
| Type: | Defect | Priority: | Minor |
| Reporter: | Steve Miner | Assignee: | Stuart Halloway |
| Resolution: | Unresolved | Votes: | 0 |
| Labels: | patch | ||
| Attachments: |
|
| Patch: | Code |
| Approval: | Screened |
| Description |
|
Summary: patch leaves version.properties file out of sources JAR, where it causes problems for tools. The "sources" jar (at least since Clojure 1.4 and including 1.5 RC) has a bad version.properties file in it. The resource clojure/version.properties is literally: version=${version} The regular Clojure jar has the correct version string in that resource. I came across a problem when I was experimenting with the sources jar (as used by IDEs). I naively added the sources jar to my classpath, and Clojure died on start up. The bad clojure/versions.properties file was found first, which led to a parse error as the clojure version was being set. |
| Comments |
| Comment by Steve Miner [ 11/Feb/13 10:04 AM ] |
|
Notes from the dev mailing list: The "sources" JAR is generated by another Maven plugin, configured here: The simplest solution might be to just exclude the file from the sources jar. It looks like maven-source-plugin has an excludes option which would do the trick: http://maven.apache.org/plugins/maven-source-plugin/jar-mojo.html#excludes |
[CLJ-1175] NPE in clojure.lang.Delay/deref Created: 06/Mar/13 Updated: 24/May/13 |
|
| Status: | Open |
| Project: | Clojure |
| Component/s: | None |
| Affects Version/s: | None |
| Fix Version/s: | Release 1.6 |
| Type: | Defect | Priority: | Minor |
| Reporter: | Alan Malloy | Assignee: | Stuart Halloway |
| Resolution: | Unresolved | Votes: | 3 |
| Labels: | None | ||
| Attachments: |
|
| Patch: | Code and Test |
| Approval: | Screened |
| Description |
|
Summary: Delays get into a corrupt state if an exception thrown, allowing deref to behave differently on back-to-back calls. Patch causes Delay to rethrow the original exception, includes tests. If a Delay wraps a function which throws an exception, then forcing that delay multiple times causes behavior which is, to me at least, surprising and unexpected: the first time it is forced, the expected exception is thrown; but after that it will behave as if all locals the expression refers to are nil. This can manifest in multiple ways, depending on the expression being delayed: ;; calling a local as a function causes an NPE inside clojure.lang.Delay (let [f #(/ 1 0) d (delay (f))] [(try (force d) (catch Exception e e)) (try (force d) (catch Exception e e))]) [#<ArithmeticException java.lang.ArithmeticException: Divide by zero> #<NullPointerException java.lang.NullPointerException>] ;; if nil is a valid value, this can cause subsequent forces to "succeed" ;; even though the first fails as it should (let [x (java.util.Date.) d (delay (seq x))] [(try (force d) (catch Exception e e)) (try (force d) (catch Exception e e))]) [#<IllegalArgumentException java.lang.IllegalArgumentException: Don't know how to create ISeq from: java.util.Date> nil] The reason for this is that clojure.core/delay creates a ^:once function, promising to call it only once, so that the compiler can do locals-clearing on its lexical closure. However, when an exception is thrown the Delay object is left thinking it has never called the function, so when it is forced again it calls the function again, breaking its promise to the compiler and causing the function to run after its locals have been cleared. In fact, once we realize that locals-clearing is involved, we can make the delay behave differently the first N times it is forced, instead of only the first time, by constructing an expression which throws an exception before using all of its locals: (let [x (java.util.Date.)
y (Long. 1)
d (delay (let [y (seq y)]
(cons (seq x) y)))]
[(try (force d)
(catch Exception e e))
(try (force d)
(catch Exception e e))
(try (force d)
(catch Exception e e))])
[#<IllegalArgumentException java.lang.IllegalArgumentException: Don't know how to create ISeq from: java.lang.Long>
#<IllegalArgumentException java.lang.IllegalArgumentException: Don't know how to create ISeq from: java.util.Date>
(nil)]
I'm not sure what the right fix for this issue is: perhaps the best choice is even to leave it alone, and just document that delay's behavior is undefined if the expression throws an exception. However, I propose making the Delay remember the first exception that was thrown, and rethrow it on subsequent force attempts. This makes sense, in a way: the "result" of the expression was this exception e being thrown, and so this should happen every time. It might be preferable to have the Delay retry the expression until it succeeds, but I don't believe this is possible without abandoning locals-clearing, which would cause perfectly-valid delays to now run out of memory, holding onto no-longer-needed locals just in case the expression needs to retry at some later date. |
[CLJ-1176] clojure.repl/source fails when *read-eval* bound to :unknown Created: 06/Mar/13 Updated: 24/May/13 |
|
| Status: | Open |
| Project: | Clojure |
| Component/s: | None |
| Affects Version/s: | Release 1.5 |
| Fix Version/s: | Release 1.6 |
| Type: | Defect | Priority: | Minor |
| Reporter: | Tim McCormack | Assignee: | Unassigned |
| Resolution: | Unresolved | Votes: | 0 |
| Labels: | None | ||
| Attachments: |
|
| Patch: | Code |
| Approval: | Screened |
| Description |
|
clojure.repl/source is broken in Clojure 1.5.0 when *read-eval* is bound to :unknown, since source-fn reads without binding. Reproduce:
Expected: Source of drop-last. Actual: RuntimeException Reading disallowed - *read-eval* bound to :unknown |
| Comments |
| Comment by Tim McCormack [ 06/Mar/13 4:04 PM ] |
|
The attached patch just binds *read-eval* to true inside source-fn. |
| Comment by Stuart Halloway [ 29/Mar/13 6:24 AM ] |
|
Note: Allowing this implies that you trust the data on your classpath. If there are reasons somebody might not, we should reject this patch and people will have to be explicit when calling source. |
| Comment by Tim McCormack [ 29/Mar/13 6:37 AM ] |
|
Ugh, that's a fair point when it comes to sandboxing. I'll check with the owners of clojurebot and lazybot. |
| Comment by Tim McCormack [ 04/May/13 10:40 PM ] |
|
I haven't come up with any scenarios where this is problematic, and I haven't heard anything back from the bot owners. As for sandboxing, clojure.repl can easily be excluded. |
| Comment by Gabriel Horner [ 24/May/13 9:42 AM ] |
|
Looks good |
[CLJ-1187] Clojure loses quoted metadata on empty literals Created: 22/Mar/13 Updated: 24/May/13 |
|
| Status: | Open |
| Project: | Clojure |
| Component/s: | None |
| Affects Version/s: | Release 1.5, Release 1.6 |
| Fix Version/s: | Release 1.6 |
| Type: | Defect | Priority: | Minor |
| Reporter: | Nicola Mometto | Assignee: | Unassigned |
| Resolution: | Unresolved | Votes: | 0 |
| Labels: | None | ||
| Attachments: |
|
| Patch: | Code and Test |
| Approval: | Screened |
| Description |
|
user=> (meta '^:foo []) while This bug propagates to ^:const vars: |
| Comments |
| Comment by Nicola Mometto [ 22/Mar/13 2:12 PM ] |
|
After patch: user=> (meta '^:foo []) |
| Comment by Stuart Halloway [ 29/Mar/13 6:13 AM ] |
|
I believe the title should read "Clojure loses quoted metdata on empty literals". |
| Comment by Stuart Halloway [ 29/Mar/13 6:16 AM ] |
|
At first glance, the implementation looks wrong in that it blocks non-IObjs ever getting to EmptyExpr. Probably all persistent collections are IObjs, but would not want to bake this in. |
| Comment by Nicola Mometto [ 29/Mar/13 7:00 AM ] |
|
You're right, I've updated my patch, it should work as expected now |
| Comment by Andy Fingerhut [ 04/Apr/13 9:44 PM ] |
|
Nicola: Your updated patch 001-CLJ-1187.patch dated Mar 29, 2013 gives syntax errors when I try to compile it. |
| Comment by Nicola Mometto [ 05/Apr/13 9:06 AM ] |
|
Oh, the irony, I messed up some parentheses writing java. Sorry for it, here's the correct patch, it applies on upstream/master. |
| Comment by Gabriel Horner [ 24/May/13 9:14 AM ] |
|
Looks good |
[CLJ-944] compiler makes different concrete maps then the reader Created: 04/Mar/12 Updated: 24/May/13 |
|
| Status: | Open |
| Project: | Clojure |
| Component/s: | None |
| Affects Version/s: | Release 1.3, Release 1.4, Release 1.5 |
| Fix Version/s: | Release 1.5, Release 1.6 |
| Type: | Defect | Priority: | Major |
| Reporter: | Alf Kristian Støyle | Assignee: | Unassigned |
| Resolution: | Unresolved | Votes: | 2 |
| Labels: | None | ||
| Environment: |
Clojure 1.3 om Mac OS 10.7, Clojure 1.5.0 alpha1 on Linux x86_64 (OpenJDK 1.7.0 b147) |
||
| Attachments: |
|
| Patch: | Code and Test |
| Approval: | Screened |
| Description |
|
I (Stu) agree with Nicola's assessment in the comments: the single real problem here is that the compiler's MapExpr parser emits maps differently from other map-makers, e.g. RT's factory functions. Patch clj944-plus-tests does three things:
Original report follows: Hi guys, I am getting the following exception: (.containsKey {:one 1} :one)
;=> ClassCastException clojure.lang.PersistentArrayMap cannot be cast to clojure.lang.PersistentHashMap
The map is a clojure.lang.PersistentArrayMap, which obviously has a containsKey method (https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/PersistentArrayMap.java#L95). Casting it works fine though: (.containsKey ^clojure.lang.PersistentArrayMap {:one 1} :one)
;=> true
The mailing list suggest that the compiler injects an incorrect cast to clojure.lang.PersistentHashMap. In this case it should probably be cast to a clojure.lang.Associative, the highest common interface having the .containsKey method. The problem is not present in Clojure 1.2.1. |
| Comments |
| Comment by Nicola Mometto [ 30/Oct/12 5:02 PM ] |
|
The attached patch fixes the issue, by emitting IPersistentMap instead of Persistent{Hash|Array}Map as class type for maps literals |
| Comment by Nicola Mometto [ 01/Nov/12 3:48 PM ] |
|
I uploaded another patch fixing the same problem in a different way. This approach is more consistent, making the type of the compiler's internal representation of a map literal equal to the one of the reader. Note that this second approach while being more consistent, breaks some tests that assume some operations on maps (specifically `seq` and `print`) to be order dependent, and written with the hash-map return order implementation in mind. That should not be the case and if the second patch is preferred over the first one, I'll gladly fix those tests. |
| Comment by Stuart Halloway [ 01/Mar/13 12:09 PM ] |
|
Approach #2, relying on consistent choice of concrete map class by size throughout, feels quite fragile. Approach #1 seems to abuse the method name getJavaClass(), now having it return "get the base type I would need for cast". Maybe there needs to be a different thing entirely? |
| Comment by Nicola Mometto [ 01/Mar/13 2:17 PM ] |
|
Patch #2 should get merged (IMHO) regardless of the fragility of its approach to fixing this ticket's bug, since it fixes another bug: prior to the patch: user=> (class {:a 1}) after the patch: user=> (class {:a 1}) This should also lead to some minor performance enhancement since prior to this moment, every map def'ed would be a HashMap instead of an ArrayMap So, I think patch #2 should be applied if not for this ticket's bug, at least for the reason stated above. |
| Comment by Rich Hickey [ 13/Apr/13 9:41 AM ] |
|
This should not have passed screening. There are two issues, should be separate. I have no idea what has been screened nor what will be applied should it be approved. There's contention in the discussion but no resolution. |
| Comment by Nicola Mometto [ 13/Apr/13 12:06 PM ] |
|
I don't think that there are two issues here. The underlying cause of those two symtoms is fixed by the patch 002 that i submitted (incorporated in Stu's clj944-plus-tests patch. Stuart said that this approach feels fragile but the bug is caused by the fact that everywhere else clojure returns a PersistentArrayMap when the element count is <= than the PersistentHashMap threshold, and when emitting maps, it doesn't. Making clojure emit maps consistently with how clojure does internally everywhere else looks to me like the only solution, and I don't really see how making clojure consistent is a fragile approach. But again, if somebody can suggest a better solution to this problem, I'll gladly submit another patch. |
[CLJ-1121] -> and ->> have unexpected behavior when combined with unusual macros Created: 06/Dec/12 Updated: 24/May/13 |
|
| Status: | Open |
| Project: | Clojure |
| Component/s: | None |
| Affects Version/s: | Release 1.5 |
| Fix Version/s: | Release 1.6 |
| Type: | Defect | Priority: | Minor |
| Reporter: | Gary Fredericks | Assignee: | Stuart Halloway |
| Resolution: | Unresolved | Votes: | 4 |
| Labels: | None | ||
| Attachments: |
|
| Patch: | Code and Test |
| Approval: | Screened |
| Description |
|
My intuitive understanding of the classic threading macros is that the meaning of forms like (-> a b c) can be understood syntactically independent of the meaning of the symbols involved or the fact that the two threading macros are defined recursively. However the recursive definition breaks that expectation. After (macroexpand-1 (macroexpand-1 '(-> a b c))) => (c (-> a b)) c is now in control if it is a macro, and is now seeing the argument (-> a b) rather than (b a) as would be the case if we had written (c (b a)) originally. Admittedly I do not know of a realistic example where this is an important distinction (I noticed this when playing with a rather perverse use of ->> with macros from korma), but at the very least it means that the behavior of the threading macros isn't quite as easy to accurately explain as I thought it was. |
| Comments |
| Comment by Gary Fredericks [ 07/Dec/12 9:19 AM ] |
|
I just realized that my patch also implements CLJ-1086. |
| Comment by Stuart Halloway [ 22/Dec/12 9:48 AM ] |
|
Would be nice if tests also demonstrated that metadata is preserved correctly. |
| Comment by Gary Fredericks [ 26/Dec/12 8:16 PM ] |
|
New patch in response to stuarthalloway feedback. |
| Comment by Tim McCormack [ 09/Jan/13 6:47 PM ] |
|
This patch also prevents an infinite loop in the macroexpander when fed the following expression: (->> a b (->> c d)) Edit: Far simpler example. |
[CLJ-873] Allow the function / to be referred to in namespaces other than clojure.core Created: 10/Nov/11 Updated: 24/May/13 Resolved: 24/May/13 |
|
| Status: | Closed |
| Project: | Clojure |
| Component/s: | None |
| Affects Version/s: | Release 1.1, Release 1.2, Release 1.3, Release 1.4 |
| Fix Version/s: | Release 1.6 |
| Type: | Enhancement | Priority: | Minor |
| Reporter: | Chris Gray | Assignee: | Unassigned |
| Resolution: | Completed | Votes: | 7 |
| Labels: | None | ||
| Attachments: |
|
| Patch: | Code and Test |
| Approval: | Ok |
| Description |
|
The attached patch gives the programmer the option of referring to the division function in namespaces other than just clojure.core. For example, (ns foo The above lines do not compile without this patch. |
| Comments |
| Comment by Chris Gray [ 10/Nov/11 9:50 AM ] |
|
I have signed the CA and it is in the mail. |
| Comment by Chris Gray [ 20/Nov/11 6:21 PM ] |
|
My CA has now been applied. This patch is quite simple – can someone have a look at it please? |
| Comment by Alex Miller [ 09/Dec/11 9:34 AM ] |
|
FYI, I have run into this in actual code as well (implementing a query language function library). |
| Comment by Andy Fingerhut [ 24/Feb/12 8:00 PM ] |
|
clj-873-namespace-divides-patch.txt is same as Chris's, just updated to apply cleanly to latest master as of Feb 24, 2012. The test he added does fail without the code fix, and passes with it. He is now on the list of contributors. |
| Comment by Chris Gray [ 30/Mar/12 1:11 PM ] |
|
A short further discussion of this patch appeared here: http://groups.google.com/group/clojure-dev/browse_thread/thread/f095980802a82747/b723726c77c1ec64 Also, I assume this bug is what is referred to in Clojurescript's core.cljs, where it says ";; FIXME: waiting on cljs.core//" |
| Comment by Stuart Halloway [ 22/Oct/12 7:12 PM ] |
|
Thanks all. It is nice to have supporting real-world stories such as Alex's in the comments. |
| Comment by Andy Fingerhut [ 22/Oct/12 7:19 PM ] |
|
I should have added a comment here a while back if it would have helped, but David Nolen's |
| Comment by Brandon Bloom [ 02/Jan/13 12:49 AM ] |
|
This also affects a two of my libraries: 1) CSS generation library I'm working on, which wants to be able to do division with pixels and other units. 2) Factjor which defines binary math operators against a stack. |
| Comment by Nicola Mometto [ 24/May/13 8:39 AM ] |
|
clojure.lang.EdnReader should get patched aswell. |
[CLJ-1122] Add contributing.md file to github repository (shows clear message on issues/pull request create form) Created: 09/Dec/12 Updated: 24/May/13 |
|
| Status: | Open |
| Project: | Clojure |
| Component/s: | None |
| Affects Version/s: | None |
| Fix Version/s: | Release 1.6 |
| Type: | Enhancement | Priority: | Minor |
| Reporter: | Max Penet | Assignee: | Unassigned |
| Resolution: | Unresolved | Votes: | 0 |
| Labels: | None | ||
| Attachments: |
|
| Patch: | Code |
| Approval: | Screened |
| Description |
|
This adds a clear message when someone wants to create a pull request/issue and invites the user to read the contribution guidelines: see https://github.com/blog/1184-contributing-guidelines. The same thing could be done for all the clojure/* repositories. The content of the file is just a markdown version of http://clojure.org/contributing Preview here: https://github.com/mpenet/clojure/blob/aef170ca5eca1b71a2eb1ef320223d1277df0e5e/CONTRIBUTING.md |
| Comments |
| Comment by Stuart Halloway [ 02/Jan/13 6:31 AM ] |
|
Please change this to link to the definitive prose, so we don't have to maintain that in two places. |
| Comment by Max Penet [ 02/Jan/13 6:51 AM ] |
|
Feel free to correct the wording, I used something simple. |
| Comment by Gabriel Horner [ 17/May/13 9:04 AM ] |
|
Stu, he linked to clojure.org as you requested so I'm moving this along. |
[CLJ-1072] Replace old metadata reader macro syntax Created: 21/Sep/12 Updated: 24/May/13 Resolved: 24/May/13 |
|
| Status: | Closed |
| Project: | Clojure |
| Component/s: | None |
| Affects Version/s: | Release 1.4 |
| Fix Version/s: | Release 1.6 |
| Type: | Enhancement | Priority: | Trivial |
| Reporter: | Sam Aaron | Assignee: | Stuart Sierra |
| Resolution: | Completed | Votes: | 0 |
| Labels: | None | ||
| Attachments: |
|
| Patch: | Code |
| Approval: | Ok |
| Description |
|
5 files still have old metadata reader syntax hash-caret instead of just caret: src/clj/clojure/core.clj |
| Comments |
| Comment by Stuart Sierra [ 21/Sep/12 7:56 AM ] |
|
Modified this ticket to cover all remaining cases of old metadata syntax. Added patch. |
[CLJ-896] Make browse-url aware of xdg-open Created: 13/Dec/11 Updated: 24/May/13 Resolved: 24/May/13 |
|
| Status: | Closed |
| Project: | Clojure |
| Component/s: | None |
| Affects Version/s: | None |
| Fix Version/s: | Release 1.6 |
| Type: | Enhancement | Priority: | Minor |
| Reporter: | Jasper Lievisse Adriaanse | Assignee: | Unassigned |
| Resolution: | Completed | Votes: | 3 |
| Labels: | None | ||
| Environment: |
All platforms that provide xdg-open (as part of freedesktop.org) benefit from this. Fix was tested on OpenBSD. |
||
| Attachments: |
|
| Patch: | Code |
| Approval: | Ok |
| Waiting On: | Rich Hickey |
| Description |
|
clojure.java.browse/browse-url tests to see if it's running on Mac OS to fall back to "/usr/bin/open" in order |
| Comments |
| Comment by Andy Fingerhut [ 28/Feb/12 6:19 PM ] |
|
|
| Comment by Andy Fingerhut [ 29/Feb/12 1:18 PM ] |
|
clj-896-browse-url-uses-xdg-open-patch2.txt is based more on the patch attached to I think this patch improves on both of the previous patches for Tested on: Mac OS X 10.6.8 It would be great if someone could test it on a BSD system. The only possible issue I can think of is whether the output of the "which" command is different there than on the Linux system I tested. If someone wants to make a patch that doesn't use "which", but instead checks the PATH, I'd recommend they also test on Windows in cmd.exe to make sure it works correctly there. |
| Comment by Stuart Sierra [ 09/Nov/12 9:04 AM ] |
|
Screened. Verified on Mac OS X. |
| Comment by Jasper Lievisse Adriaanse [ 09/Nov/12 9:41 AM ] |
|
And I've tested it on OpenBSD. |
[CLJ-783] clojure.inspector/inspect-tree doesn't work on sets --patch in the description by Jason Wolfe Created: 28/Apr/11 Updated: 24/May/13 Resolved: 24/May/13 |
|
| Status: | Closed |
| Project: | Clojure |
| Component/s: | None |
| Affects Version/s: | None |
| Fix Version/s: | Release 1.6 |
| Type: | Enhancement | Priority: | Minor |
| Reporter: | Armando Blancas | Assignee: | Unassigned |
| Resolution: | Completed | Votes: | 1 |
| Labels: | None | ||
| Environment: |
Any |
||
| Attachments: |
|
| Patch: | Code |
| Approval: | Ok |
| Waiting On: | Rich Hickey |
| Description |
|
As reported by Jason Wolfe on March 19, 2009 in the clojure group: clojure.inspector/inspect-tree doesn't work on sets; patch attached I was debugging with inspect-tree and noticed that it errors when it I made a small patch (below) that makes inspect-tree work on Cheers, Index: src/clj/clojure/inspector.clj
(defmulti is-leaf collection-tag) -(defmethod is-leaf :map [m]
(defn tree-model [data] |
| Comments |
| Comment by Andy Fingerhut [ 14/Feb/12 12:54 PM ] |
|
Created a properly formatted patch, attached, for Jason's enhancement. I tested it with (inspect-tree (:members (clojure.reflect/reflect java.lang.Math))) and it worked, whereas it had many errors without Jason's changes. |
| Comment by Andy Fingerhut [ 23/Feb/12 11:58 PM ] |
|
Jason Wolfe has signed a CA. Patch applies cleanly with latest master as of Feb 14, 2012. No errors, warnings, or test failures with the patch applied. No doc strings need updating. |
| Comment by Stuart Sierra [ 09/Nov/12 4:12 PM ] |
|
Screened. |
[CLJ-863] interleave should accept 1 or 0 arguments Created: 24/Oct/11 Updated: 24/May/13 Resolved: 24/May/13 |
|
| Status: | Closed |
| Project: | Clojure |
| Component/s: | None |
| Affects Version/s: | Release 1.3 |
| Fix Version/s: | Release 1.6 |
| Type: | Enhancement | Priority: | Trivial |
| Reporter: | Joe Gallo | Assignee: | Unassigned |
| Resolution: | Completed | Votes: | 5 |
| Labels: | None | ||
| Attachments: |
|
| Patch: | Code and Test |
| Approval: | Ok |
| Description |
|
interleave should handle 0 and 1 arguments in the same way that concat does (i.e., 0 args --> empty seq, 1 args --> identity). |
| Comments |
| Comment by Rich Hickey [ 15/Jun/12 9:31 AM ] |
|
(lazy-seq nil) should be () |
| Comment by Joe Gallo [ 15/Jun/12 10:13 AM ] |
|
Hey Rich, if you're talking about the first line of the diff: + ([] (lazy-seq nil)) Then that's the implementation, not the tests – given an empty vector of arguments, return (lazy-seq nil), which I just copied from the existing definition of concat. Cheers, |
| Comment by Marc Dzaebel [ 03/Oct/12 1:19 PM ] |
|
(defn interleave [& s] (apply mapcat list s)) |
| Comment by Matthew O. Smith [ 03/Oct/12 8:47 PM ] |
|
Marc's definition doesn't work for no arguments. Maybe: (defn interleave |
| Comment by Marc Dzaebel [ 05/Oct/12 1:07 PM ] |
|
Yes, but my solution is too slow, as it uses "apply". |
| Comment by Andy Fingerhut [ 01/Jan/13 11:54 AM ] |
|
Patch clj-863-make-interleave-handle-odd-args-like-concat-patch-v1.txt dated Jan 1 2013 is identical to Joe Gallo's 0001-make-interleave-handle-odd-arugments-in-the-same-man.patch patch dated Oct 24 2011, except it returns () instead of (lazy-seq nil) as per Rich's comment. If concat should also return () instead of (lazy-seq nil), perhaps another ticket should be created to fix that. Also presumptuously changing ticket state from Incomplete back to Vetted, since the reason it was marked Incomplete should now be addressed, and it was Screened before. |
[CLJ-1143] Minor correction to doc string of ns macro Created: 10/Jan/13 Updated: 24/May/13 Resolved: 24/May/13 |
|
| Status: | Closed |
| Project: | Clojure |
| Component/s: | None |
| Affects Version/s: | Release 1.6 |
| Fix Version/s: | Release 1.6 |
| Type: | Defect | Priority: | Trivial |
| Reporter: | Andy Fingerhut | Assignee: | Unassigned |
| Resolution: | Completed | Votes: | 0 |
| Labels: | None | ||
| Attachments: |
|
| Patch: | Code |
| Approval: | Ok |
| Description |
|
The doc string of ns says "If :refer-clojure is not used, a default (refer 'clojure) is used." 'clojure should be replaced with 'clojure.core Clojure group thread: https://groups.google.com/forum/?fromgroups=#!topic/clojure/rDjZodxOMh8 |
| Comments |
| Comment by Andy Fingerhut [ 10/Jan/13 1:34 PM ] |
|
clj-1143-ns-doc-string-correction-v1.txt dated Jan 10 2013 replaces (refer 'clojure) with (refer 'clojure.core) in the doc string of the ns macro. |
[CLJ-1101] *default-data-reader-fn* should be set!-able in REPL Created: 03/Nov/12 Updated: 24/May/13 Resolved: 24/May/13 |
|
| Status: | Closed |
| Project: | Clojure |
| Component/s: | None |
| Affects Version/s: | Release 1.5 |
| Fix Version/s: | Release 1.6 |
| Type: | Enhancement | Priority: | Minor |
| Reporter: | Steve Miner | Assignee: | Unassigned |
| Resolution: | Completed | Votes: | 0 |
| Labels: | None | ||
| Attachments: |
|
| Patch: | Code |
| Approval: | Ok |
| Description |
|
In |
| Comments |
| Comment by Steve Miner [ 03/Nov/12 9:32 AM ] |
|
Add *default-data-reader-fn* to the special bindings in main.clj so that it is set!-able in the REPL |
| Comment by Steve Miner [ 03/Dec/12 10:07 AM ] |
|
This is a one-liner that makes *default-data-reader-fn* convenient to use in the REPL, similar to how *data-readers* works. I'd like to have this fix in Clojure 1.5. |
| Comment by Steve Miner [ 12/Mar/13 8:10 PM ] |
|
work-around for REPL: (alter-var-root #'clojure.core/*default-data-reader-fn* (constantly my-default-reader)) |
[CLJ-908] Functions with metadata print poorly Created: 10/Jan/12 Updated: 24/May/13 Resolved: 24/May/13 |
|
| Status: | Closed |
| Project: | Clojure |
| Component/s: | None |
| Affects Version/s: | Release 1.3, Release 1.4 |
| Fix Version/s: | Release 1.6 |
| Type: | Enhancement | Priority: | Minor |
| Reporter: | Alan Malloy | Assignee: | Unassigned |
| Resolution: | Completed | Votes: | 0 |
| Labels: | None | ||
| Attachments: |
|
| Patch: | Code |
| Approval: | Ok |
| Waiting On: | Rich Hickey |
| Description |
|
1.3 removed the metadata slot on most functions, and made .withMeta return a new wrapping function that provides metadata. This changes the way functions with metadata print: instead of #<user$eval595$fn_596 user$eval595$fn_596@3d48ff04> we now see #< clojure.lang.AFunction$1@581de498>. I might argue that we should "lie" and print the class of the original wrapped function since it's more useful than AFunction$1, but that's debatable. The two things I propose changing are:
If it would be desirable to print the class of the original "wrapped" function, then I can easily add another patch for that. |
| Comments |
| Comment by Andy Fingerhut [ 19/May/12 3:30 AM ] |
|
clj-908-Print-metadata-and-anonymous-classes-better-patch2.txt dated May 19, 2012 only has context line changes from the previous one, 0001-Print-metadata-and-anonymous-classes-better.patch dated Jan 10, 2012. The previous one no longer applies cleanly to the latest master, while the new one does. |
| Comment by Stuart Sierra [ 09/Nov/12 9:21 AM ] |
|
Screened. |
[CLJ-1164] typos in instant.clj Created: 14/Feb/13 Updated: 24/May/13 Resolved: 24/May/13 |
|
| Status: | Closed |
| Project: | Clojure |
| Component/s: | None |
| Affects Version/s: | Release 1.4, Release 1.5 |
| Fix Version/s: | Release 1.6 |
| Type: | Defect | Priority: | Trivial |
| Reporter: | Steve Miner | Assignee: | Unassigned |
| Resolution: | Completed | Votes: | 0 |
| Labels: | None | ||
| Attachments: |
|
| Patch: | Code |
| Approval: | Ok |
| Description |
|
There are a few typographical mistakes in instant.clj. |
| Comments |
| Comment by Steve Miner [ 14/Feb/13 12:01 PM ] |
|
Fixes a couple of typos. No code changes. |
| Comment by Gabriel Horner [ 10/May/13 11:25 AM ] |
|
For anyone wondering about the UTC change see |
[CLJ-1099] better error message when passing non-seq to seq Created: 01/Nov/12 Updated: 24/May/13 Resolved: 24/May/13 |
|
| Status: | Closed |
| Project: | Clojure |
| Component/s: | None |
| Affects Version/s: | None |
| Fix Version/s: | Release 1.6 |
| Type: | Enhancement | Priority: | Minor |
| Reporter: | Stuart Halloway | Assignee: | Unassigned |
| Resolution: | Completed | Votes: | 0 |
| Labels: | None | ||
| Attachments: |
|
| Patch: | Code |
| Approval: | Ok |
| Description |
|
Design discussion here. This patch improves Clojure's error message for a single common error: passing a non-seq where a seq is neede. More importantly, it is intended as a prototype for other similar improvements in the future. Error message before: (cons 1 2) => IllegalArgumentException Don't know how to create ISeq from: java.lang.Long Error message after: user=> (cons 1 2)
ExceptionInfo Don't know how to create ISeq from: java.lang.Long
user=> (ex-data *e)
{:instance 2}
|
| Comments |
| Comment by Michael Klishin [ 12/Nov/12 10:34 AM ] |
|
Wouldn't it be better to make it read "Don't know how to create ISeq from: 2 (java.lang.Long)"? How many beginners will figure |
| Comment by Stuart Halloway [ 12/Apr/13 11:36 AM ] |
|
Hi Michael, ex-info messages should not, in general, pr-str things into their bodies. This raises the question of print-length and print-level in a place where the user doesn't have good control, while the whole point of ex-info is to be in the data business, not the string business. Users can control printing from ex-data any way they like. There are two possible ways to make beginners aware of ex-data: Tell them about it in one (or a few places) in docs, or in an infinite number of places saying "This would have been useful here, but we didn't use it because you might not know about it." I prefer the former. That said, I think it would be great to increase the visibility of ex-info and ex-data early on in documentation for beginners, and to make sure that things like exception printing in logs are flexible enough not to lose the benefits of ex-info. |
[CLJ-1018] range's behavior is inconsistent Created: 29/Jun/12 Updated: 24/May/13 Resolved: 24/May/13 |
|
| Status: | Closed |
| Project: | Clojure |
| Component/s: | None |
| Affects Version/s: | Release 1.1, Release 1.2, Release 1.3, Release 1.4, Release 1.5 |
| Fix Version/s: | Release 1.5, Release 1.6 |
| Type: | Defect | Priority: | Minor |
| Reporter: | Devin Walters | Assignee: | Unassigned |
| Resolution: | Completed | Votes: | 0 |
| Labels: | patch, range | ||
| Attachments: |
|
| Patch: | Code and Test |
| Approval: | Ok |
| Description |
|
Problem statement: The current behavior of range is inconsistent. (range 0 9 0) has always produced (). (range 0 9 -1) has always produced (). (range 9 0 1) has always produced (). However, (range 9 0 0) produces (9 9 9 9 ...), and (range 0 0 0) produces '(0 0 0 0 ...) Proposal: Make the behavior of range consistent when using a step of 0 to make it produce an empty list. Please see attached code and patch. |
| Comments |
| Comment by Mike Anderson [ 01/Jul/12 4:08 AM ] |
|
Agree it is good to fix the inconsistency, but I think an infinite sequence of zeros is the correct result, as implied by the current docstring definition. It's also mathematically cleanest: range should produce an arithmetic progression until the end value is equalled or exceeded. Empty lists only seem to make sense as a return value when start >= end. |
| Comment by Devin Walters [ 01/Jul/12 12:36 PM ] |
|
Hi Mike, Could you explain how you think the docstring definition implies this behavior? Maybe I'm missing something, but I was surprised. For instance, in the case of (range 3 9 0), if start were truly inclusive as the docstring says, the result would be (3), not (). You mentioned that you think the infinite sequence of 0's is consistent and in keeping with the definition of range. I'm not sure I agree. (0,0] is an empty set of length zero, and [0,0) is an empty set of length zero. You state that empty list only makes sense for start >= end, except this is not the current behavior. Could you help me understand what you believe the appropriate behavior would be in each of the following three cases? (range 0 10 0), (range 10 0 0), and (range 0 0 0)? A few options to consider: Editing to Add (Note: I don't think the way someone else did something is always the right way, just wanted to do some digging on how other people have handled this in the past): |
| Comment by Dimitrios Piliouras [ 05/Jul/12 4:13 PM ] |
|
It does make sense NOT to allow a step of zero (at least to me)... I wasn't going to say anything about this but if other popular languages do not allow 0, then I guess it makes more sense than I originally gave myself credit for... However, if we want to be mathematically correct then the answer would be to return an infinte seq with the start value like below. After all, what is a step of 0? does it make any difference how many steps you take if with every step you cover 0 distance? obviously not...you start from x and you stay at x forever...we do have repeat for this sort of thing though... (take 5 (range 3 9 0)) => (3 3 3 3 3) +1 for not allowing 0 step |
| Comment by Mike Anderson [ 08/Jul/12 8:49 AM ] |
|
@Devin quite simple: a lazy sequence of nums starting from x with step 0.0 until it reaches an end value of y (where y > x) is an infinite sequence of x. Consider the case where start is 0 and end is infinity (the default), you would expect sequences to go as follows: step +2 : 0 2 4 6 8.... It would be inconsistent to make 0 a special case, all of these are valid arithmetic progressions. And all of these are consistent with the current docstring. If you make 0 a special case, then people will need to write special case code to handle it. Consider the code to create a multiplication table for example: (for [x (range 10)] This works fine if you produce an infinite sequence of zeros for step 0, but fails if you create an empty list as a special case for step 0. As a related issue, I'd personally also favour negative step sizes also producing an infinite sequence. If we don't want to allow this though, then at least the docstring should be changed to say "a lazy seq of non-decreasing nums" and a negative step should throw an error. |
| Comment by Devin Walters [ 09/Jul/12 7:09 PM ] |
|
Carrying over a message from the clojure-dev list by Stuart Sierra:
yes
not if they have any sense
not me
I doubt it.
Not that I know of.
I doubt it. Lazy seqs are not ideal for high-performance code anyway.
I think the problem is that the result of `range` with a step of 0 was never specified. Don't assume that the tests are specifications. Many of the tests in Clojure were written by over-eager volunteers who defined the tests based on whatever the behavior happened to be. The only specification from the language designer is the docstring. By my reading, that means that `range` with a step of 0 should return an infinite seq of the start value, unless the start and end values are equal. -S |
| Comment by Devin Walters [ 09/Jul/12 7:10 PM ] |
|
Carrying over a message by Michal Marczyk: With a negative step, the comparison is reversed, so that e.g. (range 3 0 -1) evaluates to (3 2 1) I think this is the useful behaviour; the docstring should perhaps be Agreed on zero step. Cheers, |
| Comment by Devin Walters [ 20/Jul/12 5:10 PM ] |
|
Adding a new patch after hearing comments. This patch makes (range 9 3 0) => (9 9 9 9 ...), (range 3 9 0) => (3 3 3 3 ...), and () will be returned when (= start end). Also updated the docstring. |
| Comment by Timothy Baldridge [ 27/Nov/12 3:01 PM ] |
|
Marking as vetted |
| Comment by Timothy Baldridge [ 27/Nov/12 3:04 PM ] |
|
Patch applies cleanly. We've discussed this issue to death (for as simple as it is). I think it's time to mark it as screened. |
| Comment by Timothy Baldridge [ 27/Nov/12 3:06 PM ] |
|
For some reason I'm not allowed to edit the attachments list. When you apply the patch, please apply inconsistent_range_fix.diff as that is the most recent version of the fix. |
| Comment by Rich Hickey [ 09/Dec/12 6:44 AM ] |
|
As someone who has to read these tickets, I'd really appreciate it if you could keep the description up to date and accurate, with examples of the current and intended behavior and the strategy to be used in fixing. I can't follow every thread to see what the latest thinking is, especially on a patch like this where the original mission was changed. Thanks |
| Comment by Devin Walters [ 10/Dec/12 3:53 PM ] |
|
@Tim: I've removed the other attachments. @Rich: Understood. I will update the description this evening. |
[CLJ-1078] Added queue, queue* and queue? to clojure.core Created: 26/Sep/12 Updated: 23/May/13 |
|
| Status: | Open |
| Project: | Clojure |
| Component/s: | None |
| Affects Version/s: | Release 1.5 |
| Fix Version/s: | None |
| Type: | Enhancement | Priority: | Trivial |
| Reporter: | Timothy Baldridge | Assignee: | Unassigned |
| Resolution: | Unresolved | Votes: | 2 |
| Labels: | data-structures, queue | ||
| Attachments: |
|
| Patch: | Code and Test |
| Description |
|
This patch adds functions for PersistentQueue. queue, queue? and queue* match the list functions of the same naming conventions. Patches include updates to tests. |
| Comments |
| Comment by Andy Fingerhut [ 28/Sep/12 8:43 AM ] |
|
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. |
| Comment by Timothy Baldridge [ 26/Oct/12 5:23 PM ] |
|
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. |
| Comment by Andy Fingerhut [ 26/Oct/12 5:43 PM ] |
|
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 (http://dev.clojure.org/display/design/JIRA+workflow under "Development" heading). % git clone git://github.com/clojure/clojure.git |
| Comment by Timothy Baldridge [ 26/Oct/12 6:08 PM ] |
|
I was using git apply. I tried the method you show above, and now I'm seeing the same issues you show above. |
| Comment by Andy Fingerhut [ 26/Oct/12 6:26 PM ] |
|
Just so you know, the preferred way to create and apply patches are the "git format-patch master --stdout > 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 < 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. The "patch -p1 < 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. |
| Comment by Timothy Baldridge [ 26/Oct/12 9:15 PM ] |
|
Just so you know, the preferred way to create and apply patches are the "git format-patch master --stdout > 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 < 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. The "patch -p1 < 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. |
| Comment by Timothy Baldridge [ 26/Oct/12 9:16 PM ] |
|
added patch |
| Comment by Andy Fingerhut [ 26/Oct/12 9:37 PM ] |
|
That one applies cleanly and passes all tests. It should show up on the next list of prescreened patches. Thanks. |
| Comment by Rich Hickey [ 29/Nov/12 9:54 AM ] |
|
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 [1 2 3]) could be made to 'adopt' the collection as front. |
| Comment by Andy Fingerhut [ 11/Dec/12 1:00 PM ] |
|
Patch queue.patch dated Oct 26 2012 no longer applies cleanly after recent |
| Comment by Steve Miner [ 06/Apr/13 8:06 AM ] |
|
See also CLJ-976 (tagged literal support for PersistentQueue) |
| Comment by John Jacobsen [ 23/May/13 8:54 PM ] |
|
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. |
[CLJ-1210] error message for (clojure.java.io/reader nil) — consistency for use with io/resource Created: 23/May/13 Updated: 23/May/13 |
|
| Status: | Open |
| Project: | Clojure |
| Component/s: | None |
| Affects Version/s: | Release 1.5 |
| Fix Version/s: | None |
| Type: | Enhancement | Priority: | Minor |
| Reporter: | Trevor Wennblom | Assignee: | Unassigned |
| Resolution: | Unresolved | Votes: | 0 |
| Labels: | None | ||
| Description |
|
This seems to a common idiom: (clojure.java.io/reader (clojure.java.io/resource "myfile")) When a file is available these are the behaviors: => (clojure.java.io/reader "resources/myfile") => (clojure.java.io/resource "myfile") => (clojure.java.io/reader (clojure.java.io/resource "myfile")) If the file (resource) is unavailable: => (clojure.java.io/reader "resources/nofile") => (clojure.java.io/resource "nofile") => (clojure.java.io/reader (clojure.java.io/resource "nofile")) The main enhancement request is to have a better error message from `(clojure.java.io/reader nil)`. I'm not sure if io/resource should return something like 'resource "nofile" not found' or if io/reader could add a more helpful suggestion. |
[CLJ-1201] There should also be writing in clojure.edn Created: 15/Apr/13 Updated: 23/May/13 |
|
| Status: | Open |
| Project: | Clojure |
| Component/s: | None |
| Affects Version/s: | Release 1.5 |
| Fix Version/s: | None |
| Type: | Enhancement | Priority: | Minor |
| Reporter: | Vitaly Shukela | Assignee: | Unassigned |
| Resolution: | Unresolved | Votes: | 0 |
| Labels: | edn | ||
| Description |
|
In clojure.edn I see only "read" and "read-string". 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. |
| Comments |
| Comment by Andy Fingerhut [ 23/May/13 5:56 PM ] |
|
Related clojure-dev message: https://groups.google.com/forum/?fromgroups#!topic/clojure-dev/fLJWh9A3OuA and enhancement proposal wiki page: http://dev.clojure.org/display/design/Representing+EDN |
[CLJ-999] Wrong link in gh-pages index (api-index.html) Created: 18/May/12 Updated: 20/May/13 Resolved: 20/May/13 |
|
| Status: | Resolved |
| Project: | Clojure |
| Component/s: | None |
| Affects Version/s: | Release 1.3 |
| Fix Version/s: | None |
| Type: | Defect | Priority: | Trivial |
| Reporter: | Bogdan Popescu | Assignee: | Tom Faulhaber |
| Resolution: | Completed | Votes: | 0 |
| Labels: | docs, documentation | ||
| Patch: | None |
| Description |
|
The api-index.html includes wrong links for the following:
The links point to pages that do not exist. The problem is that the documentation for those entries is on a "parent" page, for example, the link clojure.core.protocols-api.html#clojure.core.protocols/internal-reduce should have been clojure.core-api.html#clojure.core.protocols/internal-reduce Not a huge bug for me, but you might want to get it fixed. And please give my huge thanks to whoever is in charge of the documentation, I'm the developer behind Dash, a Mac OS X documentation browser, and I was in the process of creating a documentation set for Clojure, and because you guys have an index, you made my work 1000 times easier. |
| Comments |
| Comment by Andy Fingerhut [ 11/Mar/13 3:01 PM ] |
|
Is this fixed now? Tom Faulhaber has regenerated the docs after the recent Clojure 1.5 release, and I think updated other things besides, so it might be. |
| Comment by Tom Faulhaber [ 11/Mar/13 4:43 PM ] |
|
Nope, not fixed. This one either slipped by me or came in right when I was changing jobs so didn't stick in my brain. I'll take a look now. Thanks for the report, Bogdan, and thanks for the bump, Andy to get it on my radar. |
| Comment by Gabriel Horner [ 10/May/13 4:00 PM ] |
|
Tom, I'm happy to help if you need it. Could you document on a wiki page how autodoc is run here? I couldn't find such a page. |
| Comment by Tom Faulhaber [ 20/May/13 4:18 PM ] |
|
This is fixed with gh-pages commit 919143e (autodoc doesn't follow the regular Clojure release path since it's a website built off the source checkins). |
| Comment by Tom Faulhaber [ 20/May/13 4:24 PM ] |
|
Gabriel, Thanks for the offer. I fixed this one, but may take you up on it if more come up. There is currently no wiki page about the autodoc process but it's an excellent suggestion. I'll put it on my list to write something up. In the meantime source on the autodoc program itself is at https://github.com/tomfaulhaber/autodoc and a description of how it works is at http://tomfaulhaber.github.io/autodoc. Two caveats: (1) autodoc is currently undergoing a bunch of work (thus this bug fix) in preparation for a new release and (2) the documentation doesn't talk much about how it's used for documenting Clojure itself. |
[CLJ-1147] Threading macro (->) does not permit inline function declarations Created: 14/Jan/13 Updated: 19/May/13 |
|
| Status: | Open |
| Project: | Clojure |
| Component/s: | None |
| Affects Version/s: | Release 1.5 |
| Fix Version/s: | None |
| Type: | Defect | Priority: | Minor |
| Reporter: | Stephen Nelson | Assignee: | Unassigned |
| Resolution: | Unresolved | Votes: | 0 |
| Labels: | None | ||
| Description |
|
(-> [1 2 3] (fn [args] apply + args)) CompilerException java.lang.Exception: Unsupported binding form: 1, compiling:(NO_SOURCE_PATH:1:13) The expression is expanded to: (fn [1 2 3] [args] apply + args) If this is intended behaviour then at the least the compiler error message is confusing. It would be preferable if the -> macro checked for (fn..) before treating a form as a sequence and injecting the argument. |
| Comments |
| Comment by Andy Fingerhut [ 15/Jan/13 12:56 AM ] |
|
Note that this works as you might have hoped: (-> [1 2 3] ((fn [args] (apply + args)))) because it expands into: ((fn [args] (apply + args)) [1 2 3]) Your suggestion that -> 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? |
| Comment by Gabriel Horner [ 17/May/13 2:56 PM ] |
|
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. |
| Comment by Stephen Nelson [ 19/May/13 10:29 PM ] |
|
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..). 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 – hardly a reasonable expectation for a novice user. 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?). |
[CLJ-1183] java interop - cannot call a final method on non-public superclass Created: 13/Mar/13 Updated: 18/May/13 |
|
| Status: | Open |
| Project: | Clojure |
| Component/s: | None |
| Affects Version/s: | Release 1.4, Release 1.5 |
| Fix Version/s: | None |
| Type: | Defect | Priority: | Major |
| Reporter: | Shlomi | Assignee: | Unassigned |
| Resolution: | Unresolved | Votes: | 1 |
| Labels: | None | ||
| Attachments: |
|
| Description |
|
when trying to call a method on a concrete class that is defined as final on its super class that is not public, the runtime throws: "java.lang.IllegalArgumentException: Can't call public method of non-public class" even when fully annotated, Reflection is still used and the call fails. you can read the full description here https://groups.google.com/d/msg/clojure/p2tBMT-BIYc/mDQB8cSponMJ I included a sample project that demonstrate the problem |
| Comments |
| Comment by Shlomi [ 13/Mar/13 6:51 AM ] |
|
in my sample project, i used a nested class, but i didnt have to (as pointed by Marko Topolnik). changing the java code to: abstract class AbstractParent{ public class test extends AbstractParent {} and the clojure to: (ns call-test.core (:gen-class)) would produce the same error, java.lang.IllegalArgumentException: Can't call public method of non-public class: public final int AbstractParent.x() |
| Comment by zoowar [ 16/May/13 12:05 PM ] |
|
This issue affects the upcoming netty-4.0 release in which the public modifier of AbstractBootstrap was removed. |
| Comment by Matthew Phillips [ 18/May/13 3:48 AM ] |
|
To get Netty 4 working with Clojure I had to create a set of public static Java methods for the various inaccessible Netty calls, which I then call from Clojure. A PITA, but works fine. Happy to post code if anyone would find it useful. |
| Comment by Shlomi [ 18/May/13 4:31 AM ] |
|
Matthew, i kinda left that project after running to these and other troubles (focused on previous Netty until version 4 will become ready and be properly documented), but i'd still like to see your code. you have a github account or a gist with it? Clojure devs - are there any plans of checking this problem out? it came up from Netty, but the problem is pretty generic |
| Comment by Matthew Phillips [ 18/May/13 7:22 PM ] |
|
Shlomi: here's a gist with the code I'm using in it. It's not comprehensive, just the bits I needed. |