[CLJ-944] (.containsKey {:one 1} :one) throws Exception Created: 04/Mar/12 Updated: 13/Apr/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 |
| Approval: | Vetted |
| Description |
|
Patch clj944-plus-tests does three things:
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-1018] range's behavior is inconsistent Created: 29/Jun/12 Updated: 12/Apr/13 |
|
| Status: | Open |
| 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: | Unresolved | 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-1161] sources jar has bad versions.properties resource Created: 11/Feb/13 Updated: 12/Apr/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 Sierra |
| Resolution: | Unresolved | Votes: | 0 |
| Labels: | patch | ||
| Attachments: |
|
| Patch: | Code |
| Approval: | Vetted |
| Description |
|
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-1154] Compile.java closes out preventing java from reporting exceptions Created: 31/Jan/13 Updated: 12/Apr/13 |
|
| Status: | Open |
| Project: | Clojure |
| Component/s: | None |
| Affects Version/s: | Release 1.4 |
| Fix Version/s: | Release 1.5, Release 1.6 |
| Type: | Defect | Priority: | Major |
| Reporter: | Robert (Bobby) Evans | Assignee: | Unassigned |
| Resolution: | Unresolved | Votes: | 1 |
| Labels: | None | ||
| Approval: | Vetted |
| Description |
|
I was trying to compile a project that has some native dependencies. I am using clojure-maven-plugin version 1.3.13 with Maven 2.0. I forgot to set java.library.path properly so that the native library could be found, and only got an error of [INFO] ------------------------------------------------------------------------ [ERROR] BUILD ERROR [INFO] ------------------------------------------------------------------------ [INFO] Clojure failed. [INFO] ------------------------------------------------------------------------ I traced this down to Compile.java, where it is flushing and closing out |
| Comments |
| Comment by Stuart Halloway [ 01/Mar/13 10:45 AM ] |
|
I have encountered this problem as well. Did not verify the explanation, but sounds reasonable. |