#clojure log - Mar 02 2016

The Joy of Clojure
Main Clojure site
Google Group
IRC
List of all logged dates

2:55 solatis: are promises/futures actually used often by clojure programmers? or is it more often core.async?

2:56 or do they complement each other?

3:00 prohobo: HAHA!

3:00 (= is the ONLY equality operator in clojure <3

3:00 thank god

3:01 amalloy: aside from ==, and identical?, and...

3:02 prohobo: damn it

3:02 still better than clisp's eq eql equal equalp

3:03 tolstoy: I don't think I've ever used == or identical?, come to think of it.

3:09 amalloy: == is tough to justify. identical? is useful sometimes

3:10 prohobo: i assume identical isn't just looking for truthy/falsy but more along the lines of same address space?

3:10 same object?

3:10 errr form/atom

3:11 ridcully: its the java ==: object identity

3:12 where = is along .equals

3:12 i assume there is more to it, but thats my naive view on the world here

3:30 renl: hi in clojure destructing, i can destruct a map like [{:keys [a b c]} map1] what if I wanna destruct 2 similar maps in the same local binding like [{:keys [a b c]} map1 {:keys [a b c]} map2]?

3:31 opqdonut: don't use :keys, just normal map destructuring

3:32 you could use something like [{a1 :a b1 :b c1 :c} map1 {a2 :a b2 :b c2 :c} map2] if you really must

3:32 but I'

3:32 d just use (map1 :a) etc in the body

3:33 renl: thanks :D that was what i guessed but was wondering if there were some other magic i wasnt aware of heh

3:59 prohobo: clojure makes the simplest things moderately confusing

4:00 cool

4:04 shadow6ram420: slow loris still in my search bar. :)

4:05 TEttinger: ha

4:05 shadow6ram420: you mentioned tech support? are you programming in clojure or just looking for tech experts?

4:06 there's a pretty good supply for both topics here :)

4:06 shadow6ram420: i just miss the old chris pirillo chat i used to visit

4:07 have been looking any tech community to lurk and just somthing for the second screen.

4:08 i am not a programmer but have fallowed along to a few c++ lessons.

4:12 prohobo: shadow6ram420: i recommend #ubuntu-offtopic or something akin to that

4:12 TEttinger: ah ok, yeah clojure's a good friendly community

4:12 that too

4:12 prohobo: if you want random discussions about computer stuff

4:13 here we talk about dangerous mammals and clojure

4:14 btw, what's the point of destructuring function args?

4:14 well i can see the use for destructuring a map

4:15 but a vector? what difference does it make

4:15 shadow6ram420: who me? i cmae here for deadly mammal chat ty tho.

4:43 TEttinger: prohobo: actually it can be quite handy

4:43 like you could use [10 20 30] to represent a 3d point

4:44 if you want to bind that to x, y, z, you could destructure to (let [[x y z] pt] ...) where pt is the above three-element vector

4:51 prohobo: TEttinger: ah i haven't gotten to let yet

4:52 TEttinger: ah, it's the same destructuring as in fn args

4:52 prohobo: i just saw something like (defn foo [[arg1 arg2 & opts]] ...)

4:52 TEttinger: ah!

4:52 there's a good benefit there

4:52 prohobo: and that essentially works exactly the same as (defn foo [arg1 arg2 & opts] ...)

4:53 what's the benefit?

4:53 tdammers: it's not exactly the same

4:53 you pass the vector as one argument

4:53 TEttinger: normally, if you wanted to pass a collection to the second kind of fn you just entered, you'd need apply

4:54 prohobo: hmmm

4:54 i guess ill see

4:54 TEttinger: ,(defn foo [a b & more] (+ a b (count more)))

4:54 clojurebot: #'sandbox/foo

4:54 TEttinger: ,(foo 1 2 3 4 5)

4:55 clojurebot: 6

4:55 TEttinger: ,(defn bar [[a b & more]] (+ a b (count more)))

4:55 clojurebot: #'sandbox/bar

4:55 TEttinger: ,(bar (range 1 6))

4:55 clojurebot: 6

4:55 TEttinger: similar to

