Fork me on GitHub
#clojure
<
2017-12-10
>
qqq04:12:54

Is there a standard way of storing a Directed Acyclic Graph in an Entity-Attribute-Value store ?

noisesmith04:12:53

an adjacency list would be a simple way to do it

qqq04:12:35

do you store the child list as a single vector, and when you add/del one child, overwrite the entire vector ?

noisesmith04:12:31

that's an implementation decision, the totally denormalized version would be to make each child relation a separate entry

matheusashton04:12:30

hello every one, I'm starting to learn clojure (my first real functional language) after doing some functional JS

matheusashton04:12:12

do you recomend any sql abstractions to use in my project with postgres?

matheusashton04:12:07

I saw korma, but looks like it is abandoned, and I didn't like the yesql and hugsql approach

seancorfield05:12:19

@matheusashton I'd recommend HoneySQL which lets you compose query fragments, on top of clojure.java.jdbc which is the Clojure Contrib library for JDBC operations.

seancorfield05:12:18

Also @matheusashton since you're new to Clojure and interested in SQL, I'll recommend the #beginners and #sql channels.

qqq05:12:46

Is there a clojure tool that will take a codebase, and show me all defns / defs taht are not used? It can assume I'm not doing something weird via string->symbol->resolve-in-ns

qqq05:12:01

is boot-check the closest for boot ?

qqq05:12:09

yagn ieems to depend on lein

qqq05:12:37

$ boot check/with-yagni latest report from yagni.... [You Rock!]

seancorfield05:12:37

Yes, boot-check runs Yagni

siva07:12:24

Gorilla REPL crashes every time when I use it on my Mac.

siva07:12:34

Does anyone else have the same problem?

New To Clojure07:12:30

@konanki.sivaram Use :plugins [[lein-gorilla "0.4.0"]] instead of :plugins [lein-gorilla "0.4.0"]

spangler08:12:51

How do people feel about doing things like http requests inside of dosync, for example?

spangler08:12:46

I find myself in a situation where I am receiving many (kafka) messages asynchronously, any of which triggers a particular http call. But I only want to make that call once.

spangler08:12:53

So, I receive the message, dosync to assoc something under a key and trigger a request only if that key doesn’t exist yet

spangler08:12:08

Can I do this without triggering a request inside the dosync?

spangler08:12:42

Ah, dosync may retry anyway, so that doesn’t work

spangler08:12:22

Hmmm, how do I avoid the race condition here: deref to see if key exists, if not dosync to add key and then (at some point) trigger request

spangler08:12:31

Multiple threads could deref and see the missing key, both add the key and trigger request, unless those are somehow a single transaction

spangler08:12:36

I guess in a single dosync it can check the key and add it in, no need for a separate deref

spangler08:12:03

the question is when the request is triggered to guarantee it only happens once

spangler08:12:14

Maybe this is finally a use case for agents

spangler08:12:45

Ah that is actually a quite elegant solution

spangler08:12:16

I finally understand what agents are for

mbjarland08:12:58

