Fork me on GitHub
#clojure
<
2019-03-27
>
robertfw00:03:26

I'm tearing my hair out trying to figure out why com.stuartsierra.component isn't shutting down one of my components. I have other components that shut down just fine. I can't spot any material difference in this one. I'm about to start trying to expose some details from within component itself but thought I would ask here if there are any common tripping hazards I might not be thinking of

noisesmith00:03:36

you need to return a valid component map from both startup and teardown of each component

noisesmith00:03:48

that's the most common reason that teardowns get short-circuited

robertfw00:03:35

yeah that looks fine. everything starts up properly and inspecting the component in the system it's all well and good

robertfw00:03:09

i've got a log statement (and heck, a println, to rule out a logging issue) on the first line of the (stop) function and that never gets called

hiredman00:03:27

most likely you do some operation on the record that turns it in to a normal map

hiredman00:03:46

in which case the nop stop function that component defines for Object is called

hiredman00:03:00

(some operation in your start function)

hiredman00:03:27

a common thing that does that is dissoc'ing a field a record is defined as having, but here are other things that do it too

robertfw00:03:40

I was just about to ask...does dissoc do it?

hiredman00:03:22

user=> (defrecord Foo [a])
user.Foo
user=> (assoc (->Foo {}) :a 1 :b 2)
#user.Foo{:a 1, :b 2}
user=> (dissoc (assoc (->Foo {}) :a 1 :b 2) :b)
#user.Foo{:a 1}
user=> (dissoc (assoc (->Foo {}) :a 1 :b 2) :a)
{:b 2}
user=> 

robertfw00:03:32

well, you saved my considerable head of hair from losing (any more) hairs

robertfw00:03:37

have been tearing them out for the past hour

yuhan00:03:53

Why does group-by return a map of vectors instead of respecting the original collection type?

yuhan00:03:45

