<< Back to previous view

[TRDR-8] Fix for parsing of tagged literals Created: 12/Sep/13  Updated: 13/Sep/13  Resolved: 13/Sep/13

Status: Closed
Project: tools.reader
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Defect Priority: Major
Reporter: Alex Coventry Assignee: Nicola Mometto
Resolution: Completed Votes: 0
Labels: bug, patch

Attachments: Text File 0001-Fix-for-ctor-reading.patch     Text File reader.patch    
Patch: Code
Approval: Ok

 Description   

Parsing of tagged literals fails at the moment, e.g.

user> (require '[clojure.tools.reader :as r] :reload) (r/read-string "#java.lang.String[\"Hi\"]")
nil
ArrayIndexOutOfBoundsException 15 clojure.lang.RT.aget (RT.java:2239)

Attached patch corrects this problem, and brings the clojure logic in line with what's in LispReader.java



 Comments   
Comment by Nicola Mometto [ 13/Sep/13 7:18 AM ]

Thanks for the patch, can you post a patch that is the result of git format-patch so that we can keep your authorship on the commit?
(apply the patch, git add <path/to/reader.clj>, git commit -m "Fix ctor reading", git format-patch origin/master)

Also, can you please put the result of (count entries) in the let so that we compute it only once?

Thanks

Comment by Alex Coventry [ 13/Sep/13 12:06 PM ]

No worries, Nicola. I've attached a revised patch.

Best regards,
Alex

Comment by Nicola Mometto [ 13/Sep/13 12:38 PM ]

fixed https://github.com/clojure/tools.reader/commit/d9374f90448a4ff52ad83a2b75be2fa520a24db8





[TNS-17] doesn't track namespace when ns decl isn't first in file Created: 04/Feb/14  Updated: 04/Feb/14

Status: Open
Project: tools.namespace
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Enhancement Priority: Minor
Reporter: Trevor Wennblom Assignee: Stuart Sierra
Resolution: Unresolved Votes: 0
Labels: bug, enhancement


 Description   

This was first filed for ns-tracker https://github.com/weavejester/ns-tracker/issues/15 but I understand it's more specific to tools.namespace.

(I realize this is likely a very low priority, but it'd still be nice to see fixed if possible. Thanks!)


It appears ns-tracker tools.namespace will cease following a namespace when there's non-commented content before the namespace declaration.

works:

;-begin
(ns myproject.core)
(println "hi")
;-end

untracked — (any of the four possibilities when uncommented, for example):

;-begin
1
;;; (println "before ns")
;;; (println "loading" *file*)
;;; :abc
(ns myproject.core)
(println "hi")
;-end





[TMACRO-2] protect let-bound symbols from macrolet expansion Created: 26/Nov/12  Updated: 27/Nov/12  Resolved: 27/Nov/12

Status: Resolved
Project: tools.macro
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Defect Priority: Minor
Reporter: Tom Jack Assignee: Konrad Hinsen
Resolution: Completed Votes: 1
Labels: bug, patch

Attachments: Text File 0001-Don-t-apply-macro-expansion-to-protected-forms.patch     File macrolet-protect.diff    
Patch: Code and Test

 Description   

As discussed here: https://groups.google.com/d/msg/clojure-dev/-/UheAzkyI_WcJ

Patch macrolet-protect.diff fixes the issue and provides a test.



 Comments   
Comment by Tom Jack [ 26/Nov/12 2:55 PM ]

D'oh, patch macrolet-protect.diff has a bug — it doesn't macroexpand-1 if the symbol is protected.

Comment by Tassilo Horn [ 27/Nov/12 1:38 AM ]

This patch supersedes Tom's patch as discussed on the clojure-dev mailinglist. See

Message-ID: <CADygAw4ArNq4Z2=ZJmT6MwkBw160ShJmfQwoFEh4VOiwxfjDKQ@mail.gmail.com>

for reference.

The patch also adds letfn* as a form introducing protected symbols. That one was completely missing.

I added test cases for both let as well as letfn.

Comment by Konrad Hinsen [ 27/Nov/12 8:40 AM ]

Patch applied: https://github.com/clojure/tools.macro/commit/19c8197e10079f04e55d81c26884b9248762c2ca

Thanks!





[NREPL-51] Pretty-printing reference returned by clojure.tools.nrepl.server/start-server causes multimethod exception Created: 12/Apr/14  Updated: 18/Apr/14  Resolved: 18/Apr/14

Status: Closed
Project: tools.nrepl
Component/s: None
Affects Version/s: 0.2.3
Fix Version/s: 0.2.4

Type: Defect Priority: Minor
Reporter: Michael Nygard Assignee: Chas Emerick
Resolution: Completed Votes: 0
Labels: bug


 Description   

I was accidentally printing the reference returned by start-server by calling it as the final function in my main method, which causes this error:

java.lang.IllegalArgumentException: Multiple methods in multimethod 'print-method' match dispatch value: class clojure.tools.nrepl.server.Server -> interface clojure.lang.IDeref and interface clojure.lang.IRecord, and neither is preferred
at clojure.lang.MultiFn.findAndCacheBestMethod(MultiFn.java:136)
at clojure.lang.MultiFn.getMethod(MultiFn.java:111)
at clojure.lang.MultiFn.getFn(MultiFn.java:119)
at clojure.lang.MultiFn.invoke(MultiFn.java:167)
at clojure.core$pr_on.invoke(core.clj:3266)
at clojure.core$pr.invoke(core.clj:3278)
at clojure.lang.AFn.applyToHelper(AFn.java:161)
at clojure.lang.RestFn.applyTo(RestFn.java:132)
at clojure.core$apply.invoke(core.clj:601)
at clojure.core$prn.doInvoke(core.clj:3311)
at clojure.lang.RestFn.invoke(RestFn.java:408)
at clojure.main$eval_opt.invoke(main.clj:299)
at clojure.main$initialize.invoke(main.clj:316)
at clojure.main$null_opt.invoke(main.clj:349)
at clojure.main$main.doInvoke(main.clj:427)
at clojure.lang.RestFn.invoke(RestFn.java:421)
at clojure.lang.Var.invoke(Var.java:419)
at clojure.lang.AFn.applyToHelper(AFn.java:163)
at clojure.lang.Var.applyTo(Var.java:532)
at clojure.main.main(main.java:37)



 Comments   
Comment by Michael Nygard [ 12/Apr/14 12:09 PM ]

I cloned this from NREPL-37, but cannot change any of the other fields. Thanks Jira.

Basically, this is the same dispatch problem as NREPL-37 but on clojure.pprint/simple-dispatch.

Version affected is 0.2.3.

Comment by Chas Emerick [ 12/Apr/14 12:21 PM ]

Thanks, should have thought of this when I fixed the related issue.

Comment by Chas Emerick [ 18/Apr/14 10:04 AM ]

Committed, will be available in 0.2.4-SNAPSHOT momentarily.





[NREPL-49] Chas, where are you? You said you were going to the Hops & Hominy restaurant Created: 25/Mar/14  Updated: 28/Mar/14  Resolved: 28/Mar/14

Status: Closed
Project: tools.nrepl
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Defect Priority: Blocker
Reporter: Andy Fingerhut Assignee: Chas Emerick
Resolution: Not Reproducible Votes: 0
Labels: bug
Environment:

San Francisco


Attachments: JPEG File IMG_20140326_174912.jpg    

 Description   

You said you, Gary, and Chris were going to meet me at Hops & Hominy restaurant after Clojure/West. I am here, but I don't see you guys anywhere.

Steps to reproduce: Walk around the restaurant, looking for you at every table. You are not there.



 Comments   
Comment by Chas Emerick [ 26/Mar/14 2:13 PM ]

This is officially the most awesome JIRA ticket, ever. <3 Andy. :-D

Comment by Chas Emerick [ 26/Mar/14 2:45 PM ]

People keep asking, so: yes, we got there and all had a good time.

Comment by Justin Balthrop [ 26/Mar/14 7:40 PM ]

Chas, I'm having a similar issue. You said you'd be around, but I can't find you.

Comment by Aaron Brooks [ 26/Mar/14 7:55 PM ]

I've re-run the tests and found Chas to be in the Garden Court of the Palace Hotel. See the attached test results.

Comment by Chas Emerick [ 28/Mar/14 12:07 PM ]

@Justin, this is likely a race condition. I was there (as indicated by the test results, thanks Aaron), but you weren't. If Reid had finished his test.check scheduler, we could have prevented a buggy interleaving. Since we've all decamped from SF at this point, I don't know that we'll be able to properly reach a resolution.

I'm closing this as 'not reproducible' for now.





[NREPL-46] nREPL crashes when required more than one time with :reload-all Created: 21/Dec/13  Updated: 21/Dec/13

Status: Open
Project: tools.nrepl
Component/s: None
Affects Version/s: 0.2.2
Fix Version/s: None

Type: Defect Priority: Critical
Reporter: Alex Fowler Assignee: Chas Emerick
Resolution: Unresolved Votes: 1
Labels: bug
Environment:

Irrelevant, but the provided test case project is for CounterClockWise on Eclipse. Although it should run just fine with vanilla lein.


Attachments: Zip Archive nrepl-test.zip    

 Description   

When the namespace "clojure.tools.nrepl.server" is required more than once with :reload-all option, nREPL crashes. Accrding to current info it occures because some protocol instances get re-evaluated and are no longer the same JVM classes as they were before reload-all.

Steps to reproduce the bug in CCW:
1) Import the project into the workspace
2) Go into the core.clj
3) Click Clojure -> Load file in REPL
4) After the evaluation is complete, try evaluating (+ 1 2) in the repl. You should see no response at all.
5) Try writing something with letters, like "nrepl". The autocompletion will try and freeze and fail with the above exception.
6) Play around more to get a full hang or kill the REPL/Java to revive Eclipse.

Upon trying CCW autocompetion, the following exception occures, what might give some hint as to why:

Exception in thread "nREPL-worker-2" java.lang.IllegalArgumentException: No implementation of method: :send of protocol: #'clojure.tools.nrepl.transport/Transport found for class: clojure.tools.nrepl.middleware.pr_values$pr_values$fn$reify__1283
at clojure.core$_cache_protocol_fn.invoke(core_deftype.clj:541)
at clojure.tools.nrepl.transport$eval7291$fn_7292$G7280_7299.invoke(transport.clj:16)
at clojure.tools.nrepl.middleware.interruptible_eval$evaluate$fn_7726$fn_7739.invoke(interruptible_eval.clj:75)
at clojure.main$repl$fn__6597.invoke(main.clj:279)
at clojure.main$repl.doInvoke(main.clj:277)
at clojure.lang.RestFn.invoke(RestFn.java:1096)
at clojure.tools.nrepl.middleware.interruptible_eval$evaluate$fn__7726.invoke(interruptible_eval.clj:56)
at clojure.lang.AFn.applyToHelper(AFn.java:159)
at clojure.lang.AFn.applyTo(AFn.java:151)
at clojure.core$apply.invoke(core.clj:617)
at clojure.core$with_bindings_STAR_.doInvoke(core.clj:1788)
at clojure.lang.RestFn.invoke(RestFn.java:425)
at clojure.tools.nrepl.middleware.interruptible_eval$evaluate.invoke(interruptible_eval.clj:41)
at clojure.tools.nrepl.middleware.interruptible_eval$interruptible_eval$fn_1345$fn_1348.invoke(interruptible_eval.clj:171)
at clojure.core$comp$fn__4154.invoke(core.clj:2330)
at clojure.tools.nrepl.middleware.interruptible_eval$run_next$fn__7760.invoke(interruptible_eval.clj:138)
at clojure.lang.AFn.run(AFn.java:24)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)






[NREPL-38] Certain Calendar values don't seem to be able to print Created: 12/Jan/13  Updated: 13/Jan/13  Resolved: 13/Jan/13

Status: Closed
Project: tools.nrepl
Component/s: None
Affects Version/s: 0.2.0
Fix Version/s: 0.2.1

Type: Defect Priority: Major
Reporter: Julian Birch Assignee: Unassigned
Resolution: Completed Votes: 0
Labels: bug
Environment:

Ubuntu 12.10, running through Leiningen 2



 Description   

If I try to run lein repl outside of a project folder, I get Clojure 1.4.0.
I then run

(println (javax.xml.bind.DatatypeConverter/parseDateTime "2008-07-21T19:17:29"))

which produces

IndexOutOfBoundsException start 26, end 2, s.length() 28 java.lang.AbstractStringBuilder.append (AbstractStringBuilder.java:476)
#inst "2008-07-21T19:17:29.000+01:

Note the absence of a closing '"'.

My apologies in advance if this is impossible to reproduce.



 Comments   
Comment by Andy Fingerhut [ 13/Jan/13 9:55 AM ]

I can reproduce this with Clojure 1.4.0 and 1.5.0-RC2 if I do it within "lein2 repl" (I was using Leiningen version 2.0.0-preview10 to reproduce the problem).

If I use "java -cp clojure.jar clojure.main" to start a REPL session, with either Clojure 1.4.0 or 1.5.0-RC2 for clojure.jar, I don't see any problem. I was testing on Mac OS X 10.6.8 with Oracle/Apple JDK 1.6.0_37.

I also don't see this problem if I use Leiningen version 1.7.1, tested with both Clojure 1.4.0 and 1.5.0-RC2.

This appears to be some kind of bad interaction between Leiningen 2.0.0-preview10 and Clojure.

Comment by Andy Fingerhut [ 13/Jan/13 10:05 AM ]

I also reproduced this issue with the latest version of Leiningen, which is 2.0.0-RC2. Email sent to the Leiningen developer email list so they know about it.

Comment by Chas Emerick [ 13/Jan/13 10:52 AM ]

This is an nREPL bug involving an API mismatch between java.io.Writer.write() and java.lang.AbstractStringBuilder.append().

The fix is simple; patch release coming later today.

Comment by Chas Emerick [ 13/Jan/13 12:29 PM ]

Fixed with b9e930a1.

Will be a part of [org.clojure/tools.nrepl "0.2.1"], to be released later today.





[NREPL-37] Printing reference returned by clojure.tools.nrepl.server/start-server causes multimethod exception Created: 20/Dec/12  Updated: 26/Feb/13  Resolved: 26/Feb/13

Status: Closed
Project: tools.nrepl
Component/s: None
Affects Version/s: 0.2.0-RC1
Fix Version/s: 0.2.2

Type: Defect Priority: Minor
Reporter: Vaughn Dickson Assignee: Chas Emerick
Resolution: Completed Votes: 0
Labels: bug


 Description   

I was accidentally printing the reference returned by start-server by calling it as the final function in my main method, which causes this error:

java.lang.IllegalArgumentException: Multiple methods in multimethod 'print-method' match dispatch value: class clojure.tools.nrepl.server.Server -> interface clojure.lang.IDeref and interface clojure.lang.IRecord, and neither is preferred
at clojure.lang.MultiFn.findAndCacheBestMethod(MultiFn.java:136)
at clojure.lang.MultiFn.getMethod(MultiFn.java:111)
at clojure.lang.MultiFn.getFn(MultiFn.java:119)
at clojure.lang.MultiFn.invoke(MultiFn.java:167)
at clojure.core$pr_on.invoke(core.clj:3266)
at clojure.core$pr.invoke(core.clj:3278)
at clojure.lang.AFn.applyToHelper(AFn.java:161)
at clojure.lang.RestFn.applyTo(RestFn.java:132)
at clojure.core$apply.invoke(core.clj:601)
at clojure.core$prn.doInvoke(core.clj:3311)
at clojure.lang.RestFn.invoke(RestFn.java:408)
at clojure.main$eval_opt.invoke(main.clj:299)
at clojure.main$initialize.invoke(main.clj:316)
at clojure.main$null_opt.invoke(main.clj:349)
at clojure.main$main.doInvoke(main.clj:427)
at clojure.lang.RestFn.invoke(RestFn.java:421)
at clojure.lang.Var.invoke(Var.java:419)
at clojure.lang.AFn.applyToHelper(AFn.java:163)
at clojure.lang.Var.applyTo(Var.java:532)
at clojure.main.main(main.java:37)



 Comments   
Comment by Chas Emerick [ 02/Feb/13 7:35 AM ]

The fact that the returned record is also a clojure.lang.IDeref is a temporary compatibility measure, a result of changing to returning a record.

Adding a print-method implementation for the Server type that explicitly delegates to the IRecord implementation would resolve the problem.

Comment by Chas Emerick [ 26/Feb/13 4:42 AM ]

Fixed @ http://github.com/clojure/tools.nrepl/commit/0f016eb





[NREPL-19] Android: nREPL starts with no namespace Created: 11/May/12  Updated: 20/Jun/12  Resolved: 20/Jun/12

Status: Closed
Project: tools.nrepl
Component/s: None
Affects Version/s: 0.2.0
Fix Version/s: None

Type: Defect Priority: Major
Reporter: Alexander Yakushev Assignee: Chas Emerick
Resolution: Completed Votes: 0
Labels: android,, bug
Environment:

Android w/ Clojure 1.4.0, REPLy client / Eclipse CCW client



 Description   

When I start the nREPL on the Android device (by calling `(clojure.tools.nrepl.server/start-server :port 9999)`) it all goes well. But when I try to connect to this REPL using any of the clients I find myself in an empty namespace (or something like that). The var ns is unbound, no functions from the clojure.core are available. At the beginning REPLy tries to perform some actions but they fail (says that it cannot find symbol `defn` - because nothing from clojure.core is being mapped).