4:55 ,(apply foo (range 1 6))

4:55 clojurebot: 6

4:56 prohobo: o_o

4:56 i cant see it

4:56 TEttinger: not sure I picked a good example

4:56 apply lets you turn a seq of arguments into individual args, essentially

4:56 ,(+ 1 2 3 4)

4:56 clojurebot: 10

4:57 TEttinger: ,(apply + [1 2 3 4])

4:57 clojurebot: 10

4:57 TEttinger: if you just did that last one without apply... not working

4:57 ,(+ [1 2 3 4])

4:57 clojurebot: #error {\n :cause "Cannot cast clojure.lang.PersistentVector to java.lang.Number"\n :via\n [{:type java.lang.ClassCastException\n :message "Cannot cast clojure.lang.PersistentVector to java.lang.Number"\n :at [java.lang.Class cast "Class.java" 3176]}]\n :trace\n [[java.lang.Class cast "Class.java" 3176]\n [clojure.core$cast invokeStatic "core.clj" 351]\n [clojure.core$_PLUS_ invokeStatic "co...

4:58 TEttinger: if you know something is going to give you a vector or seq of some kind, you can either use apply along with a fn that takes individual args, or you can use a fn that destructures that vector or seq

4:59 (if you have that kind of logic where you know there's a bunch of elements, but other fns aren't a good fit like map or reduce)

4:59 prohobo: ah i see

4:59 apply is like a split

4:59 TEttinger: yeah, similar indeed

5:00 it's one of the most common fns in clojure, along with map, filter, reduce...

5:00 I'm only mentioning the fns that take other fns as args, because they're the most useful in general

5:01 tdammers: on a related note; I wonder why function composition isn't anywhere near as popular in clojure as it is in other FP languages

5:01 same for currying

5:01 TEttinger: tdammers: have you seen justin_smith's one-liners in here? :)

5:01 tdammers: not that I consciously remember :D

5:01 TEttinger: he's gotten some pretty good point-free style stuff working before

5:02 tdammers: yeah, but it's not a very common idiom, is it

5:02 TEttinger: and that often uses comp, juxt, and partial

5:02 yeah, it isn't as practical I suppose as in haskell where currying is there anyway

5:02 tdammers: e.g., in Haskell I'd write sth like: foo = apply bar

5:03 TEttinger: (partial apply bar) might come close, but I agree that it isn't as common

5:03 tdammers: yeah

5:03 TEttinger: not quite sure why

5:03 tdammers: especially not to *define* foo

5:03 (def foo (partial apply bar))

5:03 TEttinger: the fns are a bit more verbose, partial instead of the implicit currying

5:04 mpenet: well, the more you write clojure code the more you tend to avoid apply in my exp.

5:04 TEttinger: mpenet: I think it largely depends on how much you control the environment too

5:04 if using a lib that has weird conventions, it may be more common, I'd think

