2016-03-02
| 02:55 | solatis | are promises/futures actually used often by clojure programmers? or is it more often core.async? |
| 02:56 | solatis | or do they complement each other? |
| 03:00 | prohobo | HAHA! |
| 03:00 | prohobo | (= is the ONLY equality operator in clojure <3 |
| 03:00 | prohobo | thank god |
| 03:01 | amalloy | aside from ==, and identical?, and... |
| 03:02 | prohobo | damn it |
| 03:02 | prohobo | still better than clisp's eq eql equal equalp |
| 03:03 | tolstoy | I don't think I've ever used == or identical?, come to think of it. |
| 03:09 | amalloy | == is tough to justify. identical? is useful sometimes |
| 03:10 | prohobo | i assume identical isn't just looking for truthy/falsy but more along the lines of same address space? |
| 03:10 | prohobo | same object? |
| 03:10 | prohobo | errr form/atom |
| 03:11 | ridcully | its the java ==: object identity |
| 03:12 | ridcully | where = is along .equals |
| 03:12 | ridcully | i assume there is more to it, but thats my naive view on the world here |
| 03: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]? |
| 03:31 | opqdonut | don't use :keys, just normal map destructuring |
| 03:32 | opqdonut | you could use something like [{a1 :a b1 :b c1 :c} map1 {a2 :a b2 :b c2 :c} map2] if you really must |
| 03:32 | opqdonut | but I' |
| 03:32 | opqdonut | d just use (map1 :a) etc in the body |
| 03:33 | renl | thanks :D that was what i guessed but was wondering if there were some other magic i wasnt aware of heh |
| 03:59 | prohobo | clojure makes the simplest things moderately confusing |
| 04:00 | prohobo | cool |
| 04:04 | shadow6ram420 | slow loris still in my search bar. :) |
| 04:05 | TEttinger | ha |
| 04:05 | TEttinger | shadow6ram420: you mentioned tech support? are you programming in clojure or just looking for tech experts? |
| 04:06 | TEttinger | there's a pretty good supply for both topics here :) |
| 04:06 | shadow6ram420 | i just miss the old chris pirillo chat i used to visit |
| 04:07 | shadow6ram420 | have been looking any tech community to lurk and just somthing for the second screen. |
| 04:08 | shadow6ram420 | i am not a programmer but have fallowed along to a few c++ lessons. |
| 04:12 | prohobo | shadow6ram420: i recommend #ubuntu-offtopic or something akin to that |
| 04:12 | TEttinger | ah ok, yeah clojure's a good friendly community |
| 04:12 | TEttinger | that too |
| 04:12 | prohobo | if you want random discussions about computer stuff |
| 04:13 | prohobo | here we talk about dangerous mammals and clojure |
| 04:14 | prohobo | btw, what's the point of destructuring function args? |
| 04:14 | prohobo | well i can see the use for destructuring a map |
| 04:15 | prohobo | but a vector? what difference does it make |
| 04:15 | shadow6ram420 | who me? i cmae here for deadly mammal chat ty tho. |
| 04:43 | TEttinger | prohobo: actually it can be quite handy |
| 04:43 | TEttinger | like you could use [10 20 30] to represent a 3d point |
| 04:44 | TEttinger | 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 |
| 04:51 | prohobo | TEttinger: ah i haven't gotten to let yet |
| 04:52 | TEttinger | ah, it's the same destructuring as in fn args |
| 04:52 | prohobo | i just saw something like (defn foo [[arg1 arg2 & opts]] ...) |
| 04:52 | TEttinger | ah! |
| 04:52 | TEttinger | there's a good benefit there |
| 04:52 | prohobo | and that essentially works exactly the same as (defn foo [arg1 arg2 & opts] ...) |
| 04:53 | prohobo | what's the benefit? |
| 04:53 | tdammers | it's not exactly the same |
| 04:53 | tdammers | you pass the vector as one argument |
| 04:53 | TEttinger | normally, if you wanted to pass a collection to the second kind of fn you just entered, you'd need apply |
| 04:54 | prohobo | hmmm |
| 04:54 | prohobo | i guess ill see |
| 04:54 | TEttinger | ,(defn foo [a b & more] (+ a b (count more))) |
| 04:54 | clojurebot | #'sandbox/foo |
| 04:54 | TEttinger | ,(foo 1 2 3 4 5) |
| 04:55 | clojurebot | 6 |
| 04:55 | TEttinger | ,(defn bar [[a b & more]] (+ a b (count more))) |
| 04:55 | clojurebot | #'sandbox/bar |
| 04:55 | TEttinger | ,(bar (range 1 6)) |
| 04:55 | clojurebot | 6 |
| 04:55 | TEttinger | similar to |
| 04:55 | TEttinger | ,(apply foo (range 1 6)) |
| 04:55 | clojurebot | 6 |
| 04:56 | prohobo | o_o |
| 04:56 | prohobo | i cant see it |
| 04:56 | TEttinger | not sure I picked a good example |
| 04:56 | TEttinger | apply lets you turn a seq of arguments into individual args, essentially |
| 04:56 | TEttinger | ,(+ 1 2 3 4) |
| 04:56 | clojurebot | 10 |
| 04:57 | TEttinger | ,(apply + [1 2 3 4]) |
| 04:57 | clojurebot | 10 |
| 04:57 | TEttinger | if you just did that last one without apply... not working |
| 04:57 | TEttinger | ,(+ [1 2 3 4]) |
| 04: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... |
| 04: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 |
| 04:59 | TEttinger | (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) |
| 04:59 | prohobo | ah i see |
| 04:59 | prohobo | apply is like a split |
| 04:59 | TEttinger | yeah, similar indeed |
| 05:00 | TEttinger | it's one of the most common fns in clojure, along with map, filter, reduce... |
| 05:00 | TEttinger | I'm only mentioning the fns that take other fns as args, because they're the most useful in general |
| 05: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 |
| 05:01 | tdammers | same for currying |
| 05:01 | TEttinger | tdammers: have you seen justin_smith's one-liners in here? :) |
| 05:01 | tdammers | not that I consciously remember :D |
| 05:01 | TEttinger | he's gotten some pretty good point-free style stuff working before |
| 05:02 | tdammers | yeah, but it's not a very common idiom, is it |
| 05:02 | TEttinger | and that often uses comp, juxt, and partial |
| 05:02 | TEttinger | yeah, it isn't as practical I suppose as in haskell where currying is there anyway |
| 05:02 | tdammers | e.g., in Haskell I'd write sth like: foo = apply bar |
| 05:03 | TEttinger | (partial apply bar) might come close, but I agree that it isn't as common |
| 05:03 | tdammers | yeah |
| 05:03 | TEttinger | not quite sure why |
| 05:03 | tdammers | especially not to *define* foo |
| 05:03 | tdammers | (def foo (partial apply bar)) |
| 05:03 | TEttinger | the fns are a bit more verbose, partial instead of the implicit currying |
| 05:04 | mpenet | well, the more you write clojure code the more you tend to avoid apply in my exp. |
| 05:04 | TEttinger | mpenet: I think it largely depends on how much you control the environment too |
| 05:04 | TEttinger | if using a lib that has weird conventions, it may be more common, I'd think |
| 05:05 | mpenet | Just checked our (large'ish) codebase, 3 apply calls (on external libs that do unrolled option maps in api) |
| 05:05 | mpenet | yeah |
| 05:05 | TEttinger | woah |
| 05:06 | mpenet | on carmine too sometimes |
| 05: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 |
| 05:07 | TEttinger | I'm pretty rusty with clojure though |
| 05:28 | tangled_z | ugh, got disconnected. |
| 05:38 | sunset-shimmer | hello! |
| 05:39 | prohobo | hello |
| 05: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 |
| 05:43 | ridcully | sunset-shimmer: your text got cut herish: `I like it, but` |
| 05:43 | sunset-shimmer | I am Cursive user and Cursive cannot help me with autocompletion of such functions (functions that was generated with macro) |
| 05:43 | sunset-shimmer | the question is - is it possible in principle? |
| 05:47 | tangled_z | Hi guys, can anyone advice how I could add middleware to a compojure-api api? |
| 05:50 | sunset-shimmer | By "it" I mean autocompletion for such functions. May be anyone who uses Cursive too can help me? |
| 05:53 | sunset-shimmer | tangled_z: hi! Did you try did it like in this example https://github.com/metosin/compojure-api/wiki/Building-Documented-Apis#middleware |
| 05:55 | Leonidas | ,@(java.util.concurrent.FutureTask. (fn [& _] 42)) |
| 05:55 | clojurebot | eval service is offline |
| 05:55 | Leonidas | Any idea why this code does not terminate? |
| 05:56 | Leonidas | Calling .get on it does not work either. |
| 06:01 | amalloy | futuretask doesn't run a thing unless you ask it to |
| 06:01 | amalloy | @(doto (...) (.run)) |
| 06:07 | tangled_z | sunset-shimmer: hi! thanks for replying |
| 06:08 | tangled_z | 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}]] |
| 06:08 | tangled_z | sunset-shimmer: could you explain what the [wrap-head [wrap-params reffer to? |
| 06:09 | tangled_z | Im trying to put wrap-cors into it |
| 06:09 | tangled_z | but Im not sure if (wrap-cors) should replace "wrap-head" or "wrap-params" in the example |
| 06: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. |
| 06: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? |
| 06:31 | sunset-shimmer | tangled_z: I did't know any. I can try to compose one myself if you have some time for waiting. |
| 06:31 | tangled_z | sunset-shimmer: sure! that would be nice of you. |
| 06:32 | tangled_z | Im trying to basically put the example from here https://github.com/r0man/ring-cors into the compojure-api middleware |
| 06:34 | sunset-shimmer | okay! I'll be back in a moment. |
| 06:47 | sunset-shimmer | well, http://pastebin.com/PhgqsRDS that code compiled without errors at any rate |
| 06:47 | sunset-shimmer | did you have compile time errors? |
| 06:48 | sunset-shimmer | GET http://localhost:3000/api/ping -> {"ping":"pong"} |
| 06:50 | tangled_z | sunset-shimmer: ooh that made progress,thanks! no compile errors |
| 06:50 | sunset-shimmer | but if we need params like in example... http://pastebin.com/ixhEkKyH that gives error! |
| 06:51 | tangled_z | yeah i was about to say, i just tried that |
| 06:51 | tangled_z | :( |
| 06:51 | tangled_z | any idea why? |
| 06:53 | sunset-shimmer | not yet. but lets try to replace vector with lambda. |
| 06:54 | tangled_z | hmm |
| 06:55 | sunset-shimmer | http://pastebin.com/ZSaf9qfP |
| 06:55 | sunset-shimmer | like here |
| 06:56 | tangled_z | oooh no errors! |
| 06:56 | sunset-shimmer | great! |
| 06:56 | tangled_z | :D |
| 06:56 | tangled_z | let me see if this works for data transfer |
| 06:56 | sunset-shimmer | yes |
| 06:57 | sunset-shimmer | I mean, let's go. |
| 06:59 | tangled_z | Ok, hmmm... Nope. chrome still says that cross origin requests are not supported |
| 06:59 | Empperi | you can do that with CORS |
| 07:00 | Empperi | but yeah, it still says that and will *always* say that |
| 07:00 | Empperi | thank god |
| 07:01 | tangled_z | Empperi: what do you mean? |
| 07:01 | tangled_z | Im trying to use cors and it's not working. I cant figure out where the problem is. |
| 07:02 | Empperi | CORS is a slightly tricky beast which requires multiple pieces to be put together to make it work |
| 07:02 | Empperi | unnecessarily many imho |
| 07:02 | tangled_z | Empperi: yeah it is always a pain for me. :( Struggled with it when I was learning django an |
| 07:02 | tangled_z | and now again with clj |
| 07:02 | Empperi | https://www.refheap.com/52e1ce4a5a560301a3d952909 |
| 07:03 | Empperi | that's what you need on the server side |
| 07:04 | Empperi | after that it should be relatively straightforward |
| 07:05 | Empperi | when you try to make a cross domain request browser first sends an OPTION request |
| 07:06 | Empperi | then it'll receive those headers and find that the domain it is currently sitting on is declared at Access-Control-Allow-Origin: |
| 07:06 | Empperi | after that you can make the XHR request to that domain |
| 07:06 | Empperi | oh and yeah, that "Auth" header part: specific to our app :) |
| 07:07 | Empperi | but generic enough |
| 07:07 | Empperi | it's a bit tedious since you need to list *every* HTTP method you like to use and *every* HTTP header |
| 07:07 | tangled_z | Empperi: thanks a lot for the code and explanation! |
| 07:07 | tangled_z | Erm |
| 07:07 | tangled_z | Though |
| 07:08 | tangled_z | It's more low level than what Im working with, Im not sure how to connect it with my own code. |
| 07:08 | tangled_z | Would you have a use-example? |
| 07:08 | Empperi | unfortunately no, this is a closed source project |
| 07:08 | Empperi | but you pretty much need to add that stuff into HTTP responses sent from the server |
| 07:09 | Empperi | after that browsers will handle everything else automatically |
| 07:09 | Empperi | so you can just make a GET request or whatever and browser will under the hood make that OPTION request |
| 07:09 | tangled_z | Ohhhh, I see! |
| 07:09 | tangled_z | and so the "host" is the host that I am allowing the connection to? |
| 07:09 | Empperi | but of course you need to handle that OPTION request :) |
| 07:10 | Empperi | yeah |
| 07:10 | Empperi | that is the host which is serving the javascript trying to make the cross domain XHR request |
| 07:11 | Empperi | 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 |
| 07:11 | tangled_z | What do you mean by "handling the option request"? will that not be done automatically? |
| 07:11 | Empperi | depends on your application |
| 07:12 | Empperi | but OPTIONS is a HTTP request just like GET is |
| 07:12 | Empperi | let's say you're trying to make GET https://bar.com/api/save-the-world |
| 07:13 | Empperi | browser will first call OPTIONS https://bar.com/api/save-the-world |
| 07:13 | Empperi | 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 |
| 07:13 | Empperi | if both match then it proceeds to make the original GET request |
| 07:14 | Empperi | 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 |
| 07:14 | Empperi | the easiest way to handle this is to make a universal OPTIONS mapping which receives all OPTIONS requests |
| 07:15 | Empperi | and just return the headers |
| 07:15 | Empperi | 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 |
| 07:16 | Empperi | so in essence when your javascript calls *any* cross domain URL it'll first do that OPTIONS call - always |
| 07:16 | Empperi | so you'll end up doubling your XHR requests |
| 07:16 | tangled_z | Empperi: Ahh yes, that makes sense! |
| 07:17 | Empperi | so make damn sure your OPTIONS handler is lightning fast, meaning it doesn't do any additional stuff :) |
| 07:17 | Empperi | we created a middleware for that |
| 07:18 | Empperi | it rules out using OPTIONS within our application in route mappings but that shouldn't be a problem |
| 07:18 | sunset-shimmer | I should save your conversation for the future use... |
| 07:19 | tangled_z | so that means you can't use cors? |
| 07:19 | Empperi | sure you can use it |
| 07:19 | tangled_z | sunset-shimmer: Oh, I always save helpful conversations :) |
| 07:19 | Empperi | it just makes stuff slightly slower |
| 07: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! |
| 07:20 | Empperi | we can't do OPTIONS mappings within our application if the middleware stops those requests and handle those itself |
| 07:20 | sunset-shimmer | tangled_z: did you test it at localhost? Chrome doesn't support localhost for CORS |
| 07:21 | Empperi | yes, that is an additional hassle, forgot that |
| 07:21 | Empperi | but you can tell chrome to accept those |
| 07:21 | Empperi | it's ok for development |
| 07:22 | tangled_z | Wait what |
| 07:22 | tangled_z | Yeah I tested it with chrome -_- |
| 07:27 | Empperi | anyway, I need to do some work :) |
| 07:27 | Empperi | hope that clarified a bit |
| 07:27 | tangled_z | Alright! Thanks for the advice! :) |
| 07:27 | tangled_z | Yeah that was a massive help :) |
| 07:27 | Empperi | CORS is pretty complex beast but security stuff tends to be :P |
| 07:27 | tangled_z | Yeahh it makes sense why |
| 07:28 | tangled_z | Just a paaaaain atm |
| 07:28 | Empperi | indeed |
| 07:28 | tangled_z | Spent far far longer on it than id want to |
| 07: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 |
| 07: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 |
| 07:28 | Empperi | and that equals as cross domain request for browsers |
| 07:29 | tangled_z | That sounds frustrating |
| 07:29 | tangled_z | All I'm doing is trying to communicate between localhost:3000 and localhost:3994 at the moment! |
| 07:32 | sunset-shimmer | amoe, me too |
| 07:33 | tangled_z | Oh my god WHAT |
| 07:34 | tangled_z | It was a typo on the f'cking client the entire time |
| 07:34 | tangled_z | God damn it. |
| 07:34 | tangled_z | Ok, thanks for the help sunset-shimmer and Empperi. (At least now I know about middle-ware and headers more in depth) |
| 07:35 | sunset-shimmer | you are welcome! |
| 07:35 | tangled_z | :D |
| 07:35 | tangled_z | Yeah it was helpful. |
| 07:35 | Empperi | lol |
| 07: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 |
| 07:41 | amoe | Why would someone write "(let [] (some-expr))"? what use is a let without any bindings? |
| 07:42 | opqdonut | amoe: well you can use (let [] ...) instead of (do ...) to turn multiple expressions into one |
| 07:42 | opqdonut | amoe: but yeah, let [] doesn't make much sense |
| 07:42 | Empperi | but it's just stupid to do it like that |
| 07:43 | Empperi | I didn't even know that compiles :) |
| 07:43 | sunset-shimmer | lol |
| 07:43 | opqdonut | well it's nice for macro-writing that you can have empty lets |
| 07:43 | opqdonut | and empty dos |
| 07:43 | opqdonut | etc |
| 07:45 | Empperi | true, with macros empty let can make sense |
| 07:46 | Empperi | one doesn't have to handle the special case then |
| 12:28 | morbid_ape | hi everyone |
| 12:28 | morbid_ape | burn all jews in oven |
| 12:28 | morbid_ape | death to infidel |
| 12:28 | morbid_ape | 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 | morbid_ape | death to infidels |
| 12:37 | morbid_ape | 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 | 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 | 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 | justin_smith | ,(doc short) |
| 12:57 | morbid_ape | bitwise operators are for infidels |
| 12:57 | morbid_ape | 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 | justin_smith | the plot thickens! |
| 13:00 | rcassidy | weird, i get Short |
| 13:00 | rcassidy | ,(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 | morbid_ape | 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 | justin_smith | WorldsEndless: many lookups are classpath relative |
| 13:02 | justin_smith | but some are file system relative |
| 13:02 | justin_smith | the latter is very prone to breaking in deployed code though |
| 13:03 | WorldsEndless | Sounds like a messy problem... |
| 13:03 | WorldsEndless | 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 | justin_smith | 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 | justin_smith | 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 | justin_smith | (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 | justin_smith | WorldsEndless: the default is resources |
| 13:08 | justin_smith | 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 | justin_smith | 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 | cortexman | maybe i just need to reverse the order of my arguments |
| 13:26 | cortexman | 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 | cortexman | 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 | Shayanjm | here's a direct example of the input/expected output: https://gist.github.com/shayanjm/2f731644ffd964df6961 |
| 15:41 | Shayanjm | 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 | wgator | \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 | amalloy | 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 | amalloy | (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 | boom | I have a compojure application, and when attempting to build an uberjar, it gives me an error |
| 16:56 | boom | 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 | boom | 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 | cortexman | 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 | cortexman | 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 | tolstoy | @(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 | tolstoy | That sort of thing works for me all the time. |
| 17:25 | tolstoy | 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 | cortexman | 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 | amalloy | 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 | justin_smith | ,(force 1) |
| 17:42 | clojurebot | 1 |
| 17:43 | justin_smith | ,(force (delay 42)) |
| 17:43 | clojurebot | 42 |
| 17:43 | justin_smith | cool! |
| 17:43 | justin_smith | 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 |
| 18:48 | eeepc | i just want to get kicked out of a bunch of channels |
| 18:48 | eeepc | why is no one cooperating?? |
| 18:48 | eeepc | #trump2016 |
| 18:48 | eeepc | cant stump the trump |
| 18:48 | eeepc | cant stump the trump |
| 18:48 | eeepc | cant stump the trump |
| 18:48 | eeepc | cant stump the trump |
| 18:48 | eeepc | 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 | renl | as opposed to doing filter twice with inverse conditions |
| 20:31 | renl | oh partition-by i answered my own question heh |
| 20:41 | amalloy | that's not what partition-by does |
| 20:44 | amalloy | ,(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? |