Fork me on GitHub

in my UI code i often have to map 1 thing to 2 things. i typically do this using reduce and into. works great. But because the val and coll come after the f, the code is hard to read. So I wrote a reduceb that just puts the args in the order I want. My code now looks like this:

(reduceb [] (range 1 10)
  (fn [rows elt]
    (-> rows
        (into [elt]) ; in real life these two lines are more complicated
        (into [elt]))))
Is there a better way of doing this? Solutions I don’t like include naming the anonymous function so that I can use normal reduce.

Chris O’Donnell01:07:33

Do you mean something like this?

user> (into [] (comp (map (fn [x] [x x])) cat) (range 10))
[0 0 1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9]


i mean i guess that works. i’m really just trying to get the [] and the (range 10) up front because the anonymous function can be quite large at times. i find it easier to read the code knowing what the initialization and looping constructs are

Chris O’Donnell01:07:25

Ah, I understand now. Not sure I have an answer that you like, then.


this may seem like a nit-picky thing, but does anyone know why reduce-indexed doesn't exist?


@antonoutkine there's areduce which provides an index arg for reducing arrays


I don't know why there isn't an indexed reduce though, it's simple enough to make one out of reduce


right, especially given map-indexed and filter-indexed


although maybe I'm just being a perfectionist


There is no filter-indexed in core




reduce-kv works for vectors

👍 8

anyone know what this is used for and where it comes from? ->Channels


the -> prefix usually indicates a factory function generated by defrecord


so it would come from a (defrecord Channels [...])

Mario C.04:07:35

Quick question about Midje: When I run the command lein with-profile <name-A>,<name-B> midje does it look in my test directory and run all the files there?

Mario C.04:07:48

If so, is there a way I can just have midje run one specific file?

Mario C.04:07:40

I want to test that a result that I get back is a map with a key :_id. I can't figure out how to write that in a midje checker

Mario C.04:07:15

I don't care about the value of the _id


@mario.cordova.862 There's a #midje channel but I've no idea how active it is. Midje is... not idiomatic... so it's a minority testing engine...


I like what it does with README files but I wouldn't use it for anything else. I'm trying to get Expectations up to speed on README files so I can stop using Midje but I'm not there yet.


Midje brings a lot of "magic" to bear. My general advice would be to avoid it as a beginner. Learn how clojure.test works first -- since that's what all the tooling is based on.

Mario C.05:07:10

I didn't even know that Expectations existed! We are using midje in my internship so thats what I am learning but maybe I can bring this framework up to the team.


Well, there's an #expectations channel too, but I'll still recommend learning everything about clojure.test first before deciding you don't want to use it 🙂

Mario C.05:07:02

@seancorfield Thanks! Will def start learning clojure.test!


how can I print emojis to terminal... is the a list that work with clojure?


Clojure will print emojis just fine...


how do you use them? just wanting to use them in println's


I don't understand the question. Emojis print just fine.


for me it's just printing the text. when I muck around with it I get an error lol


So... you're not doing it right? Can you share what you've tried?


(println "U+2705 Finished inlining css")


The “U+2705” string is not how Clojure represents raw unicode. Just use \u instead of U+ like this

(println "\u2705 Done.")


That's not a Unicode escape sequence.


sorry I don't quite know what that means


im just copy pasting them it seems to be working


Why should I use clojure.set/differenceinstead of disj?

