Fork me on GitHub

How do people feel about the separate .specs namespace, especially for datastructures? Is it a pattern that’s paid off?

👍 4

doing the same with protocol definitions definitely makes sense, I haven't tried it with specs but I could imagine it having similar advantages


I guess it just feels funny to me to manipulate a datastructure in foo, and then in foo.specs define a bunch of keys in foo as well as the fdefs for foo. I get that the dependency graph works and it can be a forcing function to think about foo more, but it feels a bit like foo.h 😉

Alex Miller (Clojure team)02:11:24

you’re not defining a bunch of keys in foo. You’re defining keys that happen to use the foo qualifier.

Alex Miller (Clojure team)02:11:30

keywords and symbols are not “in” namespaces, they are qualified by names that may also correspond to namespaces


is there a fn for assigning a namespace to a map? something akin to

(into #:person{} {:name "luke"}) ;; => #:person{:name "luke"}


@lwhorton I think you'd need to do a reduce-kv and do (keyword "person" (name k)) on all the keys and reconstruct it.


:person/name is an atomic keyword, as is :name, so merging maps takes the keys as-is.


i had something like that going, just wasn’t sure if there was first class support for it:

(defn assign-namespace [m ns]
    (fn [m k v]
      (let [new-kw (if (and (keyword? k)
                            (not (qualified-keyword? k)))
                     (keyword (name ns) (name k))
        (assoc m new-kw v)))


for comparsion, with Specter:

user=> (setval [MAP-KEYS NAMESPACE] "some-ns" {:a 1 :b 2})
{:some-ns/a 1, :some-ns/b 2}


that doesn’t do the same checks ofc, but that could be added easily 🙂


Do you mean this: #:qualifier{:a 10 :b 5}


Oh, nvm, I see what you're trying to do


yes, but i’m taking data in from an api, converting it to namespaced keys, conforming it, then stuffing it into datomic


You mean not as a literal


@lwhorton This seems to work:

(defn qualify
     [ns m]
     (clojure.edn/read-string (str "#" ns m)))

user=> (qualify :test {:a 10})
#:test{:a 10}


You might have issues if some things in your map can not round-trip over to EDN and back though, like say a Java object

braai engineer09:11:53

Could I extend my Clojure syntax with a data reader literal that expands from #[...] to #(apply vector ...), so that I can write #[(+ % 5) 6] and it would be equivalent to #(vector (+ % 5) 6)? Can't be a macro because it's not following the operational form, but maybe #[ could be start of data reader that discards a trailing ]?

braai engineer09:11:52

Unfortunately when I put #[1 2 3] into REPL, it moans that Reader tag must be a symbol clojure.lang.LispReader$CtorReader.invoke (, but #v[1 2 3] could work. It would be nice to be able to change reader behaviour at runtime without forking in order to support more customisable "DSL reader macros"


Rich actively doesn’t want to expose reader macros, as it will lead to a balkanisation of the language. So my understanding is you’ll never be able to do this.


great now I'm getting perl flashbacks


I assume you are aware [1 2 3] already makes a vector, and this is just an example?

braai engineer09:11:52

Unfortunately when I put #[1 2 3] into REPL, it moans that Reader tag must be a symbol clojure.lang.LispReader$CtorReader.invoke (, but #v[1 2 3] could work. It would be nice to be able to change reader behaviour at runtime without forking in order to support more customisable "DSL reader macros"


My understanding of data readers is that it’s strongly suggested that the literals are namespaced, and unnamespaced literals are reserved for clojure.core. So your example should be: #petrus/v[1 2 3]


But it turns out you can still use unnamespaced data reader symbols, nothing will complain — but it’s frowned upon.


OK, some quick experimentation shows: src/data_readers.clj

{orestis/v orestis/my-vector
 v orestis/my-vector}
(defn my-vector [x]
  (println "Reading" x)
  (conj x "orestis"))
Clojure 1.9.0
user=> #v[(+ % 5) 6]
IllegalStateException Attempting to call unbound fn: #'orestis/my-vector  clojure.lang.Var$Unbound.throwArity (

user=> (require 'orestis)
user=> #v[(+ % 5) 6]
Reading [(+ % 5) 6]
CompilerException java.lang.RuntimeException: Unable to resolve symbol: % in this context, compiling:(NO_SOURCE_PATH:3:4)

user=> #v '[(+ % 5) 6]
Reading (quote [(+ % 5) 6])
CompilerException java.lang.RuntimeException: Unable to resolve symbol: quote in this context, compiling:(NO_SOURCE_PATH:0:0)

user=> #v ['(+ % 5) 6]
Reading [(quote (+ % 5)) 6]
[(+ % 5) 6 "orestis"]

👍 4

Oh wait — of course, the unable to resolve symbol % is because the compiler tries to evaluate whatever the data reader returns.


@petrus for interest what is the use case?


I understand clojure 1.10.0-betaX’s datafy :thumbsup:, but I don’t really get what nav is for… can anyone enlighten me? I think I’m being dumb this morning.


Any Polylith users here? I'm curious if I can use a luminus and swagger project as a polylith base to easily generate a REST service with something like 'lein new luminus +swagger'.


instead of writing a bunch of bespoke ETL code, do pipelines/frameworks already exist which handle the monotony and abstract away the side-effecting? i’m thinking something akin to what an interceptor chain (i.e. pedestal) does for a web stack, but applied to an ETL “pipeline”?


there’s a lot bound up in extracting data from web apis ( all the http error handling cases, for example ), and there’s a lot of places where i want to delay side-effecting so parallelization is easier, but as i write said stack it just feels like this has been written hundreds of times before


@domparry does Dataflow and datasplash fit @lwhorton’s requirement?


I think so. Its based on apache beam.....


It's perfect for the parallelization bit, and we have at least one case that includes a side effect via calling an api during the pipeline.


not sure @sneakypeet, ill take a look though, thanks!


i ran into an odd state last night when working with nrepl and a large amount of files. i want to try and debug the root cause here without doing a “hard reset” on my environment:

clj -A:dev
Exception in thread "main" java.lang.ExceptionInInitializerError
	at clojure.main.<clinit>(
make: *** [dev] Error 1
is there anywhere I should start to dig?


at some point the jvm process died, then any further attempts to use clojure with any deps.edn aliases fails with the above message. i can still run clojure without aliases. i’m not sure if this is some weird .m2 state with deps that built a corrupt classpath (or something, just blind guesses here)


are you on 1.10 @lwhorton?


Check your user.clj for some brokenness or remove it from the classpath. See


clojure isn't successfully loading -- likely your user.clj is the culprit


there is a regression in error printing in this particular case


aha. that was it. not sure where the error is but commenting out everything but the ns declaration brings things back to working.


actually it looks like the issue was that a ns required inside user.clj had a compilation error


yeah any failure to load user.clj in any way (including transitive deps) will cause this. It'll get fixed before 1.10 final.


Does anyone know if there is an obvious choice of library for connecting to a postgres sql database within clojure?


i see quite a few

noisesmith19:11:19 with the postgres jdbc adaptor


the latter is not a clojure specific lib, it's the java lib from postgres


@U051SS2EU thanks, looks just the ticket. Could you please explain the postgres jdbc adaptor part? From here its just a jar file


Do i need to include this jar file as part of my project?


right, it's a dependency that you add, then if you ask for a postgres connection, it is looked up


great, ill look into how to add the jar as a dependency in my leiningen project file, thanks 🙂


it's basically a "dependency injection" thing - you tell jdbc "use the thing called postgres"


it's like any other dep in project.clj


I'm not sure how to specify a local .jar file as a dependency


compared to say something like [org.clojure/java.jdbc "0.7.8"]


[organization/project "version"]


don't use a local jar file, use the maven coordinates - the postgres project offers those


[org.postgresql/postgresql "42.2.5"] looks like the most recent stable


awesome!!! Thank man, its all working


in an emergency you can publish a jar to a private repo, or as a last resort embed the jar in your own artifact, but finding a maven repo with the jar you want is probably going to be the winning option


though with deps.edn you can add a dep to a github repo...


@U46LFMYTD Also, if you have any JDBC/SQL-specific questions, feel free to join #sql and ask there (it's easier for me to see questions asked there as it is lower volume).


@U04V70XH6 got it, thanks! 🙂


p.s. I maintain the Clojure Contrib org.clojure/java.jdbc project, as well as HoneySQL (a composable DSL for SQL).


java.jdbc is working perfectly for me right now, good job


im happy i can create nice applications in clojure so quickly


maybe an #emacs question, but in Emacs, cider-grimoire is producing a 'Bad url: /' error, thoughts?


I don't know what it should produce, but would really like the clojure grimoire usage examples right in emacs.


Grimoire hasn’t seen a code change or an outage over 1min in several months - is perfectly stable. Not sure about the CIDER client. I know there’ve been noises to work on it recently.


I'm assuming it's something wrong with my setup.


didn't know about cool resource!


hmm... I think what I really wanted was the community clojure docs inside of emacs... was misremembering the name.


suppose i have an iterative algorithm , and I compute a lazy seq with (iterate update-fn initial-value). I remember seeing a function somewhere called something like "fixed point" which would iterate until a convergence predicate is satisfied and return the next value. Does anyone remember what this function is called?


do you actually care about the intermediate values?


if you don't, then don't use iterate (which builds a seq of intermediate values that you don't need), if you do might be interesting