Fork me on GitHub

Is there a feature request for named protocol impls? Currently extend-protocol-defined functions look like this in the stacktrace:

at app.core$eval3547$fn__3548.invoke(core.clj:23)
	at app.core$eval3522$fn__3523$G__3513__3532.invoke(core.clj:14)
Needless to say these aren't exactly descriptive. Not to mention the lines it refers to are where extend-protocol and defprotocol were called, not where the function definition is. I'd hope for something like app.core/MyProtocol/IfaceImplemented/function_name_1234 with the line number where the "offending" piece of code is, not the definition.


I don't know, but is where you want to look for one. And if you don't find one, create one their, this would be a nice improvement

Alex Miller (Clojure team)03:11:56

without thinking about it a lot, I think this is a lot more complicated than it appears. perfectly fine to file a request at ask.clojure though


How does (fn foo [] "something") work? Just a change to that would probably help, if it just did: at app.core$eval3547$Protocol_function-name__1234 I think that would already help, or even if just function name


I'll come back after a bit more debugging \


Getting rid of the eval or fixing the line numbers was beyond me, but I could improve it a little. My logs are now like this:

at app.core$eval3965$ProtocolName__FnName__3966.invoke(core.clj:23)
at app.core$eval3940$ProtocolName3932__3941$__FnName3930__3950.invoke(core.clj:14)
Is this something that could make it into core?

Alex Miller (Clojure team)05:11:26

I can’t answer that without doing a lot more work

👍 3
Alex Miller (Clojure team)05:11:59

The way to start is to put a request on

👍 3

you can use extend

👎 3

user=> (defprotocol p (f [_]))
user=> (extend String p {:f (fn string-f [_] (throw (ex-info "" {})))})
user=> (f "")
Execution error (ExceptionInfo) at user/eval233$string-f (REPL:1).

Daniel Stephens12:11:02

Is it documented anywhere how edn/read-string deals with multiple forms? From testing it seems it just ignores anything past a valid first form, regardless of validity. Is this behaviour something that can be relied upon?

Daniel Stephens12:11:46

I read through for a while but I might have missed something


> Reading multiple EDN values from stdin


(replace stdin with any other reader in your program)

Daniel Stephens12:11:00

thanks, that's interesting, so to read multiples from a string you would first turn it into a stream? At the moment I'm more hoping just to clarify from a security point of view that all further forms are just completely ignored since I currently just need the first form.


yes, you can rely on that: > Reads one object from the string s.

🎉 3

With edn/read you can read as many objects as you want from a given reader.

👍 3
Daniel Stephens12:11:23

Oh gah, my bad, I interpreted object a bit more vaguely than is intended!

Daniel Stephens12:11:50

thanks for the help 🙂

👍 3

Has anyone successfully gotten a cloud provider CI/CD to work with a Luminus template project?


I am not using system or anything similar


but using the general design pattern of starting/stopping all stateful stuff in one chunk has been enlightening