generic question. Say I’m building a library and in the default namespace I need an instance of a parser. I will need this parser for every call into the library. I could have a (def parser ...) directly in the main namespace of the library, but for some fuzzy reason this makes me feel slightly dirty and I would feel more pure with lets say a memoized function returning the parser. Opinions? Is it ok and good style to just (def things or is it indeed somehow better to keep things in functions? One difference I see is that the def gets potentially ’unnecessarily` evaluated on load. The user of my lib might elect to not call any functions in my namespace etc...

New To Clojure09:12:15

@mbjarland Could use https://github.com/stuartsierra/component to avoid re-defining global variables on load.

New To Clojure09:12:44

That's what was recommended to me instead of global atoms

qqq10:12:53

cloc dumps ttl lines, ttl white space, ttl comments is there some other tool that will dump ttl + also summaries for each file ?

schmee12:12:35

cloc --by-file?

schmee12:12:12

tokei -f gets you a per-file summary

qqq18:12:07

@U3L6TFEJF: cloc --by-file is awesome; thanks!

qqq10:12:25

i.e. I want a table of four columns: file name, comments, whitespace, line-count // though two clumns of just filename and line-count is fine, if it's better than wc -l

siva12:12:51

I do that. The repl starts and works for some time and then it stops working. Now I don’t seem to have that problem.

sova-soars-the-sora17:12:26

Good Morning Everybody 🙂

qqq19:12:55

besides fn -> \lambda is there a standard set of "prettify these clojure keyword" setup ?

vemv19:12:07

some setups also prettify #{}

ido19:12:50

Sorry guys but I still cannot understand what those cmd line tool just released https://clojure.org/reference/deps_and_cli here are for. What gap did I have that they are trying to fill?

noisesmith19:12:28

they are for people who have never tried clojure and want something minimal to fire it up

ido19:12:26

@alexmiller pointed me to https://clojure.org/guides/deps_and_cli. But if I have leiningen, what do i need those for?

noisesmith19:12:37

you don't, and it's not for you

noisesmith19:12:22

it's for people who haven't used clojure and want a simple way to fire up a clojure repl. Or people who want something ligher weight / more targetted than lein or boot for running a repl.

dominicm19:12:41

I also get the impression that they provide an official solution from the clojure team for launching a clojure repl. Previously it was sufficiently simple to not matter.

noisesmith19:12:49

in the past we could use clojure.jar for that, clojure.jar no longer runs standalone because of clojure.spec.alpha

ido19:12:43

Like people have a python repl

noisesmith19:12:55

right, python just runs as a standalone command

qqq19:12:42

dumb question: why does clojure.spec.alpha prevent clojure.jar from being standalone ?

noisesmith19:12:01

because it's not part of clojure.core, it's a separate artifact

noisesmith19:12:17

so you need to construct a classpath with at least three artifacts to make it work iirc

qqq19:12:03

you can't just 'stuff it in the *.jar" ? I thought jars were just zips/tar files and you could throw stuff into it

dominicm19:12:27

@qqq That leads to a classpath conflicts.

ido19:12:33

And tools.deps.alpha?

noisesmith19:12:51

deps.alpha knows how to resolve deps, that is why it is there

noisesmith19:12:07

it helps construct a classpath and download jars that you might need

ido19:12:17

Isn't that what mvn is for?

noisesmith19:12:30

but unlike lein or boot it isn't for packaging or deploying and doesn't have tooling for plugins

noisesmith19:12:51

yes, you could use mvn for that, but then you need an mvn command for running clojure

noisesmith19:12:18

and mvn is also a packaging and plugin and deployment tool like leiningen or boot are

ido19:12:02

Thanks @noisesmith I was afraid I am missing something here.

qqq19:12:56

is there a builtin for (magic [f1 f2 f3 f4] [x1 x2 x3 x4]) => [(f1 x1) (f2 x2) (f3 x3) (f4 x4)] }

noisesmith19:12:11

the closest thing would be (map #(%1 %2) ...)

qqq20:12:49

(def a-z 
  (mapv int->char  (range (char->int \a) (inc (char->int \z))))) 
(def letters-lower "abcdefghijklmnopqrstuvwxyz")
besides listing out the answer, is there a way to make the def of a-z shorter ?

vemv21:12:12

Is there something like (binding [*ns* 'afsdfsd] ::a) but that works? ('work' -> result in :afsdfsd/a)

bronsa21:12:49

read time happens too early for that to work

vemv21:12:37

yeah, guessed so... thanks for the confirmation! useful coming from tools.analyzer author 🙂

Bravi22:12:56

hey everyone, how can I lowercase the keys in map? 😄 I have the following:

{:CurrentGame 1
 :Score 30}
and I want to lowercase the keywords

Bravi22:12:46

this response comes from the server as json and when it is converted from json using clj-http, that’s how it shows up

Bravi22:12:13

solved it like this

(defn lower-case-keys [result]
  (if (map? result)
    (into {}
          (for [[k v] result]
            [(keyword (lower-case (name k))) v]))
    (map lower-case-keys result)))

gklijs22:12:35

(reduce-kv #(assoc %1 (keyword (lower-case ( name %2))) %3) {} json-response) something this

Bravi22:12:01

I like that one too!

Bravi22:12:22

I just needed my fn to support vectors / lists too

Bravi22:12:29

didn’t know about reduce-kv, thanks!

joelsanchez23:12:10

personally I like to use my own syntax sugar

joelsanchez23:12:13

(defn map-keys [f m]
  (->> m
       (map (fn [[k v]]
              [(f k) v]))
       (into {})))

(defn map-vals [f m]
  (->> m
       (map (fn [[k v]]
              [k (f v)]))
       (into {})))

nathanmarz23:12:55

@bravilogy with specter: (transform [MAP-KEYS NAME] clojure.string/lower-case m)

nathanmarz23:12:10

also does not change the type of the map and much higher performance than other approaches, especially for small maps

Chris O’Donnell23:12:55

you can also do it with transducers and avoid creating the intermediate seq like this @bravilogy

(defn lower-case-keys [m]
  (into {} (map (fn [[k v]] [(-> k name lower-case keyword) v])) m))