Fork me on GitHub
#clojure
<
2018-07-02
>
otwieracz05:07:08

@seancorfield and what about https://github.com/uswitch/clj-soap? Is there something obviously wrong with it?

matan05:07:08

Hey a transducers question: what are currently some noteable transduction contexts used out there? I need to showcase to some scala devs today

sundarj08:07:54

core.async and RxJS both support transducers

matan06:07:09

hey thanks 🙂

matan06:07:27

how do you have time to learn all this? what's your day job? 😉

matan06:07:03

would you consider profitably collaborating on projects?

mdallastella13:07:51

My company and yours are really similar 🙂

sundarj18:07:08

i just picked these things up as i went, mostly in my spare time 😛

emccue07:07:11

@slawek098 Have you tried NOT doing SOAP?

otwieracz07:07:41

What do you mean?

emccue07:07:56

And clj-soap hasn't been updated in forever.

seancorfield14:07:59

Note: I forked that to get it working on Clojure 1.5.1 but gave up on it because it didn't do what I needed. /cc @slawek098

emccue07:07:47

which isn't a bad thing on its own, but the only issue is that one

emccue07:07:13

so for your own sanity I would go with a more proven solution

emccue07:07:39

The libraries @seancorfield mentioned should be fine

emccue07:07:32

And the reason I personally would not use soap are

emccue07:07:47

1. I am a young idiot and soap has a bad rep

emccue07:07:56

2. I don't understand it so it scares me

emccue07:07:30

3. Most of the modern web uses JSON, so it feels like there needs to be justification to not use that.

emccue07:07:59

All of the above may or may not matter to you

emccue07:07:42

(by JSON I mean REST, which yeah, I used the wrong thing for comparison)

emccue08:07:07

honestly, I would like to know what the use cases are nowadays

emccue08:07:30

so if you could explain that to me it would be greatly appreciated

otwieracz08:07:07

@emccue I'd love to use REST, of course. I just need to talk with SOAP-only service…

emccue08:07:17

thems the ropes then

emccue08:07:58

just go down the java path, find the best way there, do interop

emccue08:07:07

thats one of the biggest strengths of clojure

seancorfield14:07:59

Note: I forked that to get it working on Clojure 1.5.1 but gave up on it because it didn't do what I needed. /cc @slawek098

seancorfield14:07:09

@slawek098 @gon Just noticed that Zeto-Ltd's version is a fork off mine 🙂 So that would now be my recommendation since it's more recently updated 🙂

delaguardo15:07:24

In my company we wrote soap library which is not requires java interop for making SOAP requests and can process WSDLs without recompiling your source code. It uses zippers in combination with selmer to build valid SOAP payload. So for library users it looks like their doing REST requests instead of SOAP. How many of you folks are interesting in such kind of library so I can arguing with source code owners about open sourcing it?

jmckitrick15:07:41

That would be excellent, @delaguardo

jmckitrick15:07:22

It’s hard to argue Clojure over Scala for XML web services.

jmckitrick15:07:53

Scala is as good at XML as Clojure is at JSON, roughly speaking in my experience.

nickmbailey15:07:26

@delaguardo sounds very interesting

delaguardo15:07:51

Thanks for feedback. I will spend some time to add more tests and documentation and publish it at the end of this week. Stay tuned)

cristibalan21:07:02

Hi. I'm having a major hair pulling moment. I have code that I believe should do the exact same thing behaving differently. Unfortunately can't paste the actual code, but here's the gist of it. The second-fn call appears to handle the data in two differently based on wether two comes from the function call or if it is a literal. Is there some very obvious and devious known gotcha I'm missing here? Any help and pointers very much appreciated. Thanks.

;; does not work
(let [[one two] (first-fn)
      three (second-fn two)]
  (prn two))

;; works fine
(let [[one two] (first-fn)
      two '{literally the actual value of two copy pasted from above}
      three (second-fn two)]
  (prn two))

arrdem21:07:33

There’s a lot which could be happening here, but why are you using backtick there not quote?

cristibalan21:07:41

Regardless of what second-fn actually does, I would have expected the behaviour to be identical.

cristibalan21:07:21

Sorry, I mistyped when composing the example. I am using an apostrophe to quote the pasted in my code as it contains lists.

cristibalan21:07:25

I have a bajillion print statements going deep in all the functions and the data seems to be identical until some point where it just gets treated differently.

dpsutton21:07:25

is two a vector?

dpsutton21:07:33

or some kind of sequence?

hiredman21:07:36

have you checked if they are actually equal using '='?

cristibalan21:07:46

Yes, I have checked with =

arrdem21:07:56

There’s nowhere near enough information here for us to commentate on what could be happening. two is data-independent of three and second-fn in either of these examples and it’s fairly easy to come up with examples where object equality missbehaves with non-Clojure objects.

hiredman21:07:12

e.g. if you used prn at any point, in the process of checking if the two things are equal, you are not actually checking the two things for equality

cristibalan21:07:28

two is just a regular hash-map, no funny objects

bronsa21:07:01