(defn create-chat-subsystem
  "Creates an object that holds the info required to manage
  the chat subsystem, including sending notifications to
  users when messages are sent."
  [db ^JedisPool redis-client-pool]
  (let [;; Map of user-id to callbacks to call when a
        ;; new message comes through for them.
        connections (atom {})
        subsystem {::connections connections
                   ;; Objects needed to manage subscribing to redis
                   ;; for messages posted on other nodes.
                   ::redis-client (.getResource redis-client-pool)
                   ::redis-pub-sub (chat-messages-listener db connections)
                   ::subscription-executor (Executors/newSingleThreadExecutor
                                             (-> (BasicThreadFactory$Builder.)
                                                 (.namingPattern "chat-subsystem-%s")
    (.submit (::subscription-executor subsystem)
             (reify Runnable
               (run [_]
                   (.psubscribe (::redis-client subsystem)
                                (::redis-pub-sub subsystem)
                                (into-array [(message-key "*" "*")]))))))


and designing complex stuff like this finally feels tenable


so thanks to just the community at large for emphasizing non-global-ness and managing stateful components


has anyone seen this issue? we're using CLI/deps and trying to download dependencies results in these errors:


Downloading: metosin/ring-swagger-ui/2.2.10/ring-swagger-ui-2.2.10.pom from central
Downloading: metosin/ring-http-response/0.9.1/ring-http-response-0.9.1.pom from central
Downloading: cprop/cprop/0.1.17/cprop-0.1.17.pom from central
Download corrupted: Checksum validation failed, expected <html><head><meta but is e77f06aade54d598b1bbbae2b323931860869c21
Download corrupted: Checksum validation failed, expected <html><head><meta but is 6ecc4f0b6bce542e93079bf778210431a6cff9c6
Download corrupted: Checksum validation failed, expected <html><head><meta but is b40aeb79526974d53f99da42b38dea46fffe1ee6
Download corrupted: Checksum validation failed, expected <html><head><meta but is 60283f999a6296706d4595f38a1502b2e6e2ae44


for pretty much every package


clean install of clojure still has this issue


My first guess would be that it's an HTTP proxy issue

Alex Miller (Clojure team)20:11:31

you've got bad downloads in your ~/.m2/repository

Alex Miller (Clojure team)20:11:17

this can be the result of a lot of different issues but maven will sometimes download an html error page and save it as a jar/etc

Alex Miller (Clojure team)20:11:08

you could either rm ~/.m2/repository or maybe more selectively remove parts of it to fix

Alex Miller (Clojure team)20:11:16

after that you, should use clj -Sforce to force a re-download of all the deps and compute a fresh classpath


Will that work with loading CIDER as well?

Alex Miller (Clojure team)03:11:43

sorry, not sure what you're asking, sorry


I’ve always used lein with just a little exposure to clj tools. So now that I’m starting CIDER on a clj tools project and running into the same error @U0ELT5ZDE mentioned, I’m not sure how to solve it. I’m going to try clearing m2 again and cross my fingers…..


clj starts fine from any other directory, but in the project, it has the same ‘download corrupted’ and ‘file not found exception’.


@alexmiller thanks, I tried doing that


weird thing is that only one computer has this issue


both clean installs


nuked the repositories for both, brew reinstalled clojure, etc,

Alex Miller (Clojure team)21:11:45

have you tracked down the file in your repo that's actually an html page and looked at it?

Alex Miller (Clojure team)21:11:02

from the error it looks like it's an .asc checksum file

Alex Miller (Clojure team)21:11:33

probably something in the last dep you downloaded if you've got a fresh repo

Alex Miller (Clojure team)21:11:28

using -Sthreads 1 might help ensure serializability of the log messages too


there is an interesting test failure, it seems the sort fn is returning strings in the wrong order -

(is (= '("xd507n6mE"
             (sort #(compare %2 %1) '("xd507n6mE"
the sorted coll below was retrieved from postgresql -
I am trying to test if postgres returned a sorted coll, for that I was running a sort on the returned coll, and interestingly the manual sort returns an unsorted coll !


is there a question here? lots of stuff going on here and not sure what you're looking for


yup my sort is failing, so trying to understand why ...


maybe the above is more explanatory


This is the definition of lexicographic ordering. If two strings are different, then either they have different characters at some index that is a valid index for both strings, or their lengths are different, or both. If they have different characters at one or more index positions, let k be the smallest such index; then the string whose character at position k has the smaller value, as determined by using the < operator, lexicographically precedes the other string. In this case, compareTo returns the difference of the two character values at position k in the two string -- that is, the value: this.charAt(k)-anotherString.charAt(k) If there is no index position at which they differ, then the shorter string lexicographically precedes the longer string. In this case, compareTo returns the difference of the lengths of the strings -- that is, the value: this.length()-anotherString.length() For finer-grained String comparison, refer to Collator.


how did you come up with your expectation?


ah, you want a case insensitive comparison?


your fundamental issue is that you don't like that (compare "c" "B") is positive


(compare "a" "b") is -1 (a comes before b) but (compare "a" "B") is positive, (a comes after B)


aah got you ... its the case sensitivity that is causing the problem


you could lower-case in the compare


(.compareToIgnoreCase "a" "B")


(sort #(.compareToIgnoreCase %2 %1)


(sort-by string/lower-case ...)


will also work