Fork me on GitHub
#clojure
<
2016-08-03
>
maxim01:08:15

Would be nice to hear your opinion.

Alex Miller (Clojure team)01:08:53

Don't know - prob best to file a jira for it

Alex Miller (Clojure team)01:08:10

I'll try to look at it later this week

Alex Miller (Clojure team)01:08:44

A patch would be even better :)

cddr03:08:29

@mkaschenko: Had a quick look at the code and noticed there's an ":escape-slash" option that you can turn off which should get you the same as ruby

maxim03:08:50

Thank you guys.

cddr04:08:25

@mokr: The platform differences are not theoretical either. I remember fixing a bug once in a ruby test suite caused by the difference in the order files were returned between osx and linux.

iamyemeth07:08:47

hey guys, is there a corresponding function that can be used as an equivalent to the map namespace reader literal?

iamyemeth07:08:36

#:user{:name “John"}
;; something like this
(add-ns {:name “John”} :user)

mpenet07:08:03

I don't think so no

borkdude07:08:20

what does this even do?

mpenet07:08:38

{:user/name "John"}

borkdude07:08:05

with specter: (transform (walker keyword?) #(keyword "user" (name %)) {:a 1 :b {:c 3}})

borkdude07:08:28

;;=> #:user{:a 1, :b #:user{:c 3}}

mpenet07:08:51

it's almost shorter with reduce-kv I think

mpenet07:08:14

yours is recursive tho, not sure it's desirable

mpenet07:08:29

the opposite is possible with a bit of black magic:

borkdude07:08:52

hmm, private function in 1.9.0?

nathanmarz08:08:41

@borkdude @mpenet a better way to do that with specter is to express "keyword namespace" as a new navigator:

(defnav KW-NS []
  (select* [this kw next-fn]
    (next-fn (namespace kw)))
  (transform* [this kw next-fn]
    (let [kw-name (name kw)
          new-ns (next-fn (namespace kw))]
      (keyword new-ns kw-name)
      )))

(setval [ALL FIRST KW-NS] "user" {:a 1 :b 2 :c 3})
;; => {:user/a 1, :user/b 2, :user/c 3}

nathanmarz08:08:14

now that concept is composable and reusable

mpenet08:08:32

I would just write a 2 line function that takes a map and return a the new map, just as composable

mpenet08:08:58

but I don't really know specter, I guess if you're using it why not

nathanmarz08:08:45

I don't think that's nearly as composable

nathanmarz08:08:44

e.g.: working on sorted maps without changing the type, changing the namespace of just one keyword in the map, working on a sequence of maps

nathanmarz08:08:21

there's infinite examples I could list

mpenet08:08:19

still, if you need to change just 1 key you would probably just use assoc, for sequence of map you can just use map etc etc. As I said for complex transformations why not, but I doubt it's the default

mpenet08:08:38

preserving the type shouldnt be too hard, it's just an (empty ..) call away I think

nathanmarz08:08:28

even for just one key I think the Specter code is better (in my opinion):

(update mymap :a (fn [kw] (keyword "user" (name kw))))
(setval [:a KW-NS] "user" mymap)

nathanmarz08:08:52

and then you can use the navigator to do other things, such as (transform [:a KW-NS] (fn [s] (str s s)) mymap)

nathanmarz08:08:27

the thing is, while using empty to preserve the type is possible, it's a constant burden you have to deal with every time you write a function that manipulates a data structure

nathanmarz08:08:55

it's classic complexity... all you want to do is manipulate the nested keywords but you have this extra burden interwoven in the function

nathanmarz08:08:36

another separate concern is performance, the optimal way to reduce through the map is totally different for small maps vs. larger maps

nathanmarz08:08:03

specter is able to encapsulate those different mechanisms for you so you don't have to worry about it

mpenet08:08:21

reduce-kv should be fast enough in most cases, I'd expect it to be optimised well too

mpenet08:08:33

but as I said, I am sure specter would be great in more involved cases

mpenet08:08:53

or if you need to reuse that in many transformations

mpenet08:08:40

did your work on specter sparked new tickets for performance optimisations in core btw?

mpenet08:08:02

it's full of clever tricks for sure

nathanmarz08:08:15

for small maps (PersistentArrayMap) the highest performance mechanism I found was using the "keyIterator" and "valIterator" methods, for large maps it was reduce-kv + transient PersistentHashMap

nathanmarz08:08:38

I made some suggestions on a ticket about a proposed map-vals function, but otherwise didn't find anything to optimize in core

nathanmarz08:08:53

the work on specter was more about discovering those best methods and abstracting them away

mpenet08:08:54

I guess most of these optimisation could land in c.c.proto/kv-reduce

nathanmarz08:08:25

well, kv-reduce knows nothing about the output

nathanmarz08:08:04

the optimizations baked into specter are based on knowing that the output type is the same as the input type (for ALL)

jell09:08:05

what is the best way to write a SOAP client in Clojure nowadays?

borkdude10:08:19

@nathanmarz: [this](https://clojurians.slack.com/archives/clojure/p1470213401002703) looks really cool but I don't know Specter well enough yet to understand it

borkdude10:08:03

pff, why doesn't Slack support that kind of formatting

nathanmarz10:08:23

@borkdude: happy to explain it... maybe we should continue discussion in #C0FVDQLQ5

dominicm13:08:59

Is there a quick way to scan for a resource so I know the path prefix to use? Only intended for use at the REPL.

lambeta13:08:57

from the clojure.spec >By default map-of will validate but not conform keys because conformed keys might create key duplicates that would cause entries in the map to be overridden. If conformed keys are desired, pass the option `:conform-keys true’. any example of conform keys causing entries overridden?

lvh13:08:14

If a particular namespace is aliased to e.g. x, is there a shorthand for producing the namespaced keyword in that ns?

lvh13:08:38

heh, as I typed that I tried ::x/name — and it worked 🙂

dominicm14:08:54

@lvh: I think that is new

shaun-mahood14:08:20

Does anyone here use clojure-clr at all?

bostonaholic14:08:26

@shaun-mahood: there’s a #C060SFCPR channel

shaun-mahood14:08:19

@bostonaholic: yeah, it doesn't seem to have much going on in there. From everything I've seen in the past few years, it seems like the only action in the clojure-clr space is in maintaining the language and in Arcadia. This is kind of my last ditch effort to see if there's anything I've missed.

mpenet14:08:33

@lambeta: try with/without the conform-keys opt

(s/def ::1 (s/and string? (s/conformer (constantly :boom))))
(s/def ::x (s/map-of ::1 string? :conform-keys true))
(s/conform ::x {"foo" "bar"} )

mpenet14:08:52

I think that's what it refers to

mpenet14:08:06

in theory the conformed key value can overwrite another valid key

mpenet15:08:12

ex:

(s/def ::1 (s/and string? (s/conformer (constantly "boom"))))
(s/def ::x (s/map-of ::1 string? :conform-keys true))
(s/conform ::x {"foo" "bar" "boom" "default"})
foo is conformed to "boom" then "boom" -> "default" map entry overwrites it. no matter the number of entries in your original map you'll always get 1 entry if you conform with this spec

mpenet15:08:26

ocd makes me want to have a "?" added to that option name tho, :conform-keys? would be nicer

bodie15:08:27

doesn't ? suffix usually imply a bool fn?

mpenet15:08:50

when used with kw options, it indicates a bool option

mpenet15:08:26

it's inconsistent right now, even clj.spec has kw options with ? atm

dbushenko15:08:05

is core.match abandoned?

akiva15:08:29

Not sure. My first guess is that it’s not a priority.

mpenet15:08:20

it's not maintained at the very least

akiva15:08:43

I wonder if @dnolen is the one to ask; he has the last commit, I believe.

Alex Miller (Clojure team)15:08:43

core.match is not actively maintained by anyone afaik

Alex Miller (Clojure team)15:08:54

@lvh @domina re ::x/name - it’s always worked that way. autoresolved keywords can be ::foo for current ns ::alias/foo to use ns aliases or even ::fully.qualified/foo (although not really any reason to do that)

ghadi15:08:25

from my own experience though, people tend to get a bit itchy when you see "last commit 7 months" ago in github. I find clojure libraries, even dormant ones, to be pretty hardy against rot

ghadi15:08:37

re: core.match

Alex Miller (Clojure team)15:08:57

yeah, I think it does what it does and continues to do so :)

ghadi15:08:05

but that's certainly a different concern than active maintainership

mpenet15:08:50

core.match is stable, but there are a lot of open jiras (bugs & improvements)

Alex Miller (Clojure team)15:08:50

if someone wanted to take it over and act as an active owner that’s another option

dpsutton16:08:25

that is some pretty dense code

seancorfield16:08:50

^ what @alexmiller said… That’s how I ended up maintaining java.jdbc and more recently tools.cli 🙂

dnolen16:08:20

@dbushenko: not abandoned per se, just don’t have cycles for it myself. if you want to help out let me know. There’s some enhancements, fixes I’ve been wanting to do for a couple of years now just needs somebody to care as I’m too tied up with ClojureScript etc. to devote time to it now.

dbushenko17:08:36

@dnolen: it looks extremely complex, i don't expect i can get into it so deeply that i could implement something there...

tianshu17:08:08

Is there a built-in function that drop the last item of a vector and return a vector?

markmarkmark17:08:29

doglooksgood: there's pop

tianshu17:08:55

find it, pop

hlship18:08:47

Does anyone have a pointer to copyright / fair reuse information related to the Clojure logo? I’m looking into the possibility of creating special keycaps with the Clojure logo on them.

dpsutton18:08:05

i'm interested in working with core.match, will need some time to get up to speed with it though

mokr18:08:26

Like @jell I would like a recommendation about writing a SOAP client in Clojure. Anyone? Context on my part: Don’t know SOAP and I’m not big on Java/interop. All I need is to just tease some useful data out of a system and I don’t have a lot of time to invest in the task. Far fetched, maybe?

lvh18:08:26

any recommended ways of doing key destructuring in a macro? Right now typing stuff like:

[{::keys [~'path-segs ~'name ~'schema]}]
which doesn’t seem great.

lvh18:08:48

@mokr: java interop is your best bet, unfortunately

lvh18:08:56

@mokr: You don’t wanna parse WSDL yourself

lvh18:08:58

it is not pleasant

mokr18:08:09

Thanks. What was the latter referring to, exactly? SOAP is not pleasant, or parsing WDSL?

lvh18:08:55

well that is true for both of them

lvh18:08:17

Java clients might be awful but they still provide a ton of value if SOAP is what you want

jasonbell18:08:21

@mokr: I would have gone for the WSDL -> Java and then use those classes via Java Interop.

lvh18:08:34

I have done both, FWIW

lvh18:08:41

the java route + interop is soooo much easier

lvh18:08:58

unless you have like some weird degenerate WSDL case like EC2

mokr18:08:29

Don’t know if it’s weird. It is an internal enterprise system.

lvh18:08:13

probably not then

lvh18:08:29

I mean, it might be weird, but some AWS APIs are weird in a super specific way

lvh18:08:06

so that it’s easier to just extract information on what APIs exist from the WSDL rather than feed it to a SOAP generator or whatever

mokr18:08:24

Thanks, again, this adds to my impression about interacting with SOAP. Do you think I would gain anything by going for an external script in Python, Perl or similar?

mokr18:08:36

Any “simple” language having a nice library would do. As long as I can call it from Clojure and pass some parameters that would be used in the query.

mokr18:08:00

Using clojure.java.shell

mokr18:08:05

to call it

lvh18:08:16

java has some excellent SOAP libraries

lvh18:08:23

Python has some particularly awful ones

lvh18:08:28

I mean, insofar that they can be excellent

lvh18:08:34

so, Java interop is still your best bet

mokr18:08:20

Some interop research and experience would absolutely be useful, so I think I will try that route and see where it takes me. Thanks again.

rmuslimov19:08:52

And there still an option generate and parse xmls, without any SOAP libraries

manderson19:08:29

Any ideas on how to short-circuit a map operation if an exception is thrown? My use case: if an iteration of map throws an exception, I'd like to stop processing and return the sequence of already processed values to that point.

mokr19:08:50

@rmuslimov: And send them using HTTP POST? After some more googling I get the impression that I can get away with something as simple as that. Or am I perhaps missing something?

rmuslimov19:08:47

@mokr yep, we have bunch of python apps working that way. and now in clojure I’m still thinking it will be the easiest/fastest path

mokr19:08:04

That would be just fantastic for what I need it for.

mokr19:08:16

@manderson: Don’t know if it would work or be any good, but my first thought was to try using a combo of: reduce, try, catch and reduced instead of map.

manderson19:08:29

hm. good thought @mokr. that might be the easiest impl. I was looking at how keep is implemented in core and realizing there's a lot going on with chunked-seq's etc.

manderson19:08:57

thought this might be a common enough pattern as to have a lib somewhere already...

markmarkmark19:08:30

you could pass a fn into map that catches the exception and returns a sentinel value when an exception is thrown, then use take-while or something to take results until the sentinel value is encountered

manderson19:08:49

another good thought @markmarkmark , but in my case I don't want the rest to process. Maybe map is the wrong use for this as my function could be performing side effects.

dg19:08:56

If you think of implementing your own map by using reduce, it should also be relatively straightforward

markmarkmark19:08:08

map is lazy, so it won't process the rest if it's stopped by take-while

manderson19:08:29

ah, that's right.

manderson19:08:08

Ok, i'll try out some of these options. thanks for the ideas!

markmarkmark19:08:26

something like that

manderson19:08:51

Awesome! Both are great options.

manderson19:08:45

❤️ the clj community

snowell19:08:54

If I have a record defined in one namespace and an instance of that record stored in a central state atom, how can I (in a different namespace) execute a function on that instance?

snowell20:08:16

I should say Protocol actually

snowell20:08:23

The record implements the Protocol

manderson20:08:56

@snowell: call the function on the protocol and pass the record in as the first param.

snowell20:08:13

Hmm. I get a TypeError that says it’s not a function

snowell20:08:42

This is clojurescript, so maybe I need to ask over there...

manderson20:08:03

Ah... ok, not as familiar with Cljs, could be a difference.

voxdolo21:08:17

@mokr, @rmuslimov: I've been down all of the aforementioned routes to interact with SOAP APIs in my current app. I currently just use clj-http to throw HTTP posts of the payloads I generate using clojure.data.xml. Those payloads conform with the varying SOAP interfaces I interact with (3 in this app) and I've found maintaining the code much easier keeping it all in Clojure.

voxdolo21:08:29

I started off using the JAX-WS code generators and using them via interop and that was fine until I needed to start extending the code... at which point it became onerous pretty quickly.

rattboi21:08:24

I'm having a hard time coming up with the functional solution to something that seems fairly trivial

voxdolo21:08:34

not to mention, having multiple SOAP APIs I interact with from one app, re-use was completely out of the question with the generated code between the different WSDLs. In straight clojure, I've been able to abstract reasonably.

rattboi21:08:51

I have a list of strings that I want to filter by some filter terms

rattboi21:08:40

I have a list of filter terms (strings)

rattboi21:08:18

I want to filter the list of strings by the list of filter terms, returning a new list with only the items that match ALL filters

rattboi21:08:49

I have a mess that's trying to map some filters that are partialed

rattboi21:08:58

and I keep getting lost on how many terms I get back

rattboi21:08:27

https://gist.github.com/rattboi/1dc8debbc8610dc98b4efddf28409f03 here's what I have that will filter with one term. I'm not positive what I need to do to apply all filters.

rattboi21:08:11

should I move this to #C053AK3F9 ?

markec21:08:56

I’m kinda new here, so can’t really judge if it should go to #C053AK3F9

markec21:08:08

but if I understood problem, solution can be something like

rattboi21:08:42

heh, I finally was getting somewhere similar to you

rattboi21:08:57

(every? some? (map #(re-find (re-pattern %) "EIT_1WORLD_GIFF") '("GIFF" "asdf")))

rattboi21:08:35

that's great. Thanks

markec21:08:45

glad I could help

rattboi21:08:11

I was having a hard time figuring out how to get the "item" bound. You broke it into multiple functions, and that makes sense.

markec21:08:43

I always try that kind of approach with Clojure - multiple functions, each function doing one thing and doing it good

markec21:08:58

I think it pays off, as lot of nested forms are really hard to understand

akiva22:08:08

That’s a basic tenet of FP for most. Better to have a hundred tiny functions that each do one thing well than one monolithic function that does many things poorly. I’m paraphrasing here, of course.

dpsutton22:08:26

anyone using kafka with clojure? I'm trying to get a proof of concept up and running, with kafka 0.8.2.2 with the local copy of zookeeper included with kafka and using clj-kafka, but i'm getting broken pipe errors. anyone work with these products by any chance?

jasonbell22:08:36

what errors are you getting?