user=> (doto (java.util.HashMap.) (.put 1 1))
{1 1}
user=> (= (doto (java.util.HashMap.) (.put 1 1)) {1 1})
true

bronsa21:07:06

lots of stuff like this that could be happening

nooga21:07:10

;; does not work meaning what happens?

cristibalan21:07:13

I am using prn extensively to try to figure it out. I understand you are saying that prn might be hiding the true value of the displayed data. What should I use instead?

bronsa21:07:22

check (class two)

bronsa21:07:47

and (meta two) if for whatever reason second-fn depends on meta

bronsa22:07:01

and if the keys or values of two are numbers, check whether they are floats/bytes/chars etc

hiredman22:07:07

well, you have both things named two in you example above, I would rename one of them to two* and prn (= two tow*)

cristibalan22:07:35

keys are uuids, so string. meta might be an avenue, as I am later using zippers to go through some subparts of two and then edit the tree.

bronsa22:07:59

clojure.zip depends on metadata

cristibalan22:07:05

And I think zippers might use some meta, as I noticed some with-meta calls in the source of vector-zip.

cristibalan22:07:29

Progress! Thanks. Should I be doing anything special when working with data that has meta?

cristibalan22:07:50

I am not familiar with this part of clojure.

cristibalan22:07:10

Regardless of whether clojure.zip is using metadata, I don't understand why this should matter? The zipper part is somewhere about 10 calls deep within second-fn. I would expect that if I pass identical data in second-fn, it should behave the same way. How would meta affect this?

cristibalan22:07:12

I will definitely try to print (meta blah) for all the things, even tho I don't understand why.

hiredman22:07:52

I would start with checking your two twos for equality without using prn first

bronsa22:07:09

it might not be the issue, I'm just listing possible culprits

nooga22:07:44

would = take metadata into account?

cristibalan22:07:19

At this point there should be no meta yet tho. I'll be back in a bit with the response.

hiredman22:07:31

in this case = returning true wouldn't rule anything out, but returning false would tell you that your two twos are in fact different

bronsa22:07:27

first thing I'd do is check for type btw

bronsa22:07:35

to rule out sorted maps or things like that

arrdem22:07:52

Isn’t there a library floating around for composing before and after operations onto var-bound functions as pseudo-hooks?

bronsa22:07:59

or arraymap vs hashmap and a broken second-fn that relies on ordering

hiredman22:07:04

and so far, my understanding is you've only checked (= two (read-string (pr-str two*))) effectively

hiredman22:07:10

robert-hooke

cristibalan22:07:59

Hm. It's a bit difficult to literally compare them with = as the map is keyed by random uuids so I have to write a fn to normalize the data, heh. I was hoping actually copy pasting the hash would be enough. I have been doing that lots of times and haven't had issues so far.

cristibalan22:07:40

(meta two) is nil tho

bronsa22:07:41

store the interim value of two into a var and play with two and two-literal at the repl

hiredman22:07:49

(= two (read-string (pr-str two)))

hiredman22:07:23

alarm bells going off over "write a fn to normalize the data"

cristibalan22:07:47

two is a hash that mostly looks like this btw

{"xxx" {:kind "hiccup", :content [[:p ("some" " " [:em ("bold")] " " "para")] [:p ("This is a " [:a {:href ""} ("moo")] " sentence.")]], :id "xxx"}}

hiredman22:07:51

so you aren't exactly copying and pasting two, so could be a bug in your "normalize the data"

cristibalan22:07:31

No. I am literally copy and pasting. I would have to write a fn to normalize in order to be able to compare with =.

cristibalan22:07:45

Because the :id changes every time I run the fn.

bronsa22:07:20

store one instance of two into a var

bronsa22:07:39

then you won't need to keep testing stuff from within your function using print

bronsa22:07:58

literally do (defn your fun [..] (let [[one two]] ..) (def x two) ..)

bronsa22:07:04

and then use x to do the comparisons

bronsa22:07:20

don'd do this in production but for debugging it's ok

cristibalan22:07:22

Oh, I can do a def within a defn. Had no idea 🙂

cristibalan22:07:28

I'm not sure what to actually look for. I have two in a var and a copy pasted version in another var and poking at them they seem identical.

cristibalan22:07:56

Oh. That's true.

bronsa22:07:25

I find it hard to believe that both ^ can be true and (second-fn two) <> (second-fn <value-of-two-copy-pasted>)

bronsa22:07:54

given that by copy pasting a value from the repl into the repl you're essentially just doing (read-string (pr-str

cristibalan22:07:01

Tell me about it. I am literally losing my mind.

bronsa22:07:56

can you start by telling us what it means for (second-fn two) to "not work"?

dpsutton22:07:17