eg. I would expect (group-by even? #{1 2 3 4 5}) to return a map of hash sets

yuhan00:03:47

it's easy enough to roll my own version which does that:

(defn group-by*
  "Like `group-by` but preserves the original collection type"
  [f coll]
  (let [emp (empty coll)]
    (persistent!
      (reduce
        (fn [ret x]
          (let [k (f x)]
            (assoc! ret k (conj (get ret k emp) x))))
        (transient {}) coll))))

yuhan00:03:55

but I'm wondering why the default implementation does it that way

akiel12:03:10

Is there a way to control the name of a reify class? I like to have that for profiling to be able to see which implementation I have in the profiler.

akiel12:03:34

ok but it would be helpful.

akiel12:03:24

By the way: Using ZGC in Java 12 was not suchessful for my compiled code. I still had 5 sec pauses. So I droped the idea to evaluate code during runtime. Now I just use good old protocol dispatch for my expressions. The protocol dispatch is so fast that it’s not slower than directly compiled code.

stathissideris12:03:56

what do you prefer for the name of a http://micrometer.io wrapper: clj-micrometer or micrometer-clj?

robertfw17:03:22

I feel like I see many more clj-* names than *-clj

Alex Miller (Clojure team)12:03:59

reify needs to gen a unique classes every time so you wouldn't want to force a particular name

Alex Miller (Clojure team)12:03:55

protocol dispatch is designed for speed, for sure

akiel13:03:52

but a named prefix like in (fn my-fn [x]) would be possible?

Alex Miller (Clojure team)13:03:27

you could just use a deftype?

akiel13:03:34

yes I could. I also could use defrecord. But for me the code is more readable using reify.

bronsa13:03:56

then you can implement your own named-reify macro on top of deftype and new

akiel13:03:19

it’s ok. I’m not totally lost in the profiler. I only liked to ask if I was missing something. But thanks.

Henry14:03:17

https://medium.com/dartlang/making-dart-a-better-language-for-ui-f1ccaf9f546c is there a way to do something like this in clojure? tldr: interpolate values into a list like so:

[:item-1
 (add-when condition?
   :optional-item-1
   :optional-item-2)
 :item-2]

Henry14:03:06

assuming its impossible as macros can't expand to multiple expressions as far as I know?

danielneal14:03:08

I use (concat [:item-1] (when condition? [:item-3 :item-4]) [:item5])

4
danielneal14:03:30

you can do stuff with macros and splicing but its unidiomatic imo

bronsa14:03:15

s/macros/syntax-quote/

bronsa14:03:51

less performant but I also like

`[:item-1 ~@(when cond? [:item-3 :item-4]) :item-5]

danielneal14:03:00

^ like this guy 😛

akiel14:03:15

(cond-> [:item-1] 
  condition? 
  (conj :optional-item-1 :optional-item-2)
  :always
  (conj :item-2))

Henry14:03:28

going to give the concat a go for now, seems reasonably nice

stathissideris14:03:29

I still don’t understand why clojure.datafy.nav needs both k and v

ghadi15:03:53

to transform v

ghadi15:03:06

rather, to return a transformed v

jsabeaudry17:03:25

java-time/interval is in the doc but somehow it looks like it can’t be found (I’m on clojure 1.10)

jsabeaudry17:03:27

java-time/minus can be found without problem

noisesmith17:03:09

@jsabeaudry781 surely this would be a question of your java-time version, and not your clojure version?

Lennart Buit17:03:06

is that clojure.java-time-the-library?

Lennart Buit17:03:33

In that case, you will need to add https://www.threeten.org/threeten-extra/ before you get interval’s

4
👍 4
Lennart Buit17:03:41

(they didn’t make it into java.time.* but were included in an “extra” library made available by the original proposers of the java.time rework)

jsabeaudry17:03:51

Thanks for that! Somehow I missed it in the doc

Lennart Buit17:03:51

Yeah, I missed it the first few times too

Lennart Buit17:03:31

Also, I like that clojure.java-time is correct and such, but it doesn’t feel very idiomatic to use from clojure. I looked at juxt/tick, but thats just not complete and/or mature…

Lennart Buit17:03:18

are there other libraries I should be looking at? That are both correct and have nice clojure APIs?

ghadi17:03:21

My 2c: learn the java time api

10
ghadi18:03:27

All the clojure wrapper libraries get some things fundamentally wrong

dominicm18:03:59

Have you evaluated tick at all? I think it has a novel twist

ghadi18:03:32

what's the twist @U09LZR36F?

dominicm18:03:45

It works in clojurescript

dominicm18:03:21

I can't speak too much about the design, as I've just been peripheral to it.

Lennart Buit18:03:58

(btw, not trying to offend, tick just doesn’t feel “done” to me just yet)

ghadi18:03:19

java.time fits all my needs

dominicm18:03:16

Tick is trying to stick to the java.time api.

dominicm18:03:52

@UDF11HLKC we're using it in production with several clients, but you're right that there's still some gaps.

Lennart Buit18:03:11

Right, I like its way of doing things tho, feels less like a direct wrapper around a java api. Thats why I was asking, I was hoping that I completely missed something as elaborate as clojure.java-time, but with a more clojure-esque API

Lennart Buit18:03:22

And thats in the little things right, for example, clojure.java-time does a lot of “java-style” overloading

dominicm18:03:53

@UDF11HLKC are there any particular gaps that are a problem for you?

Lennart Buit18:03:56

It’s been a while, can’t come up with specifics sadly

dominicm18:03:50

If you check it out again, please feel free to open issues for anything you're missing.

jjttjj19:03:15

I'm generating the following code using reflection on a javaclass to generate a reify that will implement all methods on the class. The end result looks like this: https://gist.github.com/jjttjj/95ff42fedd49893d51a4333da3abe436 The type hints on return values and arguments are needed to avoid ambiguity. Currently I'm generating the code as a quoted list of symbols, spitting it to a source file, and reading it. Is there a better way to do this? Is it possible to generate an elaborate reify like this with a macro?

noisesmith19:03:27

most macros return a list of symbols (the quoting is done so they remain symbols)

noisesmith19:03:19

the gotcha is that for metadata like type hints you can't just use the metadata reader macro, you need to return a call to with-meta

noisesmith19:03:55

so instead of ^void foo you'd have (with-meta foo {:tag void})

jjttjj20:03:07

ok so

(^void currentTime [this ^long time]
          (cb {:time time, :type :currentTime}))
would become
((with-meta current-time {'void true}
            [this (with-meta {'long true} time)]
                    (cb {:time time, :type :currentTime}))
                    
and that should work fine?

noisesmith20:03:54

I edited the metadata after checking in my repl

jjttjj20:03:06

got it thanks

noisesmith20:03:39

the with-meta call should only wrap the symbol, and the macro quoting would mean it needs to look different from that

noisesmith20:03:59

but that's the basic idea - you need to return a list that has the right metadata on the symbols in it

joelsanchez22:03:08

I think people have forgotten or don't know, but, Insomnia, the REST client ( https://insomnia.rest/) has been supporting EDN without any add-on since some months ago

joelsanchez22:03:35

just thought it was worth a mention. I know about this because I added the feature 😛

👏 28