However I can do (in-ns 'anywhere) it works. Everything else in the REPL works correctly (as far as I see). The issue itself is minor but I'm afraid that it is caused by some crash during nREPL initialization that might lead to other problems in future.



 Comments   
Comment by Alexander Yakushev [ 11/May/12 11:06 AM ]

Can't edit, I meant the *ns* var, of course.

Comment by Alexander Yakushev [ 19/May/12 4:32 PM ]

With the help of Daniel Solano Gómez I managed to fix this bug. The problem was caused by the lack of user namespace in the Android-patched Clojure. nREPL assumes that the user namespace is present and uses it by default.

Here's the so called fix I ended up with:

...
(let [user-ns (create-ns 'user)]
  (binding [*ns* user-ns]
    (clojure.tools.nrepl.server/start-server :port 9999)))
...

The issue can be closed now.

Comment by Chas Emerick [ 27/May/12 4:04 PM ]

A follow up Q: user is created by clojure.lang.RT's static initialization. Is the lack of that in "Android-patched Clojure" an optimization of some sort?

Comment by Alexander Yakushev [ 27/May/12 4:49 PM ]

Exactly, Daniel Solano Gómez removed it because it's initialization took additional time, it seems.





[NREPL-16] nrepl.middleware.interruptible_eval/interruptible_eval raises a stack inconsistence Exception if the call to clojure.main/repl fails Created: 12/Apr/12  Updated: 20/Apr/12  Resolved: 16/Apr/12

Status: Closed
Project: tools.nrepl
Component/s: None
Affects Version/s: 0.2.0
Fix Version/s: None

Type: Defect Priority: Major
Reporter: Alexander Yakushev Assignee: Chas Emerick
Resolution: Completed Votes: 0
Labels: bug
Environment:

clojure 1.4.0-beta5, Android



 Description   

If the call to clojure.main/repl in `evaluate' raises an exception before the :init part gets evaluated (so the expression `(push-thread-bindings @bindings)' is executed) then nREPL crashes with the following exception:

java.lang.IllegalStateException: Pop without matching push

It happens because after the underlining exception in clojure.main/repl is caught by the try block in `evaluate', the `finally' black calls (pop-thread-bindings) which were not actually "pushed".



 Comments   
Comment by Chas Emerick [ 16/Apr/12 5:34 PM ]

Fixed in 0.2.0-beta6. Please give it a try and see how it works on Android.

Comment by Alexander Yakushev [ 20/Apr/12 1:40 PM ]

It is OK now. OK in a sense that if something wrong happens inside the clojure.main/repl function then the stacktrace points there after the application dies.
Thanks for you help!





[MATCH-87] Bad interaction with core.async Created: 11/Sep/13  Updated: 01/Dec/13

Status: Reopened
Project: core.match
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Defect Priority: Minor
Reporter: Stefan Fehrenbach Assignee: David Nolen
Resolution: Unresolved Votes: 0
Labels: bug
Environment:

[org.clojure/core.async "0.1.0-SNAPSHOT"] (more specifically core.async-0.1.0-20130827.050117-78)
[org.clojure/core.match "0.2.0-rc5"]



 Description   

This prints "foo" as expected:

(defn works []
  (.log js/console
        (match ["qux" "foo"]
          ["qux" "bar"] 1
          ["qux" x]     x)))

This fails with an exception: Uncaught Error: No matching clause: ["qux" "foo"]
in up-to-date Chromium

(defn fails []
  (go
   (.log js/console
         (match (<! (go ["qux" "foo"]))
           ["qux" "bar"] 1
           ["qux" x]     x))))

I don't know either core.async nor core.match very well. My best guess is a undesired interaction between the nonlocal control flow for backtracking and the core.async state machine.

Note that this is a version of core.async where http://dev.clojure.org/jira/browse/ASYNC-15 is fixed.



 Comments   
Comment by David Nolen [ 11/Sep/13 12:24 PM ]

This is not a bug, it's not possible to use <! outside of go blocks.

Comment by Stefan Fehrenbach [ 11/Sep/13 12:48 PM ]

Does that count as outside? Anyway, this should not be outside. Same problem.

(defn fails []
  (go (let [m (<! (go ["qux" "foo"]))]
        (.log js/console
              (match m
                ["qux" "bar"] 1
                ["qux" x] x)))))
Comment by David Nolen [ 11/Sep/13 1:17 PM ]

Sorry missed the surrounding go! However note tickets about interaction between core.match and core.async are extremely low priority without more information about whether the bug is actually in ASYNC or in MATCH. I just don't have the bandwidth to do that sort of investigation at the moment.

Still, thanks for the report.

Comment by Stefan Fehrenbach [ 11/Sep/13 2:05 PM ]

I see. I'm not so sure whether I should report this to ASYNC, any thoughts?
I'm not familiar with either library, but I'll try to investigate further when I have the time.
For now, I guess I'll do more stupid matching. It really is a shame, core.match is a perfect fit for dispatching on messages and channels coming from alts!. Anyways, thanks for your work!

Comment by David Nolen [ 30/Nov/13 2:28 PM ]

Is this still a problem? I think core.async recently added better analysis of the dot form.

Comment by Stefan Fehrenbach [ 01/Dec/13 2:45 AM ]

Hi, thanks for thinking about this. I got side tracked and did not look into it any further.
Unfortunately it still does not work.

Tested versions:
[org.clojure/clojurescript "0.0-2080"]
[org.clojure/core.async "0.1.242.0-44b1e3-alpha"]
[org.clojure/core.match "0.2.0"]





[MATCH-61] Exception thrown when matching using :seq when there is a seq call in the tail of the occurrences Created: 22/Jun/12  Updated: 28/Jul/13  Resolved: 20/Jun/13

Status: Closed
Project: core.match
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Defect Priority: Major
Reporter: Emma Tosch Assignee: David Nolen
Resolution: Completed Votes: 0
Labels: bug, seq
Environment:

with Clojure 1.3



 Description   

The following match throws:

(let [q '(a) y '(b) z '(c)]
  (match [q (seq y) z]
    [([_] :seq) _ _] 'a
    [_ _ _] 'b))

Looking at the macro expansion there's something clearly wrong simply with the fact that the seq expression occurs in multiple places instead of just at the beginning of the macro expansion.



 Comments   
Comment by Emma Tosch [ 22/Jun/12 5:33 PM ]

https://gist.github.com/626088b01817ac638fae
Two expressions, macro-expanded. The only difference between the expressions is that the second occurrence in the second expression is seq'ed. The second let is the one throwing the exception; it's the one with the binding

(clojure.core/let [q_tail_3472 q_tail_3472
q_head_3471 q_head_3471
ocr-3470 (seq y)
z z]
...)

Comment by David Nolen [ 20/Jun/13 7:35 AM ]

fixed, http://github.com/clojure/core.match/commit/7b02b83478862a8fcaa3367871d043d4a40d9413





[LOGIC-156] Two consecutive calls to run* return different results Created: 22/Feb/14  Updated: 05/Mar/14

Status: Open
Project: core.logic
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Defect Priority: Major
Reporter: Mauro Lopes Assignee: David Nolen
Resolution: Unresolved Votes: 0
Labels: bug

Attachments: File core.clj     File core.clj    

 Description   

Calling run* twice with the same input may return different results for no apparent reason.
See attachment.



 Comments   
Comment by David Nolen [ 05/Mar/14 9:19 AM ]

The problematic code incorrectly uses finite domain operations on fresh variables that have not be assigned domains. Can we get an updated version of the problematic code that demonstrate the issue after the corrections?

Comment by Mauro Lopes [ 05/Mar/14 9:25 PM ]

Sure. I have just added a new code version with finite domains assigned to each variable that is involved in an fd operation. The problem persists.





[LOGIC-155] Dynamic variables are not seen inside a logic query Created: 28/Jan/14  Updated: 28/Jan/14

Status: Open
Project: core.logic
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Defect Priority: Major
Reporter: Reinout Stevens Assignee: David Nolen
Resolution: Unresolved Votes: 0
Labels: binding, bug, dynamic
Environment:

core.logic version 0.8.6
clojure version 1.5.1



 Description   

core.logic does not work correctly with dynamic variables, as illustrated by the following code:

(def ^:dynamic dvar 'original)
(binding [*dvar* 'changed]
(logic/run* [?x] (logic/== ?x dvar)))

;;outputs (original), expected (changed)

To the best of my knowledge this used to work in older versions, although I do not know when the behaviour changed.



 Comments   
Comment by David Nolen [ 28/Jan/14 10:56 AM ]

This is because core.logic became lazy (been a year now? . There are now non lazy run variants or you can use doall yourself.





[LOGIC-127] Swapping noms turns maps (and other collections) into seqs Created: 02/Apr/13  Updated: 28/Jul/13  Resolved: 10/Apr/13

Status: Closed
Project: core.logic
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Defect Priority: Major
Reporter: Jiří Maršík Assignee: Nada Amin
Resolution: Completed Votes: 0
Labels: bug, nominal

Attachments: Text File INomSwap-vectors-maps.patch     Text File INomSwap-vectors-maps-with-test.patch    
Approval: Accepted

 Description   

When I unify two binders, the swapping procedure turns all the maps inside the body into seqs of key/value pairs, which do not unify with maps, leading to the following trickiness:

(require '[clojure.core.logic :as l])
(require '[clojure.core.logic.nominal :as n])
(l/run* [q]
  (l/fresh [body]
    (n/fresh [a b]
      (l/== (n/tie a {:k a}) (n/tie b body))
      (l/== {:k q} body))))
;=> ()
; Expected (a_0)

For my purposes, fixing this by adding two new implementations of INomSwap for vectors and maps works well.



 Comments   
Comment by Jiří Maršík [ 02/Apr/13 11:14 AM ]

Oops, sorry for the malformatted code snippet. Here it is inside a code tag.

(require '[clojure.core.logic :as l])
(require '[clojure.core.logic.nominal :as n])
(l/run* [q]
        (l/fresh [body]
                 (n/fresh [a b]
                          (l/== (n/tie a {:k a}) (n/tie b body))
                          (l/== {:k q} body))))
;=> ()
; Expected (a_0)
Comment by David Nolen [ 02/Apr/13 11:22 AM ]

This seems like a easy one to fix, perhaps Nada can see quicker than I can. If not I can take a look.

Also your patch may very well solve the issue best, feel free to attach it to the ticket. We won't be able to apply it until you've submitted your Contributor Agreement - if you have a free moment please send it in. Thanks!

Comment by Jiří Maršík [ 02/Apr/13 11:48 AM ]

The patch that I use to fix the issue. I haven't signed the CA, but I would definitely like to. Might take a while to arrive though, since I'm in Europe and I'm lazy.

Comment by Nada Amin [ 03/Apr/13 2:36 AM ]

The patch LGTM. I would also add a test from the ticket example.

I guess we have to wait until the CA arrives, now.

Comment by Jiří Maršík [ 03/Apr/13 4:28 AM ]

I have also added the test case, the new patch INomSwap-vectors-maps-with-test.patch contains both the fix and the test case. I have just signed the CA and I plan to post it today.

Comment by Jiří Maršík [ 09/Apr/13 10:55 AM ]

OK, the CA has arrived and been processed.

http://clojure.org/contributing

  • Jiri Marsik (jirkamarsik)
Comment by Nada Amin [ 10/Apr/13 3:32 AM ]

Applied as https://github.com/clojure/core.logic/commit/d73c836c0d4bab2af12b4bdedb31daad4a661fb6

Thanks!





[LOGIC-116] ClassCastException in core.logic depending on ordering Created: 08/Mar/13  Updated: 28/Jul/13  Resolved: 17/Mar/13

Status: Closed
Project: core.logic
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Defect Priority: Major
Reporter: Matthew O. Smith Assignee: David Nolen
Resolution: Completed Votes: 0
Labels: 0.8.0, bug

Attachments: File corefail.clj    

 Description   

I have two files:
1 -https://github.com/m0smith/LogicPuzzles/blob/master/src/logicpuzzles/coresucceed.clj
2 -https://github.com/m0smith/LogicPuzzles/blob/master/src/logicpuzzles/corefail.clj

The first one compiles and runs fine. The second throws a ClassCastException. The only difference is that rule-0 is moved in the second file.



 Comments   
Comment by David Nolen [ 11/Mar/13 7:40 AM ]

There's far too much context here. Do you have a minimal case? Thanks much!

Comment by Matthew O. Smith [ 11/Mar/13 9:15 AM ]

Here is the stack trace. I will try to narrow it down further.

java.lang.ClassCastException: clojure.lang.PersistentList cannot be cast to clojure.lang.IPersistentSet
at clojure.core$disj.invoke (core.clj:1420)
clojure.core.logic.ConstraintStore/fn (logic.clj:339)
clojure.lang.ArrayChunk.reduce (ArrayChunk.java:58)
clojure.core.protocols/fn (protocols.clj:94)
clojure.core.protocols$fn_5854$G5849_5863.invoke (protocols.clj:19)
clojure.core.protocols$seq_reduce.invoke (protocols.clj:31)
clojure.core.protocols/fn (protocols.clj:60)
clojure.core.protocols$fn_5828$G5823_5841.invoke (protocols.clj:13)
clojure.core$reduce.invoke (core.clj:6030)
clojure.core.logic.ConstraintStore.remc (logic.clj:338)
clojure.core.logic$remcg$fn__3272.invoke (logic.clj:2374)
clojure.core.logic$BANG$reify_3422.invoke (logic.clj:2719)
clojure.core.logic$composeg$fn__2569.invoke (logic.clj:1141)
clojure.core.logic$composeg$fn__2569.invoke (logic.clj:1142)
clojure.core.logic$run_constraint$fn__3285.invoke (logic.clj:2397)
clojure.core.logic$fix_constraints.invoke (logic.clj:2424)
clojure.core.logic$run_constraints$fn__3290.invoke (logic.clj:2434)
clojure.core.logic.Substitutions.bind (logic.clj:612)
clojure.core.logic$run_constraints_STAR_$fn__3296.invoke (logic.clj:2444)
clojure.core.logic.Substitutions.bind (logic.clj:612)
clojure.core.logic$run_constraints_STAR_$fn__3296.invoke (logic.clj:2446)
clojure.core.logic$EQEQ$fn__2647.invoke (logic.clj:1255)
clojure.core.logic.Substitutions.bind (logic.clj:612)
clojure.core.logic$rembero$fn_3465$_inc3466$fn3475$fn3476$_inc3477$fn3478$_inc_3479.invoke (logic.clj:2790)
clojure.core.logic$eval2628$fn_2633$_inc_2634.invoke (logic.clj:1223)
clojure.core.logic$eval2628$fn_2633$_inc_2634.invoke (logic.clj:1223)
clojure.core.logic$eval2628$fn_2637$_inc_2638.invoke (logic.clj:1220)
clojure.core.logic$eval2628$fn_2633$_inc_2634.invoke (logic.clj:1223)
clojure.core.logic$eval2628$fn_2633$_inc_2634.invoke (logic.clj:1223)
clojure.core.logic$eval2628$fn_2633$_inc_2634.invoke (logic.clj:1223)
clojure.core.logic$eval2628$fn_2637$_inc_2638.invoke (logic.clj:1220)
clojure.core.logic$eval2628$fn_2633$_inc_2634.invoke (logic.clj:1223)
clojure.core.logic$eval2628$fn_2637$_inc_2638.invoke (logic.clj:1220)
clojure.core.logic$eval2628$fn_2629$fn_2630.invoke (logic.clj:1225)
clojure.lang.LazySeq.sval (LazySeq.java:42)
clojure.lang.LazySeq.seq (LazySeq.java:67)
clojure.lang.RT.seq (RT.java:473)
clojure.core$seq.invoke (core.clj:133)
clojure.core$take$fn__4112.invoke (core.clj:2501)
clojure.lang.LazySeq.sval (LazySeq.java:42)
clojure.lang.LazySeq.seq (LazySeq.java:60)
clojure.lang.LazySeq.first (LazySeq.java:82)
clojure.lang.RT.first (RT.java:566)
clojure.core$first.invoke (core.clj:55)
clojure.pprint$pprint_reader_macro.invoke (dispatch.clj:50)
clojure.pprint$pprint_list.invoke (dispatch.clj:77)
clojure.lang.MultiFn.invoke (MultiFn.java:163)
clojure.pprint$write_out.invoke (pprint_base.clj:194)
clojure.pprint$pprint_vector$fn__7949.invoke (dispatch.clj:83)
clojure.pprint$pprint_vector.invoke (dispatch.clj:82)
clojure.lang.MultiFn.invoke (MultiFn.java:163)
clojure.pprint$write_out.invoke (pprint_base.clj:194)
clojure.pprint$pprint$fn__7359.invoke (pprint_base.clj:250)
clojure.pprint$pprint.invoke (pprint_base.clj:248)
clojure.pprint$pprint.invoke (pprint_base.clj:245)
logicpuzzles.corefail$show.invoke (corefail.clj:9)
logicpuzzles.corefail$eval3796.invoke (corefail.clj:153)
clojure.lang.Compiler.eval (Compiler.java:6511)
clojure.lang.Compiler.load (Compiler.java:6952)
user$eval971.invoke (NO_SOURCE_FILE:1)
clojure.lang.Compiler.eval (Compiler.java:6511)
clojure.lang.Compiler.eval (Compiler.java:6477)
clojure.core$eval.invoke (core.clj:2797)
clojure.main$repl$read_eval_print__6405.invoke (main.clj:245)
clojure.main$repl$fn__6410.invoke (main.clj:266)
clojure.main$repl.doInvoke (main.clj:266)
clojure.lang.RestFn.invoke (RestFn.java:1096)
clojure.tools.nrepl.middleware.interruptible_eval$evaluate$fn__544.invoke (interruptible_eval.clj:56)
clojure.lang.AFn.applyToHelper (AFn.java:159)
clojure.lang.AFn.applyTo (AFn.java:151)
clojure.core$apply.invoke (core.clj:601)
clojure.core$with_bindings_STAR_.doInvoke (core.clj:1771)
clojure.lang.RestFn.invoke (RestFn.java:425)
clojure.tools.nrepl.middleware.interruptible_eval$evaluate.invoke (interruptible_eval.clj:41)
clojure.tools.nrepl.middleware.interruptible_eval$interruptible_eval$fn_585$fn_587.invoke (interruptible_eval.clj:171)
clojure.core$comp$fn__4034.invoke (core.clj:2278)
clojure.tools.nrepl.middleware.interruptible_eval$run_next$fn__578.invoke (interruptible_eval.clj:138)
clojure.lang.AFn.run (AFn.java:24)
java.util.concurrent.ThreadPoolExecutor.runWorker (ThreadPoolExecutor.java:1145)
java.util.concurrent.ThreadPoolExecutor$Worker.run (ThreadPoolExecutor.java:615)
java.lang.Thread.run (Thread.java:722)

Comment by Matthew O. Smith [ 11/Mar/13 9:24 AM ]

I tightened up the fail case https://github.com/m0smith/LogicPuzzles/blob/master/src/logicpuzzles/corefail.clj . Is that enough?

Comment by David Nolen [ 11/Mar/13 10:17 AM ]

Thanks can you add the failing code to the ticket as an attachment? Thanks.

Comment by Matthew O. Smith [ 11/Mar/13 6:23 PM ]

corefail.clj exhibits the error

Comment by David Nolen [ 17/Mar/13 6:29 PM ]

fixed, http://github.com/clojure/core.logic/commit/7e4d0b6b71707e248fd4d0de3f6c090b50a18624





[LOGIC-75] Combining maps and finite domains in core.logic returns only one result Created: 11/Dec/12  Updated: 28/Jul/13  Resolved: 12/Dec/12

Status: Closed
Project: core.logic
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Defect Priority: Major
Reporter: Frederik De Bleser Assignee: David Nolen
Resolution: Completed Votes: 0
Labels: bug
Environment:

Clojure 1.4.0, core.logic 0.8.0-beta2



 Description   

I'm trying to combine maps with finite domains with some odd results.

A simple query using finite domains correctly returns all values:

(run* [q]
	  (fresh [x]
	    (infd x (interval 1 3))
	    (== q x)))
	
	;=> (1 2 3)

But putting this result in a map returns only the first value:

(run* [q]
	  (fresh [x]
	    (infd x (interval 1 3))
	    (== q {:foo x})))
	
	;=> ({:foo 1})

FYI this works with vectors:

(run* [q]
	  (fresh [x]
	    (infd x (interval 1 3))
	    (== q [x])))
	
	;=> ([1] [2] [3])

But lcons seems to fail as well:

(run* [q]
	  (fresh [x]
	    (infd x (interval 1 3))
	    (== q (lcons x 'foo))))
	
	;=> ((1 . foo))


 Comments   
Comment by David Nolen [ 12/Dec/12 11:53 AM ]

fixed, http://github.com/clojure/core.logic/commit/c96402f3e60b1118446b3e681d98e444e4ce417d





[LOGIC-74] Bug in conde (ClojureScript) Created: 26/Nov/12  Updated: 28/Jul/13  Resolved: 17/Mar/13

Status: Closed
Project: core.logic
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Defect Priority: Minor
Reporter: Kevin De Valck Assignee: David Nolen
Resolution: Declined Votes: 0
Labels: bug
Environment:

[org.clojure/clojure "1.4.0"]
[org.clojure/core.logic "0.8.0-beta2"]



 Description   

While working on a project I found a somewhat strange behaviour. I reworked the problem in some simple predicate. Let's take this predicate foobad.

(defn foobad 
  [?bar]
  (l/project [?bar]
    (l/fresh [?var]
      (l/conde 
        [(l/== true (instance? js/Array ?bar))
          (membero ?var (seq ?bar))]))))

When running (l/run* [?f] (foobad 0)) it produces this error:

#<Error: No protocol method ISeqable.-seq defined for type number: 0>

Because 0 is not an instance of Array it should not be entering that conde clause where it tries (seq 0).

With this workaround we get a normal behaviour:

(defn foo 
  [?bar]
  (l/project [?bar]
    (l/fresh [?var]
      (l/conde 
        [(l/== true (instance? js/Array ?bar)) 
         (fresh [?s]
          (l/== ?s (seq ?bar))
          (membero ?var ?s))]))))

Running (l/run* [?f] (foo 0)) gives us (), which is what we expect.
While 0 is clearly not an instance of Array that conde clause is still executed resulting in previous error.



 Comments   
Comment by David Nolen [ 28/Dec/12 12:49 AM ]

I'm assuming this is referring the ClojureScript version of core.logic?

Comment by David Nolen [ 17/Mar/13 7:00 PM ]

This is not a bug. Goals do not delay evaluation in this way.





[LOGIC-52] Bug in finite domains (+fd, infd) Created: 10/Sep/12  Updated: 28/Jul/13  Resolved: 26/Oct/12

Status: Closed
Project: core.logic
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Defect Priority: Major
Reporter: naeg Assignee: David Nolen
Resolution: Completed Votes: 1
Labels: +fd, bug, finite-domains, infd
Environment:

Clojure 1.4, core.logic 0.8-alpha3



 Description   

When running the code:

(run* [q]
(fresh [a b c d]
(infd a b c d (domain 1 3 4 5))
(+fd b 1 a)
(+fd c 1 b)
(+fd d 1 c)
(== q [a b c d])))

I get the ouput:

([5 4 3 1])

But I would expect:

()

Because [5 4 3 1] is no sequence where the next element is always one number higher than the one before.

It seems to me like +fd behaves as it would take the next element in the domain, instead of taking the next higher number (I hope I didn't misunderstand +fd or infd).



 Comments   
Comment by naeg [ 11/Sep/12 4:48 PM ]

There is workaround using membero:

(run* [q]
  (fresh [a b c d]
    (everyg #(membero % [1 3 4 5]) [a b c d])
    (+fd b 1 a)
    (+fd c 1 b)
    (+fd d 1 c)
    (== q [a b c d])))

=> ()

Note that this is quite a lot slower than it would be with infd.

Comment by David Nolen [ 26/Oct/12 1:03 AM ]

This is fixed try the latest 0.8.0 beta





[JMX-7] Extend Destract protocol on nil to handle Null references gracefully Created: 23/Aug/12  Updated: 26/Jul/13  Resolved: 18/Sep/12

Status: Resolved
Project: java.jmx
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Defect Priority: Major
Reporter: Jürgen Hötzel Assignee: Unassigned
Resolution: Completed Votes: 0
Labels: bug

Attachments: Text File 0001-fix-duplicate-definition-of-test-objects-data.patch     Text File 0002-Test-Destract-protocol-on-nil-refs-JMX-7.patch     Text File 0003-Extend-Destract-protocol-on-nil-to-handle-null-refer.patch    
Patch: Code and Test
Approval: Accepted

 Description   

JMX Attributes can have null references. Currently a Exception is thrown because the "null-type" is not handled via objects->data:

user> (jmx/mbean "java.lang:type=GarbageCollector,name=PS MarkSweep")
{:LastGcInfo #<IllegalArgumentException java.lang.IllegalArgumentException: No implementation of method: :objects->data of protocol: #'clojure.java.jmx/Destract found for class: nil>, :CollectionCount 0, :CollectionTime 0, :MemoryPoolNames #<String[] [Ljava.lang.String;@57b8fe29>, :Name "PS MarkSweep", :Valid true, :ObjectName #<ObjectName java.lang:type=GarbageCollector,name=PS MarkSweep>}

After applying this patch:

user> (jmx/mbean "java.lang:type=GarbageCollector,name=PS MarkSweep")
{:LastGcInfo nil, :CollectionCount 0, :CollectionTime 0, :MemoryPoolNames #<String[] [Ljava.lang.String;@2225be1e>, :Name "PS MarkSweep", :Valid true, :ObjectName #<ObjectName java.lang:type=GarbageCollector,name=PS MarkSweep>}



 Comments   
Comment by Nick Bailey [ 31/Aug/12 4:42 PM ]

I don't suppose you know of a standard mbean that ships with most jvms we could use to write a test case for this?

Comment by Jürgen Hötzel [ 10/Sep/12 9:21 AM ]

I don't know of a standard MBean attribute which is reproducible Null. "LastGcInfo" of "java.lang:type=GarbageCollector,name=PS MarkSweep" is non-Null after a garbage collection.

I think its better to test the Destract protocol directly instead of using a "live" MBean in this case.

BTW. there was also a duplicate definition of the existing Destract tests in test-objects->data. Patches enclosed.

Comment by Nick Bailey [ 18/Sep/12 11:20 PM ]

Committed:

https://github.com/clojure/java.jmx/commit/31b58b9c78baa9f6f31a51cd6e8b8b729af4622a





[JDBC-94] Parsing of sqlite or HSQLDB in-memory databases fail Created: 01/Apr/14  Updated: 01/Apr/14

Status: Open
Project: java.jdbc
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Defect Priority: Major
Reporter: Peter Schwarz Assignee: Sean Corfield
Resolution: Unresolved Votes: 0
Labels: bug
Environment:

Using the following driver dependencies:
[org.hsqldb/hsqldb "2.3.2"]
[org.xerial/sqlite-jdbc "3.7.2"]



 Description   

When entering a sqlite memory db uri: "jdbc:sqlite::memory:", the following error occurs:

SQLException out of memory org.sqlite.DB.throwex (DB.java:370)

This is a vague exception which occurs when the db is not actually created (see https://bitbucket.org/xerial/sqlite-jdbc).

Likewise, when parsing a HSQLDB in-memory db url: "jdbc:hsqldb:mem:testdb", the following error occurs:

2014-04-01T14:13:11.996-0500  SEVERE  could not reopen database
org.hsqldb.HsqlException: Database lock acquisition failure: lockFile: org.hsqldb.persist.LockFile@2be0e04[file =/.lck, exists=false, locked=false, valid=false, ] method: openRAF reason: java.io.FileNotFoundException: /.lck (Permission denied)

It appears to be creating the equivalent connection for

{:subprotocol "hsqldb" :subname ""}
but should be creating
{:subprotocol "hsqldb" :subname "mem:testdb" }



 Comments   
Comment by Sean Corfield [ 01/Apr/14 3:17 PM ]

Thanx Peter. That sounds reasonably easy to repro so I'll create a couple of test cases shortly.





[JDBC-50] insert-rows (incorrectly) patches incomplete records Created: 21/Mar/13  Updated: 06/Apr/13  Resolved: 06/Apr/13

Status: Resolved
Project: java.jdbc
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Defect Priority: Major
Reporter: Cees van Kemenade Assignee: Sean Corfield
Resolution: Completed Votes: 0
Labels: bug, docs
Environment:

Postgres database on Debian machine


Attachments: File jdbcIssue.clj    

 Description   

When using sql/insert-rows with a dataset that contains incomplete rows the rows will be patched with values from the preceding rows. The behaviour to be expected is not documented.

I would expect insert-rows either only accepts complete rows. When accepting incomplete rows I would expect patching with nil-values instead of values from other rows.

Attached you find an example and the output when running in comments.



 Comments   
Comment by Sean Corfield [ 06/Apr/13 3:10 PM ]

This looks like an old / long-standing bug that no one has run into before.

In the new (soon-to-be 0.3.0) release, (clojure.java.jdbc.sql/insert :table [1 1] [2] []) would throw an exception:

IllegalArgumentException insert called with inconsistent number of columns / values clojure.java.jdbc.sql/insert-multi-row (sql.clj:116)

I will update clojure.java.jdbc/insert-rows to throw a similar exception.

Comment by Sean Corfield [ 06/Apr/13 3:38 PM ]

Fixed in 0.3.0-SNAPSHOT by throwing an exception if the value-groups are not all the same length.

Currently relies on the DB to trap column names not matching value groups (which is known not to work on SQLite but does work on other DBs as far as I know).

insert-rows is deprecated in 0.3.0 - use insert! instead going forward (which does more validation).





[JDBC-49] jdbc insert-records can not handle spaces in columnames Created: 21/Mar/13  Updated: 06/Apr/13  Resolved: 06/Apr/13

Status: Resolved
Project: java.jdbc
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Defect Priority: Major
Reporter: Cees van Kemenade Assignee: Sean Corfield
Resolution: Completed Votes: 0
Labels: bug
Environment:

Postgres on Debian


Attachments: File jdbcIssue2.clj    

 Description   

If a database contains column-names that include spaces an sql/insert-record will fail. However, inserting via sql/do-commands or sql/insert-rows works as expected.

Attached you find a file showing the error.



 Comments   
Comment by Cees van Kemenade [ 22/Mar/13 1:21 AM ]

Further analysis based on a suggestion of Sean leads to:

It seems to be that there is an issue in the naming-strategy in this issue. Either in the way I define it of the way it is implemented
(sql/with-connection db
(sql/with-naming-strategy {:keyword identity :entity (fn [x] (str \" x \"))}
...
))

When I remove the naming-strategy and replace the offending insert by a manual quoting strategy via
(sql/insert-records "test_jdbc_naming3" {((fn [x] (str \" x \")) "b- b") 7})
which corresponds to
(sql/insert-records "test_jdbc_naming3" {"\"b- b\"" 7})
then the code runs fine.

So the issue is located in the handling of the naming-strategy, or in the way I defined the naming-strategy (for postgres).

Comment by Sean Corfield [ 06/Apr/13 4:14 PM ]

Fixed in 0.3.0-SNAPSHOT by wiring as-str variable into compatibility layer as :entities argument.





[JDBC-35] Wrong timezone for java.sql.Date, java.sql.Time and java.sql.Timestamp objects returned by with-query-results Created: 20/Jul/12  Updated: 12/Sep/12  Resolved: 12/Sep/12

Status: Resolved
Project: java.jdbc
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Defect Priority: Major
Reporter: Jestine Paul Assignee: Sean Corfield
Resolution: Declined Votes: 0
Labels: bug

Attachments: File resultset-timezone.diff    

 Description   

Our database stores date and time related information in UTC. But, the results from with-query-results creates objects in the local timezone. This is causing a lot of unexpected behavior when constructing Joda DateTime objects in clj-time. Currently, the with-query-results function is using the single argument getter functions in the ResultSet

getDate(int columnIndex)
getTime(int columnIndex)
getTimestamp(int columnIndex)

We can solve this problem if we can optionally pass the timezone information and call the two argument getter functions.

getDate(int columnIndex, Calendar cal)
getTime(int columnIndex, Calendar cal)
getTimestamp(int columnIndex, Calendar cal)



 Comments   
Comment by Sean Corfield [ 21/Jul/12 1:30 AM ]

Can you provide a self-contained test case? Lots of people are using java.jdbc in production without running into this problem, and at World Singles we've had this in production for a long time in a high traffic environment without seeing any problems with timezones. Dates go in and out of the database unchanged, which is exactly as expected - and we have databases running in three different timezones.

Comment by Jestine Paul [ 21/Jul/12 5:29 AM ]

I have added a new test and it is failing with my Postgresql.

https://github.com/jestinepaul/java.jdbc/commit/195397b1b2a0245d2439ab9963fe2138450a27f3

Comment by Sean Corfield [ 21/Jul/12 1:03 PM ]

Looking at recommended practices out there, such as listed here: http://stackoverflow.com/questions/2532729/daylight-saving-time-and-timezone-best-practices one important thing is: "On Servers, set hardware clocks and OS clocks to UTC. Use NTP services on all servers." The same advice is repeated here: http://www.dbspecialists.com/blog/database-theory/intelligent-date-handling/

Looking further into PostgreSQL (a database I generally don't use), I see this: http://stackoverflow.com/questions/6151084/which-timestamp-type-to-choose-in-a-postgresql-database which seems to contain a lot of PostgreSQL-specific stuff. However, that article makes it clear that you need to set the database timezone to UTC in order to SELECT timestamp columns correctly.

In my opinion, the behavior you're seeing is not a bug (in java.jdbc) but an artifact of your environment being set up incorrectly. I'll leave this ticket open for a little while for more discussion but without a concrete patch that is shown to not affect other use cases, I will close this ticket by the end of August.

Comment by Jestine Paul [ 23/Jul/12 1:26 PM ]

As mentioned earlier, the database server timezone is in UTC and the JDBC library runs on a client machine set to local time. If the database has a date value of 2012-7-23, it changes to 2012-7-22 on the client side (if the client is running at timezone greater than UTC) when coerced using to-date-time in clj-time. This is extremely dangerous and is not specific to any database. I noticed it first on Sybase Enterprise Server and I have now also replicated it in the test case with Postgresql.

I have attached a patch which fixes this problem by passing in an optional parameter. The test case is also modified to use clj-time, as it expresses the problem more clearly. Please let me know if you need any more clarification.

p.s. I have already mailed the CA and should reach Durham in a few days.

Comment by Sean Corfield [ 12/Sep/12 8:01 PM ]

Since the proposed patch requires the user to pass in a list of columns to treat specially - and reorders columns in results and adds some performance overhead for all users, not just those wanting to adjust column values - I believe users who choose to run JDBC clients in timezones different to the database, against the widely-listed best practice recommendations, should bear the burden of adjusting the columns themselves in their own client code. Since they already know which columns to adjust and they know the difference between UTC and local time, they should be able to make the adjustments easily enough as part of post-processing the resultset-seq.





[JDBC-33] update-or-insert does not work with oracle Created: 21/May/12  Updated: 10/Jun/12  Resolved: 10/Jun/12

Status: Resolved
Project: java.jdbc
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Defect Priority: Minor
Reporter: Brian Tatnall Assignee: Sean Corfield
Resolution: Completed Votes: 0
Labels: bug
Environment:

clojure 1.3.0
clojure.java.jdbc 0.2.1
oracle 10.2.0.4.0



 Description   

According to the oracle documentation

For a prepared statement batch, it is not possible to know the number of rows affected in the database by each individual statement in the batch. Therefore, all array elements have a value of -2. According to the JDBC 2.0 specification, a value of -2 indicates that the operation was successful but the number of rows affected is unknown.

As documented update-values returns (-2) which means that the (if (zero?)) check in update-or-insert-values will never return true.

Oracle does provide the number of rows updated via an the method getUpdateCount on instances of Statement.

The following change fixes this problem for oracle users, but I am not sure how it will affect other drivers.

(defn oracle-do-prepared
  "Executes an (optionally parameterized) SQL prepared statement on the                                           
  open database connection. Each param-group is a seq of values for all of                                        
  the parameters.                                                                                                 
  Return a seq of update counts (one count for each param-group)."
  [sql & param-groups]
  (with-open [^PreparedStatement stmt (prepare-statement (connection) sql)]
    (if (empty? param-groups)
      (transaction* (ƒ [] (vector (.executeUpdate stmt))))
      (do
        (doseq [param-group param-groups]
          (set-parameters stmt param-group)
          (.addBatch stmt))
        (transaction* (ƒ [] (let [result (.executeBatch stmt)
                                  count  (.getUpdateCount stmt)]
                              (vector count))))))))


 Comments   
Comment by Sean Corfield [ 22/May/12 12:17 AM ]

Interesting. (.getUpdateCount stmt) is a standard part of the JDBC API so it looks reasonable to see if the result of the (.executeBatch stmt) is a single sequence with a -2 value, the code could call (.getUpdateCount stmt) and return that (single) value as a sequence. It looks like that should be completely portable but it will be hard to test since none of the other DBs return -2 as far as I know and I don't have an Oracle install to test against





[CTYP-133] Typechecker fails when checking involves an object from reify Created: 13/Apr/14  Updated: 13/Apr/14

Status: Open
Project: core.typed
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Defect Priority: Major
Reporter: Daniel Ziltener Assignee: Ambrose Bonnaire-Sergeant
Resolution: Unresolved Votes: 0
Labels: bug
Environment:

Clojure 1.6.0, core.typed 0.2.44



 Description   

The error message is

No method in multimethod 'check' for dispatch value: :reify

The following is a minimal test case which fails:

core.clj
(ns core-typed-bug.core
  (:require [clojure.core.typed :refer :all]))

(ann-protocol ITypedTest
              get-data [ITypedTest -> Any])
(defprotocol> ITypedTest
  (get-data [this]))

(ann typed-test [String -> ITypedTest])
(defn typed-test [input]
  (reify ITypedTest
    (get-data [_] input)))

(defn> testfn :- Any
  [asdf :- Keyword, in :- ITypedTest]
  (get-data in))

Likely similar to bug http://dev.clojure.org/jira/browse/CTYP-132






[CTYP-132] typechecker fails when checking a Protocol whose method gets called using dot notation Created: 12/Apr/14  Updated: 13/Apr/14  Resolved: 13/Apr/14

Status: Closed
Project: core.typed
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Defect Priority: Minor
Reporter: Daniel Ziltener Assignee: Ambrose Bonnaire-Sergeant
Resolution: Completed Votes: 0
Labels: bug
Environment:

Clojure 1.6.0, core.typed 0.2.44



 Description   

The error message is

No method in multimethod 'check' for dispatch value: :host-interop

The following is a minimal test case which fails:

core.clj
(ns core-typed-bug.core
    (:require [clojure.core.typed :refer :all]))
 
(defprotocol> ITypedTest
    (get-data [this]))
 
(defn> testfn :- Any
    [asdf :- Keyword, in :- ITypedTest]
    (.get-data in))

It works, however, when calling (get-data in) instead of (.get-data in).



 Comments   
Comment by Nicola Mometto [ 12/Apr/14 7:13 PM ]

tools.analyzer.jvm returns a :host-interop node when, like in this case, it encounters an interop form of the form (.foo bar) and can't determine whether it's a no-arg method call or a field-access.

I don't know enough about core.typed internals but it looks like there should be an add-check-method for :host-interop that behaves like check methods for :instance-field/:instance-call that resolve to runtime reflection (not :validated)

Comment by Ambrose Bonnaire-Sergeant [ 13/Apr/14 12:44 AM ]

Thanks Daniel & Nicola, fixed https://github.com/clojure/core.typed/commit/fa22d52d8e9855ebbaf2593ec5e848ba714b25fc





[CTYP-122] annotation fails on recur Created: 16/Mar/14  Updated: 23/Mar/14  Resolved: 16/Mar/14

Status: Closed
Project: core.typed
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Defect Priority: Minor
Reporter: Christian S Assignee: Ambrose Bonnaire-Sergeant
Resolution: Completed Votes: 0
Labels: bug
Environment:

Mac OS X, clojure 1.5.1, Oracle JDK 1.7.0_45



 Description   

The following test case fails on check-ns. The issue seems to be the use of recur. The test case is modelled after clojure.core/<

huhu.clj
(ns huhu (:require [clojure.core.typed :refer :all]))
  (ann testcase [Number Number * -> boolean])
  (defn testcase
    ([x] true)
    ([x y] false)
    ([x y & more]
     (if (testcase x y)
       (if (next more)
         (recur y (first more) (next more))
         (testcase y (first more)))
       false)))

This is the result of check-ns:

(check-ns)
Start collecting huhu
Finished collecting huhu
Collected 1 namespaces in 26.58 msecs
Start checking huhu
AssertionError Assert failed: (AnyType? t)  clojure.core.typed.type-rep/ret (type_rep.clj:825)

If a recursive call instead of recur would be used it works. This is not a workaround to be applicable in every case.



 Comments   
Comment by Christian S [ 16/Mar/14 8:01 AM ]

clojure.core.typed version is [org.clojure/core.typed "0.2.37"]

Comment by Ambrose Bonnaire-Sergeant [ 16/Mar/14 8:38 AM ]

Fixed in 0.2.38-20140316.133526-3





[CTYP-67] core.typed doesn't interact well with inlining Created: 21/Sep/13  Updated: 25/Sep/13  Resolved: 25/Sep/13

Status: Closed
Project: core.typed
Component/s: None
Affects Version/s: 0.2.0
Fix Version/s: None

Type: Defect Priority: Major
Reporter: Julian Birch Assignee: Ambrose Bonnaire-Sergeant
Resolution: Completed Votes: 0
Labels: bug


 Description   

(cf compare)

gives

(Fn [Comparable Any -> Number])

but

(cf (fn [v x] (compare v x)) (Fn [Comparable Any -> Number]))

fails the type check.

(Credit: cspent on IRC figured out that the problem was that it was inlining the compare function, and therefore not using the annotation.)



 Comments   
Comment by Ambrose Bonnaire-Sergeant [ 25/Sep/13 3:24 AM ]

Fixed https://github.com/clojure/core.typed/commit/044434b33c4d9ce1df95170bfff3c45a9c2cdbb6





[CTYP-55]  clojure.lang.RT/longCast is interpreted incorrectly Created: 11/Sep/13  Updated: 11/Sep/13

Status: Open
Project: core.typed
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Defect Priority: Minor
Reporter: Chris McDevitt Assignee: Ambrose Bonnaire-Sergeant
Resolution: Unresolved Votes: 0
Labels: bug


 Description   

tested version: 0.2.5

Functions that cast to long like neg? / pos? don't work with type checking. eg. (cf (pos? (dec 1)))

> (cf (long (dec 1)))

Type Error (myapp.core:1:5) Type mismatch:

Expected: 	long

Actual: 	AnyInteger
ExceptionInfo Type Checker: Found 1 error  clojure.core/ex-info (core.clj:4327)


 Comments   
Comment by Chris McDevitt [ 11/Sep/13 12:03 PM ]

workaround is (cf (#'pos? (dec 1)))





[CTYP-38] Core.typed doesn't understand inner class syntax inside non-nil-return Created: 30/Aug/13  Updated: 25/Sep/13  Resolved: 09/Sep/13

Status: Closed
Project: core.typed
Component/s: None
Affects Version/s: 0.2.0
Fix Version/s: None

Type: Defect Priority: Minor
Reporter: Max Gonzih Assignee: Ambrose Bonnaire-Sergeant
Resolution: Completed Votes: 0
Labels: bug


 Description   

Following code snippet illustrates that non-nil-return call has no effect on recipient-type-to function.
Core.typed still assumes that Message$RecipientType/TO can return nil.

(non-nil-return javax.mail.Message$RecipientType/TO :all)

(ann recipient-type-to [-> Message$RecipientType])
(defn ^Message$RecipientType recipient-type-to []
  (Message$RecipientType/TO))

(comment
  Type mismatch:
  Expected:       (Fn [-> Message$RecipientType])
  Actual:         (Fn [-> (U Message$RecipientType nil)]))


 Comments   
Comment by Ambrose Bonnaire-Sergeant [ 09/Sep/13 3:45 AM ]

This is not an issue with inner class syntax.

This is rather about nilable fields. TO here is a static field, nilable-param only takes methods.

core.typed doesn't yet support overriding fields.

Comment by Ambrose Bonnaire-Sergeant [ 09/Sep/13 3:47 AM ]

Related: http://dev.clojure.org/jira/browse/CTYP-50





[CTYP-20] Missing :require of clojure.main? Created: 20/Mar/13  Updated: 25/Sep/13  Resolved: 25/Mar/13

Status: Closed
Project: core.typed
Component/s: None
Affects Version/s: 0.2.0
Fix Version/s: None

Type: Defect Priority: Minor
Reporter: Mike Anderson Assignee: Ambrose Bonnaire-Sergeant
Resolution: Completed Votes: 0
Labels: bug


 Description   

Affects version 0.1.8 (but version isn't listed as a valid version in JIRA)

clojure.core.typed refers to clojure.main/repl (line 725 in master)

However clojure.main is not required by the clojure.core.typed namespace, so you get an error if clojure.main has not already been loaded. This can happen in various circumstances, e.g. running "mvn test"

Code to reproduce / fix:

(ns some.namespace
(:require [clojure.main]) ;; this line is needed to avoid an error
(:require [clojure.core.typed :refer [ann inst cf fn> pfn> check-ns ann-form]]))



 Comments   
Comment by Ambrose Bonnaire-Sergeant [ 25/Mar/13 3:05 AM ]

Thanks for the report, fixed.

https://github.com/clojure/core.typed/commit/59f4f5b216a45c2ace5dfbe088dc10796ad565b0





[CMEMOIZE-12] NPE with memoize/ttl Created: 05/Dec/13  Updated: 19/Feb/14

Status: Open
Project: core.memoize
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Defect Priority: Minor
Reporter: Scott Morgan Assignee: Fogus
Resolution: Unresolved Votes: 1
Labels: bug
Environment:

org.clojure/core.memoize "0.5.6"



 Description   

I'm trying still trying to reproduce it, but I noted this in my logs if my compojure app on a subsequent request to the memoized function.

java.lang.NullPointerException
at clojure.core.memoize$through_STAR_$fn_401$fn_402.invoke(memoize.clj:53)
at clojure.lang.Delay.deref(Delay.java:33)
at clojure.core$deref.invoke(core.clj:2128)
at clojure.core.memoize$build_memoizer$fn__456.doInvoke(memoize.clj:140)
at clojure.lang.RestFn.applyTo(RestFn.java:137)
at clojure.lang.AFunction$1.doInvoke(AFunction.java:29)
at clojure.lang.RestFn.invoke(RestFn.java:436)



 Comments   
Comment by Aaron Iba [ 19/Feb/14 4:49 PM ]

I have the same exact stack trace / line numbers in my logs. I have no idea how to reproduce. I would love to get advice on how to debug this.

In my case, this is running in a web app (ring) context.

Comment by Nicola Mometto [ 19/Feb/14 6:13 PM ]

I noticed that core.memoize throws an NPE if the function memoized throws an exception.
I don't know if this is what you're running into but it might be something to look into.





[CMEMOIZE-6] assert on ttl fn value makes any callable other than a pure clojure.lang.Fn be rejected Created: 27/Jun/13  Updated: 28/Jun/13  Resolved: 28/Jun/13

Status: Resolved
Project: core.memoize
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Defect Priority: Major
Reporter: Max Penet Assignee: Fogus
Resolution: Completed Votes: 0
Labels: bug, patch

Attachments: Text File fix-assert.patch    
Patch: Code

 Description   

ttl memoize used to accept multimethods for instance, this is no longer the case since the latest version where an assert? was introduced that checks using fn?

The patch attached allows any of the following: clojure.lang.IFn, clojure.lang.AFn, java.lang.Runnable, java.util.concurrent.Callable.

(I am a registered contributor listed under "Maximilien Penet (mpenet)")



 Comments   
Comment by Fogus [ 28/Jun/13 7:17 AM ]

This is fixed on master. I will push a point-release out to Maven Central later today.

Comment by Fogus [ 28/Jun/13 7:31 AM ]

Applied to master. A new release will come soon.





[CLJS-796] (get [42] nil) => 42 Created: 11/Apr/14  Updated: 14/Apr/14  Resolved: 14/Apr/14

Status: Closed
Project: ClojureScript
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Defect Priority: Major
Reporter: Alex Coventry Assignee: Unassigned
Resolution: Declined Votes: 0
Labels: bug
Environment:

r2156



 Comments   
Comment by Francis Avila [ 12/Apr/14 9:23 PM ]

This is a duplicate of CLJS-728 and is fixed by this commit, which is included in r2197 and above.





[CLJS-740] undeclared-ns warnings are broken Created: 02/Jan/14  Updated: 17/Jan/14  Resolved: 17/Jan/14

Status: Closed
Project: ClojureScript
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Defect Priority: Minor
Reporter: Erik Ouchterlony Assignee: Unassigned
Resolution: Completed Votes: 0
Labels: Compiler, bug, patch,

Attachments: File fix-undeclared-ns-warnings.diff    
Patch: Code

 Description   

In the recent versions of cljs, the undeclared-ns warnings have stopped working. This patch seems to be the culprit.



 Comments   
Comment by David Nolen [ 02/Jan/14 12:58 PM ]

Great thanks!

Comment by David Nolen [ 07/Jan/14 10:32 AM ]

CLJS-615

Comment by David Nolen [ 17/Jan/14 9:26 AM ]

fixed, https://github.com/clojure/clojurescript/commit/b8cf302b1500e88e0602e72fa6aec6f7328a1a00





[CLJS-737] tool.reader can't handle white-space Created: 30/Dec/13  Updated: 09/Jan/14  Resolved: 09/Jan/14

Status: Closed
Project: ClojureScript
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Defect Priority: Minor
Reporter: Andrew Zures Assignee: Unassigned
Resolution: Completed Votes: 0
Labels: bug
Environment:

MBP running lion 10.7.5


Attachments: Text File 0001-Bump-tools.reader-version-to-0.8.3.patch     PNG File Screen Shot 2013-12-30 at 4.40.47 PM.png     PNG File Screen Shot 2013-12-30 at 4.41.14 PM.png     PNG File Screen Shot 2013-12-30 at 4.44.42 PM.png    

 Description   

I believe the tool.reader (may some other part of ClojureScript) cannot handle a file with a large amount of white space. I have a cljx generated file with nothing but a namespace and about 300-400 lines of white-space. The entire file is simply a namespace and whitespace (file attached shows white-space in red). I get a stackoverflow error arising mainly from clojure.tools.reader$read.invoke(reader.clj:727). I have screenshots of the beginning and end of the stackoverflow attached. If I remove the whitespace, ClojureScript will compile, which leads me to believe it is the white space that is the cause of the issue.



 Comments   
Comment by Nicola Mometto [ 30/Dec/13 5:13 PM ]

Updating to tools.reader >=0.8.1 should fix this issue.

Comment by Nicola Mometto [ 30/Dec/13 5:21 PM ]

Attached a patch that bumps tools.reader to the lastest version (0.8.3)

Can you apply this and verify that it solves the issue?

Remeber you'll have to clean the lib/ folder form old tools.reader jars.

Comment by David Nolen [ 09/Jan/14 5:17 PM ]

fixed, https://github.com/clojure/clojurescript/commit/e85e63115eb5dbd6971919b4c2bfb9124b277212





[CLJS-716] Lookup for Date keys does not work in PersistentMaps and PersistentSets Created: 06/Dec/13  Updated: 12/Mar/14

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Defect Priority: Minor
Reporter: Sunil Gunisetty Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: bug
Environment:

Clojurescript version "0.0-2080"
Browser : Firefox 25.0.1
: Chrome 31.0.1650.63



 Description   

Lookup of js/Date objects fails, if there are more than 8 elements in the map. Works correctly if the map contains 8 elements or less.

Examples :

1. Map with more than 8 elements

cljs.user> (def test-map
{
:a 1
:b 2
#inst "2013-12-19T05:00:00.000-00:00" 3
:d 4
:e 5
#inst "2013-12-06T05:00:00.000-00:00" 6
:g 7
:h 8
:i 9
:j 10
})

cljs.user> (test-map #inst "2013-12-19T05:00:00.000-00:00")
nil

2. Map with 8 elements

cljs.user> (def test-map
{
:a 1
:b 2
#inst "2013-12-19T05:00:00.000-00:00" 3
:d 4
:e 5
#inst "2013-12-06T05:00:00.000-00:00" 6
:g 7
:h 8
})

cljs.user> (test-map #inst "2013-12-19T05:00:00.000-00:00")
3



 Comments   
Comment by David Nolen [ 06/Dec/13 5:07 PM ]

This is because JS Dates don't hash consistently, http://dev.clojure.org/jira/browse/CLJS-523





[CLJS-697] top-level symbol reference doesn't get an automatically inserted ns-name Created: 23/Nov/13  Updated: 23/Nov/13  Resolved: 23/Nov/13

Status: Closed
Project: ClojureScript
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Defect Priority: Major
Reporter: Limbo Peng Assignee: Unassigned
Resolution: Completed Votes: 0
Labels: Compiler, bug, namespace
Environment:

org.clojure/clojurescript "0.0-2030"



 Description   

I'm trying to use a Node.js module (with nested namespaces) in ClojureScript - the code goes like this:

(ns myapp)
(def evernote (js/require "evernote"))
(def token "TOKEN")
(defn do-sth []
  (let [client (evernote.Evernote.Client. (js-obj "token" token))]
    (.log js/console client)))
(do-sth)

which gets compiled (with :simple optimization) to:

var myapp = {}
myapp.evernote = require("evernote")
myapp.token = "TOKEN"
myapp.do_sth = function() {
  var a = new evernote.Evernote.Client({token:myapp.token})
  return console.log(a)
}
myapp.do_sth()

which will obviously fail with error "Uncaught ReferenceError: evernote is not defined".



 Comments   
Comment by David Nolen [ 23/Nov/13 11:55 PM ]

fixed, https://github.com/clojure/clojurescript/commit/d4bf88269e1d96468a19fd481f32628d4eafec9d





[CLJS-685] Cannot call method 'fromArray' of undefined -- Clojurescript 0.0-2030 Created: 17/Nov/13  Updated: 26/Nov/13  Resolved: 22/Nov/13

Status: Closed
Project: ClojureScript
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Defect Priority: Minor
Reporter: John Chijioke Assignee: Unassigned
Resolution: Completed Votes: 0
Labels: Compiler, bug, errormsgs
Environment:

Linux 3.2.0-52-generic x86_64 GNU/Linux, java 1.7, clojure 1.5.1



 Description   

Clojurescript 0.0-2030

This line from compile cljs.core is causing problems:

cljs.core.PersistentQueue.EMPTY = (new cljs.core.PersistentQueue(null, 0, null, cljs.core.with_meta(cljs.core.PersistentVector.EMPTY, cljs.core.PersistentArrayMap.fromArray([new cljs.core.Keyword(null, "end-line", "end-line", 2693041432), 3820, new cljs.core.Keyword(null, "end-column", "end-column", 3799845882), 69], true)), 0));

error message: Uncaught TypeError: Cannot call method 'fromArray' of undefined.

That's the first mention of fromArray in that file. I don't know if it's an ordering problem.



 Comments   
Comment by John Chijioke [ 17/Nov/13 11:10 PM ]

I solved it by replacing [] with cljs.core.PersistentVector.EMPTY. I think this must be a reader problem.

Comment by David Nolen [ 17/Nov/13 11:32 PM ]

This ticket needs more details, how can this error be reproduced?

Comment by Peter Taoussanis [ 22/Nov/13 3:03 AM ]

Hi, I'm seeing the same problem with tools.reader 0.8.0.

Any Clojurescript file (even an empty file) will produce the error.

Clojure: 1.6.0-alpha2
Clojurescript: 0.0-2030
Cljsbuild: 1.0.0
tools.reader: 0.8.0

Tried `lein cljsbuild clean`.

Problem is resolved by dropping back to tools.reader 0.7.10.

Update: have created an issue on the tools.reader GitHub page: https://github.com/clojure/tools.reader/issues/7

Update 2: this isn't something specific to Cljs 0.0-2030 btw, tools.reader 0.8.0 seems to produce the same error against at least Cljs 0.0-2060, 0.0-2027, 0.0-2024.

Comment by Nicola Mometto [ 22/Nov/13 6:49 AM ]

tools.reader 0.8.0 introduces end-column/end-line metadata, this needs to be elided as per line/column to avoid this bootstrapping issue.

Comment by David Nolen [ 22/Nov/13 8:02 AM ]

fixed, http://github.com/clojure/clojurescript/commit/36d401797f85c99794eef8a71239641930c36871

Comment by Peter Taoussanis [ 22/Nov/13 10:30 AM ]

Thanks a lot David, Nicola - much appreciated! Cheers

Comment by John Chijioke [ 26/Nov/13 6:32 AM ]

Thanks David. Cheers!





[CLJS-608] re-seq does not terminate in some cases Created: 06/Oct/13  Updated: 17/Oct/13  Resolved: 17/Oct/13

Status: Closed
Project: ClojureScript
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Defect Priority: Major
Reporter: Russell Mull Assignee: Unassigned
Resolution: Completed Votes: 0
Labels: bug
Environment:

Clojurescript 1913


Attachments: File re-seq-20131017.diff    

 Description   

re-matches behaves as expected:

;; clojure:
(re-matches #"\s*" "") ;; ""

;; clojurescript:
(re-matches #"\s*" "") ;; ""

re-seq does not:

;; clojure:
(re-seq #"\s*" "") ;; ("")

;; clojurescript:
(re-seq #"\s*" "") ;; infinite sequence of ""


 Comments   
Comment by Travis Thieman [ 17/Oct/13 12:34 PM ]

Patch: 20131017

Always allow one pass through the string, but terminate the lazy sequence if the end of the string is reached after the first match.

Comment by David Nolen [ 17/Oct/13 1:28 PM ]

We should have a test in the patch, thanks!

Comment by Travis Thieman [ 17/Oct/13 2:34 PM ]

Patch revised with test added

Comment by David Nolen [ 17/Oct/13 2:44 PM ]

fixed, http://github.com/clojure/clojurescript/commit/e483c4a63560cd9df4c96722beaf390006e50b9e





[CLJS-598] (js->clj nil) => Type Error Created: 25/Sep/13  Updated: 26/Sep/13  Resolved: 26/Sep/13

Status: Closed
Project: ClojureScript
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Defect Priority: Minor
Reporter: Michael O. Church Assignee: Unassigned
Resolution: Completed Votes: 0
Labels: bug
Environment:

This happened both on my local ClojureScript and in the online version: http://himera.herokuapp.com/index.html .


Attachments: Text File 0001-Argument-order-fix-in-js-clj.patch    
Patch: Code

 Description   

(js->clj nil) throws a type error instead of returning nil. This is because the satisfies? function is being used with the wrong argument order.



 Comments   
Comment by David Nolen [ 26/Sep/13 9:52 AM ]

fixed, http://github.com/clojure/clojurescript/commit/9f5df0965957e012d4ec86944abba056ccd8ecc2





[CLJS-575] cljsc.bat emit FileNotFoundException when compile samples in windows Created: 25/Aug/13  Updated: 05/Oct/13

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Defect Priority: Major
Reporter: Park Sang Kyu Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: Compiler, bug, patch
Environment:

in windows 7


Attachments: File cljsc.bat.diff     File cljsc-path.bat    
Patch: Code

 Description   

cljsc.bat emit FileNotFoundException when it compile samples of the ClojureScript project in windows like below.

------------------------------------------------
Exception in thread "main" java.io.FileNotFoundException: Could not locate cljs/closure__init.class
or cljs/closure.clj on classpath:
------------------------------------------------

It is caused by lack of a backslash in the end of path of the system environment variable, %CLOJURESCRIPT_HOME% set by a user.
In the case CLASSPATH is set to "C:\\clojure\clojurescriptsrc\clj;C:\\clojure\clojurescriptsrc\cljs" and this make it impossible for javac to find cljs/clojure.clj file.

So it can be solved by adding a backslash to the path of %CLOJURESCRIPT_HOME%.

I attached the patched file, "cljsc-path.bat"



 Comments   
Comment by David Nolen [ 04/Sep/13 11:04 PM ]

Can we please get a proper git diff thanks (and please send in your CA)! Also would be nice to get Windows users to check this out.

Comment by Park Sang Kyu [ 15/Sep/13 3:16 AM ]

git diff

Comment by David Nolen [ 05/Oct/13 11:55 AM ]

Thank you! Have you sent in your CA? http://clojure.org/contributing





[CLJS-573] checkboxes 'indeterminate' attribute gets munged in advanced mode Created: 19/Aug/13  Updated: 21/Aug/13  Resolved: 21/Aug/13

Status: Closed
Project: ClojureScript
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Defect Priority: Major
Reporter: Xavi Caballé Assignee: Unassigned
Resolution: Declined Votes: 0
Labels: Compiler, bug
Environment:

ClojureScript 0.0-1853, Clojure 1.5.1, Java 1.6.0_51, OS X 10.7.5



 Description   

HTML5 defines an indeterminate attribute for checkboxes
http://www.w3.org/TR/html5/forms.html#checkbox-state-(type=checkbox)
Trying to set this attribute with ClojureScript
(set! (.-indeterminate checkbox-element) true))
doesn't work when compiling in advanced mode.

Looking at the generated JavaScript code, I see that the indeterminate property gets munged. I don't know which externs files the ClojureScript compiler uses by default, but the indeterminate property is not referenced in Closure Compiler's externs for HTML5
https://code.google.com/p/closure-compiler/source/browse/externs/html5.js

In my project I've worked around this by adding this to my own externs file

/** @type {boolean} */
HTMLInputElement.prototype.indeterminate;

but I guess this should be "built-in" into the ClojureScript compiler (or Google's Closure Compiler)?



 Comments   
Comment by Jozef Wagner [ 19/Aug/13 6:26 AM ]

This issue should be addressed in the Closure Compiler bugtracker

Until they fix it, you can use your own externs file (tutorial), which is a perfectly valid approach.

Comment by Xavi Caballé [ 21/Aug/13 5:09 AM ]

ok, thanks.
I just submitted a patch to fix this in the Closure Compiler
https://code.google.com/p/closure-compiler/issues/detail?id=1068





[CLJS-516] PersistentArrayMap keys uniqueness Created: 05/Jun/13  Updated: 19/Nov/13  Resolved: 19/Nov/13

Status: Closed
Project: ClojureScript
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Defect Priority: Minor
Reporter: Sergey Kupriyanov Assignee: Michał Marczyk
Resolution: Completed Votes: 1
Labels: bug

Attachments: Text File 0001-CLJS-516-make-array-map-work-as-if-by-assoc.patch    

 Description   

PersistentArrayMap does not check the uniqueness of keys at init.

PersistentHashSet also affected.

cljs.user> (array-map 1 10 2 20 1 100)
{1 10, 2 20, 1 100}

cljs.user> (hash-set 1 1 2 3)
#{1 1 2 3}

Simple (dirty?) workaround - init map by assoc.

(defn array-map
  [& keyvals]
  (apply assoc cljs.core.PersistentArrayMap/EMPTY keyvals))


 Comments   
Comment by David Nolen [ 05/Jun/13 8:40 AM ]

Yes that solution is likely too slow. Clojure already solved this problem, we should probably port the existing solution.

Comment by David Nolen [ 04/Sep/13 11:08 PM ]

See CLJS-583 and CLJS-584

Comment by Michał Marczyk [ 05/Sep/13 1:29 AM ]

Fix and test, independent of CLJS-583 and CLJS-584.

From the commit message:

The approach taken is to (1) pour input into an array (or extract internal array with IndexedSeq), (2) construct output array by copying from the first array while checking for duplicates, (3) install output array in new array map.

Clojure does all that, except it also makes an initial pass over the array constructed in (1) to check if there are any duplicate keys. If in fact there are none, it skips (2) and just uses the original array in (3).

Crucially, there is a reason for this in Clojure which is absent in ClojureScript, namely if a new array is to be constructed, its length must be known ahead of time, so the check-for-duplicates loop also counts the number of unique items. In JS-land we can simply grow an array. Since presumably nobody's going to construct huge array maps ("slightly larger than the threshold" might make sense; a lot larger would totally kill performance), I don't think we'd gain much by avoiding the allocation, and if there are duplicates, it's good not to have to pay the price by doing the quadratic scan for duplicates twice.

I chose to pour non-IndexedSeq varargs into arrays so that the quadratic looping would be over an array rather than a seq.

Comment by Michał Marczyk [ 20/Sep/13 8:48 PM ]

Patch against current master.

Comment by David Nolen [ 19/Nov/13 9:24 PM ]

fixed by CLJS-584 - https://github.com/clojure/clojurescript/commit/d929ae942bc2859cc7b684334affc1b590173f88 and CLJS-583 https://github.com/clojure/clojurescript/commit/fe9b5577cd9b9784d0c0c75edccc4441c99ee924





[CLJS-485] clojure.string/replace ignores regex flags Created: 12/Mar/13  Updated: 19/Mar/14

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Defect Priority: Minor
Reporter: Esa Virtanen Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: bug, patch, test

Attachments: Text File 0001-Take-regex-flags-m-i-into-account-in-clojure.string-.patch    
Patch: Code and Test

 Description   

The replace function in namespace clojure.string ignores regex flag provided in the match pattern. For example:

CLJS
clojure.string/replace "I am NOT matched" #"(?i)not " "")
=> "I am NOT matched"
CLJ
clojure.string/replace "I am NOT matched" #"(?i)not " "")
=> "I am matched"

The attached patch fixes this by parsing the m and i flags, if set, from the match object, instead of explicitly setting only "g".



 Comments   
Comment by Chas Emerick [ 19/Mar/14 9:29 AM ]

I can confirm the bug. The attached patch applies cleanly, and works as expected.

Esa, sorry for the long delay (this one must have slipped through the cracks)! Could you please submit a contributor's agreement, so that your patch can be merged? More info is here:

http://clojure.org/contributing





[CLJS-476] Reading a value from a module does not work if the module is def'ed Created: 22/Feb/13  Updated: 19/Nov/13  Resolved: 19/Nov/13

Status: Closed
Project: ClojureScript
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Defect Priority: Minor
Reporter: Paul Gearon Assignee: Unassigned
Resolution: Declined Votes: 0
Labels: Compiler, bug, scope
Environment:

Clojure 1.5.0-RC16
Clojurescript 0.0-1586
java version "1.7.0_04"
Java(TM) SE Runtime Environment (build 1.7.0_04-b21)
Java HotSpot(TM) 64-Bit Server VM (build 23.0-b21, mixed mode)
OSX Mountain Lion 10.8.2



 Description   

Referring to a value in a module can have a scoping issue when using the "static accessor" operator of module/VALUE_NAME. The static accessor works if the module is loaded into a local value but not if def'ed. This example uses the mmap module for Node.js, and successfully reads the PROT_READ value:

(ns stat.core)
(defn -main []
  (let [m (js/require "mmap")]
    (println "value: " m/PROT_READ)))
(set! *main-cli-fn* -main)

This correctly prints "value: 1"

However, if the value for m is def'ed instead, then the compiler assumes that the reference to m is local to the function and therefore not defined:

(ns stat.core)
(def m (js/require "mmap"))
(defn -main []
  (println "value: " m/PROT_READ))
(set! *main-cli-fn* -main)

/Users/pag/src/test/clj/stat/target/stat.js:12836
  return cljs.core.println.call(null, "value: ", m.PROT_READ)
                                                 ^
ReferenceError: m is not defined
    at Function.stat.core._main (/Users/pag/src/test/clj/stat/target/stat.js:12836:50)
    at cljs.core.apply.b (/Users/pag/src/test/clj/stat/target/stat.js:5621:14)
    at cljs.core.apply.a (/Users/pag/src/test/clj/stat/target/stat.js:5656:18)
    at Object.<anonymous> (/Users/pag/src/test/clj/stat/target/stat.js:12844:17)
    at Module._compile (module.js:449:26)
    at Object.Module._extensions..js (module.js:467:10)
    at Module.load (module.js:356:32)
    at Function.Module._load (module.js:312:12)
    at Module.runMain (module.js:492:10)
    at process.startup.processNextTick.process._tickCallback (node.js:244:9)

In this case, the value of m.PROT_READ should have been stat.core.m.PROT_READ.

On the other hand, using . syntax fixes the scoping issue:

(ns stat.core)
(def m (js/require "mmap"))
(defn -main []
  (println "value: " (.-PROT_READ m)))
(set! *main-cli-fn* -main)


 Comments   
Comment by David Nolen [ 19/Nov/13 9:26 PM ]

the slash syntax is reserved for real CLJS namespaces for everything else the dot syntax must be used.





[CLJS-475] Node.js target fails with optimizations set to :none or :whitespace Created: 21/Feb/13  Updated: 29/Jul/13

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Defect Priority: Minor
Reporter: Paul Gearon Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: Compiler, bug
Environment:

Clojure 1.5.0-RC16
Clojurescript 0.0-1586
java version "1.7.0_04"
Java(TM) SE Runtime Environment (build 1.7.0_04-b21)
Java HotSpot(TM) 64-Bit Server VM (build 23.0-b21, mixed mode)
OSX Mountain Lion 10.8.2


Attachments: GZip Archive out-none.tar.gz     GZip Archive out-whitespace.tar.gz     File pr.js-none     File pr.js-whitespace    

 Description   

Compiling a hello world program for Node.js works fine if using optimizations of :advanced or :simple, but if using :none or :whitespace then an error will be reported for either "goog undefined" or "goog.string" undefined respectively.

The program is shown here:

(ns pr.core)
(defn -main []
  (println "Hello World!"))
(set! *main-cli-fn* -main)

This program is in src/cljs/pr/core.cljs. The repl line used to compile is:

(cljs.closure/build "src/cljs" {:output-to "src/js/pr.js" :target :nodejs :pretty-print true :optimizations :none})

When compiled with optimizations of :none, the output is:

$ node src/js/pr.js 

/Users/pag/src/test/clj/pr/src/js/pr.js:1
(function (exports, require, module, __filename, __dirname) { goog.addDependen
                                                              ^
ReferenceError: goog is not defined
    at Object.<anonymous> (/Users/pag/src/test/clj/pr/src/js/pr.js:1:63)
    at Module._compile (module.js:449:26)
    at Object.Module._extensions..js (module.js:467:10)
    at Module.load (module.js:356:32)
    at Function.Module._load (module.js:312:12)
    at Module.runMain (module.js:492:10)
    at process.startup.processNextTick.process._tickCallback (node.js:244:9)

When running with optimizations of :whitespace the output is:

$ node src/js/pr.js 

/Users/pag/src/test/clj/pr/src/js/pr.js:493
goog.string.Unicode = {NBSP:"\u00a0"};
                    ^
TypeError: Cannot set property 'Unicode' of undefined
    at Object.<anonymous> (/Users/pag/src/test/clj/pr/src/js/pr.js:493:21)
    at Module._compile (module.js:449:26)
    at Object.Module._extensions..js (module.js:467:10)
    at Module.load (module.js:356:32)
    at Function.Module._load (module.js:312:12)
    at Module.runMain (module.js:492:10)

When running with optimizations of either :simple or :advanced, the output is:

$ node src/js/pr.js 
Hello World!

I have included the two javascript output files that match the above errors.



 Comments   
Comment by Paul Gearon [ 21/Feb/13 4:40 PM ]

Remaining generated files

Comment by David Nolen [ 25/Feb/13 3:46 PM ]

This is a known bug. We need goog.require/provide to actually mean something to Node.js. I'm not sure how this can be made to work. I've been hoping for a patch for this since ClojureScript was first announced, but I haven't seen anything yet.





[CLJS-464] `get-in` not behaving like Clojure when accessing non-existing inner maps Created: 26/Jan/13  Updated: 27/Jul/13  Resolved: 28/Jan/13

Status: Closed
Project: ClojureScript
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Defect Priority: Major
Reporter: Roman Gonzalez Assignee: Unassigned
Resolution: Completed Votes: 0
Labels: bug
Environment:

Gentoo 64, oracle-jvm


Attachments: Text File get-in-fix.patch    

 Description   

In Clojurescript:
(get-in {:a {:b 1}} [:a :b :c])
=> Error: 1 is not an instance of ILookup

In Clojure:
(get-in {:a {:b 1}} [:a :b :c])
=> nil



 Comments   
Comment by Roman Gonzalez [ 26/Jan/13 11:01 PM ]

Code and Test patch v1

Comment by David Nolen [ 27/Jan/13 5:25 PM ]

Isn't this a duplicate of CLJS-458? That's been fixed in master.

Comment by Roman Gonzalez [ 28/Jan/13 10:06 PM ]

Hey David,

Thanks for your prompt reply, I tested latest version of github's master with the test-case I added and got this error.

```shell
Testing with V8
out/core-advanced-test.js:1: Error: No protocol method ILookup.-lookup defined for type number: 2
function d(a){throw a;}var e=void 0,f=!0,g=null,h=!1;function aa(){return func
^
Error: No protocol method ILookup.-lookup defined for type number: 2
at Error (<anonymous>)
at t (out/core-advanced-test.js:5:962)
at Function.ab [as c] (out/core-advanced-test.js:11:239)
at Function.wd [as c] (out/core-advanced-test.js:49:60)
at Function.Dc [as h] (out/core-advanced-test.js:36:58)
at Nk.l.Da (out/core-advanced-test.js:176:128)
at Function.Bb [as h] (out/core-advanced-test.js:16:342)
at Function.Ye [as h] (out/core-advanced-test.js:65:210)
at Function.Lj [as c] (out/core-advanced-test.js:164:27)
at Eu (out/core-advanced-test.js:602:398)

SPIDERMONKEY_HOME not set, skipping SpiderMonkey tests
JSC_HOME not set, skipping JavaScriptCore tests
Tested with 1 out of 3 possible js targets
```

The test case is:

```gitdiff
diff --git a/test/cljs/cljs/core_test.cljs b/test/cljs/cljs/core_test.cljs
index 2d1d2f3..bf3f7bb 100644
— a/test/cljs/cljs/core_test.cljs
+++ b/test/cljs/cljs/core_test.cljs
@@ -656,6 +656,7 @@
(assert (= 1 (get-in [{:foo 1}, {:foo 2}] [0 :foo])))
(assert (= 4 (get-in [{:foo 1 :bar [{:baz 1}, {:buzz 2}]}, {:foo 3 :bar [{:baz 3}, {:buzz 4}]}]
[1 :bar 1 :buzz])))
+ (assert (nil? (get-in {:foo {:bar 2}} [:foo :bar :baz])))

;; arrays
(let [a (to-array [1 2 3])]
```

In case github's master is not the latest one, and test works on master, please discard this message.

Cheers.

Comment by David Nolen [ 28/Jan/13 10:39 PM ]

fixed, http://github.com/clojure/clojurescript/commit/2b21e9d5b09cdd09f2831d11810fa2c5ae4f14b1





[CLJS-434] ClojureScript compiler prepends "self__" to defmulti forms when metadata in form of ^:field. Created: 01/Dec/12  Updated: 20/Jan/13

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Defect Priority: Minor
Reporter: Andrew Mcveigh Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: bug
Environment:

Mac OS X (10.7), java version "1.6.0_37", leiningen 2 preview 10, cljsbuild 0.2.9.
clojure/clojurescript master 01 December 2012 - 5ac1503



 Description   

Using the def form, with the specific metadata ^:field causes the cljs compiler
to prepend "self__" to the output js form.

The browser (latest chrome/firefox) does not recognize "self__".

Test Case: Tested against master: 5ac1503
-------------

(ns test-def)

(def ^:foo e identity)
e
; test_def.e = cljs.core.identity;
; test_def.e;

(def ^:field f identity)
f
; test_def.f = cljs.core.identity;
; self__.test_def.f;
; Uncaught ReferenceError: self__ is not defined

https://gist.github.com/4185793



 Comments   
Comment by Brandon Bloom [ 01/Dec/12 5:37 PM ]

code tags

Comment by David Nolen [ 20/Jan/13 12:54 AM ]

This one is a bit annoying. We should probably use namespaced keywords internally.





[CLJS-426] subvec function not behaving consitently with invalid subranges Created: 22/Nov/12  Updated: 27/Jul/13  Resolved: 23/Nov/12

Status: Closed
Project: ClojureScript
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Defect Priority: Major
Reporter: Roman Gonzalez Assignee: Unassigned
Resolution: Completed Votes: 0
Labels: bug, patch
Environment:

Ubuntu precise 64 bits, Mac OS X Lion


Attachments: Text File cljs_subvec.patch     Text File cljs_subvec_revised1.patch     Text File cljs_subvec_revised.patch    
Patch: Code and Test

 Description   

When using the subvec function with a as a parameter vector and a range that is not in the original vector, the function returns a value:

(subvec [1 2 3] 0 4) => [1 2 3 nil]

However, when using with seqs, it works as it supposed to:

(subvec (range 3) 0 4) => ERROR: Index out of bounds

This is because the validation of ranges is not happening at build time of the subvec type, this bug contains a patch that adds a new private `build-subvec` function into cljs.core.



 Comments   
Comment by Roman Gonzalez [ 22/Nov/12 5:05 PM ]

Patch for bug

Comment by David Nolen [ 23/Nov/12 2:51 PM ]

This mostly looks good but there is a typo in the patch:

(build-subvec. meta (-assoc v v-pos val) ...
Comment by Roman Gonzalez [ 23/Nov/12 3:09 PM ]

Revised patch, removing small typo

Comment by Roman Gonzalez [ 23/Nov/12 3:18 PM ]

Removing useless ^:mutable meta on function parameter

Comment by David Nolen [ 23/Nov/12 3:25 PM ]

fixed, http://github.com/clojure/clojurescript/commit/ee25599abb214074cbeefe37b399038d70c6ab89





[CLJS-420] Unexpected behavior with dispatch on Keyword via protocols Created: 18/Nov/12  Updated: 08/Sep/13  Resolved: 08/Sep/13

Status: Closed
Project: ClojureScript
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Defect Priority: Minor
Reporter: Max Penet Assignee: Unassigned
Resolution: Completed Votes: 0
Labels: bug, enhancement


 Description   

At the moment if you create a protocol and expect it to be able to dispatch on keywords you need to do it in js/String, trying to extend on cljs.core.Keyword doesn't work as keywords are just Strings.

See https://gist.github.com/4104635



 Comments   
Comment by David Nolen [ 18/Nov/12 3:14 PM ]

This is a known issue which will have to wait for if and when Keywords and Symbols become proper types in ClojureScript.

Extending js/Object is not recommended, if you actually need to add functionality to the base JS native types the convention is different from Clojure: default instead of Object, string instead of js/String. Please refer to core.cljs if you want more examples.

Comment by Max Penet [ 18/Nov/12 3:27 PM ]

Thanks for the pointer about default and string, I didn't know about that.

I reported the issue at the demand of bbloom. It does seem to be difficult to address without taking a (major) performance hit unfortunately.

Comment by David Nolen [ 08/Sep/13 6:27 PM ]

Made moot by CLJS-576





[CLJS-394] PersistentTreeSet lookup bug Created: 15/Oct/12  Updated: 27/Jul/13  Resolved: 15/Oct/12

Status: Closed
Project: ClojureScript
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Defect Priority: Major
Reporter: Erik Ouchterlony Assignee: Unassigned
Resolution: Completed Votes: 0
Labels: bug, patch

Attachments: File bugfix-PersistentTreeSet-lookup.diff    
Patch: Code and Test

 Description   

The lookup function in PersistentTreeSet behaves differently in clojurescript than in clojure when a custom comparison function is used. If two elements are evaluated as equal, one of then is in the set and we do a lookup on the other, clojure returns the element in the set, whereas clojurescript returns the lookup element.

(let [compare-quot-2 #(compare (quot %1 2) (quot %2 2))
s (sorted-set-by compare-quot-2 1)]
(get s 0))

Should return: 1
Returns: 0



 Comments   
Comment by David Nolen [ 15/Oct/12 10:02 PM ]

fixed, http://github.com/clojure/clojurescript/commit/409fcc9a824668207953b2bc47d40aaab85191d3





[CLJS-393] sebseq and sorted-set-by Created: 13/Oct/12  Updated: 27/Jul/13  Resolved: 18/Oct/12

Status: Closed
Project: ClojureScript
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Defect Priority: Major
Reporter: Erik Ouchterlony Assignee: Unassigned
Resolution: Completed Votes: 0
Labels: bug

Attachments: File bugfix-PersistentTreeMap.diff    

 Description   

ClojureScript:cljs.user> (subseq (sorted-set-by <= 1 2 3 4 5) >= 2 <= 4)
"Error evaluating:" (subseq (sorted-set-by <= 1 2 3 4 5) >= 2 <= 4) :as "cljs.core.subseq.call(null,cljs.core.sorted_set_by.call(null,cljs.core.LTEQ,1,2,3,4,5),cljs.core.GTEQ,2,cljs.core.LTEQ,4);\n"
org.mozilla.javascript.JavaScriptException: Error: No protocol method IMapEntry.-key defined for type null: (cljs/core.cljs#211)
at cljs/core.cljs:211 (anonymous)
at cljs/core.cljs:203 (_key)
at cljs/core.cljs:5535 (key)
at cljs/core.cljs:2479 (anonymous)
at cljs/core.cljs:1791 (lazy_seq_value)
at cljs/core.cljs:1840 (anonymous)
at cljs/core.cljs:238 (_seq)
at cljs/core.cljs:343 (seq)
at cljs/core.cljs:817 (anonymous)
at cljs/core.cljs:854 (anonymous)
at cljs/core.cljs:857 (anonymous)
at cljs/core.cljs:868 (anonymous)
at cljs/core.cljs:5925 (anonymous)
at cljs/core.cljs:5937 (anonymous)
at <cljs repl>:1 (anonymous)
at <cljs repl>:1



 Comments   
Comment by Erik Ouchterlony [ 17/Oct/12 5:23 PM ]

I've done some further analysis on this problem and found three different issues:

  1. The sorted-set-by in cljs doesn't support ordinary boolean operators, only comparison functions with values -1,0,1.
  2. Bug in PersistentTreeSet lookup. Resolved in CLJS-394
  3. Bug in PersistentTreeMap -sorted-seq-from. I have attached a patch that seems to resolve the issue.
Comment by David Nolen [ 17/Oct/12 9:25 PM ]

So does the patch address both 1 & 3 or only 3?

Comment by Erik Ouchterlony [ 18/Oct/12 2:48 AM ]

Only 3.

Comment by Erik Ouchterlony [ 18/Oct/12 6:04 AM ]

Here is a patch for the third issue.

Comment by Erik Ouchterlony [ 18/Oct/12 4:21 PM ]

I found a small bug in the last patch, so I attached a new one. This patch handles both the remaining issues.

Comment by David Nolen [ 18/Oct/12 5:44 PM ]

fixed, http://github.com/clojure/clojurescript/commit/e3ed0e7b69f9522e8759d0a6567afabb2a98d949





[CLJS-392] Documentation says CLJS can open connections to the REPL server from a "file://" source, and you can't Created: 09/Oct/12  Updated: 27/Jul/13  Resolved: 24/Oct/12

Status: Closed
Project: ClojureScript
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Defect Priority: Trivial
Reporter: Nahuel Greco Assignee: Unassigned
Resolution: Completed Votes: 0
Labels: bug, docs, documentation
Environment:

ClojureScript 0.0-1450



 Description   

At https://github.com/clojure/clojurescript/wiki/The-REPL-and-Evaluation-Environments there is the following paragraph:

"This is a problem for the browser-connected REPL because FireFox and Chrome both view opening a file from the file system and connecting to localhost:9000 as different domains.
(...)
Fortunately, Google has also run into this problem and has created something called a CrossPageChannel. Without going into the details, this allows an iframe served from one domain (the REPL) to communicate with the parent page which was served from another domain (the application server)."

From what I tested, you CANT connect to the REPL server at "http://localhost:9000/repl" if you initially loaded the page using the "file://" protocol. But you can if you loaded it from the same hostname on another port using "http://". The documentation is wrong, and also it needs to be clarified on what you really can change from the initial domain, like the port, without broking the REPL connection (or link to a CrossPageChannel documentation page with the details on what same-origin policy checks it can overcome).



 Comments   
Comment by David Nolen [ 23/Oct/12 7:00 PM ]

Are you unable to edit the wiki?

Comment by Nahuel Greco [ 24/Oct/12 9:27 AM ]

I didn't know the wiki had public write permissions. Also I don't know the exact CrossPageChannel limitations.

Comment by David Nolen [ 24/Oct/12 10:37 AM ]

The limitation is that it won't work with file://. We now provide a simple webserver that will serve the files present in the directory where you started browser REPL. If you goto http://localhost:9000/ we will serve index.html if it is present.

Comment by Nahuel Greco [ 24/Oct/12 10:47 AM ]

So CrossPageChannel overcomes the "same origin policy" for different ports, but not for different protocols. Thanks for the clarification.

Comment by David Nolen [ 24/Oct/12 2:48 PM ]

No problem, closing this one.





[CLJS-376] `case` doesn't match quoted symbols Created: 07/Sep/12  Updated: 27/Jul/13  Resolved: 07/Sep/12

Status: Closed
Project: ClojureScript
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Defect Priority: Major
Reporter: Shantanu Kumar Assignee: Unassigned
Resolution: Completed Votes: 0
Labels: bug
Environment:

ClojureScript



 Description   

It works fine in the Clojure 1.4.0 REPL:

user=> (let [a 'a] (case a nil :nil '& :amp :none))
:none
user=> (let [a '&] (case a nil :nil '& :amp :none))
:amp
user=> (let [a 'b] (case a nil :nil 'b :b :none))
:b

But in the CLJS Rhino REPL this is what I see:

ClojureScript:cljs.user> (let [a 'a] (case a nil :nil '& :amp :none))
:none
ClojureScript:cljs.user> (let [a '&] (case a nil :nil '& :amp :none))
:none
ClojureScript:cljs.user> (let [a 'b] (case a nil :nil 'b :b :none))
:none


 Comments   
Comment by David Nolen [ 07/Sep/12 4:48 PM ]

This did reveal a bug though the ticket description does have a user error. The tests for case can only be literals - you should not quote the test values. For example the following is how symbols should be tested:

(let [a '&] (case a nil :nil & :amp :none))

The above code that quotes the test is actually equivalent to:

(let [a '&] (case a nil :nil (quote &) :amp :none))

Which happens to work but probably isn't intended.

With the coming patch CLJS now works as Clojure.

Comment by David Nolen [ 07/Sep/12 4:49 PM ]

Fixed, http://github.com/clojure/clojurescript/commit/c8e301a9b058f81bb599026a07f97ccdf4441730





[CLJS-363] `format` %s behavior is incorrect for keyword, symbol etc. Created: 29/Aug/12  Updated: 27/Jul/13  Resolved: 29/Aug/12

Status: Closed
Project: ClojureScript
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Defect Priority: Major
Reporter: Shantanu Kumar Assignee: Unassigned
Resolution: Completed Votes: 0
Labels: bug
Environment:

ClojureScript Rhino REPL



 Description   

On the Clojure REPL, `format` works fine:

user=> (format "foo%s" :s) 
"foo:s" 
user=> (format "foo%s" 's) 
"foos"

However, on the CLJS REPL (Rhino), the output is different:

ClojureScript:cljs.user> (format "foo%s" :s) 
"foo 's" 
ClojureScript:cljs.user> (format "foo%s" 's) 
"foo 's"

Reference: http://groups.google.com/group/clojure/browse_thread/thread/b253d810536a4046



 Comments   
Comment by David Nolen [ 29/Aug/12 7:54 PM ]

fixed, http://github.com/clojure/clojurescript/commit/bf0622a594473c9a6de57fe3b5d10e0419fc7a2a





[CLJS-359] `with-meta` does not work on function objects Created: 25/Aug/12  Updated: 27/Jul/13  Resolved: 21/Nov/12

Status: Closed
Project: ClojureScript
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Defect Priority: Major
Reporter: Shantanu Kumar Assignee: David Nolen
Resolution: Completed Votes: 1
Labels: bug
Environment:

CLJS Rhino-REPL and during Compilation


Attachments: Text File CLJS-359-v1.patch     Text File CLJS-359-v2.patch    
Patch: Code and Test

 Description   

`with-meta` does not working on function objects in CLJS. Compilation fails with the following error:

Error: No protocol method IWithMeta.-with-meta defined for type function: function { return x; }

I tried it out on the REPL and found the following:

---------- BEGIN: repl-rhino ----------
ClojureScript:cljs.user> (with-meta #(do :foo) {:foo :bar})
"Error evaluating:" (with-meta (fn* [] (do :foo)) {:foo :bar}) :as "cljs.core.with_meta.call(null,(function (){\nreturn \"\\uFDD0'foo\";\n}),cljs.core.ObjMap.fromObject([\"\\uFDD0'foo\"],{\"\\uFDD0'foo\":\"\\uFDD0'bar\"}));\n"
org.mozilla.javascript.JavaScriptException: Error: No protocol method IWithMeta.-with-meta defined for type function:
function () { return "\ufdd0'foo"; }
(cljs/core.cljs#222)
at cljs/core.cljs:222 (anonymous)
at cljs/core.cljs:214 (_with_meta)
at cljs/core.cljs:806 (with_meta)
at <cljs repl>:2 (anonymous)
at <cljs repl>:2

nil
---------- END: repl-rhino ----------

Reference: https://groups.google.com/forum/?fromgroups=#!topic/clojure/pRO-5IlilNM



 Comments   
Comment by David Nolen [ 29/Aug/12 9:52 AM ]

We could create a fn wrapper type of some kind that implements all the supported arities of IFn (this means the compiler needs to guarantee that args past 20 are collected into an array-seq) that include the extra meta fields. Seems doable.

Comment by Paul deGrandis [ 28/Sep/12 3:21 PM ]

I have created that exact function wrapper - it's in Shoreleave. We can move it into CLJS proper if you like.

https://github.com/shoreleave/shoreleave-core/blob/master/src/shoreleave/efunction.cljs

Comment by David Nolen [ 28/Sep/12 3:24 PM ]

That's nice but would prefer to have as little overhead as possible.

Comment by Paul deGrandis [ 28/Sep/12 3:27 PM ]

ala unrolling the invoke call?

More than happy to start pulling together a patch.

Comment by David Nolen [ 28/Sep/12 3:34 PM ]

Yes there's actually an existing ticket for that. Thanks. We also need compiler support for function invocations when there's more then 20 arguments - though that's a different existing ticket.

Comment by Paul deGrandis [ 22/Oct/12 7:50 AM ]

I was just waiting on CLJS-365 to be completed. Did you think of a better approach than the deftype-wrapper? More than happy to push on this.

Comment by David Nolen [ 23/Oct/12 6:36 PM ]

I thought about this some more - this patch is really about adding metadata to functions at runtime - static metadata on defs are stored in cljs.analyzer/namespaces. Given that it's runtime I think your simple patch is actually OK, we can't generally optimize functions like that anyway since we won't have that kind of information available.

Comment by Brandon Bloom [ 21/Nov/12 3:29 PM ]

Patch adds a Function type and extends js/function to support metadata. There is now an Fn marker protocol.

Patch also includes an additional commit to fix the behavior of the this variable for IFn definitions.

Not tested on JavaScriptCore.

Comment by Brandon Bloom [ 21/Nov/12 4:16 PM ]

v2 of patch improves speed of fn? and utilizes reify to avoid creating an explicit Function type

Comment by David Nolen [ 21/Nov/12 4:21 PM ]

fixed, http://github.com/clojure/clojurescript/commit/6ce3b1cef3824fd36e75402f5a8ed5053252b15e





[CLJS-339] (inc nil) returns 1 instead of throwing an exception Created: 23/Jul/12  Updated: 29/Jul/13  Resolved: 29/Jul/13

Status: Closed
Project: ClojureScript
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Defect Priority: Minor
Reporter: Evan Mezeske Assignee: Unassigned
Resolution: Declined Votes: 0
Labels: bug


 Description   

(inc nil) => 1 in ClojureScript
(inc nil) => raise NullPointerException in Clojure

I think that Clojure's behavior (throwing) makes more sense in this context.



 Comments   
Comment by Evan Mezeske [ 23/Jul/12 12:44 AM ]

I observe that in my JS console, "undefined + 1 => NaN" but "null + 1 => 1". I assume this has something to do with this issue.

Comment by David Nolen [ 23/Jul/12 12:30 PM ]

Do you have any suggestions on how to make this work without slowing arithmetic down? If not I'm inclined to close this as Won't Fix.

Comment by Evan Mezeske [ 23/Jul/12 12:50 PM ]

I do not. I haven't had a chance to put a lot of thought into it, though.

I consider this kind of problem to be rather insidious. Null is not a number, and treating it as zero will lead to nasty bugs creeping into people's code.

A historical anecdote: the C function "int atoi(char* s)" takes a string and returns the number it represents. However, if the string can't be converted, it returns zero (which could also be a valid result for e.g. the string "0"). Technically, it's possible to distinguish "0 meaning error" and "0 meaning 0" by taking additional steps after the function call, but in practice people forget to do this. Thus, atoi is universally a disaster. I have literally seen the lights go off in a warehouse due to atoi's poor design (I used to work in building control).

Treating null as zero will result in similar problems. Someone forgets to check the result of a computation, it's null, and the program silently continues as if nothing is wrong. Hello, data corruption.

So I seriously urge you to not close this as Won't Fix, even if a performant solution is not yet obvious. IMHO it's worth more thought.

Comment by David Nolen [ 23/Jul/12 12:56 PM ]

Closing as Won't Fix doesn't mean we don't care, but this issue is simply a symptom of something much larger - punting on numerics. A ticket is the wrong place for this discussion as it has many nuances. It should be a part of a larger design for ClojureScript numerics. Without that larger discussion this ticket is likely to get stuck in limbo.

Comment by Evan Mezeske [ 23/Jul/12 12:59 PM ]

Fair enough! I thought Won't Fix had stronger implications than that. Do you know if there's already a design doc that addresses numerics? Or should I start one?

Comment by Fogus [ 23/Jul/12 1:04 PM ]

One place that this has burned me, that may warrant a separate card is

(update-in some-map [:foo :bar] inc)
where the key at that location did not exist. I would have preferred an exception rather than an broken 1.

Comment by Evan Mezeske [ 23/Jul/12 1:09 PM ]

@Fogus: Huh, that is the exact same use-case that burned me – I was using update-in/inc on a nested map. The default value for my [:foo :bar] was, in fact, supposed to be zero, so it silently worked for me. But when I moved that code from the client in my webapp (ClojureScript) to the server (Clojure), I found out that my original implementation was wonky.

Comment by David Nolen [ 23/Jul/12 1:17 PM ]

It doesn't seem to me that you could do that safely without fnil + 0. I too hate JS's silent failures around numerics. Been hoping someone would tackle this challenge with gusto.

Comment by Evan Mezeske [ 23/Jul/12 1:21 PM ]

@David Nolen: Yeah, fnil would do the job. In my case, I was calling update-in on what I thought was an initialized map, but it was actually nil. update-in initialized each level of nesting with an empty map, and then inc was called on nil. My fix was simply to initialize the nested maps like I meant to.

Comment by Fogus [ 23/Jul/12 1:21 PM ]

David,
That was ultimately the solution, so I suppose we need to start advocating this pattern so that others might avoid the same fate.

Comment by David Nolen [ 29/Jul/13 11:32 PM ]

tickets of this nature aren't going anywhere without a fairly serious design pass on CLJS numerics.





[CLJS-338] Incorrect implementation of IReduce by ArrayChunk Created: 22/Jul/12  Updated: 29/Jul/13

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Defect Priority: Minor
Reporter: Anton Frolov Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: bug


 Description   
(reduce + (array-chunk (array 1 2 3 4) 1 3)) => 2 (instead of 5)
(reduce + 0 (array-chunk (array 1 2 3 4) 1 3)) => 3 (instead of 5)
(reduce + (array-chunk (array 1 2 3 4) 1 1)) => 2 (instead of 0)

In src/cljs/cljs/core.cljs, line #1817:

(deftype ArrayChunk [arr off end]
  ;; ...
  IReduce
  (-reduce [coll f]
    (ci-reduce coll f (aget arr off) (inc off))) ;; should be (if (< off end) (ci-reduce coll f (aget arr off) 1) 0)
  (-reduce [coll f start]
    (ci-reduce coll f start off))) ;; should be (ci-reduce coll f start 0)


 Comments   
Comment by David Nolen [ 14/Aug/12 6:29 AM ]

Thanks for the report. ArrayChunk is an implementation detail - do these conditions actually arise?





[CLJS-309] Bug - Typo in commit "Tagged literals in the CLJS compiler and first blush tests " Created: 08/Jun/12  Updated: 08/Jun/12  Resolved: 08/Jun/12

Status: Closed
Project: ClojureScript
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Defect Priority: Major
Reporter: Raphaël AMIARD Assignee: Unassigned
Resolution: Declined Votes: 0
Labels: bug

Attachments: Text File fix-data-readers-typo.patch    
Patch: Code

 Description   

I'm pretty sure there is a typo in this commit,

cljs-data-readers is declared, but then data-readers is bound in compile-file, which makes compilation fail

Patch attached



 Comments   
Comment by Fogus [ 08/Jun/12 8:43 AM ]

I'm unable to reproduce this. Do you mind posting the steps that you ran to see the error?
Thank you.

Comment by Raphaël AMIARD [ 08/Jun/12 10:48 AM ]

Sorry, i failed to follow the implications of CLJ-890, the bug was related to my configuration, and the binding valid.





[CLJS-262] vector-seq optimizations introduced un-conj-able sequence Created: 18/May/12  Updated: 27/Jul/13  Resolved: 18/May/12

Status: Closed
Project: ClojureScript
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Defect Priority: Major
Reporter: Brian Taylor Assignee: Unassigned
Resolution: Completed Votes: 0
Labels: bug


 Description   

Due to changes introduced in commit ddd7fa3d960b0fe32083d3cb35ff064e968d53c4 "attempting to optimize seq on vectors" the following code will fail with the an error:

(conj (rest [1 2]) 4)

The error is "No protocol method ICollection.-conj defined for type object: [object Object]" and the object in question is the reify result returned by vector-seq.



 Comments   
Comment by David Nolen [ 18/May/12 9:58 PM ]

fixed, http://github.com/clojure/clojurescript/commit/1d20ac061199a0acd3a1fe5ae08579edb255f377





[CLJS-183] The pop function in PersistentVector is buggy Created: 18/Apr/12  Updated: 27/Jul/13  Resolved: 19/Apr/12

Status: Closed
Project: ClojureScript
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Defect Priority: Major
Reporter: Erik Ouchterlony Assignee: Unassigned
Resolution: Completed Votes: 0
Labels: bug

Attachments: File fix-persistentvector-pop.diff     File fix-persistentvector-pop.diff     File fix-persistentvector-pop-with-tests.diff    

 Description   

Example:

(conj (pop [1 2]) 3) => [1 2]



 Comments   
Comment by Nicola Mometto [ 18/Apr/12 10:22 AM ]

this patch fixes pop

Comment by Laszlo Török [ 19/Apr/12 2:38 AM ]

Hi,

good catch, but why not simply:

(PersistentVector. meta (dec cnt) shift root (.slice tail 0 -1))
;; you don't need to aclone and splice, .slice returns a new array

Comment by Nicola Mometto [ 19/Apr/12 3:48 AM ]

right, using slice is even faster.
patch updated

Comment by Laszlo Török [ 19/Apr/12 6:01 AM ]

Nice, thank you!

Could you please add a test that covers the issue?

e.g.

(assert (= (vec (range 33))
(-> (vec (range 33))
(pop)
(pop)
(conj 31)
(conj 32))))

Comment by Nicola Mometto [ 19/Apr/12 10:15 AM ]

sure, here it is

Comment by David Nolen [ 19/Apr/12 10:31 PM ]

Fixed, https://github.com/clojure/clojurescript/commit/053b7fd9cbb0a24617592f490893d6a746e54ec7





[CLJS-162] cljs.core/str behavior not consistent with clojure Created: 15/Mar/12  Updated: 27/Jul/13  Resolved: 19/Mar/12

Status: Closed
Project: ClojureScript
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Defect Priority: Trivial
Reporter: Roman Gonzalez Assignee: Unassigned
Resolution: Completed Votes: 0
Labels: bug
Environment:

This is the behavior on rhino repl, haven't tested on browser


Attachments: Text File CLJS-162_1.patch     Text File CLJS-162_2.patch     Text File CLJS-162.patch    

 Description   

When running the cljs.core/str function with symbols or keywords the output is not the same as in clojure

ClojureScript:cljs.user> (str "hello" :world)
"hello?'world"

The same happens with symbols, it seems the characters used internally for figuring out if a string is a keyword or symbol are not being escaped correctly on the cljs.core/str function.



 Comments   
Comment by Roman Gonzalez [ 15/Mar/12 9:18 PM ]

Added check of symbols and keywords on the private cljs.core/str* function

Comment by David Nolen [ 16/Mar/12 11:57 AM ]

The patch looks good but some tests fail now. Can you address that? Thanks!

Comment by Roman Gonzalez [ 16/Mar/12 11:55 PM ]

Thanks for checking this out David, I didn't read the developer wiki (my bad), I added a few tests and added a new small function that will allow both str* and str to behave correctly, cheers.

Note: Use CLJS-162_1.patch

Comment by Roman Gonzalez [ 19/Mar/12 5:45 PM ]

New patch which just replicates the StringBuffer code from `str*` into the `str` implementation.

Comment by David Nolen [ 19/Mar/12 9:25 PM ]

Fixed, https://github.com/clojure/clojurescript/commit/ec75a897fc7069176aff81e2df91b848c26af1c8





[CLJ-1370] ((println)) should throw CompilerException instead of NPE? Created: 06/Mar/14  Updated: 06/Mar/14  Resolved: 06/Mar/14

Status: Closed
Project: Clojure
Component/s: None
Affects Version/s: Release 1.5
Fix Version/s: None

Type: Defect Priority: Minor
Reporter: The Alchemist Assignee: Unassigned
Resolution: Declined Votes: 0
Labels: bug


 Description   

How to Reproduce

=> ((println))

NullPointerException   hello.core/eval4117 (NO_SOURCE_FILE:1)

What's Wrong?

I might be completely wrong, in which case don't hesitate to close this defect, but I wish this would throw a CompilerException with an IllegalArgumentException, just like ((nil)):

=> ((nil))
CompilerException java.lang.IllegalArgumentException: Can't call nil, compiling:(NO_SOURCE_PATH:1:2)


 Comments   
Comment by Alex Miller [ 06/Mar/14 12:37 PM ]

There is no compilation error here. The error occurs during evaluation.

user> (defn x [] ((println)))  ;; compiles just fine
#'user/x
user> (x)   ;; fails in evaluation
NullPointerException   user/x (NO_SOURCE_FILE:1)

The error is thrown when trying to evaluate (nil) where NullPointerException is a perfectly valid error.





[CLJ-1306] Cannot reduce over short[] arrays Created: 14/Dec/13  Updated: 14/Dec/13  Resolved: 14/Dec/13

Status: Closed
Project: Clojure
Component/s: None
Affects Version/s: Release 1.5
Fix Version/s: None

Type: Defect Priority: Major
Reporter: Mike Anderson Assignee: Unassigned
Resolution: Duplicate Votes: 0
Labels: bug

Attachments: File clj-1306.diff    

 Description   

Reducing over a short array currently causes an error:

(reduce + (seq (short-array 10)))
=> ClassCastException [S cannot be cast to [Ljava.lang.Object; clojure.core.protocols/fn--6037 (protocols.clj:126)

This appears to occur because ArraySeq is assumed by protocols.clj to contain an Object[] array in the ".array" field, when in fact it is a short[] array.

Proposed solution to to create ArraySeq_short (analogous to the other primitive types ArraySeq_long etc.) to handle short arrays.



 Comments   
Comment by Mike Anderson [ 14/Dec/13 7:37 AM ]

Fix for CLJ-1306

Comment by Alex Miller [ 14/Dec/13 8:17 AM ]

This was also discovered in CLJ-1200 and the patch for that issue includes ArraySeq_short as you propose. It is expected that CLJ-1200 will be included in 1.6.

Comment by Mike Anderson [ 14/Dec/13 9:29 AM ]

OK, thanks Alex!

Just to be sure: Can you confirm that a fix will definitely go into 1.6? This is a defect, and as such should have a higher priority than CLJ-1200 (which appears to be presented as an performance enhancement patch).

My patch also includes a regression test which I think could helpfully be included in the test suite.

Comment by Alex Miller [ 14/Dec/13 11:24 AM ]

Yes, I fully expect CLJ-1200 to be included and talked to Rich about it as recently as yesterday. I could split things out of that patch and pull both of these in separately. That would be objectively better but definitely more work to do all the ticket, patch, and screening work so I'd rather not. If you want to attach just the regression test to 1200, I think we could include it that way as 1200 hasn't been screened yet. Stuart Sierra is planning to screen it in the next few days.





[CLJ-1267] Reader Bug for making vector of numbers Created: 26/Sep/13  Updated: 26/Sep/13  Resolved: 26/Sep/13

Status: Closed
Project: Clojure
Component/s: None
Affects Version/s: Release 1.5
Fix Version/s: None

Type: Defect Priority: Major
Reporter: Amin Razavi Assignee: Unassigned
Resolution: Declined Votes: 0
Labels: bug
Environment:

Windows 8 , Core i7



 Description   

When Trying To Make a Vector of Numbers Like 01 04 ... it's OK!
=> (vector 04)
; [4]
But When Trying To Make a Vector of "09" It Says :
NumberFormatException Invalid Number: 09



 Comments   
Comment by Alex Miller [ 26/Sep/13 10:56 AM ]

Numbers with a leading 0 are read as octal (valid digits = 0-7). Example:

> 0100
64

So, this is the expected behavior.

Comment by Amin Razavi [ 26/Sep/13 7:49 PM ]

shame on me , sorry.





[CLJ-1258] (apply and [false true]) gives CompilerException Created: 08/Sep/13  Updated: 09/Sep/13  Resolved: 09/Sep/13

Status: Closed
Project: Clojure
Component/s: None
Affects Version/s: Release 1.4, Release 1.5
Fix Version/s: None

Type: Defect Priority: Major
Reporter: Cynthia Qiu Assignee: Unassigned
Resolution: Declined Votes: 0
Labels: bug
Environment:

Ubuntu 13.04. I run 1.4.0 by "apt-get install", and 1.5.1 by "java -cp clojure-1.5.1.jar clojure.main".



 Description   

user=> (apply and [false true])
CompilerException java.lang.RuntimeException: Can't take value of a macro: #'clojure.core/and, compiling:(NO_SOURCE_PATH:1)
user=> (apply and (list false true))
CompilerException java.lang.RuntimeException: Can't take value of a macro: #'clojure.core/and, compiling:(NO_SOURCE_PATH:2)



 Comments   
Comment by Cynthia Qiu [ 08/Sep/13 10:18 PM ]

I got it. "and" is not a function but a special form. Sorry for that.

Comment by Andy Fingerhut [ 08/Sep/13 11:57 PM ]

Minor comment on yours: Clojure and other Lisps often distinguish between "special forms" and macros. I may be missing some of the distinction, but I am pretty sure the main part is that special forms are usually built into the implementation of Lisp, whereas macros are typically defined by the user via defmacro.

In any case, neither special forms nor macros may be used with apply, only functions.

Comment by Alex Miller [ 09/Sep/13 1:26 AM ]

As per Andy's comment, this is expected behavior when trying to apply to macros.





[CLJ-1179] distinct? does not accept zero arguments Created: 09/Mar/13  Updated: 04/Jan/14  Resolved: 12/Apr/13

Status: Closed
Project: Clojure
Component/s: None
Affects Version/s: Release 1.4, Release 1.5
Fix Version/s: None

Type: Enhancement Priority: Minor
Reporter: Jean Niklas L'orange Assignee: Unassigned
Resolution: Declined Votes: 0
Labels: bug

Attachments: Text File clj-1179-distinct-zero-arguments.txt    
Patch: Code

 Description   

distinct? cannot be invoked with zero arguments. When using the pattern (apply distinct? x), this is bothersome as you have to check whether x is empty or not. It is also logical that distinct? should return true if no arguments are given, since there are no duplicates.

What (small set of) steps will reproduce the problem?

user=> (apply distinct? [])
ArityException Wrong number of args (0) passed to: core$distinct-QMARK-  clojure.lang.AFn.throwArity (AFn.java:437)

What is the expected output? What do you see instead?

I would expect distinct? to return true whenever given zero arguments.

What version are you using?

This was tested under Clojure 1.4 and Clojure 1.5.



 Comments   
Comment by Jean Niklas L'orange [ 09/Mar/13 6:08 AM ]

Attached the straightforward patch which solves this issue.

Comment by Devin Walters [ 04/Jan/14 1:32 PM ]

Is there a reason this was closed without a comment?

Comment by Alex Miller [ 04/Jan/14 2:12 PM ]

Rich declined it, implying that it was not a change he wanted. Not sure of the reason.





[CLJ-1028] (compile) crashes with NullPointerException if public function 'load' is defined Created: 20/Jul/12  Updated: 20/Jul/12  Resolved: 20/Jul/12

Status: Closed
Project: Clojure
Component/s: None
Affects Version/s: Release 1.4
Fix Version/s: None

Type: Defect Priority: Minor
Reporter: Ben Kelly Assignee: Unassigned
Resolution: Declined Votes: 0
Labels: Compiler, bug
Environment:

Linux, OpenJDK 1.6.0 64bit


Attachments: File stack-trace    

 Description   

When performing AOT compilation, if the namespace being compiled or one of the namespaces :required by it defines a public function named 'load', the compiler will crash with a NullPointerException.

The following code demonstrates this:

(ns ca.ancilla.kessler.core (:gen-class)) (defn load [x] x) (defn -main [& args] 0)

When run directly, with 'clojure -m ca.ancilla.kessler.core' or 'clojure ca/ancilla/kessler/core.clj', it runs as expected. When loaded with 'clojure -i' and (compile)d, however, or when automatically compiled by 'lein run', it results in a NullPointerException (the complete stack trace is attached).

This occurs whether or not 'load' or actually called. It does not, however, occur if 'load' is private.



 Comments   
Comment by Ben Kelly [ 20/Jul/12 12:43 PM ]

If you add (:refer-clojure :exclude [load]) to the (ns), it works fine:

(ns ca.ancilla.kessler.core (:refer-clojure :exclude [load]) (:gen-class))
(defn load [x] x)
(defn -main [& args] 0)

Thanks to llasram on IRC for discovering this.

Comment by Stuart Halloway [ 20/Jul/12 4:35 PM ]

You should not replace functions in clojure.core. This is left legal (with a loud CONSOLE warning) for compatibility, but programs that do it are in error.

Comment by Ben Kelly [ 20/Jul/12 10:06 PM ]

So, just to make sure that I have this right, then...

If I want to create a namespace with a public function that shares a name with a function in clojure.core, the only supported way of doing this is to (:refer-clojure :exclude [list of all such functions])?

If so, it would be nice if the warning were replaced with an error, rather than having the compiler emit an error and then crash.





[CLJ-1006] Quotient on bigdec may produce wrong result Created: 01/Jun/12  Updated: 01/Mar/13  Resolved: 09/Nov/12

Status: Closed
Project: Clojure
Component/s: None
Affects Version/s: Release 1.4
Fix Version/s: None

Type: Defect Priority: Major
Reporter: laurent joigny Assignee: Unassigned
Resolution: Declined Votes: 0
Labels: bug
Environment:

Linux 3.2.0-24-generic #39-Ubuntu SMP i686 GNU/Linux


Attachments: Java Source File TestBigDecimalQuotient.java    

 Description   

Hi,

As discussed on the mailing list in the message "When arithmetic on a computer bite back" (01/jun)

There may be bug in the way quotient is implemented for bigdec.

user> (quot 1.4411518807585587E17 2) ;; correct with doubles
7.2057594037927936E16
user> (quot 1.4411518807585587E+17M 2) ;; wrong with BigDecs
72057594037927935M


Laurent



 Comments   
Comment by laurent joigny [ 01/Jun/12 5:48 PM ]

I can reproduce the bug when using BigDecimal constructor on String.
See attached file for a test class.

More infos :
java version "1.6.0_24"
OpenJDK Runtime Environment (IcedTea6 1.11.1) (6b24-1.11.1-4ubuntu3)
OpenJDK Client VM (build 20.0-b12, mixed mode, sharing)

Comment by laurent joigny [ 01/Jun/12 5:49 PM ]

A simple test file, that you can drop in Clojure sources and execute to reproduce the bug on BigDecimal constructor using String as argument.

Comment by Tassilo Horn [ 03/Jun/12 4:30 AM ]

Seems to be a general precision problem. Note that in

user> (quot 1.4411518807585587E17 2) ;; correct with doubles
7.2057594037927936E16
user> (quot 1.4411518807585587E+17M 2) ;; wrong with BigDecs
72057594037927935M

the double result is actually wrong and the bigdec one is correct. The problem which lead to the wrong conclusion is that in your calculation the input number is already wrong.

So the moral is: don't use any floating points (neither doubles nor bigdecs) for computations involving divisibility tests.

For bigdecs, you can set the math context for making computations throw exceptions if they lose precision, though:

user> (binding [*math-context* (java.math.MathContext. 1 java.math.RoundingMode/UNNECESSARY)]
	       (quot (bigdec (Math/pow 2 58)) 2))
;Division impossible
;  [Thrown class java.lang.ArithmeticException]
Comment by Stuart Sierra [ 09/Nov/12 8:49 AM ]

Not a bug. Just floating-point arithmetic.





[CLJ-988] the locking in MultiFn.java (synchronized methods) can cause lots of contention in multithreaded programs Created: 08/May/12  Updated: 21/Sep/12  Resolved: 21/Sep/12

Status: Closed
Project: Clojure
Component/s: None
Affects Version/s: None
Fix Version/s: Release 1.5

Type: Enhancement Priority: Major
Reporter: Kevin Downey Assignee: Stuart Sierra
Resolution: Completed Votes: 10
Labels: bug, performance

Attachments: Text File clj-988-tests-only-patch-v1.txt     File issue988-lockless-multifn+tests-120817.diff     File issue988-lockless-multifn+tests.diff    
Patch: Code and Test
Approval: Ok

 Description   

if you call a single multimethod a lot in multithreaded code you get lots of contention for the lock on the multimethod. this contention slows things down a lot.

this is due to getMethod being synchronized. it would be great if there was some fast non-locking path through the multimethod.



 Comments   
Comment by Kevin Downey [ 08/May/12 11:30 AM ]

http://groups.google.com/group/clojure-dev/browse_thread/thread/6a8219ae3d4cd0ae?hl=en

Comment by David Santiago [ 11/May/12 6:38 AM ]

Here's a stab in the dark attempt at rewriting MultiFn to use atoms to swap between immutable copies of its otherwise mutable state.

The four pieces of the MultiFn's state that are mutable and protected by locks are now contained in the MultiFn.State class, which is immutable and contains convenience functions for creating a new one with one field changed. An instance of this class is now held in an atom in the MultiFn called state. Changes to any of these four members are now done with an atomic swap of these State objects.

The getMethod/findAndCacheBestMethod complex was rewritten to better enable the atomic logic. findAndCacheBestMethod was replaced with findBestMethod, which merely looks up the method; the caching logic was moved to getMethod so that it can be retried easily as part of the work that method does.

As it was findAndCacheBestMethod seemingly had the potential to cause a stack overflow in a perfect storm of heavy concurrent modification, since it calls itself recursively if it finds that the hierarchy has changed while it has done its work. This logic is now done in the CAS looping of getMethod, so hopefully that is not even an unlikely possibility anymore.

There is still seemingly a small race here, since the check is done of a regular variable against the value in a ref. Now as before, the ref could be updated just after you do the check, but before the MultiFn's state is updated. Of course, only the method lookup part of a MultiFn call was synchronized before; it could already change after the lookup but before the method itself executed, having a stale method finish seemingly after the method had been changed. Things are no different now in general, with the atom-based approach, so perhaps this race is not a big deal, as a stale value can't persist for long.

The patch passes the tests and Clojure and multimethods seems to work.

Comment by Kevin Downey [ 12/May/12 8:59 PM ]

this patch gets rid of the ugly lock contention issues. I have not been able to benchmark it vs. the old multimethod implementation, but looking at it, I would not be surprised if it is faster when the system is in a steady state.

Comment by Stuart Halloway [ 08/Jun/12 12:11 PM ]

This looks straightforward, except for getMethod. Can somebody with context add more discussion of how method caching works?

Also, it would be great to have tests with this one.

Comment by David Santiago [ 15/Jun/12 4:44 AM ]

Obviously I didn't write the original code, so I'm not the ideal
person to explain this stuff. But I did work with it a bit recently,
so in the hopes that I can be helpful, I'm writing down my
understanding of the code as I worked with it. Since I came to the
code and sort of reverse engineered my way to this understanding,
hopefully laying this all out will make any mistakes or
misunderstandings I may have made easier to catch and correct. To
ensure some stability, I'll talk about the original MultiFn code as it
stands at this commit:
https://github.com/clojure/clojure/blob/8fda34e4c77cac079b711da59d5fe49b74605553/src/jvm/clojure/lang/MultiFn.java

There are four pieces of state that change as the multimethod is either
populated with methods or called.

  • methodTable: A persistent map from a dispatch value (Object) to
    a function (IFn). This is the obvious thing you think it is,
    determining which dispatch values call which function.
  • preferTable: A persistent map from a dispatch value (Object) to
    another value (Object), where the key "is preferred" to the value.
  • methodCache: A persistent map from a dispatch value (Object) to
    function (IFn). By default, the methodCache is assigned the same
    map value as the methodTable. If values are calculated out of the
    hierarchy during a dispatch, the originating value and the
    ultimate method it resolves to are inserted as additional items in
    the methodCache so that subsequent calls can jump right to the
    method without recursing down the hierarchy and preference table.
  • cachedHierarchy: An Object that refers to the hierarchy that is
    reflected in the latest cached values. It is used to check if the
    hierarchy has been updated since we last updated the cache. If it
    has been updated, then the cache is flushed.

I think reset(), addMethod(), removeMethod(), preferMethod(),
prefers(), isA(), dominates(), and resetCache() are extremely
straightforward in both the original code and the patch. In the
original code, the first four of those are synchronized, and the other
four are only called from methods that are synchronized (or from
methods only called from methods that are synchronized).

Invoking a multimethod through its invoke() function will call
getFn(). getFn() will call the getMethod() function, which is
synchronized. This means any call of the multimethod will wait for and
take a lock as part of method invocation. The goal of the patch in
this issue is to remove this lock on calls into the multimethod. It in
fact removes the locks on all operations, and instead keeps its
internal mutable state by atomically swapping a private immutable
State object held in an Atom called state.

The biggest change in the patch is to the
getFn()>getMethod()>findAndCacheBestMethod() complex from the
original code. I'll describe how that code works first.

In the original code, getFn() does nothing but bounce through
getMethod(). getMethod() tries three times to find a method to call,
after checking that the cache is up to date and flushing it if it
isn't:

1. It checks if there's a method for the dispatch value in the
methodCache.

2. If not, it calls findAndCacheBestMethod() on the
dispatch value. findAndCacheBestMethod() does the following:

1. It iterates through every map entry in the method table,
keeping at each step the best entry it has found so far
(according to the hierarchy and preference tables).

2. If it did not find a suitable entry, it returns null.

3. Otherwise, it checks if the hierarchy has been changed since the cache
was last updated. If it has not changed, it inserts the method
into the cache and returns it. If it has been changed, it
resets the cache and calls itself recursively to repeat the process.

3. Failing all else, it will return the method for the default
dispatch value.

Again, remember everything in the list above happens in a call to a
synchronized function. Also note that as it is currently written,
findAndCacheBestMethod() uses recursion for iteration in a way that
grows the stack. This seems unlikely to cause a stack overflow unless
the multimethod is getting its hierarchy updated very rapidly for a
sustained period while someone else tries to call it. Nonetheless, the
hierarchy is held in an IRef that is updated independently of the
locking of the MultiFn. Finally, note that the multimethod is locked
only while the method is being found. Once it is found, the lock is
released and the method actually gets called afterwards without any
synchronization, meaning that by the time the method actually
executes, the multimethod may have already been modified in a way that
suggests a different method should have been called. Presumably this
is intended, understood, and not a big deal.

Moving on now to the patch in this issue. As mentioned, the main
change is updating this entire apparatus to work with a single atomic
swap to control concurrency. This means that all updates to the
multimethod's state have to happen at one instant in time. Where the
original code could make multiple changes to the state at different
times, knowing it was safely protected by an exclusive lock, rewriting
for atom swaps requires us to reorganize the code so that all updates
to the state happen at the same time with a single CAS.

To implement this change, I pulled the implicit looping logic from
findAndCacheBestMethod() up into getMethod() itself, and broke the
"findBestMethod" part into its own function, findBestMethod(), which
makes no update to any state while implementing the same
logic. getMethod() now has an explicit loop to avoid stack-consuming
recursion on retries. This infinite for loop covers all of the logic
in getMethod() and retries until a method is successfully found and a
CAS operation succeeds, or we determine that the method cannot be
found and we return the default dispatch value's implementation.

I'll now describe the operation of the logic in the for loop. The
first two steps in the loop correspond to things getMethod() does
"before" its looping construct in the original code, but we have to do
in the loop to get the latest values.

1. First we dereference our state, and assign this value to both
oldState and newState. We also set a variable called needWrite to
false; this is so we can avoid doing a CAS (they're not free) when
we have not actually updated the state.

2. Check if the cache is stale, and flush it if so. If the cache
gets flushed, set needWrite to true, as the state has changed.

3. Check if the methodCache has an entry for this dispatch
value. If so, we are "finished" in the sense that we found the
value we wanted. However, we may need to update the state. So,

  • If needWrite is false, we can return without a CAS, so just
    break out of the loop and return the method.
  • Otherwise, we need to update the state object with a CAS. If
    the CAS is successful, break out of the loop and return the
    target function. Otherwise, continue on the next iteration
    of the loop, skipping any other attempts to fetch the method
    later in the loop (useless work, at this point).

4. The value was not in the methodCache, so call the function
findBestMethod() to attempt to find a suitable method based on the
hierarchy and preferences. If it does find us a suitable method,
we now need to cache it ourselves. We create a new state object
with the new method cache and attempt to update the state atom
with a CAS (we definitely need a write here, so no need to check
needWrite at this point).

The one thing that is possibly questionable is the check at this
point to make sure the hierarchy has not been updated since the
beginning of this method. I inserted this here to match the
identical check at the corresponding point in
findAndCacheBestMethod() in the original code. That is also a
second check, since the cache is originally checked for freshness
at the very beginning of getMethod() in the original code. That
initial check happens at the beginning of the loop in the
patch. Given that there is no synchronization with the method
hierarchy, it is not clear to me that this second check is needed,
since we are already proceeding with a snapshot from the beginning
of the loop. Nonetheless, it can't hurt as far as I can tell, it
is how the original code worked, and I assume there was some
reason for that, so I kept the second check.

5. Finally, if findBestMethod() failed to find us a method for the
dispatch value, find the method for the default dispatch value and
return that by breaking out of the loop.

So the organization of getMethod() in the patch is complicated by two
factors: (1) making the retry looping explicit and stackless, (2)
skipping the CAS when we don't need to update state, and (3) skipping
needless work later in the retry loop if we find a value but are
unable to succeed in our attempt to CAS. Invoking a multimethod that
has a stable hierarchy and a populated cache should not even have a
CAS operation (or memory allocation) on this code path, just a cache
lookup after the dispatch value is calculated.

Comment by David Santiago [ 15/Jun/12 4:45 AM ]

I've updated this patch (removing the old version, which is entirely superseded by this one). The actual changes to MultiFn.java are identical (modulo any thing that came through in the rebase), but this newer patch has tests of basic multimethod usage, including defmulti, defmethod, remove-method, prefer-method and usage of these in a hierarchy that updates in a way interleaved with calls.

Comment by David Santiago [ 15/Jun/12 6:38 AM ]

I created a really, really simple benchmark to make sure this was an improvement. The following tests were on a quad-core hyper-threaded 2012 MBP.

With two threads contending for a simple multimethod:
The lock-based multifns run at an average of 606ms, with about 12% user, 15% system CPU at around 150%.
The lockless multifns run at an average of 159ms, with about 25% user, 3% system CPU at around 195%.

With four threads contending for a simple multimethod:
The lock-based multifns run at an average of 1.2s, with about 12% user, 15% system, CPU at around 150%.
The lockless multifns run at an average of 219ms, with about 50% user, 4% system, CPU at around 330%.

You can get the code at https://github.com/davidsantiago/multifn-perf

Comment by David Santiago [ 14/Aug/12 10:02 PM ]

It's been a couple of months, and so I just wanted to check in and see if there was anything else needed to move this along.

Also, Alan Malloy pointed out to me that my benchmarks above did not mention single-threaded performance. I actually wrote this into the tests above, but I neglected to report them at the time. Here are the results on the same machine as above (multithreaded versions are basically the same as the previous comment).

With a single thread performing the same work:
The lock-based multifns run at an average of 142ms.
The lockless multifns run at an average of 115ms.

So the lockless multimethods are still faster even in a single-threaded case, although the speedup is more modest compared to the speedups in the multithreaded cases above. This is not surprising, but it is good to know.

Comment by Stuart Sierra [ 17/Aug/12 2:58 PM ]

Screened. The approach is sound.

I can confirm similar performance measurements using David Santiago's benchmark, compared with Clojure 1.5 master as of commit f5f4faf.

Mean runtime (ms) of a multimethod when called repeatedly from N threads:

|            | N=1 | N=2 | N=4 |
|------------+-----+-----+-----|
| 1.5 master |  80 | 302 | 765 |
| lockless   |  63 |  88 | 125 |

My only concern is that the extra allocations of the State class will create more garbage, but this is probably not significant if we are already using persistent maps. It would be interesting to compare this implementation with one using thread-safe mutable data structures (e.g. ConcurrentHashMap) for the cache.

Comment by David Santiago [ 17/Aug/12 7:05 PM ]

I think your assessment that it's not significant compared to the current implementation using persistent maps is correct. Regarding the extra garbage, note that the new State is only created when the hierarchy has changed or there's a cache miss (related, obviously)... situations where you're already screwed. Then it won't have to happen again for the same method (until another change to the multimethod). So for most code, it won't happen very often.

ConcurrentHashMap might be faster, it'd be interesting to see. My instinct is to keep it as close to being "made out of Clojure" as possible. In fact, it's hard to see why this couldn't be rewritten in Clojure itself some day, as I believe Chas Emerick has suggested. Also, I would point out that two of the three maps are used from the Clojure side in core.clj. I assume they would be happier if they were persistent maps.

Funny story: I was going to point out the parts of the code that were called from the clojure side just now, and alarmingly cannot find two of the functions. I think I must have misplaced them while rewriting the state into an immutable object. Going to attach a new patch with the fix and some tests for it in a few minutes.

Comment by David Santiago [ 17/Aug/12 7:44 PM ]

Latest patch for this issue. Supersedes issue988-lockless-multifn+tests.diff as of 08/17/2012.

Comment by David Santiago [ 17/Aug/12 7:49 PM ]

As promised, I reimplemented those two functions. I also added more multimethod tests to the test suite. The new tests should definitely prevent a similar mistake. While I was at it, I went through core.clj and found all the multimethod API functions I could and ensured that there were at least some basic functionality tests for all of them. The ones I found were: defmulti, defmethod, remove-all-methods, remove-method, prefer-method, methods, get-method, prefers (Some of those already had tests from the earlier version of the patch).

Really sorry about catching this right after you vetted the patch. 12771 test assertions were apparently not affected by prefers and methods ceasing to function, but now there are 12780 to help prevent a similar error. Since you just went through it, I'm leaving the older version of the patch up so you can easily see the difference to what I've added.

Comment by Rich Hickey [ 15/Sep/12 9:05 AM ]

https://github.com/clojure/clojure/commit/83ebf814d5d6663c49c1b2d0d076b57638bff673 should fix these issues. The patch here was too much of a change to properly vet.

If you could though, I'd appreciate a patch with just the multimethod tests.

Comment by Andy Fingerhut [ 15/Sep/12 10:59 AM ]

Patch clj-988-tests-only-patch-v1.txt dated Sep 15 2012 is a subset of David Santiago's
patch issue988-lockless-multifn+tests-120817.diff dated Aug 17 2012. It includes only the tests from that patch. Applies cleanly and passes tests with latest master after Rich's read/write lock change for multimethods was committed.

Comment by Rich Hickey [ 17/Sep/12 9:20 AM ]

tests-only patch ok





[CCACHE-21] LRU and LU caches never evict entries that came in as a seed and are never accessed Created: 14/Mar/12  Updated: 14/Mar/12  Resolved: 14/Mar/12

Status: Resolved
Project: core.cache
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Defect Priority: Major
Reporter: Fogus Assignee: Fogus
Resolution: Completed Votes: 0
Labels: bug, cache, lru, lu


 Description   

If one initializes an LRU or LU cache with seed data and those datum are never touched, then they are never evicted.

  (def C (lru-cache-factory {:a 1, :b 2} :limit 2))
  
  (-> C (assoc :c 3) (assoc :d 4) (assoc :e 5))

You would expect that the cache should contain only :d and :e, but it instead includes :a, :b, :d and :e! The problem is that seeds are never added to the eviction queue.



 Comments   
Comment by Fogus [ 14/Mar/12 8:15 AM ]

Fixed in 5751b7e8d8d2f10c87b8a79c8ed9b0324368514d





[CCACHE-1] Storing falsey value in underlying struct causes failure in get with not-found arg Created: 28/Nov/11  Updated: 30/Nov/11  Resolved: 30/Nov/11

Status: Resolved
Project: core.cache
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Defect Priority: Major
Reporter: Fogus Assignee: Fogus
Resolution: Completed Votes: 0
Labels: associative, bug


 Description   

Cache c seeded with {:a nil} and accessed via (get c :a 42) returns 42 instead of nil. The reason for this is that the map vatAt delegates directly to the lookup protocol function without a has? guard.



 Comments   
Comment by Fogus [ 30/Nov/11 10:57 AM ]

Fixed in https://github.com/clojure/core.cache/commit/7f77aee164d59441caa56979821bae8f64affba7





[ASYNC-63] Variable called 'new' in vector in go block in CLJS causes "Object has no method 'call'" error Created: 07/Apr/14  Updated: 07/Apr/14

Status: Open
Project: core.async
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Defect Priority: Minor
Reporter: James Henderson Assignee: Rich Hickey
Resolution: Unresolved Votes: 0
Labels: bug, cljs
Environment:

ClojureScript 0.0-2202, core.async 0.1.267.0-0d7780-alpha, openjdk 7u51


Attachments: File compiled-cljs.js     File test_cases.clj    

 Description   

I seem to be having trouble with the combination of:

  • a variable named 'new'
  • wrapped in a vector
  • after a <! call in a go block.

Removing any of these conditions seems to work fine.

I've attached a few minimal examples in test_cases.clj and the JavaScript that the first error compiles down to in compiled-cljs.js - the errors occur on line 4 (I think inst_39771 is 21 in this case)

An obvious workaround is not to name the variable 'new'

Please let me know if you need anything more from me, and please go easy on me if this is in the wrong place/badly labelled etc - it's my first Clojure JIRA bug report

Thanks,

James



 Comments   
Comment by James Henderson [ 07/Apr/14 4:07 PM ]

Sorry, just spotted there's a newer release of core.async - I've reproduced this with 0.1.278.0-76b25b-alpha as well.

James





[ASYNC-59] Channel returned by cljs.core.async/map> is missing protocol method Channel.closed? Created: 08/Mar/14  Updated: 08/Mar/14

Status: Open
Project: core.async
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Defect Priority: Minor
Reporter: Kevin Neaton Assignee: Rich Hickey
Resolution: Unresolved Votes: 0
Labels: bug, patch
Environment:

[org.clojure/clojure "1.5.1"]
[org.clojure/clojurescript "0.0-2173"]
[org.clojure/core.async "0.1.278.0-76b25b-alpha"]


Attachments: Text File 0001-Fixed-map-by-including-impl.-for-closed.patch    
Patch: Code

 Description   

E.g.

(let [ch (->> (chan) (map> inc) (filter> even?))]
  (doseq [i (range 10)] (put! ch i)))

When filter> checks to see if the channel returned by map> is closed?, this code fails because the channel returned by map> does not implement the Channel.closed? protocol method.






[ASYNC-48] Recur fails within catch Created: 21/Dec/13  Updated: 25/Dec/13

Status: Open
Project: core.async
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Defect Priority: Major
Reporter: Gerrit Jansen van Vuuren Assignee: Rich Hickey
Resolution: Unresolved Votes: 0
Labels: bug


 Description   

This is related to
http://dev.clojure.org/jira/browse/ASYNC-7

Having a loop in a go block and the recur inside a catch statement causes an IllegalArgumentException.

The code is:

(go
(loop [i 0]
(try
(do
(+ 1 1))
(catch Exception e (do
(prn e)
(recur (inc i)))))))

;; IllegalArgumentException No implementation of method: :emit-instruction of protocol: #'clojure.core.async.impl.ioc-
;; macros/IEmittableInstruction found for class: clojure.core.async.impl.ioc_macros.Jmp clojure.core/-cache-protocol-fn
;;(core_deftype.clj:541)



 Comments   
Comment by Leon Grapenthin [ 25/Dec/13 9:14 AM ]

This doesn't work outside of a go block either.





[ASYNC-29] 50 parallel blocking takes in go-blocks as loop-binding or recur argument break go Created: 28/Oct/13  Updated: 29/Oct/13  Resolved: 29/Oct/13

Status: Resolved
Project: core.async
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Defect Priority: Major
Reporter: Leon Grapenthin Assignee: Rich Hickey
Resolution: Completed Votes: 0
Labels: bug, go, go-macro
Environment:

JVM



 Description   

This problem raises the question whether what the implications are of using <!! and >!! inside of go and whether it is legal.

What if I provide API functions that are using <!! >!! and may be invoked from within go?
Should I then also provide !! and ! versions?

Please evalute this code at the REPL to reproduce the problem: https://www.refheap.com/20225



 Comments   
Comment by Leon Grapenthin [ 29/Oct/13 9:46 AM ]

I'd like to rephrase my question: Do I have to provide {!} and {!!} macros that do the same thing and use {<!} {>!} and {<!!} {>!!} respectively? Would it make sense for core.async to provide a defasync macro that creates those two versions from the same body where you could for example use {<!!!} and {>!!!}, {alts!!!} and so on so that they would be replaced by a postwalk before the macro is defined defined twice with {!} and {!!} appended to the name? Or are there other plans of abstraction? [Quoting symbols because of jira markup]

Comment by Rich Hickey [ 29/Oct/13 9:55 AM ]

You shouldn't be using <!! and >!! in library code. We may at some point be able to detect at runtime their use in go blocks and throw errors, but currently do not.





[ASYNC-20] Case macro in go block ignores default expression Created: 20/Aug/13  Updated: 27/Sep/13  Resolved: 27/Sep/13

Status: Closed
Project: core.async
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Defect Priority: Major
Reporter: Leon Grapenthin Assignee: Timothy Baldridge
Resolution: Completed Votes: 0
Labels: bug, go
Environment:

Clojure 1.5.1 in the JVM, core.async-0.1.0-20130819.220150-69



 Description   

To reproduce the error use this code:
(go (case true
false false
nil))

An IllegalArgumentException will be thrown (as if there was no default expression).
Exception in thread "async-dispatch-46" java.lang.IllegalArgumentException: No matching clause: true



 Comments   
Comment by Timothy Baldridge [ 27/Sep/13 8:34 AM ]

fixed in: https://github.com/clojure/core.async/commit/f9b24552cf4f6b8b86f3377c7b7a42a618a9fd76





[ASYNC-18] CompilerException attempting to perform a transaction inside go block Created: 15/Aug/13  Updated: 16/Aug/13  Resolved: 16/Aug/13

Status: Closed
Project: core.async
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Defect Priority: Major
Reporter: Adam Wittenberg Assignee: Timothy Baldridge
Resolution: Declined Votes: 0
Labels: bug


 Description   

When setting up a transaction inside of a go block, receiving the following error:

CompilerException java.lang.RuntimeException: No such var: clojure.core/runInTransaction, compiling:(NO_SOURCE_PATH:2:8)

(require '[clojure.core.async :as async :refer :all])

(def bar (ref []))
(def c (chan))

(defn foo []
(<!! (go (dosync
(doseq [i (range 10)]
(alter bar conj (<! c)))))))



 Comments   
Comment by Timothy Baldridge [ 16/Aug/13 9:08 AM ]

There are two problems with the example given.

a) dosync wraps the body of the body of the transaction in a fn. Go block translation stops at fn boundaries. The same applies to doseq.

b) The bigger problem is that this example code is incorrect. A transaction body may executed multiple times in that case some messages received from the channel may be dropped.

Closing this issue as the examples are flawed. However I will recommend that you look into doing the takes outside of the transaction, and then using a function to execute the transaction outside the body of a go.





[ALGOM-4] algo.monad state-m fetch-val bug and efficiency issue Created: 08/Sep/12  Updated: 05/Feb/14  Resolved: 05/Feb/14

Status: Closed
Project: algo.monads
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Defect Priority: Minor
Reporter: Sacha De Vos Assignee: Konrad Hinsen
Resolution: Completed Votes: 0
Labels: bug, performance
Environment:

irrelevant



 Description   

;; the bug

(defn fetch-val
"Return a state-monad function that assumes the state to be a map and
returns the value corresponding to the given key. The state is not modified."
[key]
(domonad state-m
[s (fetch-state)]
(key s))) ;; does not work for integer or string keys

;; I propose replacing it with (get s key)

;; the efficiency issue :
;;
;; domonad with monad parameter binds all the monad functions,
;; looking these up in the state-m map on each call
;;
;; solution :

(defn fetch-val
"Return a state-monad function that assumes the state to be a map and
returns the value corresponding to the given key. The state is not modified."
[key]
(fn [s]
[(get s key) s]))

;; - we avoid the monad map lookups
;; - coding style brought up to par with the rest of state-m functions



 Comments   
Comment by Konrad Hinsen [ 05/Feb/14 5:52 AM ]

This was handled long ago: https://github.com/clojure/algo.monads/commit/90909e30965bb59fccc8e527d31f8aaabc9d404b





Generated at Wed Apr 23 17:12:55 CDT 2014 using JIRA 4.4#649-r158309.