Fork me on GitHub
#clojure
<
2016-09-16
>
fabrao00:09:33

What is the best way to sort this map?

{"30/07" 0, "10/08" 5, "09/08" 2, "01/08" 2, "22/08" 1, "04/08" 0, "25/07" 9, "31/07" 0, "28/07" 0, "08/08" 3, "19/08" 1, "14/08" 0, "18/08" 5, "27/07" 4, "29/07" 0, "17/08" 4, "16/08" 0, "06/08" 0, "15/08" 2, "23/07" 0, "21/08" 0, "26/07" 7, "24/07" 0, "07/08" 0, "05/08" 1, "11/08" 1, "02/08" 1, "13/08" 0, "12/08" 1, "20/08" 0, "03/08" 0}

fabrao00:09:06

This is a sequence of day

bwstearns00:09:38

do you want to sort chronologically?

bwstearns00:09:21

You can make a sorting function to use with sort-by. I forget the exact way to do it off the top of my head

bwstearns00:09:57

clojure.core/sort-by
([keyfn coll] [keyfn comp coll])
  Returns a sorted sequence of the items in coll, where the sort
  order is determined by comparing (keyfn item).  If no comparator is
  supplied, uses compare.  comparator must implement
  java.util.Comparator.  If coll is a Java array, it will be modified.
  To avoid this, sort a copy of the array.

bwstearns00:09:15

I have an example somewhere, looking for it now.

fabrao00:09:48

I tried it but I´m confuse about how to select the key from it

isaac_cambron00:09:23

What do you mean exactly by "sort the map"? Like what kind of output collection do you want?

bwstearns00:09:55

ah, wait. if you want a sorted map at the end then maybe

clojure.core/sorted-map-by
([comparator & keyvals])
  keyval => key val
  Returns a new sorted map with supplied mappings, using the supplied
  comparator.  If any keys are equal, they are handled as if by
  repeated uses of assoc.

isaac_cambron00:09:10

right, that's what i'm wondering too

akiva00:09:35

I want to go back to my suggestion earlier. Make a list of keys via (keys) and then you can manipulate the heck out of it. Sort it, filter it, do whatever, and then use the results as a means to access the map.

bwstearns00:09:27

Also make helper functions for creating a sortable date from the keys. I'd be concerned about year handling given that you appear to have multi-month data (and you could have "12/01" and "01/12" and have no good way of knowing which was first as is.

akiva00:09:05

Well put.

akiva00:09:49

It’s not unusual to want to shoe-horn FP principles into OOP structures when it’s what you know; I struggled with that a lot. There is almost always a way to address a data structure based on the answer you want from it rather than what it actually is represented by.

fabrao00:09:07

@isaac_cambron

{"30/07" 0, "10/08" 5, "09/08" 2, "01/08" 2, "22/08" 1, "04/08" 0, "25/07" 9, "31/07" 0, "28/07" 0, "08/08" 3, "19/08" 1, "14/08" 0, "18/08" 5, "27/07" 4, "29/07" 0, "17/08" 4, "16/08" 0, "06/08" 0, "15/08" 2, "23/07" 0, "21/08" 0, "26/07" 7, "24/07" 0, "07/08" 0, "05/08" 1, "11/08" 1, "02/08" 1, "13/08" 0, "12/08" 1, "20/08" 0, "03/08" 0}
=>
{"23/07" 0, "24/07" 0, "25/07" 9 ... }

isaac_cambron00:09:56

right, so you definitely need sorted-map-by because regular maps aren't sorted

isaac_cambron00:09:13

now you just need a comparator appropriate for parsing your dates

isaac_cambron00:09:31

and if your list is long enough, memorize the parse on them

fabrao00:09:43

In comparator I´m realy confuse how to select the compare key

(fn [key1 key2] (compare [(get resultado key2) key2] [(get resultado key1) key1]))

bwstearns00:09:54

The key function could make a tuple of (mm dd) where mm and dd were the inted month and day values. But going back a step a map isn't sorted so you need to decide whether you want a sorted-map or something else.

fabrao00:09:02

like in docs says

isaac_cambron00:09:28

think of the comparator as being run for you on any two keys the sorter thinks it needs to compare to get the full ordering right

isaac_cambron00:09:37

your job is just to take in two keys and compare them

akiva00:09:25