5:05 mpenet: Just checked our (large'ish) codebase, 3 apply calls (on external libs that do unrolled option maps in api)

5:05 yeah

5:05 TEttinger: woah

5:06 mpenet: on carmine too sometimes

5:07 TEttinger: I'm going to be writing a clojure wrapper for a large-ish java lib I've been writing. I haven't quite figured out cursive yet, there seems to be a bug that is normally intermittent and resolves itself but isn't for me

5:07 I'm pretty rusty with clojure though

5:28 tangled_z: ugh, got disconnected.

5:38 sunset-shimmer: hello!

5:39 prohobo: hello

5:42 sunset-shimmer: I've created macros that help me wrap requests to database in something like "with-connection" form. So, now I can write (def-db-cmd [fname args] (cmd args)) and it expands in (defun fname [cmd args] (with-connection *conn* (cmd args))). I like it, but

5:43 ridcully: sunset-shimmer: your text got cut herish: `I like it, but`

5:43 sunset-shimmer: I am Cursive user and Cursive cannot help me with autocompletion of such functions (functions that was generated with macro)

5:43 the question is - is it possible in principle?

5:47 tangled_z: Hi guys, can anyone advice how I could add middleware to a compojure-api api?

5:50 sunset-shimmer: By "it" I mean autocompletion for such functions. May be anyone who uses Cursive too can help me?

5:53 tangled_z: hi! Did you try did it like in this example https://github.com/metosin/compojure-api/wiki/Building-Documented-Apis#middleware

5:55 Leonidas: ,@(java.util.concurrent.FutureTask. (fn [& _] 42))

5:55 clojurebot: eval service is offline

5:55 Leonidas: Any idea why this code does not terminate?

5:56 Calling .get on it does not work either.

6:01 amalloy: futuretask doesn't run a thing unless you ask it to

6:01 @(doto (...) (.run))

6:07 tangled_z: sunset-shimmer: hi! thanks for replying

6:08 I didnt see that example before, but I tried working with it now, and am getting a bit confused about this part: (middleware [wrap-head [wrap-params {:keywords true}]]

6:08 sunset-shimmer: could you explain what the [wrap-head [wrap-params reffer to?

6:09 Im trying to put wrap-cors into it

6:09 but Im not sure if (wrap-cors) should replace "wrap-head" or "wrap-params" in the example

6:17 sunset-shimmer: tangled_z: I haven't used cors but it looks as you can put it in place of any. Like :middleware [wrap-cors]. I think wrap-head and wrap-params are just examples.

6:22 tangled_z: sunshet-shimmer: hmm, it keeps giving me weird errors when I try to put in my code for wrap-cors into it. would you know of any working examples of any other middleware I could have a look at?

6:31 sunset-shimmer: tangled_z: I did't know any. I can try to compose one myself if you have some time for waiting.

6:31 tangled_z: sunset-shimmer: sure! that would be nice of you.

6:32 Im trying to basically put the example from here https://github.com/r0man/ring-cors into the compojure-api middleware

6:34 sunset-shimmer: okay! I'll be back in a moment.

6:47 well, http://pastebin.com/PhgqsRDS that code compiled without errors at any rate

6:47 did you have compile time errors?

6:48 GET http://localhost:3000/api/ping -> {"ping":"pong"}

6:50 tangled_z: sunset-shimmer: ooh that made progress,thanks! no compile errors

6:50 sunset-shimmer: but if we need params like in example... http://pastebin.com/ixhEkKyH that gives error!

6:51 tangled_z: yeah i was about to say, i just tried that

6:51 :(

6:51 any idea why?

6:53 sunset-shimmer: not yet. but lets try to replace vector with lambda.

6:54 tangled_z: hmm

6:55 sunset-shimmer: http://pastebin.com/ZSaf9qfP

6:55 like here

6:56 tangled_z: oooh no errors!

6:56 sunset-shimmer: great!

6:56 tangled_z: :D

6:56 let me see if this works for data transfer

6:56 sunset-shimmer: yes

6:57 I mean, let's go.

6:59 tangled_z: Ok, hmmm... Nope. chrome still says that cross origin requests are not supported

6:59 Empperi: you can do that with CORS

7:00 but yeah, it still says that and will *always* say that

7:00 thank god

7:01 tangled_z: Empperi: what do you mean?

7:01 Im trying to use cors and it's not working. I cant figure out where the problem is.

7:02 Empperi: CORS is a slightly tricky beast which requires multiple pieces to be put together to make it work

7:02 unnecessarily many imho

7:02 tangled_z: Empperi: yeah it is always a pain for me. :( Struggled with it when I was learning django an

7:02 and now again with clj

7:02 Empperi: https://www.refheap.com/52e1ce4a5a560301a3d952909

7:03 that's what you need on the server side

7:04 after that it should be relatively straightforward

7:05 when you try to make a cross domain request browser first sends an OPTION request

7:06 then it'll receive those headers and find that the domain it is currently sitting on is declared at Access-Control-Allow-Origin:

7:06 after that you can make the XHR request to that domain

7:06 oh and yeah, that "Auth" header part: specific to our app :)

7:07 but generic enough

7:07 it's a bit tedious since you need to list *every* HTTP method you like to use and *every* HTTP header

7:07 tangled_z: Empperi: thanks a lot for the code and explanation!

7:07 Erm

7:07 Though

7:08 It's more low level than what Im working with, Im not sure how to connect it with my own code.

7:08 Would you have a use-example?

7:08 Empperi: unfortunately no, this is a closed source project

7:08 but you pretty much need to add that stuff into HTTP responses sent from the server

7:09 after that browsers will handle everything else automatically

7:09 so you can just make a GET request or whatever and browser will under the hood make that OPTION request

7:09 tangled_z: Ohhhh, I see!

7:09 and so the "host" is the host that I am allowing the connection to?

7:09 Empperi: but of course you need to handle that OPTION request :)

7:10 yeah

7:10 that is the host which is serving the javascript trying to make the cross domain XHR request

7:11 if you're serving that js from eg. https://foo.com and making a cross domain request to https://bar.com then the OPTION responses from bar.com should declare foo.com as allowed host

7:11 tangled_z: What do you mean by "handling the option request"? will that not be done automatically?

7:11 Empperi: depends on your application

7:12 but OPTIONS is a HTTP request just like GET is

7:12 let's say you're trying to make GET https://bar.com/api/save-the-world

7:13 browser will first call OPTIONS https://bar.com/api/save-the-world

7:13 and checks if the appropriate CORS headers are in place and if a) current host is allowed to make requests b) if GET method is allowed

7:13 if both match then it proceeds to make the original GET request

7:14 so, if you don't have a proper http request mapping for OPTIONS /api/save-the-world then the caller side will not receive the CORS headers and it will not work

7:14 the easiest way to handle this is to make a universal OPTIONS mapping which receives all OPTIONS requests

7:15 and just return the headers

7:15 the reason why it is like this is that there might be a scenario where one would want to limit cross domain requests per URL

7:16 so in essence when your javascript calls *any* cross domain URL it'll first do that OPTIONS call - always

7:16 so you'll end up doubling your XHR requests

7:16 tangled_z: Empperi: Ahh yes, that makes sense!

7:17 Empperi: so make damn sure your OPTIONS handler is lightning fast, meaning it doesn't do any additional stuff :)

7:17 we created a middleware for that

7:18 it rules out using OPTIONS within our application in route mappings but that shouldn't be a problem

7:18 sunset-shimmer: I should save your conversation for the future use...

7:19 tangled_z: so that means you can't use cors?

7:19 Empperi: sure you can use it

7:19 tangled_z: sunset-shimmer: Oh, I always save helpful conversations :)

7:19 Empperi: it just makes stuff slightly slower

7:20 tangled_z: Hmm. But if you need OPTIONS to pass cors, and you've disabled OPTIONS using the middleware.. hmm.. I am a bit confused!

7:20 Empperi: we can't do OPTIONS mappings within our application if the middleware stops those requests and handle those itself

7:20 sunset-shimmer: tangled_z: did you test it at localhost? Chrome doesn't support localhost for CORS

7:21 Empperi: yes, that is an additional hassle, forgot that

7:21 but you can tell chrome to accept those

7:21 it's ok for development

7:22 tangled_z: Wait what

7:22 Yeah I tested it with chrome -_-

7:27 Empperi: anyway, I need to do some work :)