any change you are destructuring wrong with (let [[one two] (first-fn) ...?

cristibalan22:07:00

@bronsa I have some prn statements to trace if some methods are called and in the non-literal case some of them are not being called.

cristibalan22:07:55

@dpsutton Thanks for the question, but no. I have a million prn statements at this point and they go pretty deep until it just doesn't.

bronsa22:07:40

are you somehow shadowing second-fn?

cristibalan22:07:41

It does seem to be related to the zipper, but whenever I try to call just that part with the literal to debug, it works.

cristibalan22:07:02

What do you mean shadowing? Like redefining it in a let?

the2bears22:07:28

I assume you've re-started the REPL?

bronsa22:07:41

there's no "redefining" of locals in clojure, just shadowing

cristibalan22:07:14

Definitely not doing that. It is a multiple arity fn, but I have prn's on each branch and it goes down the correct one.

cristibalan22:07:57

I did however just manage to reproduce the wrong behaviour by passing in the saved two.

bronsa22:07:57

I don't know what else to suggest, I suspect you are inadvertently doing something very broken in the way that you're testing the two paths and forming a broken hypothesis as a result

bronsa22:07:16

but this is just guesswork at this point

bronsa22:07:47

did you check the types of the two values?

cristibalan22:07:43

I checked with class and they're both clojure.lang.PersistentArrayMap

bronsa22:07:16

(= (pr-str two) (pr-str two-val))?

cristibalan22:07:47

That might be the ids 😞

bronsa22:07:02

why are you still comparing values with different ids

bronsa22:07:10

take two, copy paste it into two-val

cristibalan22:07:16

Good point. Result is true

bronsa22:07:11

cool, now keep testing using just two and two-val, stop generating new values everytime otherwise it'll be impossible to isolate

cristibalan22:07:50

Yeah. I have a great lead now that I have a value in a var that reproduces the bug.

bronsa22:07:55

and make sure that is true now that (not= (second-fn two) (second-fn two-val))

bronsa22:07:37

I suspect that won't be the case

cristibalan22:07:28

Yes, they are not=.

dpsutton22:07:18

can you run clojure.data/diff over them?

bronsa22:07:47

also (binding [*print-meta* true] (prn two)) and same for two-val

bronsa22:07:56

I don't know

dpsutton22:07:09

do you expect them to be exactly equal? not sure if you've got some atomic counters or uuid's on there

bronsa22:07:19

you either have some metadata on some internal value and something in second-fn depends on it

cristibalan22:07:36

What do you mean by internal value?

bronsa22:07:41

or some internal value has a type that compares = to another one but behaves differently in second-fn

bronsa22:07:45

internal as in value nested in the map

cristibalan22:07:13

@dpsutton They are literally exactly equal with =, data/diff returns some result I don't comprehend. I'll have to read the docs.

bronsa22:07:38

last resort is using (binding [*print-dup* true] (prn two) (prn two-val)) and comparing the outputs

cristibalan23:07:04

@bronsa I did the binding thing for both of them and the output is very different

bronsa23:07:14

different how

cristibalan23:07:12

At first glance, the output bad one is at least twice as big. Gimme a sec to compare them.

cristibalan23:07:57

Ok. First, there is a minor issue of some values being :level #=(java.lang.Integer. "3") in the bad one, while the literal is just :level 3.

cristibalan23:07:35

However, this is not a value that breaks later on. But the value that does break later on also has a similar issue. Gimme a sec to paste.

bronsa23:07:19

looks like this is the case then

cristibalan23:07:07

;; bad version
[[:p ^#=(clojure.lang.PersistentArrayMap/create {:line #=(java.lang.Integer. "865"), :column #=(java.lang.Integer. "862")}) ("some" " " ......

;; good version
[[:p ("some" " " .......

cristibalan23:07:06

These arrays I obtain via commonmark-hiccup which is a wrapper over commonmark-java.

cristibalan23:07:21

Could this be related?

bronsa23:07:28

are you sure that's what's causing the issue?

cristibalan23:07:53

I am sure that the values are different in up to now invisible way.

bronsa23:07:10

right that's just line/col metadata that clojure adds

bronsa23:07:13

it shouldn't make any difference

cristibalan23:07:15

I don't understand what those differences mean tho 😕

bronsa23:07:20

find the difference that causes the divergence

bronsa23:07:49

I have to go now, it's late

cristibalan23:07:57

Ok, I'll continue looking for other differences.

cristibalan23:07:29

Thank you so much for the hints. I will definitely keep you posted on what I find out.

cristibalan23:07:02

Btw, is there a way to get rid of these differences even tho they should be benign?

cristibalan23:07:05

Unfortunately, the values are identical besides these metadata changes.

sundarj23:07:33

you can strip metadata by doing (vary-meta x empty) or (with-meta x nil)

cristibalan23:07:38

I'm suspecting that since zippers use metadata, maybe it somehow grabs some of these extra and thinks they're part of the data.

cristibalan23:07:15

Thanks. I would need to get to each deeply nested value, right?

cristibalan23:07:02

Thanks. I'll see whether I can add a call right where the value is used.

Dormo23:07:22

Does anyone know if there's a generic event dispatching/handling library for Clojure? Something like re-frame, but not hooked up to a rendering library or "database"?

Dormo23:07:55

https://github.com/clojurewerkz/eep this looks like it could be good

Dormo23:07:48

I'm wondering if there are other options, though

Chris O’Donnell23:07:46

Also, pedestal's interceptor library can be required separately from the rest of the project. https://github.com/pedestal/pedestal/tree/master/interceptor