Fork me on GitHub
#clojure
<
2015-11-30
>
trancehime01:11:16

Sometime when I include cljs.core.async when I try to build my app I get some dependency error with clojure.core.cache in memoize and I didn't have any problem with lein deps :tree so I wonder what else I can do? Since I have already used :exclusions

trancehime06:11:03

No such var: clojure.core.cache\through ?

trancehime06:11:45

I don't get it

trancehime06:11:09

How can I include sente if it keeps giving me No such var: clojure.core.cache\through every time I include it

trancehime06:11:36

I have proper :exclusions set and everything even

noonian06:11:35

Do you see org.clojure/core.cache in the output of lein deps :tree? It sounds like you may be excluding the version of core.cache that defines through and one of your dependencies is trying to use it.

trancehime06:11:33

[com.emerick/friend "0.2.1"] -> [org.clojure/core.cache "0.6.2"] overrides...

trancehime06:11:54

an older version was overriding a later one

trancehime06:11:04

I must have missed it before

noonian07:11:20

@trancehime: No problem, I’m glad you figured it out!

trancehime07:11:54

I'm still a clojure newbie (been learning how to use CLJ+CLJS for about a month now) so I'm kind of stumbling my way through this

noonian07:11:24

Thats understandable. There is a lot to learn if you are new to Clojure entirely. You might checkout the #C053AK3F9 channel also if you run into more stumbling blocks.

danielgrosse11:11:31

Could someone please explain to me, why this triggers a NullPointerException

((fn [[_ registered _]] (
                          (println registered)
                          )) [12 34 56])

isaac11:11:28

clojure
((fn [[_ registered _]] (
                         (println registered)
                        )) [[12 34 56]])

danielgrosse11:11:11

A found it, the second parenthesis of the function where the reason.

niwinz11:11:56

It should be: ((fn [[_ registered _]] (println registered)) [12 34 56]))

niwinz11:11:20

You are wrapping the (println ...) in additional parenthesis,

niwinz11:11:38

println returns nil and in that case you are trying execute a nil that causes the NPE.

artemyarulin13:11:07

Hi, does anyone thought about using http://www.grpc.io? They have bindings for Java, but I’m a bit worried how can I use in Clojure because some protobuffs compilation

Lambda/Sierra13:11:40

@artemyarulin: I've seen protobufs used from Clojure. It can be done, but it's awkward. Protobufs are very Java-ish, you have to add an extra translation layer between Java objects and Clojure.

artemyarulin13:11:49

@stuartsierra: Thanks. OK, I’ll try and play around with it for a while

borkdude13:11:45

I had an idea, and wonder if such a thing exists: a JIT type system. A tool (IDE) keeps track of the type or structure (hashmaps) of the arguments that go into a function and deduces a type. When you call the function with something else, the tool can produce a warning: you're calling this function with a number instead of a string (because you have called it with a string 99 times already and never with a number), that could be helpful to the programmer.

borkdude13:11:19

so, nothing enforced by a compiler, but just as a programmer's tool

roelof14:11:23

@borkdude: looks like a very ambious plan to me

borkdude14:11:04

@roelof: I'm not going to implement it myself

borkdude14:11:15

Maybe an idea for @cfleming simple_smile

roelof14:11:51

oke, I cannot implement it. This sort of things are much much much more then I could chew

borkdude14:11:03

How do you make a multipart request in a test suite

borkdude14:11:46

I'm using peridot to create requests, since I also have to deal with sessions and cookies

dominicm14:11:39

@artemyarulin: There is a library around for interacting with Protobuf from Clojure, and it adds a record & leiningen compilation integration.

artemyarulin14:11:27

@dominicm: Thanks, I guess I found something already

roelof15:11:15

sorry borkur needs to be @borkdude

borkdude15:11:44

I have trouble reloading my compojure routes in Cursive. My workflow works in Emacs, but somehow the changes aren't picked up in Cursive while writing tests

borkdude15:11:06

I tried 'sync files with REPL', doesn't work. Restarting the REPL does of course

borkdude15:11:06

It does work when firing a request from the browser, so wrap-reload is triggered

