Fork me on GitHub

As a data point from the other end of the spectrum, we tend to take each milestone release of Clojure to production as they are generally very stable. That lets us take advantage of new features as soon as they appear. We originally went to production on 1.3.0 Alpha 7 (or Alpha 8 ) back in 2011 and we’re on 1.8.0 Beta 1 in production right now, with Beta 2 on staging, ready to go to production in our next build.

Alex Miller (Clojure team)03:11:59

Yeah, but you're crazy :)


The first time I read your feedback on putting 1.7.alpha something into production I was like...ok, who would do this. But after figuring your workflow out and the success you have it puts a very positive light on clojure itself. So I think it is a good advertisement for the language.


@alexmiller: the socket REPL design page mentions some special keywords to drive some REPL behavior. was that implemented yet? can't find any references in the code?


eg. :repl/attach

Alex Miller (Clojure team)15:11:01

It was implemented and then we decided we did not need it and it was removed


java -cp lein classpath` -Dclojure.server.myrepl="{:address \"\" :port 5555 :accept clojure.repl/repl :args [] :server-daemon false}" clojure.main -r`


java -cp clojure-1.8.0-RC1.jar -Dclojure.server.myrepl="{:address \"\" :port 5555 :accept clojure.epl :args [] :server-daemon false}" clojure.main -r


am i missing something here?

Alex Miller (Clojure team)15:11:58

The default repl lacks support for some useful stream redirection


oh an 'r' indeed


i can't get this thing to run

Alex Miller (Clojure team)15:11:01

there are some docs on this at btw farther down the page

Alex Miller (Clojure team)15:11:40

I would recommend that you use clojure.core.server/repl as the repl accept function - this sets up the streams for the socket appropriately which the default repl will not

Alex Miller (Clojure team)15:11:35

you are also passing a number of values you don't need to that have the same default values


first time messing around with this stuff, just copying stuff from the design page

Alex Miller (Clojure team)15:11:37

you had a typo in the accept function above - clojure.epl, not sure if that was the source of the NPE


clojure.core.server/repl works

Alex Miller (Clojure team)15:11:22

but might be able to improve the error reporting on a bad accept function. happy for a ticket if so.


hi, we've stumbled upon a core.async behaviour I'm not sure is correct, would appreciate some feedback


one example:


(let [slow (a/chan 1 (map (fn [v] (Thread/sleep 10000) v)))
        fast (a/chan 1 (map (fn [v] v)))]
      (a/>!! slow 42))
      (Thread/sleep 1000)          
      (a/>!! fast 4711))
    (let [[v c] (a/alts!! [slow fast])]


two channels, one with a "slow" xform


put to both chans in separate threads


then an alts!! call


the alts!! always waits for the slow chan (even if it returns value from fast one)


(this is [org.clojure/core.async "0.2.371"] btw)


am I going crazy here or should the fast chan have a value available after ~1s and that should be returned by alts!! call?

Alex Miller (Clojure team)16:11:10

doing Thread/sleep will I think put that sleep in the thread of the alt take

Alex Miller (Clojure team)16:11:10

to ensure that only one of the ops succeeds there is locking that occurs over each channel involved - I suspect that coupled with the transducer may be causing what you see but I would have to look at the code and think through it

Alex Miller (Clojure team)16:11:06

if you run something like this without the transducer (instead just a go block or thread that sleeps and emits a value for example)

Alex Miller (Clojure team)16:11:56

the transducer runs under the channel lock - there is a warning somewhere that you should thus not do excessive work in your channel transformation


thanks for having a look. we're aware that you don't want to do excessive work in a channel transformation... this was slightly accidental in our case


seems like the definition of an operation being "ready" (in alts!) might be a little subtle when channel tranducers are involved


the behaviour is the same even if I give the channels bigger buffers (although in this case only 1 value is ever put)


ah, I think I see now


the buffer add! is done under channel lock, and alt is waiting for same lock


Otoh I thought alt only locked the handlers involved in the alt op... 😕


i probably need to dig deep into the ReadPort/WritePort and alt impls. to understand this


alt handlers lock a shared flag


@ghadi: do you also agree that a slow channel transducer would result in the alt behaviour I'm seeing?


thanks, I'm digging through that and the channel impl


"yeah don't do that" simple_smile


point taken simple_smile


under some circumstances you might not always know the properties of the channels you're given though


and you might want to wait at most 10s


but yes, i see that you or the creator of the channels are misusing channel transducers then


(by "you" I mean me)


general rule is that channel transducers should do no I/O or side-effects


data transformations 👌