Fork me on GitHub
#clojure
<
2018-11-08
>
arrdem00:11:46

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

👍 4
noisesmith00:11:28

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

arrdem01:11:11

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

4
lwhorton05:11:11

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

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

seancorfield05:11:40

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

seancorfield05:11:44

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

lwhorton06:11:31

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

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

schmee06:11:31

for comparsion, with Specter:

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

schmee06:11:18

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

didibus06:11:05

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

didibus06:11:56

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

lwhorton06:11:01

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

didibus06:11:02

You mean not as a literal

4
didibus06:11:21

@lwhorton This seems to work:

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

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

didibus06:11:28

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

Petrus Theron09: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 ]?

Petrus Theron09: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 (LispReader.java:1406), 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"

rickmoynihan13:11:35

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.

deliciousowl14:11:35

great now I'm getting perl flashbacks

noisesmith18:11:09

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

Petrus Theron09: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 (LispReader.java:1406), 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"

orestis09:11:27

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]

orestis09:11:50

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

orestis09:11:20

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

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

user=> (require 'orestis)
nil
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
orestis09:11:12

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

sneakypeet12:11:40

@petrus for interest what is the use case?

rickmoynihan13:11:58

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.

macrobartfast14:11:28

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'.

lwhorton16:11:04

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”?

lwhorton16:11:02

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

sneakypeet16:11:52

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

domparry17:11:13

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

domparry17:11:31

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.

lwhorton17:11:59

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

lwhorton18:11:22

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>(main.java:20)
make: *** [dev] Error 1
is there anywhere I should start to dig?

lwhorton18:11:17

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)

ghadi18:11:27

are you on 1.10 @lwhorton?

ghadi18:11:00

Check your user.clj for some brokenness or remove it from the classpath. See https://dev.clojure.org/jira/browse/CLJ-2427

ghadi18:11:22

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

ghadi18:11:41

there is a regression in error printing in this particular case

lwhorton18:11:49

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

lwhorton18:11:40

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

ghadi18:11:20

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

michaellindon19:11:30

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

michaellindon19:11:50

i see quite a few

noisesmith19:11:19

clojure.java.jdbc with the postgres jdbc adaptor

noisesmith19:11:36

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

michaellindon19:11:32

@U051SS2EU thanks, clojure.java.jdbc looks just the ticket. Could you please explain the postgres jdbc adaptor part? From here its just a jar file https://jdbc.postgresql.org/download.html

michaellindon19:11:12

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

noisesmith19:11:16

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

michaellindon19:11:41

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

noisesmith19:11:43

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

noisesmith19:11:58

it's like any other dep in project.clj

michaellindon19:11:59

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

michaellindon19:11:16

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

noisesmith19:11:53

[organization/project "version"]

noisesmith19:11:21

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

noisesmith19:11:37

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

michaellindon19:11:47

awesome!!! Thank man, its all working

noisesmith19:11:02

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

noisesmith19:11:14

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

seancorfield19:11:02

@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).

michaellindon19:11:32

@U04V70XH6 got it, thanks! 🙂

seancorfield19:11:46

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

michaellindon19:11:08

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

michaellindon19:11:27

im happy i can create nice applications in clojure so quickly

macrobartfast19:11:23

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

macrobartfast19:11:09

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

arrdem19:11:36

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

macrobartfast19:11:38

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

macrobartfast19:11:12

didn't know about conj.io... cool resource!

macrobartfast19:11:27

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

michaellindon19:11:31

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?

hiredman20:11:23

do you actually care about the intermediate values?

hiredman20:11:28

if you don't, then don't use iterate (which builds a seq of intermediate values that you don't need), if you do https://dev.clojure.org/jira/browse/CLJ-1906 might be interesting