borkdude15:11:20

but I would think 'sync files in repl' would more or less do the same

dominicm15:11:29

@borkdude Might be worth trying to find out what Cursive does when you hit reload.

borkdude15:11:54

@dominicm: I see all the files I changed are being reloaded. As an extra step I reload the file where the handler is defined.

dominicm15:11:29

@borkdude but what is it actually doing? Checking for the tools.namespace dependency of some kind? er.. I mean the "sync files with REPL" as the trigger here.

borkdude15:11:48

I guess just re-evaluating the whole file in the Clojure REPL

dominicm15:11:53

Have you seen if a def'd variable appears when you add it to the file, then ask evaluate it in the repl? That should isolate the issue somewhat.

borkdude15:11:31

@dominicm: yes, that works

borkdude15:11:53

@dominicm: When I re-evaluate my routes, I think the handler I'm using doesn't see those changes somehow

dominicm15:11:24

This might be wrong, but for your reference to the handler, try #'handler

dominicm15:11:39

I just have a hunch.

borkdude15:11:44

yeah, tried that also

dominicm15:11:04

What's the connection between your handler & routes (same namespace or sep)? Has it worked if you've manually re-evaluated the handler file?

dominicm15:11:37

It might be that Cursive's clever dependency finder, isn't being quite as clever as it should be.

borkdude15:11:59

handler is in lob.handler. that references a route from lob.api.students, that is the file where the route is changed

dominicm15:11:33

Any luck using "Load file in REPL" with lob.handler open?

borkdude15:11:09

aaah, found it

borkdude15:11:25

I referenced lob.api.students from lob.api, which I had to reload also

borkdude15:11:39

hmm, wish Cursive would detect this

dominicm15:11:55

See if you can create an isolated case, and bug report it to them.

borkdude15:11:57

lob.handler references lob.api, not lob.api.students, so I was wrong

borkdude15:11:09

Cursive doesn't understand macros very well

borkdude15:11:17

which might be the root of the problem

dominicm15:11:46

https://cursiveclojure.com/userguide/repl.html Scroll down to "Interaction with the editor"

roelof15:11:57

I noticed the same as I tried the clojure koans on Cursive

dominicm16:11:36

Interesting. I wonder if Cursive has a bug tracker?

borkdude16:11:16

@cfleming is active here, he might have a solution and if not, I'm happy to file something

dominicm16:11:34

https://github.com/cursiveclojure/cursive/issues/1179 I don't suppose you fit into this category do you?

borkdude16:11:01

@dominicm: it's a similar problem

dominicm16:11:43

@borkdude: Interesting. It's a shame cursive is in an awkward position. tools.namespace is PERFECT for this.

dominicm16:11:15

But it can't load it, because, it would inject the dependency & would also remove some of it's control.

borkdude16:11:26

It seems I can't place a breakpoint in a compojure route either

borkdude16:11:50

so, how do I simulate a multi-part request in Ring for unit testing?

borkdude16:11:05

I see peridot does already do something: https://github.com/xeqi/peridot

borkdude16:11:06

but not sure how to call it

roelof16:11:37

So a perfect IDE for clojure do not exist. but still I love to use cursive

xeqi16:11:50

@borkdude you can call peridot.multipart/build with the params you want to send, and then merge that with other request data

sander17:11:48

is there a more transducery way of writing (map f (into [] g coll) (into [] h coll))? this is a bit repetitive

borkdude18:11:59

@xeqi: thanks, I'll take a look at it

ghadi18:11:39

sander: if you can post what f g h do probably

canweriotnow18:11:40

Any library/technique suggestions for flattening a deeply nested map for CSV export?

ghadi18:11:59

canweriotnow: clojure.core is the best library

canweriotnow18:11:44

@ghadi Yeah, I know it hjas everything I need, but I'm trying to figure out how to use something like this:

{
    "id": "12345678-1234-5678-1234-567812345678",
    "actor":{
        "mbox":""
    },
    "verb":{
        "id":"",
        "display":{
            "en-US":"created"
        }
    },
    "object":{
        "id":""
    }
}

