Fork me on GitHub
#clojure
<
2016-09-02
>
josh_tackett03:09:12

Looking for XML to JSON anyone know a good library?

seancorfield03:09:07

@josh_tackett XML -> Clojure data structures (clojure.data.xml) -> JSON (clojure.data.json or Cheshire)

viesti07:09:33

hmm, having hard time with :pedantic? :abort and cider-jack-in (using Leiningen 2.7.0). cider-jack-in fails with

Could not start nREPL server: Possibly confusing dependencies found:
[org.clojure/tools.nrepl "0.2.12"]
 overrides
[org.clojure/tools.nrepl "0.2.12" :exclusions [org.clojure/clojure]]

viesti07:09:17

started an app with duct template and it has a :repl profile, would like to move cider from :user to :repl in ~/.lein/profiles.clj`, but the project specific :repl profile overrides it. Then tried cider-jack-in but that ends up putting tools.nrepl twice in dependencies, which probably causes the above error

lmergen08:09:14

so, what would be the best way to keep track of a counter that is synchronized between threads, and where the other thread will block until count has reached N ? the most natural to me would be to keep track of an atom, and have thread A call (swap! counter inc), and have the other thread poll this counter until @(counter) == N any other ideas ?

hiredman08:09:44

there are a bunch of neat constructs in java.util.concurrent

lmergen08:09:07

yeah i want to keep it a bit readable, this is for tests, rather than “actual” code

hiredman08:09:23

you could just use a Semaphore

lmergen08:09:06

yes this is really a semaphore, is that concept even used at all in clojure ?

hiredman08:09:21

oh, duh, use a countdownlatch

hiredman08:09:39

imergen: java.util.concurrent is a great package, you should not avoid using it when it doesn't have a clojure wrapper

lmergen08:09:15

ok, i will get over my high horse and look into it 🙂

dexter08:09:21

does anyone here use riemann?

lmergen08:09:52

we’re actually right in the middle of selecting riemann or some alternative — it’s a good candidate for what we want

dexter08:09:57

I'm trying to publish it a message containing a vector of messages so I can do something like (last (:ExceptionMessageChain %)) but while tags seems to be a vec so they are clearly possible it just seems like a string so I need to do read-string which itself seems dangerous and then I've got the issue of hoping I escaped the strings appropriately

chrisetheridge08:09:13

does (methods my-multi-method) work when using an uberjar?

hiredman08:09:48

you likely are not properly loading all the namespaces that have defmethods in them, which is why they aren't there

chrisetheridge08:09:05

that could definitely be it. let me take a look

chrisetheridge09:09:16

yup that was it @hiredman - my repl ns was loading them, but not the main ns. hence why the jar was different 🙂

chrisetheridge09:09:19

thanks for the help!

quoll10:09:01

@lmergen: if you want a Clojure idiom for Countdown Latch, use a promise. These block until delivered. And they're implemented using java.util.concurrent.CountDownLatch

lmergen10:09:29

thanks @quoll, i feel this is indeed the right approach

sandarr9512:09:32

He first time using slack, so don't know if this proper use but: I'm making a game where there's a master process that is able to start new games for people and then you can join that game via a client (telegram bot api). First I thought about putting all games in an atom as a "global" state but that means that if game1 changes, the state gets changed globally. Meaning game2 also would undergo an atomic "change" (although nothing would actually change) while game2 has nothing to do with game1. So I moved on to try and design it with async channels so every game would have its own event channel which may change the state. This seemed like better design except that sometimes a client event only needs to observe the state the game is in and do something on its own (for example showing what other players are in the game). From a talk from Rich Hickey (don't remember precisely which one) I heard an observing action should never interrupt or do something to the this that's observed. He used the analogy of a baseball game and people watching the game. When someone wants to see what's happening they just observe but the game moves on just the same. That would be possible by using an atom/ref but not with the channels. I hope the problem is clear now, but it basically boils down to: One implementation does something I like but does something else I don't want while the other implementation is the other way around. I'm looking for either solving the thing I don't want in a certain implementation or using a combination of both or other implementations so the thing I don't want doesn't apply. Again first time using slack, so if you have any tips at all I would love to hear them and hopefully someone here knows their way better around these kinds of design structures and finds a solve. (As for what the games about if you're interested. I'm trying to make Town of Salem playable via Telegram by using the telegram bot api)

manutter5112:09:46

@sandarr95 Have you looked at re-frame? (https://github.com/Day8/re-frame). It’s for writing client-side stuff, but it sounds like the general philosophy behind it might apply

chrisetheridge13:09:16

yeah the re-frame design ideas sound great for this kind of application

chrisetheridge13:09:30

but, it sounds like your application is very event driven. async is great for event driven applications

manutter5114:09:32

I was thinking that too. Re-frame has its own mechanism for queuing and dispatching events, but there’s no reason async couldn’t be part of that

chrisetheridge14:09:42

yeah it has it’s own event system, but the theory / thinking behind it can definitely be applied here. it is really well explained

robert-stuttaford14:09:00

one of the best readmes i've seen for any project

chrisetheridge14:09:06

yup, definitely one of the best

chrisetheridge14:09:15

learned a lot from it, even though i haven’t used it much at all

akiva14:09:58

I had no intention of using re-frame until I read that. Now it’s what I plan on using for my next project.

shyambalu14:09:34

+1 for reframe

manutter5114:09:42

I’ve just been using it for my first “real” Clojurescript/reagent app for work, and I’ve found only one really serious problem with it so far — it makes it really hard to go back to vanilla Java/Javascript

shyambalu14:09:33

in the docs section they have an explicit section about how to apply re-frame for game loops

sandarr9514:09:51

I wanted to thank you all but I'm so busy reading ;)

sandarr9514:09:48

@shyambalu: I cant find that part, in what file is it?

caio15:09:25

@sandarr95 you can use a combination of the two. imagine a channel that receives transformer functions (a function that receives the game datastructure and returns the transformed game). you pass the consumed function to a swap! on the atom, so that every transformation to the game is serialized through the channel. idk if the hich hickey quote applies here, as we’re talking about the baseball players, not the audience, right? If there’s some observation that needs to be done, a simple derefon the game atom would do the trick without blocking anything

caio15:09:36

here’s a snippet for a game:

(let [game-state (atom {})
      game-port  (chan)]
  (defn curr-game-state
    "Game state getter. Simply derefs the game state atom"
    []
    @game-state)

  (defn play!
    "Adds a play to the queue of plays. A play is a transformation to the game state"
    [f]
    (>!! game-port f))

  (go-loop ;; the game loop. consumes messages in
      [next-play-fn (<! game-port)]
    (swap! game-state next-play-fn)))

caio15:09:38

then the player’s code would simply call curr-game-state or play!

caio15:09:30

(play! (fn [game-state] (assoc {:player-one {:score 100}})) is an example of play

caio15:09:02

as a side note: I wrapped stuff in a let clause, so you can implement a multi-game code by just wrapping this with a macro to declare the game functions

caio15:09:51

(defmacro defgame [game-name]
  `(let [game-state# (atom {})
         game-port#  (chan)]
     (defn ~(symbol (str game-name "-state"))
       "Game state getter. Simply derefs the game state atom"
       []
       @game-state#)

     (defn ~(symbol (str "play-" game-name "!"))
       "Adds a play to the queue of plays. A play is a transformation to the game state"
       [f]
       (>!! game-port# f))

     (go-loop ;; the game loop. consumes messages in
         [next-play-fn# (<! game-port#)]
       (swap! game-state# next-play-fn#))))
so you’d declare a game as (defgame my-game) and the functions would be play-my-game! and my-game-state

sandarr9516:09:33

Hey wow this looks really promising, thought about a similar construct myself too, just one other small thing: If I want to manage all running games, I would have some kind of running-games state like: => (def running-games (atom {})) But if I now: => (swap! conj running-games (defgame _)) I have nested atoms... I don't know how wrong that is but it feels wrong. What construct actually serves my purpose I think quite perfect is where I have a single atom of which I can share subsets, and the other processes get to see only the subset and modify only the subset: => (def running-games (atom {:game1 (->Gamerecord args) :game2 (->Gamerecord args)})) => (defn run-game [game game-port] (go-loop [event (<! game-port)] (do (swap! game handle-event event) (recur (<! game-port))))) => (run-game (:game1 running-games) (chan)) So in this case the subsets of collection in an atom would themselves act like atoms in the sense that you can deref and swap! them. And this would make it so if a state change from game1 and game2 happen at the same time they can both be applied because it is known that they don't interfere with each other, yet the master process can talk about them as a whole. I must say that I see that this is really just nested atoms that you don't see. It could be possible that I am missing the obvious here btw

caio16:09:53

the global state don’t need to be an atom, only the games

sandarr9516:09:29

I saw you send something but you removed it but it pointed out the issue pretty well, because if I do need to start and stop games, running-games has changing state so it must be something like an atom. Or my design in general is bad...

dpsutton16:09:22

i'm running into issues serializing some data with cheshire to json because i'm using an org joda time DateTime. is there a good way to have this happen automatically?

dpsutton16:09:46

i think i'm being an idiot

dpsutton16:09:51

so don't worry about me 🙂

sandarr9516:09:18

https://github.com/clj-time/clj-time/ Maybe this does the trick, made a little project with it but I believe it uses Joda Time and supports parsing at least to java long/clj numbers

caio16:09:28

yeah. I was out to lunch and couldn’t finish what I started writing. I was going to say that then it should be the other way around: only a single atom for all game states (redux/re-frame ideas)

sandarr9516:09:02

https://github.com/cgrand/megaref I'm gonna try using this, don't know if its the best solution but it looks like it does what I thought of

sandarr9516:09:37

Thanks a lot for the help and thought though, re-frame looks promising too

Alex Miller (Clojure team)17:09:41

symbols can’t start with a +

Alex Miller (Clojure team)17:09:22

or rather +1 specifically is tokenized as a number

Alex Miller (Clojure team)17:09:42

++1 is an invalid number so parses as a symbol ok

Alex Miller (Clojure team)17:09:28

really it’s parsing by prefix so once it gets to ++ it shouldn’t be trying to parse a number anymore

tengstrand17:09:46

Ok, good answer!

spacepluk18:09:49

does anybody know about a nice article about lazy-seqs gotchas? I'm blowing the heap and I can't figure out why 😕

Alex Miller (Clojure team)18:09:01

I guess that usually results in a stack overflow

Alex Miller (Clojure team)18:09:19

for running out of heap, you’re mostly likely holding onto the head of a large lazy sequence

grav18:09:22

I contributed a patch to a github project. The pull request is accepted but there isn’t yet a release on clojars. What’s the best way of including the project as a dependency in a deployment setup until it’s officially released? Should I add my own fork to Clojars?

grav18:09:42

(i haven’t pushed anything to Clojars before)

chris18:09:53

install it in your local maven repo and reference that version

chris18:09:50

assuming you don’t need to share it with anyone yet

grav18:09:53

Ok. Not sure if I have access to it, though. Could I add it directly to my own project as a temp solution?

grav18:09:53

I do need to deploy it remotely somewhere else, which I don’t have access to apart from my own project’s git repo

chris18:09:32

I would do the second answer on this page

Alex Miller (Clojure team)18:09:48

you can fork and publish to clojars under your own id

chris18:09:00

just tick the version on your version of the library, and install that version in your local maven repo

chris18:09:23

then lein/maven should use that version rather than pulling from clojars

chris18:09:49

and when your fix makes it into the mainline you don’t have to do anything except update the version number

chris18:09:20

note that I’m basing all of this off my knowledge of maven, and lein might handle things a little differently

chris18:09:41

wow, I missed that you did need to deploy it somewhere else, sorry. a forked version to clojars is the best way to do this

grav18:09:53

Cool, thanks for the hints 🙂

grzm21:09:55

I'm trying to specify a logback.xml file to an uberjar using java -jar -Dlogback.configurationFile=/path/to/logback.xml myuber.jar and it's not overriding the one on the classpath (`config/logback.xml`) in the project directory during compilation. Is this due to AOT? How are others working around this?

gfredericks21:09:13

shouldn't have anything to do with AOT

grzm21:09:19

Good, 'cause that's another area I would need to learn more about 🙂

tanzoniteblack21:09:12

@grzm probably not a real solution to your current problem, but I ended up getting so frustrated with logback/log4j xml files not ever wanting to work as I think they should and just started using https://github.com/ptaoussanis/timbre for my logging needs

tanzoniteblack21:09:26

that wasn’t a clojure specific frustration, always had the same issue in java as well

grzm21:09:30

@tanzoniteblack I've heard of other people having success with timbre as well. This is really the first issue I've had with logback/sl4j (though I haven't been using it much)

paul.legato23:09:10

@tanzoniteblack I wrote onelog for similar reasons: dead simple, zero-configuration Clojure logging that just works. https://github.com/pjlegato/onelog/

paul.legato23:09:26

Never waste time screwing around with an XML file again.

grzm23:09:24

The xml config itself doesn't bother me. Figuring out why the -D configuration parameter isn't getting picked up is 😕 Suppose that should be the next thing I try to debug: see if I can get other parameters to be read in the same jar from the command line.

grzm23:09:08

Interestingly I do set this successfully in my test environment via :jvm-opts ["-Dlogback.configurationFile=test/config/logback.xml"] in my project.clj file. So it gets picked up in some conditions.

hiredman23:09:27

grzm: aot clojure compilation isn't going to effect how the java logback library looks for configuration files

grzm23:09:09

@hiredman thanks for the confirmation. I no longer think that's the issue, but still don't know what the next step in my debugging should be.

hiredman23:09:47

you should check to see that the file you are specifying actually exists, and check the logback docs to see if that option overrides what it finds on the classpath

hiredman23:09:56

I would also look at the syntax for your java call

hiredman23:09:23

I don't think you can define a property between the -jar flag and the jar file name

grzm23:09:51

I've seen it both ways 🙂 I've been trying both as well

grzm23:09:57

looks like it might be a path issue. Added wrinkle is that it's running in a Docker container.