Fork me on GitHub
#beginners
<
2018-02-20
>
fmn00:02:04

@lee.justin.m Sorry for not being clear. I meant when using the library https://github.com/tolitius/mount to manage state, we can use the provided macro defstate to manage states. Apparently I have a problem where some of the states started not in order and some of them started multiple times when used in cljs.

justinlee00:02:57

Oh I didn’t know about that library.

Henry00:02:52

can I use an atom to store a string and then swap it like so?

(def some-string (atom ""))

(swap! some-string "Some new String")

Henry00:02:02

Or rather … why dioesn’t this work?

mfikes00:02:21

Perhaps you are looking for reset!

Henry00:02:35

why is that?

mfikes00:02:20

Well, reset! takes a value and sets the atom to have that value

Henry00:02:36

ahhh now i understand swap 😄

Henry00:02:39

thank you

mfikes00:02:10

Otherwise, if you wanted to use swap! you could do something like (swap! some-string (constantly "foo"))

arrdem00:02:40

swap! is for altering the value by applying a function. reset! is just swap! (constantly v)

mfikes00:02:47

The important bit is that swap! takes an update fn while reset! dispenses with that and takes a value

Henry00:02:00

yup just made click 🙂

Henry00:02:04

thanks a lot

hawari05:02:41

Hi everyone, I want to make sure, is there going to be a significant performance hit if I have a function that structured like this?

(defn retrieve-entity
  [id & [{:keys [include-detail?]}]]
  (let [main-entity (retrieve-from-db id)
        hydrate-details #(assoc % :minor-entity (retrieve-by-parent (:minor-id main-entity)))]
    (cond-> main-entity
      include-detail? hydrate-details)))

hawari05:02:19

Do I better off to create a separate function for hydrate-details with defn?

andy.fingerhut05:02:00

I haven't done any measurements on that recently, but am not aware of any reason why having #(...) or (fn [...] ...) inside of one function is slower, vs. using defn at the top level earlier in the file.

andy.fingerhut05:02:05

There are multiple places in Clojure core library code that use functions defined inside of other functions like that, including ones considered performance-sensitive.

hawari06:02:27

I see, glad to know that I don't have to refactor it, thank you @andy.fingerhut

hawari11:02:17

Hi everyone, how can I use map only to a hash-map values? For example if I have

{:first [1 2 3]
 :second [4 5 6]}
and I map the values with function inc, I want the result to be
{:first [2 3 4]
 :second [5 6 7]}

sundarj16:02:52

another approach, just for fun:

user=> (into {} (map (juxt key (comp str val)) {:first [1 2 3]}))
{:first "[1 2 3]"}

andy.fingerhut11:02:38

So there are multiple variations of a function called "map-vals" that you can copy and use (or use a library like 'medley' that defines it): https://github.com/weavejester/medley

andy.fingerhut11:02:11

Once you have map-vals, you can call it like this to achieve the effect you ask for: (map-vals #(mapv inc %) d1)

andy.fingerhut11:02:43

(mapv inc [1 2 3]) gives you [2 3 4]

xtreak2911:02:49

You can find some approaches here : https://stackoverflow.com/questions/1676891/mapping-a-function-on-the-values-of-a-map-in-clojure

(let [foo {:first [1 2 3]
           :second [1 2 3]}]
  (into {} (for [[k v] foo] [k (mapv inc v)])))
I hope map-vals is added to the core : https://dev.clojure.org/jira/browse/CLJ-1959

schmee11:02:58

if this is something you find yourself doing frequently, I recommend Specter: https://github.com/nathanmarz/specter

schmee11:02:40

your example would be (transform [MAP-VALS ALL] inc your-map)

hawari11:02:56

whoa, thanks a lot guys! I'll look into it

hawari11:02:43

I've looked into medley before, think I'll just use that, as it's not something that I'll do frequently

Peter Wilkins11:02:49

(def x [{:foo 2 :bar 11}
        {:bar 99 :foo 1}
        {:bar 55 :foo 2}
        {:foo 1 :bar 77}])

;sort by :foo, and where :foo is equal, sort by :bar
(sort-by (juxt :foo :bar) x)
;=>({:foo 1, :bar 77} {:bar 99, :foo 1} {:foo 2, :bar 11} {:bar 55, :foo 2})

Peter Wilkins12:02:08

how to sort high to low on :foo? with juxt or comp? I can't figure out how to slip the comparator in?

(sort-by (juxt (partial :foo >) :bar) x)
I get a npe.

Peter Wilkins12:02:15

(->> m
  (sort-by (comp (partial :totalAudienceSize >) :catch-all)
  ))
doesn't order correctly

rauh12:02:09

@poppetew

(fn [{:keys [foo bar]}]
             [(- foo) (- bar)])

rauh12:02:18

Or: (sort-by (juxt :foo :bar) (comp - compare) x)

Peter Wilkins12:02:43

I get it eventually - thanks. (apply brain coffee)

timo14:02:22

I am having this issue as well with env vars that getting loaded but are not available when referencing env in another namespace. Anyone knows what's the problem? Thanks!

timo14:02:14

This problem actually occurred after a lein uberjar

Will15:02:21

If I have a map like this {:a 1 :c 2 :d 3 :e 4} with 10 more key value pairs , Is there a simpler way that takes less code to return a map with all of the keys besides one other than select-keys?

bronsa15:02:30

(dissoc {:a 1 :b 2} :b) -> {:a 1}

dpsutton15:02:34

also, it can take multiple keys if you need to dissoc a few (dissoc {:a 1 :b 2 :c 3 :d 4} :a :b) => {:c 3, :d 4}

Will15:02:27

That’s exactly what I needed! thanks @dpsutton @bronsa

Will16:02:08

Is there a library to convert the keys in a map from camelcase to underscores?

bronsa16:02:28

yes but don’t do that

Will16:02:45

how come?

bronsa16:02:13

because doing key conversion often turns out to be more pain than it’s worth

bronsa16:02:29

if you really need to, use that

bronsa16:02:38

but I would urge you to consider if you need to

bronsa16:02:20

same as doing string -> keyword conversion

Will16:02:34

Thank you, the reason I need to convert is so I can insert my map straight into the database rather than having to create another map with each column

bronsa16:02:01

and why can’t you use in your app keys with the same casing as in your db?

bronsa16:02:08

that is what I’m suggesting

Will16:02:18

The object is coming from java 😞

bronsa16:02:29

fair enough then

noisesmith16:02:47

@josmith2016 this might just be common sense, but I find that the rules for data conversions that work best are: 1) don’t convert unless forced to 2) convert at a boundary between systems when forced to