canweriotnow18:11:39

To columns like id,actor_mbox,verb_id,verb_display_en-us,object_id

canweriotnow18:11:08

I think I need something like medley's reduce-kv?

ghadi18:11:18

naaah, hang on

ghadi18:11:02

(let [getter (fn [path]
               (fn [row] (get-in row path)))

      gets (map getter [[:id]
                        [:actor :mbox]
                        [:verb :id]
                        [:verb :display]
                        [:object :id]])

      make-row (apply juxt gets)]
  make-row)

ghadi18:11:41

that ^ returns you a function that you can use to map over each row.

ghadi18:11:39

learning libraries besides clojure.core is not necessary

ghadi18:11:39

stuff like Spectre makes you learn a little DSL to do shit that's built-in

robert-stuttaford18:11:42

not always true, but a great attitude to have. the core is very capable

ghadi18:11:36

I'm being intentionally provocative, gets lost in Slack 😃

ghadi18:11:02

But it's important to push the boundaries of core from the inside -> out, rather than starting with a lib

jr18:11:49

canweriotnow: is your data dynamic? a function can be implemented to do that to any map with reduce-kv

canweriotnow18:11:02

@jr yes, I know the structure but not necessarily which keys will be present in advance.

jr18:11:42

(defn map->csv-map
  ([map] (map->csv-map "" map))
  ([prefix map]
   (reduce-kv (fn [m k v]
                (let [prefixed (if (empty? prefix)
                                 k
                                 (str prefix "_" k))]
                  (merge m (if (map? v)
                             (map->csv-map prefixed v)
                             {prefixed v}))))
              {}
              map)))

canweriotnow18:11:38

oh wow that's exactly it. Thanks!

cfleming19:11:40

@borkdude: I’m happy to receive an issue for that - AFAIK routes should be reloaded correctly, Cursive really just does a load-file so there’s no magic on the actual loading.

cfleming19:11:16

Cursive’s issues with macros only affect the editor, never the REPL - what you evaluate in the REPL works like any other editor.

borkdude19:11:55

@cfleming: the issue in my case was that the handler does not get re-evaluated when a route that it uses gets re-evaluated

cfleming19:11:36

@borkdude: Oh, so your handler ns calls an impl ns, the impl has changed but the handler has not?

borkdude19:11:37

(don't mind the indenting, it's a copy and paste issue)

borkdude19:11:16

@cfleming: that's very common when you develop a ring app

borkdude19:11:46

@cfleming: normally, the wrap-reload middleware takes care of reloading, but when I'm writing tests, I'm not using that

cfleming19:11:08

@borkdude: I’m planning a change for protocols, that will reload implementations of protocols when then the protocol has changed

cfleming19:11:19

That could be applied here.

cfleming19:11:44

I’m surprised that tools.namespace handles that, though - I’m sure there’s no compojure-specific magic there.

cfleming19:11:10

@borkdude: Note that if you reload the handler ns that will always be reloaded even if it hasn’t changed, and its deps as well.

cfleming19:11:31

Using Load file in REPL.

borkdude19:11:51

but in test, I don't use a ring server, only a handler

borkdude19:11:40

@cfleming: yeah, that's what I want: the handler should be redefined, because one of it's parts has changed

cfleming19:11:22

Ok. But I’m a bit confused - you say this workflow works in Emacs, even in test?

cfleming19:11:59

i.e. you reload the impl ns and the handler is somehow reloaded?

borkdude19:11:03

@cfleming: no, it doesn't actually

borkdude19:11:23

@cfleming: I only bumped into this problem now, using Cursive. In emacs there is the same problem

sander19:11:27

ghadi: this is the extended (map f (into [] g coll) (into [] h coll)) I'm trying to write in a nicer way: https://gist.github.com/sander/30c3c36c005b3eee71fc#file-transducing-cljs-L52 . I hope to use the same transducer (composition) on core.async channels, this is just for debugging still

cfleming19:11:56

@borkdude: Ok, that makes more sense - thinking about it, it requires quite a lot of magic

xeqi19:11:10