(defonce my-set (atom #{"1" "2" "3"}))
=> #{"1" "2" "3"}
(swap! my-set disj "1")
=> #{"2" "3"} 
(swap! my-set clojure.set/difference #{"2"})
=> #{"3"} 


Seems equal to me in outcome, as long as I just have one item to be removed. Am I missing something here?


If your goal is to remove a single element from a set, then there is every reason to use disj


clojure.set/difference is most appropriate when you already have two sets, and want all the elements of the first that are not in the second.


Thanks Andy. I was following a tutorial and stumbled over that part where the author decided to use clojure.set/difference in the same way I showed there. Didn't make sense to me.


@noisesmith > core.async only works inside one vm, akka works across vms / hosts iirc that's right, but serialization is a pain in the cross vm/host scenario ... something that's trivial with clojure


anyway even in a single vm, in what sense does core.async provide (or enable building) back-pressure?


yes, >! and >!! both put backpressure on the caller


@matan @noisesmith CSP channels provide backpressure in the sense that IO operations happen only when the reader and the writer are both ready to transfer. That's why core.async communication operations are said to be parking/blocking : they wait for the other end to be ready. The actor model is fundamentally different because sending a message to an actor is a fire-and-forget operation, completing immediately without any control of recipient's ability to process messages. To implement backpressure on top of an actor system, an extra layer is needed to enable bidirectional communication between producer and consumer. This is basically what they did with akka streams, a declarative streaming engine that happens to be implemented with actors but where actors are mostly absent from user API because they're not backpressured as-is.

Mario C.17:07:44

Does anyone have any experience with a clojure REPL wrapping a result in a lazyseq?


you called str


if you use pr-str instead you get the normal printed representation

Mario C.17:07:34

No I am not calling str. I inserting to a postgres db.

Mario C.17:07:26

(sql/insert! @url
                              (keyword (:cars table-names))
                              {:body car-info
                               :_id  (.toString (:_id interview))


OK, something called str, the repl doesn't wrap anything in a lazyseq on its own, but a lazy object returns a silly string starting with "clojure.lang.LazySeq" instead of something that looks like the contents


.toString does the same thing str does on a single input


user=> (str (map inc (range 10)))
user=> (pr-str (map inc (range 10)))
"(1 2 3 4 5 6 7 8 9 10)"


user=> (.toString (map inc (range 10)))

Mario C.17:07:02

That should return a map. As it does but for some weird reason this repl is wrapping it in a lazyseq


no, your repl isn't doing that, your code is, somewhere


for example you used filter or map to update the value


are you sure insert! doesn't return a lazy seq?


oh, I might be misunderstanding the problem here

Mario C.17:07:29

It does not

Mario C.17:07:56

It returns a map. seancorfield proved it to me a while back.


what does the result that you have a problem with actually look like


are you sure you understood what he proved?

Mario C.17:07:14

The result I have problem with is that the insert! returns a map. But when I println the result it is a lazyseq


I work with sean and we use a lot, and the first insert! call I found in the code base calls first on the result


maybe you misunderstood what he proved to you?

Mario C.17:07:43

Well, he fired up a repl and showed me the result of insert! and it indeed returned a map.


are you sure he didn't use one of the other insert functions like insert-record?

Mario C.17:07:29

I am also doing (extend-protocol sql/IResultSetReadColumn PGobject...)


(oh, insert-record doesn't exist, not sure what I am thinking of)

Mario C.17:07:56

But that function doesn't do anything wraps it in a lazyseq


anyway, insert! returns a seq of generated keys


(which are likely wrapped in a map in some way)

Mario C.17:07:32

In general, operations return
the number of rows affected, except for a single record insert where any
generated keys are returned (as a map).

Mario C.17:07:14

(println (type (insert-function-that-does-saving-goes-here))) ==> clojure.lang.LazySeq



boot.user=> (jdbc/insert! db-spec :status {:name "foo"})
({:generated_key 9})
boot.user=> (jdbc/insert! db-spec :status {:name "foo"} {:row-fn :generated_key :result-set-fn first})


Coming from the js/redux world I’m accustomed to use reducers as pure functions that depends of the type of an action and it’s payload like so:

const my_reducer_example = (state, action) => {
   switch(action.type) {
       case: 'FOO':
       case: 'BAR':
            return state.filter(bar_fn);
            return state;
If I want to rewrite this in clojure, would multimethods be the way to go? Or maybe protocols?


Given that I have multiple reducers which accept the same type of actions


Also @mario.cordova.862

boot.user=> (type (jdbc/insert! db-spec :status {:name "foo"}))


That namespace docstring (`In general, operations return...`) seems to be referring to a very old version of the API. It's misleading, so I'll remove that.

Mario C.18:07:11

So if I understood you correctly the insert! function does, in fact, return a seq?

Mario C.18:07:54

@seancorfield The strange thing is that I don't get a result that looks like your example, ( { :generated_key 50 } )

Mario C.18:07:38

I actually get something that looks like ( { :id 1 :body "value" } )

Mario C.18:07:51

The map in there is what I actually want.


I'm using MySQL. You're using a different DB.


What actually gets returned from an insert -- specifically from a PreparedStatement that is configured to return generated keys -- varies between databases, unfortunately.


PostgreSQL returns the entire row I believe.

Mario C.18:07:57

But whatever that what actually is, will be in a seq, regardless?


Yes, a single-element sequence for insert!. A multi-element sequence for insert-multi!.


Long ago, the API was different and you could indeed get back either a map or a sequence of maps. That's what that one line of the namespace docstring referred to.

Mario C.18:07:47

@seancorfield Thank you for clearing that up

Mario C.18:07:14

I was going crazy thinking I was doing something that was putting it in a lazyseq


@pablore Just to make sure: have you seen the re-frame project? It is the most redux-like front end solution out there and you won’t have to reinvent the wheel.


Arguably, the explicit verbosity of writing out the dynamic dispatch functions by hand is part of the charm of redux because it makes it easier to see what actions might modify a given piece of state.


I know re-frame, but this is a backend app that I am making


But multimethods and protocols should work fine too.


@sundbp hey does anyone know how the #profile is determined when setting up a config file with:

Karol Wójcik19:07:25

I have some difficulties when it comes to understand ring handlers. In Node.js for example everything is asynchronous by default. What is a difference between the handler from Node.js and the handler from the Ring world? What are these asynchronous handlers and how to they differ from normal one in Ring? How the ring knows when the request is asynchronous or synchronous? As always thanks in advance for your responses. You are all great!


In node.js you don't have threads so you can only get parallelism via async handlers. In ring your webserver will use a thread pool to handle requests, or it might use async workers or even combine the approaches. Typical ring code doesn't even have to care which approach the underlying server is using.


if you have intense enough throughput that you need async for the performance boost, you'll probably end up using something based on netty, in my experience the aleph webserver (which offers its own ring adapter) works quite well


if you are ok with nodejs performance, you won't have to worry about performance on the jvm


tech empower has done multiple rounds of benchmarks of different webstacks, and nodejs with whatever database is never better then the middle of the pack


oh, sorry, I thought they only listed 100 when I said middle of the pack. nodejs is never in the top 50 out of 273 tested

Karol Wójcik19:07:09

Ok so to sum up I will never know when my server calls the asynchronous handler?

Karol Wójcik19:07:43

Or it's server dependant?


I am not sure, the async handler stuff is pretty new in ring and I've never needed it


I suspect you implement one or the other, and the ring adapter has to figure it out


it is a flag you pass to the adapter you use


ring is a spec that defines a bunch of different parts, the part that turns a given webserver (like jetty) is called an adapter


the official jetty adapter has an :async? option

Karol Wójcik20:07:30

What if there are many requests per server. Will the jetty auto scale the number of threads?


we have this kind of non-standard (it is netty based, so not that far from the beaten path) webserver I am using in a project at work, it provides some custom logic for dealing with a protocol built on top of http and websockets which we plugin in to which exposes an entirely not http like interface, and then I also have an in house ring adapter plugged in for http handlers


there is a configuration parameter if I recall


I think jetty defaults to a 50 thread threadpool

Karol Wójcik20:07:26

;OOO That's the huge amount


I've never had to change it, most of the jetty services I've exposed have been internal things, but you might want to adjust that if you are serving end users


50 threads is nothing

Karol Wójcik20:07:15

In Node.js I had only 1 thread 😛


I had a bug in some code once that caused the jvm to spawn something like 10k threads (that were sitting around doing nothing) and no one noticed it until at one point in a repl on a server I asked the jvm for a stack dump of all the threads

😱 4
Karol Wójcik20:07:27

I had no idea that the jvm threads are so cheap


linux is pretty ok at multithreading these days

Karol Wójcik20:07:16

Are there better systems for multithreading?

Karol Wójcik20:07:28

How can I check how many threads my app allocates?


jstack is pretty useful


(count (Thread/getAllStackTraces)) will tell you at the repl, you will be shocked at how many threads you have running


(9 with lein repl, 4 with clj)

Karol Wójcik20:07:11

hmm but is there a way to somehow check that in application?

Karol Wójcik20:07:24

Other than manually logging that value?\


yes, any kind of reporting/health check framework will tell you


but it isn't always very meaningful to know, so I wouldn't get hung up on it

Karol Wójcik20:07:49

Ok thank you! I'm really grateful that you spare your time on me.