noisesmith17:02:21

if it’s coming from java, sadly the “boundary” might be fuzzy, since interop is so trivial - so maybe the database layer boundary is a better place for the conversion

Will19:02:49

Does anybody know how to get an sql timestamp from a string using the clojure.java-time library?

Will20:02:54

I’m getting this error Text '2018-02-19 18:20:25.355' could not be parsed at index 10 when trying to convert it with this piece of code (jt/sql-timestamp (:date receipt)) Where (:date receipt) = 2018-02-19 18:20:25.355

seancorfield20:02:33

@josmith2016 That's because the string you are trying to parse is not in the default ISO format that Java Time expects. You'll need to construct an appropriate formatter and do the parsing directly (and then have clojure.java-time convert it to sql-timestamp).

seancorfield20:02:53

Actually, I think a simpler solution will be to replace that space with T and then it will parse automatically (jt/sql-timestamp (clojure.string/replace (:date receipt) " " "T"))

seancorfield20:02:17

That format -- with a T separating date and time instead of a space -- is a standard ISO format @josmith2016

Will21:02:13

Say I don't have my string in that format. Would I want to create the formatter using clojure objects and methods or using Java classes and methods @seancorfield

seancorfield21:02:02

You can create a formatter (using jt/formatter) and then jt/parse your string using it. You probably want to read the Java Time documentation for details of the formatter patterns https://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.html @josmith2016