@borkdude if your using peridot and sending a file in the params it will make it a multipart request. Ex: (request session url :request-method :put :params {:picture (io/file ..)})

borkdude19:11:33

@xeqi: that's what I had before, but it didn't work somehow

borkdude19:11:40

@xeqi: I'll try again

cfleming19:11:30

@borkdude: In the meantime, if you call Load file in REPL in the handler ns, that will always be loaded (since it always loads the file you tell it to) and any transitive deps will be loaded in the right order.

borkdude19:11:54

@cfleming: ok, so I would only have to load the handler then

cfleming19:11:41

@borkdude: Right, as long as there’s an explicit dependency chain from the handler to the impl. This is sometimes not true in tests that test some functionality indirectly, but in your case sounds like it should work.

borkdude19:11:46

I guess it has something to do with ring headers having to be strings instead of longs, but I'm not sure. This is one of those situations when static typing makes sense...

canweriotnow19:11:19

@jr made a few tweaks:

canweriotnow19:11:07

This ensures the keys will be strings so that (str prefix "_" k) doesn't choke on keyword keys, and puts all the values in vectors so I can just (apply merge-with into list-of-maps)

devn20:11:09

`Who runs this Slack?

devn20:11:21

Err wrong channel, sorry.

devn20:11:52

WTB: well-maintained emacs configuration that works well in the console and has the bare essentials and not much more: cider, clojure-mode, completion, paredit

borkdude20:11:03

@xeqi: fwiw, I analysed this and I think the problem is the string vs. long in the headers under content-length: https://gist.github.com/borkdude/ec80dddf2c5bc5b38f74

borkdude20:11:13

@xeqi: if you want, I can file an issue

ghadi20:11:03

canweriotnow: Keeping in line with the tactic of flattening the whole map, another thing you can do is to make the keys be the original path: {["level_one" "two" "three"] value} so you can vary the choice about naming the keys independently of flattening

canweriotnow20:11:19

I like that...

canweriotnow20:11:04

What I've got now is kind of the inverse:

{"object_verb_display_en-US" ["will visit"], "actor_objectType" ["Agent" "Agent"], "verb_display_en-US" ["planned" "answered"], "object_object_definition_name_en-US" ["Some Awesome Website"], "object_verb_id" [""], "object_object_id" [""], "actor_mbox" [""], "object_actor_objectType" ["Agent"], "object_definition_description_en-US" ["Example activity description"], "object_objectType" ["SubStatement" "Activity"], "object_definition_name_en-US" ["Example Activity"], "object_id" [""], "object_actor_mbox" [""], "verb_id" ["" ""]}

canweriotnow20:11:30

But I can already see I'm going to run into a problem when a key is present, then not, then present again re: rows, since there aren't any nil/blank placeholders between values in my vectors... hmm...

ghadi20:11:21

yah... the problem of flattening a tree into CSV is not fun (esp with 1->N relationships). Perhaps revisit my idea of being explicit about what you select

ghadi20:11:33

i.e. explicit paths, if that is an option

canweriotnow20:11:44

E.g., I don't know what map "object_actor_mbox" [""] came from

canweriotnow20:11:51

after the fact.

canweriotnow20:11:39

If I could iterate over all the maps to get the keys, and then set paths for the getter dynamically, that solution would work.

canweriotnow20:11:04

The problem domain is based on a spec that determines the overall structure, so I could theoretically map out all possible paths... we actually use Prismatic schema to validate these things, so I probably have a good list of valid keys in my codebase.

canweriotnow20:11:20

I'll revisit that and let you know what I come up with simple_smile

canweriotnow20:11:56

I especially like the idea of making the keys be the path.

domkm21:11:22

Question for anyone using Validateur: The API looks nice except that it appears to me that the validation tuple [valid? map-of-errors] is entirely redundant because, if it is valid, the tuple will always be [true {}]. In other words, the tuple is unnecessary and validators could just return a map of errors (`(empty? errors)` => true). Is my understanding correct or am I missing something crucial?

anmonteiro21:11:52

hey guys, hoping anyone can clear a doubt

anmonteiro21:11:46

is it possible to use partial with a record's function? been trying (partial .record-fn arg1) but throwing an error because of the .

ghadi21:11:44

(partial protocol-function-name arg1)

ghadi21:11:58

dot-anything is compiler magic

anmonteiro21:11:07

forgot to try that

anmonteiro21:11:22

didn't define protocols yet because I was just prototyping

anmonteiro21:11:33

I was putting everything on the Object

anmonteiro21:11:48

so time to define them now

tcrayford21:11:19

@domkm: yeah, but it makes writing client code easier. Instead of (if (empty? validation), it becomes (if valid?

anmonteiro21:11:26

thanks a lot!

domkm21:11:12

@tcrayford: Sorry, I don't follow. Wouldn't the test for [true {}] and {} be (if (first x) ... and (if (empty? x) ... respectively?

domkm21:11:24

@tcrayford: I just checked validation-set and in fact it completely ignores the leading boolean in the tuple: https://github.com/michaelklishin/validateur/blob/master/src%2Fcljx%2Fvalidateur%2Fvalidation.cljx#L539-L543

tcrayford21:11:42

@domkm: I'm just theorizing, I don't use validatuer

tcrayford21:11:58

but if you're destructuring the tuple returned…

codemartin21:11:20

Is it possible to have an atom always put on a channel whenever it's updated? In that way, one could "listen" to an atom

codemartin21:11:38

@borkdude: That is amazing! Thank you! Boy is Clojure nice to work with or what

jstew21:11:30

observer pattern? pfft simple_smile

jstew21:11:42

I love that we're not in here talking about design patterns BTW. It's a breath of fresh air.

xeqi21:11:04

@borkdude an issue would be nice, looks like ring added a type hint in 1.4 that causes the problem

borkdude21:11:47

@xeqi: type hints never cause problems right?

xeqi21:11:48

Though that should have been a string to start with

borkdude21:11:18

@xeqi: I'll do it tomorrow, closed my work laptop now

xeqi21:11:44

@borkdude sarcasm or serious question?

borkdude21:11:04

@xeqi: serious, I thought they were only 'hints' for the compiler to prevent reflection, not enforced types

borkdude21:11:08

@xeqi: clearly I haven't used them enough. tell me.

bronsa21:11:00

type hints are one of the most inconsistent aspect of clojure

bronsa21:11:45

sometimes they are enforced, sometimes they are not. sometimes a wrong type hint will be silently ignored, sometimes it will cause an exception at compile time, sometimes an exception at runtime when you don't expect it

xeqi21:11:52

https://github.com/ring-clojure/ring/commit/bb4a079a94330cea9d4d9999b1a141750680b5e0 type hints the header value as a string, but peridot causes a long to returns there. The Long constructor would be happy with either, but it seems the Clojure compiler had to reflect there?

ghadi21:11:35

bug is in peridot then

bronsa21:11:45

@xeqi: I don't see how a type hint would be necessary there

bronsa21:11:50

get-in can never return a primitive

ghadi21:11:53

HTTP Headers are strings

bronsa21:11:00

and Long only takes long or String

xeqi21:11:28

@ghadi Yep, just happened to work on ring <1.4

xeqi21:11:18

@bronsa I'm not sure, on phone so can't check so was going by commit msg

borkdude21:11:38

@xeqi: I made an issue. https://github.com/xeqi/peridot/issues/25 If you want more info like ring version etc, I can answer tomorrow.

borkdude21:11:47

ah I see, when you use a type hint, Clojure will choose the constructor matching that type, right?

borkdude21:11:08

if you don't hint, it doesn't work?

borkdude21:11:57

I see, this causes the exception I had: (let [f (fn [^String s] (Long. s))] (f 1))

ghadi21:11:28

bronsa: let's move to #C06E3HYPR re: reflection

karlis23:11:39

curious, is there a reason why there’s no update! and update-in! for transients in core? persistent updates wrap assoc & we already have assoc!.

ghadi23:11:59

no update! because that will beg the question about transients for every conceivable operation, no update-in! because transients only apply to a plain map, not nested things