7:27 hope that clarified a bit

7:27 tangled_z: Alright! Thanks for the advice! :)

7:27 Yeah that was a massive help :)

7:27 Empperi: CORS is pretty complex beast but security stuff tends to be :P

7:27 tangled_z: Yeahh it makes sense why

7:28 Just a paaaaain atm

7:28 Empperi: indeed

7:28 tangled_z: Spent far far longer on it than id want to

7:28 amoe: I'm finding the auto-reloading functionality of "lein ring server" to be very flaky, as in it doesn't notice changed files half the time, and I can't figure out why

7:28 Empperi: we had to do CORS requests since we had to serve our app on HTTP (don't ask) but we still wanted to make all our XHR requests with HTTPS

7:28 and that equals as cross domain request for browsers

7:29 tangled_z: That sounds frustrating

7:29 All I'm doing is trying to communicate between localhost:3000 and localhost:3994 at the moment!

7:32 sunset-shimmer: amoe, me too

7:33 tangled_z: Oh my god WHAT

7:34 It was a typo on the f'cking client the entire time

7:34 God damn it.

7:34 Ok, thanks for the help sunset-shimmer and Empperi. (At least now I know about middle-ware and headers more in depth)

7:35 sunset-shimmer: you are welcome!

7:35 tangled_z: :D

7:35 Yeah it was helpful.

7:35 Empperi: lol

7:35 tangled_z: I am so annoyed with myself right now. Like, I was so convinced that "CORS is difficult so I MUST have made the mistake on the server" that I never double checked the client-side stuff

7:41 amoe: Why would someone write "(let [] (some-expr))"? what use is a let without any bindings?

7:42 opqdonut: amoe: well you can use (let [] ...) instead of (do ...) to turn multiple expressions into one

7:42 amoe: but yeah, let [] doesn't make much sense

7:42 Empperi: but it's just stupid to do it like that

7:43 I didn't even know that compiles :)

7:43 sunset-shimmer: lol

7:43 opqdonut: well it's nice for macro-writing that you can have empty lets

7:43 and empty dos

7:43 etc

7:45 Empperi: true, with macros empty let can make sense

7:46 one doesn't have to handle the special case then

12:28 morbid_ape: hi everyone

12:28 burn all jews in oven

12:28 death to infidel

12:28 allahu akhbar

12:35 phillord: Is there a syntax for getting a short int in Clojure?

12:37 Bronsa: phillord: there's no real short type in the JVM

12:37 morbid_ape: Bronsa you filthy jew

12:37 Bronsa: only int/long exist at the VM level

12:37 morbid_ape: burn in oven you foul jew

12:37 death to infidels

12:37 you foul infidel

12:37 Bronsa: puredanger: ping

12:38 phillord: Bronsa: learn something every day!

12:39 morbid_ape: allahu akhbar!!!! allahu akhbar!!!! allahu akhbar!!!! allahu akhbar!!!! allahu akhbar!!!! allahu akhbar!!!! allahu akhbar!!!! allahu akhbar!!!! allahu akhbar!!!! allahu akhbar!!!! allahu akhbar!!!! allahu akhbar!!!! allahu akhbar!!!!

12:39 demophoon: ops?

12:39 Bronsa: amalloy_:

12:55 justin_smith: phillord: it is possible to put a short into a ByteBuffer though

12:55 morbid_ape: allahu akhbar!!!! allahu akhbar!!!! allahu akhbar!!!! allahu akhbar!!!! allahu akhbar!!!! allahu akhbar!!!! allahu akhbar!!!! allahu akhbar!!!! allahu akhbar!!!! allahu akhbar!!!! allahu akhbar!!!! allahu akhbar!!!! allahu akhbar!!!!

12:55 allahu akhbar!!!! allahu akhbar!!!! allahu akhbar!!!! allahu akhbar!!!! allahu akhbar!!!! allahu akhbar!!!! allahu akhbar!!!! allahu akhbar!!!! allahu akhbar!!!! allahu akhbar!!!! allahu akhbar!!!! allahu akhbar!!!! allahu akhbar!!!!

12:55 justin_smith: (or the universally agreed representation of one)

12:55 morbid_ape: 4allahu akhbar!!!! allahu akhbar!!!! allahu akhbar!!!! allahu akhbar!!!! allahu akhbar!!!! allahu akhbar!!!! allahu akhbar!!!! allahu akhbar!!!! allahu akhbar!!!! allahu akhbar!!!! allahu akhbar!!!! allahu akhbar!!!! allahu akhbar!!!!

12:56 phillord: justin_smith: true -- I guess I am not worried about performance here, though. Really I just need a range which is smaller than int. There are probably better ways to do this, now that I think more clearly

12:56 justin_smith: phillord: you could just use bitwise-and

12:57 * phillord nods

12:57 justin_smith: ,(doc short)

12:57 morbid_ape: bitwise operators are for infidels

12:57 death to infidels

12:57 clojurebot: "([x]); Coerce to short"

12:57 justin_smith: ,(short 32768)

12:58 clojurebot: #error {\n :cause "Value out of range for short: 32768"\n :via\n [{:type java.lang.IllegalArgumentException\n :message "Value out of range for short: 32768"\n :at [clojure.lang.RT shortCast "RT.java" 1153]}]\n :trace\n [[clojure.lang.RT shortCast "RT.java" 1153]\n [sandbox$eval47 invokeStatic "NO_SOURCE_FILE" 0]\n [sandbox$eval47 invoke "NO_SOURCE_FILE" -1]\n [clojure.lang.Compiler eval "Co...

12:58 justin_smith: ,(short 32767)

12:58 clojurebot: 32767

12:58 morbid_ape: CLOJURE IS INFIDEL PROGRAMMING LANGUAGE

12:59 justin_smith: ,(type (short 1)) ; haha

12:59 clojurebot: java.lang.Short

12:59 justin_smith: oh wait, in my repl at home that returns java.lang.Long

12:59 the plot thickens!

13:00 rcassidy: weird, i get Short

13:00 ,(clojure-version)

13:00 clojurebot: "1.8.0"

13:00 justin_smith: rcassidy: never mind, PEBKAC on my end

13:00 rcassidy: ha, gotcha

13:00 justin_smith: so yeah, it does return a Short

13:01 morbid_ape: SIEG HEIL

13:01 HEIL HITLER

13:02 justin_smith: Bronsa's info is usually good, so I wonder what's going on there - the official docs mention short as a primitive and Short as a class https://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html

13:02 WorldsEndless: How to relative paths work in a project? If I specify a file at "resources/myfile.docx" where is it actually going to look relative to my application dir?

13:02 justin_smith: WorldsEndless: it depends who is looking

13:02 WorldsEndless: many lookups are classpath relative

13:02 but some are file system relative

13:02 the latter is very prone to breaking in deployed code though

13:03 WorldsEndless: Sounds like a messy problem...

13:03 How can I reliably reference files shipped with my app?

13:03 justin_smith: WorldsEndless: the best practice is that unless you specifically need something that is on disk, use classpath relative lookup

13:03 WorldsEndless: use clojure.java.io/resource and that returns something as found on the classpath

13:04 morbid_ape: sieg heil

13:04 justin_smith: your resources and your source dirs are all on the classpath, both at dev time and when running from a jar

13:04 morbid_ape: 4allahu akhbar!!!! allahu akhbar!!!! allahu akhbar!!!! allahu akhbar!!!! allahu akhbar!!!! allahu akhbar!!!! allahu akhbar!!!! allahu akhbar!!!! allahu akhbar!!!! allahu akhbar!!!! allahu akhbar!!!! allahu akhbar!!!! allahu akhbar!!!!

13:05 WorldsEndless: justin_smith: So are you saying that a resources/myapp.docx call will check in each location until it finds a matching one, or not?

13:06 justin_smith: WorldsEndless: I'm saying that if you have a file in resources/myapp.docx and resources in in your resources-path (which is the default in lein) then (io/resource "myapp.docx") will find that as a readable resource as runtime

13:07 WorldsEndless: note it will give you something you can read from, but not a file- because things inside jars are not yet files

13:07 (at deploy time that is)

13:07 WorldsEndless: I don't see a :resources-path specified in my project.clj, so I guess it just checks project/resources ?

13:07 rhg135: Usually url

13:07 justin_smith: but you can slurp it or send it via a ring handler or whatever

13:07 WorldsEndless: the default is resources

13:08 WorldsEndless: in a repl, try io/resource - you should get a non-nil return value for things in your resources directory, and they will be included in an uberjar

13:09 and the point of io/resource is it works the same, whether in a repl with files on disk or in a java process with files inside the same jar

13:10 WorldsEndless: Ah! I see. beautiful

13:25 cortexman: is there a version of conj that preserves the order of the arguments?

13:26 maybe i just need to reverse the order of my arguments

13:26 i'm doing conj on a bunch of dicts, and the last one comes first

13:27 justin_smith: cortexman: it has nothing to do with conj, hash-maps do not preserve order

13:27 cortexman: i need a vector of maps that are in a certain order

13:27 justin_smith: and vectors always conj to the end, and lists always conj to the beginning

13:27 cortexman: i see.. hmm..

13:28 ah.

13:28 justin_smith: so by picking between () and [] as your starting value, you should get the order you want, right?

13:28 morbid_ape: YOU ARE A FILTHY HOMOSEXUAL JUDEN ANIMAL PERPETRATOR

13:28 cortexman: yep

14:03 amalloy: oh, he left already

15:40 Shayanjm: So I have (yet another) optimization question. I need to perform a transformation as efficiently as reasonably possible - essentially taking a list of 'filters' with their owners attached, and turning it into a list of owners with their filters attached

15:41 here's a direct example of the input/expected output: https://gist.github.com/shayanjm/2f731644ffd964df6961

15:41 I could trivially build the output using a bunch of nested loops but was wondering if anyone had anything more performant/elegant in mind?

15:52 wgator: list T>1

15:52 \list T>1

15:58 TimMc: Shayanjm: One reduce and a map oughtta do it.

16:04 justin_smith: TimMc: or a transduce with a map transducer, since efficiency was mentioned after all

16:11 TimMc: ...I still haven't tried out transducers.

16:22 amalloy: isn't Shayanjm's problem just "implement group-by"?

16:26 Shayanjm: exactly amalloy

16:26 amalloy: so, why implement group-by instead of using group-by?

16:41 justin_smith: amalloy: I'd say it's more three filters in a vector, maps show up in more than one of the outputs, I don't see how that can be done with group-by?

16:42 amalloy: i see. i hadn't noticed that part

16:43 i guess i would say, how sure are you that performance matters here? start with the really dumb thing of like (apply merge-with into (for [filter filters, user (:users filter)] {user [filter]})) and see what happens

16:44 (this is way more trivial than "a bunch of nested loops")

16:47 justin_smith: yeah, that actually looks close to the answer

16:51 amalloy: well it's a correct solution. whether it's fast enough is one Shayanjm can measure

16:52 justin_smith: {:user-id user :filters [filter]} but sure

16:54 boom: could i trouble someone for help with an error?

16:55 justin_smith: boom: you can always just go ahead and describe the error, but if you need to share more than one line of code, or a stack trace, use a paste site

16:55 boom: ok, I don't think it will take too many lines to describe

16:56 I have a compojure application, and when attempting to build an uberjar, it gives me an error

16:56 Compiling myapp.routes Uberjar aborting because jar failed: clojure.lang.MapEntry cannot be cast to clojure.lang.IPersistentMap

16:56 justin_smith: boom: what that means usually is that you provided a single map where it wanted a sequence of maps

16:56 boom: I've looked at myapp.routes, and the file seems to be fine, but I'm not sure if the error that 'lein uberjar' gives is related to the previous file or not

16:57 I'll double check

16:57 justin_smith: boom: does the app actually run outside the uberjar context, if you just use lein run or whatever?

16:57 boom: yes it runs fine

16:58 justin_smith: ,(def filters [{:data "DATA1" :name "NAME1" :users #{1 2 3} :url "URL1" :title "TITLE1"} {:data "DATA2" :name "NAME2" :users #{1 3} :url "URL2" :title "TITLE2"}])

16:58 clojurebot: #'sandbox/filters

16:58 justin_smith: ,map (fn [[n fs]] {:user-id n :filters fs}) (sort (apply merge-with into (for [filter filters user (:users filter)] {user [filter]}))))

16:59 clojurebot: #object[clojure.core$map 0x4a52f74d "clojure.core$map@4a52f74d"]

16:59 justin_smith: ,(map (fn [[n fs]] {:user-id n :filters fs}) (sort (apply merge-with into (for [filter filters user (:users filter)] {user [filter]}))))

16:59 clojurebot: ({:user-id 1, :filters [{:data "DATA1", :name "NAME1", :users #{1 3 2}, :url "URL1", :title "TITLE1"} {:data "DATA2", :name "NAME2", :users #{1 3}, :url "URL2", :title "TITLE2"}]} {:user-id 2, :filters [{:data "DATA1", :name "NAME1", :users #{1 3 2}, :url "URL1", :title "TITLE1"}]} {:user-id 3, :filters [{:data "DATA1", :name "NAME1", :users #{1 3 2}, :url "URL1", :title "TITLE1"} {:data "DATA2", ...

17:03 Shayanjm: looks great, thanks for your help both justin_smith & amalloy

17:12 boom: ok so I commented out the entire file except for a single route definition, and I'm still receiving the same error from 'lein uberjar'

17:14 TimMc: boom: Maybe post it on a pastebin.

17:18 amalloy: why would you call sort on a map like that? just build a sorted map to begin with. (apply merge-with into (sorted-map) (for ...))

17:19 cortexman: i am getting Caused by: java.util.concurrent.ExecutionException: java.lang.IllegalArgumentException: :db.error/not-a-data-function Unable to resolve data function: :db/id when i try to transact this: [{:db/id #db/id[:db.part/ some-part] :some/id someval}]

17:19 driving me mad

17:20 tolstoy: Maybe try (d/tempid :some-part) instead of the reader macro thing?

17:22 cortexman: tolstoy, no difference

17:22 does it matter that i have a vec of hashmaps

17:23 tolstoy: I'm not sure. Got a paste with the full function call?

17:24 @(d/transact conn [{:db/id (d/temp-id :part) :user/id (d/squuid) :user/name "Ezzie Boof"} {:db/id (d/temp-id :part) :org/name "Dance Club"}])

17:24 That sort of thing works for me all the time.

17:25 Unless I 1) forget the vector, or 2) use an incorrect value for "conn", or 3) forget the conn parameter.

17:30 cortexman: the error message is just so inscrutable

17:30 as far as i can tell, i'm doing what you pasted

17:31 tolstoy: Hm. Maybe I can fire up an app here and see if I can reproduce it.

17:33 cortexman: i'm going to keep hacking on it

17:41 amalloy: so i'm having a problem editing this macro: https://gist.github.com/amalloy/76a82d8f736afcb9ccd8 - it's a simplified version of my real problem, but the issue that i can't seem to get metadata on the list `(force ~delay-sym). you can see what i mean via: (set! *print-meta* true) (macroexpand-1 '(let-later [^String foo "test"] (.length foo)))

17:42 wait never mind, somehow when i wrote it out like that it totally works. what was i doing before that is not working. brb

17:42 justin_smith: amalloy: as an aside, I'm fascinated to see force

17:42 ,(force 1)

17:42 clojurebot: 1

17:43 justin_smith: ,(force (delay 42))

17:43 clojurebot: 42

17:43 justin_smith: cool!

17:43 I always just used deref on delays but that's super handy

17:44 tolstoy: Thinking it makes things clearer?

17:44 justin_smith: tolstoy: yeah, and also it's handy that force on non-delayed things works

17:44 tolstoy: Ah, ok.

17:45 amalloy: ~justin_smith is fascinated by force

17:45 clojurebot: Ik begrijp

17:50 amalloy: sigh. now it works perfectly, but it does me no actual good because clojure.tools.macro discards the metadata i went to all the trouble of putting on my forms

17:50 * amalloy has a love-hate relationship with c.t.macro

18:48 eeepc: i just want to get kicked out of a bunch of channels

18:48 why is no one cooperating??

18:48 #trump2016

18:48 cant stump the trump

18:48 cant stump the trump

18:48 cant stump the trump

18:48 cant stump the trump

18:48 cant stump the trump

20:30 renl: is there a way for filter to produce 2 vectors one which pass the condition and one that does not

20:30 as opposed to doing filter twice with inverse conditions

20:31 oh partition-by i answered my own question heh

20:41 amalloy: that's not what partition-by does

20:44 ,(partition-by even? (range 6))

20:44 clojurebot: ((0) (1) (2) (3) (4) ...)

20:46 pilne: ok, now this time i won't fubar my smeggin install by futzing around with too many languages >.< can i get an a-men?

Logging service provided by n01se.net