Again, use keys. Then you have a list that can be sorted however you like. All you want to do is deal with the keys and then get the value.

isaac_cambron00:09:42

so you need something that returns -1, 0, or 1 based on whether key1 is smaller, equal to, or bigger than key2

fabrao01:09:40

@akiva how do you mean? Get keys and use for sorting reference?

fabrao01:09:25

I can make the keys in right order, so how to apply it to sorting in the same sequence?

akiva01:09:59

Yeah. If you give keys a map, it returns a list of keys so it’ll give you a list of “30/07” etc. Then you can manipulate that list, such as with sort or sort-by or filter, and then map through that last to get the values from the map that you’re after.

fabrao01:09:04

hummm I´ll give a try

akiva01:09:07

And keep coming back asking questions. We’ll get this solved together.

isaac_cambron01:09:26

product> (require '[clj-time.format :as f])
product> (def orig {"30/07" 0, "10/08" 5, "09/08" 2, "01/08" 2, "22/08" 1, "04/08" 0, "25/07" 9, "31/07" 0, "28/07" 0, "08/08" 3, "19/08" 1, "14/08" 0, "18/08" 5, "27/07" 4, "29/07" 0, "17/08" 4, "16/08" 0, "06/08" 0, "15/08" 2, "23/07" 0, "21/08" 0, "26/07" 7, "24/07" 0, "07/08" 0, "05/08" 1, "11/08" 1, "02/08" 1, "13/08" 0, "12/08" 1, "20/08" 0, "03/08" 0})
#'product/orig
product> (def to-date (memoize (fn [s] (f/parse (f/formatter "dd/MM") s))))
#'product/to-date
product> (defn compare-dates [k1 k2] (compare (to-date k1) (to-date k2)))
#'product/compare-dates
product> (into (sorted-map-by compare-dates) orig)
{"23/07" 0, "24/07" 0, "25/07" 9, "26/07" 7, "27/07" 4, "28/07" 0, "29/07" 0, "30/07" 0, "31/07" 0, "01/08" 2, "02/08" 1, "03/08" 0, "04/08" 0, "05/08" 1, "06/08" 0, "07/08" 0, "08/08" 3, "09/08" 2, "10/08" 5, "11/08" 1, "12/08" 1, "13/08" 0, "14/08" 0, "15/08" 2, "16/08" 0, "17/08" 4, "18/08" 5, "19/08" 1, "20/08" 0, "21/08" 0, "22/08" 1}

isaac_cambron01:09:28

so I probably shouldn't have done that for you, but i realized i wasn't actually very familiar with sorted-map-by so i tired it out

akiva01:09:48

That’s an excellent solution, @isaac_cambron. My issue, which is by no means definite, is that I don’t like locking down data structures like that.

isaac_cambron01:09:27

sure, fair enough

bwstearns01:09:34

Locking down the date format you're saying?

akiva01:09:54

Locking down the sorting. I much prefer letting later functions fuss about that sort of thing.

akiva01:09:18

It’s why I never imbed a filter in a map. You’ll see a lot of (map #(filter …) coll).

fabrao01:09:41

(sort-by #((into {} (map-indexed (fn [i e] [e i]) ["2" "1" "3"])) (first %)) {"1" 0,"2" 0,"3" 0})

fabrao01:09:32

I think it will be right that I want

akiva01:09:38

See, to me, those are three different functions that need to be separated and then, say, brought together with comp.

akiva01:09:22

You really don’t want to have a function doing more than one thing, in my opinion.

akiva01:09:51

Like you may want an end result of the map being sorted in a certain way and filtered some other way and from an OOP perspective that’s exactly what you’d do.

akiva01:09:14

If you’re enclosing one function in another function, that, to me, is a pressure point.

akiva01:09:23

It’s where you should have two composable functions.

akiva01:09:51

I don’t know your skill level so I apologize if I’m messing that bit up.

fabrao01:09:56

of course not, I came from Java and sometimes Clojure freeze my brain 🙂

akiva01:09:11

Hahaha, heard. I spent 12 years doing C#/.NET.

fabrao01:09:47

in this time, I just want the rigth result neverming the way rs

bwstearns01:09:51

definitely easy to keep burrowing to the hard solution sometimes in clojure when there's an easier way just around the corner.

akiva01:09:03

@fabrao, well put. Make it work; then make it pretty.

fabrao01:09:34

that´s my needs now

akiva01:09:02

Gotcha. And, at the same time, I think it’s good to get a glance at the bigger picture. But, yeah, get it to work.

isaac_cambron01:09:20

you also might consider not storing the date data as strings, depending on what they really mean and how you're using them

fabrao01:09:21

I´ve rewrite this function about 10 times lol

akiva01:09:42

@fabrao, it’s a good exercise!

akiva01:09:17

I look at my early Clojure code which I wrote even after getting FP experience with F# and Common LISP and… uh… yeah, best not to be seen by other humans/animals/plants/rocks/etc.

fabrao01:09:25

@isaac_cambron I´ll use it to make linear graphic as dataset

isaac_cambron01:09:05

i mean, it all depends on how much you want to do, but i'd typically do something like: 1. parse everything 2. do all the manipulation 3. output in whatever format

fabrao01:09:56

@akiva When I remember that one day I programmed in imperative, I got itch

isaac_cambron01:09:56

for example, if you look at the code i wrote above, it inlines the parsing into the sort, which is funky. the dates are semantically dates so it's smoother if you treat them that way. Otherwise anything that has to engage in their dateness needs to parse them

akiva01:09:32

@fabrao, well, welcome to the Clojure community! Even if you end up having to go back to Java in your day job, you bet what you learn here will make you a better coder everywhere.

bwstearns01:09:28

also a vector of tuples might be the desired data structure here if you don't really care about preserving the constant time access for a random element.

fabrao01:09:04

Java is tools only now lol

akiva01:09:09

Honestly, team, I think the issue here is the idea that values are married to their keys and that link must be preserved. It honestly doesn’t have to be which is why I keep harping about (keys).

akiva01:09:32

In an OOP world, that linkage makes sense.

bwstearns01:09:02

I don't disagree. Easy enough to just sort the keys and get the appropriate values using get when you need them.

isaac_cambron01:09:28

i guess that's what i think of sorted-map-by as doing

isaac_cambron01:09:43

sort of just depends if you need the sorted keys independently of the values or not

akiva01:09:51

@isaac_cambron, it probably is. And in certain situations, when you get into performance, it may make a difference.

akiva01:09:24

I just don’t like ‘trapping’ data. I want to get data from its source and then manipulate it incrementally.

akiva01:09:18

It’s why transducers are so bad ass. You can create manipulations without stipulating the source. You just pipe them all together.

fabrao01:09:18

data as stream you mean?

bwstearns01:09:42

It doesn't sound like there's a need to have a map at the end of it. If it's feeding a line graph then it will be iterated over to provide y values

akiva01:09:53

Data as any kind of collection in the Clojure sense of the word. Whether it’s from a database or its created as a LazySeq.

akiva01:09:47

@bwstearns, in all humility, I ask, is that something a function needs to know? Filter this. Sort that. Intent in my opinion should be orthogonal and created by composition.

isaac_cambron01:09:32

i think that's basically bwstearn's point. if it needs sorted just sort it and let it come out however it comes out

fabrao01:09:40

in line graph with jfree you need a map to do it

akiva01:09:56

The map is the final product and so that should be the last in the chain. That’s all there is to it, really.

akiva01:09:11

Who cares if it’s a vector or list going in.

isaac_cambron01:09:20

hmm, but there's a practical issue there

isaac_cambron01:09:40

which is that taking a sorted seq and pushing it into a map loses order guarantees

isaac_cambron01:09:56

so at some point if you need a sorted output map you're going to have to build one

akiva01:09:58

Which is why I keep going back to keys!

akiva01:09:16

The values don’t matter; the order of the keys in the map do.

fabrao01:09:34

your talking is in high level for me, I´m in Clojure and FP only a year

akiva01:09:41

To put it another way, the moment your functions care about your intent is bad. Just like having an object’s fields all public.

akiva01:09:13

@fabrao, yeah, I know, and I apologize. I’m really being philosophical here. You can ignore most of it. Just, y’know, plant the seeds in the back of your mind and come back to it. Go back to what you typed before: make it work for now.

isaac_cambron01:09:00

sure, but at some point you have to pass a data structure to something else and if it needs a sorted map.... though that does raise an interesting question: @fabrao, are you sure you need a the keys sorted to give them to jfree?

akiva01:09:24

@isaac_cambron, yep yep yep. My fuss is that if you have one function that knows another function exists, you have the FP equivalent of ‘tightly-coupled’. In a perfect world, every function operates independently of every other function.

isaac_cambron01:09:34

oh, let's talk about this! because this is a huge learning opportunity

akiva01:09:42

For me too!

isaac_cambron01:09:54

see, this is what i was talking about: what's happening here is that you're generating the sequence of days as strings

isaac_cambron01:09:04

and then you have sort them as dates

akiva01:09:52

Yeah, @isaac_cambron is correct. You need to shape your data first.

isaac_cambron01:09:54

(@akiva I agree about decoupling, btw)

fabrao01:09:08

@isaac_cambron Yes, I have to show the days in sequence of a line graph, the problem is, when I apply something to change the map, it change the sequence

isaac_cambron01:09:28

right, but here's the thing. you want to do all your manipulation, and then format it

fabrao01:09:32

because it get lazy

isaac_cambron01:09:53

you want the keys in your map (let's stick with your existing data structure for just a sec) to be the clj-dates

isaac_cambron01:09:57

because they're dates

isaac_cambron01:09:27

that way they're a lot easier to do things like sort

isaac_cambron01:09:41

you only want to turn them into strings at the end

fabrao01:09:54

so, how to format it at the end?

isaac_cambron01:09:04

well, here's an outline:

akiva01:09:07

You want to shape your data first.

akiva01:09:49

source -> shape -> manipulate -> produce.

akiva01:09:11

So if you want to manipulate dates, you need to shape the keys into dates via map.

fabrao01:09:26

I´m doing 2 things, the data from database that count tickets per day by period and all the days with zero count

akiva01:09:29

(map clj-time-fn source)

akiva01:09:35

You’re doing at least four things.

fabrao01:09:59

I merge it, so all the days will have data

akiva01:09:09

Right, that’s the intent.

akiva01:09:28

Basically, imagine you have a treasure map and what the customer wants is the X that marks the spot.

akiva01:09:54

The X seems like a huge thing because it’s what the customer wants but really it’s just the last function.

akiva01:09:42

You have to grab the data (#1), shape the data to make it into something you don’t have to fight against (#2, which is where you are now), change the data into what you want it to be (#3), and then finally make the data into whatever format the customer wants.

isaac_cambron01:09:49

(->>
  (get-the data-from-the-database)
  (turn-it-into-the-best-data-structure)
  (your-logic-for-what-to-do-with-it)
  (turn-it-into-the-format-you-want-output))

isaac_cambron01:09:27

the trouble is you're trying to do the last step too early and saddling yourself with a hard-to-use data structure

akiva01:09:35

And you’re trying to do it all at once in one function.

akiva01:09:45

Spew out a dozen functions. Three dozen. Doesn’t matter.

fabrao01:09:47

I´m writing it as a tatoo lol

akiva01:09:56

It’s far better, in my opinion, to have a private defn- than an anonymous function because it makes things self-describing.

akiva01:09:52

(map get-recent-users users-coll) is much better than (map #(filter …) …) blah blah blah.

fabrao01:09:56

well, now I´m getting understand how to write it. I read many articles about Functional Thinking to break the imperative bareer

fabrao01:09:32

Like I said, it freezes my brain sometimes

akiva01:09:39

Same here and I’ve been doing this for years.

fabrao01:09:54

And FP worth it, many many lost writting lines ouch

akiva01:09:46

I think it’s a good thing. It’s frustrating. But it’s definitely a good thing.

fabrao01:09:09

I´m working with Java since 2010, and since last year I´ve never heard about Clojure

akiva01:09:40

Again, @fabrao, welcome to the community. Your presence here is very well valued.

fabrao01:09:48

and now I can´t look back

akiva01:09:50

Even if we choose not to pass you by reference. 😉

fabrao01:09:39

so source -> shape -> manipulate -> produce, I´m making it as tatoo in my arm

akiva01:09:21

Yep. I almost don’t even like the term ‘functional programming’ and almost want to call it ‘data-oriented programming’.

fabrao01:09:51

yep, lambda calculus is crazy you must see https://www.youtube.com/watch?v=peOk3W7KZ4o

akiva01:09:33

I should watch that. I’m an auto-didact so I don’t have a CS degree (hell, I didn’t even graduate high school).

fabrao01:09:17

is Clojure paying your bills?

akiva01:09:23

Oh, in the spirit of such, if you’re on the same road I’m on, you really need to throw down the cash for http://impostershandbook.com.

akiva01:09:26

Sometimes!

akiva01:09:47

I haven’t not coded professionally in any other language in years.

akiva01:09:09

I can’t go back to .NET and even Crockford JavaScript breaks me out into cold sweats.

isaac_cambron01:09:32

FWIW, i have a fancy CS degree and also like that book a lot. we're all imposters, at some level

fabrao01:09:50

I´m using Clojure with CA Technologies UIM

akiva01:09:23

Good, @fabrao. As I typed before, even if you don’t end up coding Clojure professionally, what you learn from FP principles is going to be a goodness for you.

fabrao01:09:21

I did some "probes" in Java and I migrated to Clojure

fabrao01:09:34

Clojure is paying my bills lol

akiva01:09:40

Excellent!

fabrao02:09:17

so, let´s start again source -> shape -> manipulate -> produce , hahaHa

akiva02:09:54

Yep. Get the data, shape the data into something you can work with, manipulate the data into whatever form is best, then produce a result the client expects.

akiva02:09:11

And by ‘client’, it could be just the results of a REST operation.

fabrao02:09:38

I stoped in get the data

akiva02:09:59

If you treat these four steps as discrete and completely unrelated, it may help.

akiva02:09:59

It’s getting late here and Mr. Robot just came on so I’m going.

fabrao02:09:24

Folks, thank you for the help

akiva02:09:33

Wait, no, it’s Thursday. Now I’m mad. I have to wait a whole week to next Wednesday.

akiva02:09:44

But I’m still out.

viesti07:09:38

@miikka odd thing is that there are no other packages that depend on byte-streams. There was a shared dependency to riddle from pandect though (which we use also). Anyway, ended up solving the problem in a different way but would have been neat to be able split the input data in memory for parallel handing though.

hans08:09:06

Is there a way to find all resources matching a given regular expression or wildcard string? I would like to include a bunch of files in the jar's resources and compute a list of them at run time.

elise_huard08:09:53

is there a usual suspect for a compojure middleware (or other) to escape html strings, or do we roll our own?

chrisetheridge08:09:20

@akiva i love your analogy of the treasure map and transforming data

hans08:09:36

@coltnz Thanks, I'll have a look!

pesterhazy08:09:06

Is there a map/`vector` hybrid data structure for clojure? I'd like fast key-based access and remember insertion order (for a FIFO cache)

hans08:09:44

@pesterhazy did you try ordered sets/maps yet?

pesterhazy08:09:06

@hans, that looks exactly right, except that I need it for clojurescript

hans08:09:35

@pesterhazy You may want to ask your clojurescript questions in #clojurescript 😄

pesterhazy08:09:42

a simple solution may also be just to store keys separately [{:a :b :c :d :e :f} [:a :c :e]}

alexyakushev09:09:07

Could anyone help? I think I found a bug/unexpected behavior in core.async: https://gist.github.com/alexander-yakushev/a03b1b6dd14c531cb6d00bd75d8519a8

alexyakushev09:09:43

TL.DR: After a take, the first pending put into a fixed-buffer channel always succeeds, even if the buffer is full.

alexyakushev09:09:18

In my case it leads to the buffer growing infinitely

joost-diepenmaat09:09:02

what’s in cat ?

alexyakushev09:09:26

cat is a concatenating transducer

alexyakushev09:09:44

Lists of values come into the channel, individual items come out

jazen09:09:37

Why is this unexpected? put and take are blocking operations and when you take one out while putting 3 into it every time the loop runs..

alexyakushev09:09:23

I expect the channel to remain blocked until its buffer is smaller than the maximum size again

jazen09:09:46

Ah okay, missed the 10 up there

joost-diepenmaat09:09:55

Not sure if it’s a bug but it’s unexpected behaviour for me @alexyakushev

joost-diepenmaat09:09:05

I would also expect the initial go-loop to block before putting in 10 and 11

fabrao11:09:26

@isaac_cambron and @akiva Thanks for your help, your advice about source -> shape -> manipulate -> produce saved my day, it´s more simpler than I´ve trying to do. I used day as Datetime and just (sort-by first days-map), format output and that´s it.

idiomancy15:09:16

does anyone know what you need to implement in a deftype in order to support the "into" operation? Or, if you're more into the "teach a man to fish" thing, could anyone tell me how to look that kind of thing up? Because it seems like there's a maze of classes and interfaces in clojure.lang

plexus15:09:23

@idiomancy look up the source of into in clojure.core. AFAIK it just does a (reduce conj ,,,), so you would have to implement conj

jjfine15:09:28

yeah, and seq if you want to pass your new type as the second argument

idiomancy15:09:56

ahh, I see, so its basically "trace the implementation of the function you want until you hit java"

gowder15:09:26

kind folks, I've written a very (very) short plain english explanation/example of basic transducer use, mainly because I find the language in the official doc very intimidating. Would someone with more experience mind giving it a quick glance-over and telling me if it's horribly inaccurate? thinking of a PR to the clojure cookbook or something like that. https://gist.github.com/paultopia/f374a964038a91e4afdb52c9376d3a33

timgilbert17:09:32

Hey, I have a syntax question: looking at https://github.com/ngrunwald/ring-middleware-format/blob/master/src/ring/middleware/format_params.clj#L21 what does the notation #^bytes signify? I was expecting just ^bytes.

mpenet17:09:16

It s the old type hint notation syntax, circa 1.2- if i recall

bfabry18:09:30

@idiomancy I'd tentatively say in clojure we're biased towards using the existing types for data, and so don't find ourselves implementing new types that act like the types we already have very often

idiomancy18:09:13

@bfabry i'm of the same bias. My boss would prefer it implemented with a wrapper that makes it work with map stuff. I built all the code with functions doing the manipulation, because I dont thing (my-special-get map key not-found) is really terrible.

hiredman18:09:45

user=> (into [] (reify clojure.lang.Seqable (seq [_] '(1 2 3))))
[1 2 3]
user=> 

idiomancy18:09:58

and one picks ones battles, naw'm sayn?

bfabry18:09:19

sure. anyway it looks like you just need to implement IPersistentCollection

hiredman18:09:46

all you need to do is to be able to produce a seq and implement Seqable

bfabry18:09:10

@hiredman he wants to support the into operation for his type. I assume that means he wants his type as the first argument

hiredman18:09:17

there are some macros people have written to make it easier to implement custom collections that implement all the right clojure interfaces

hiredman18:09:33

I think potemkin has them for maps

bfabry18:09:34

true! potemkin is popular for that I think

hiredman18:09:50

I would likely just not use into

hiredman18:09:43

(reduce my-custom-append initial-thing seq-of-things) is all you need for a custom into, without adding extra dependencies or risking screwing up implementing all the methods a custom collection needs

hiredman18:09:46

if you have some kind of pojo like object that you want to behave as a map, my guess would be it is because you are passing that object back and forth between clojure and java, I would suggest keeping it as a map on the clojure side, and wrapping and unwrapping, then you can leave all that silly stuff at the edge and not have to deal with it in clojure

bleadof18:09:23

Hi! A newbie question, but is there a good resource for learning core.async through code problems , similiar to koans?

bfabry19:09:58

@bleadof I'm not aware of anything similar to koans, but personally I found David Nolen's blog posts on cljs+core.async very helpful for understanding core.async

bleadof19:09:17

@bfabry, Cheers, I’ll check those out 🙂

shaun-mahood19:09:23

@bleadof: If you're looking for other good materials, @tbaldridge has a whole bunch of excellent videos at https://www.youtube.com/playlist?list=PLhi8pL3xn1OTDGCyXnkZStox6yFjn2583 - they require a subscription but it's well worth it in my opinion.

plexus19:09:47

Those videos are not available outside the US though, unfortunately

shaun-mahood19:09:59

@plexus: Works in Canada at least, but that really sucks that you can't access them. I wonder if there's a setting that needs to be changed or something about youtube subscriptions?

plexus19:09:34

I'm guessing there are tax reasons why it's easier not to bother with European customers. Too bad, heard good things about them

sveri19:09:35

does not work in germany execept the first one

shaun-mahood20:09:54

@tbaldridge: Any options on your end for fixing things, or is it a youtube limitiation?

tom21:09:11

With jdbc/insert-multi! is there a way to print out the SQL statements actually used?

seancorfield21:09:46

@tom not currently — there was a JIRA issue open for long time to make the actual SQL available (somehow) but it was never implemented (not sure how best to handle it that would work for all users).