2013-04-30
| 00:00 | technomancy | postgres devs should know better =\ |
| 00:00 | callen | I really wish Clojure on Android didn't have such a slow startup time. |
| 00:01 | hiredman | to be fair 1.5 is pretty old |
| 00:01 | hiredman | even 1.6 is supposed to be EOL any day now |
| 00:02 | j4x0n | Apparently they've done it before. It was fixed then someone must have recompiled. |
| 00:02 | technomancy | hiredman: actually it's just Oracle's JDK that is going to be EOLed |
| 00:02 | technomancy | OpenJDK has no such plans |
| 00:04 | callen | OpenJDK performs just fine as well, anecdotally. |
| 00:09 | tieTYT | here's some code I converted from java. How could this be changed to be more idiomatic? https://www.refheap.com/paste/43d1ca29fe152a2cd3f80f1cb |
| 00:11 | callen | tieTYT: the manual type-checking and dorun usage is very meh. |
| 00:11 | callen | as is the direct interaction with Swing. |
| 00:12 | callen | tieTYT: http://daveray.github.io/seesaw/ at least use it pedagogically, if not actually in your thing. |
| 00:12 | tieTYT | callen: I don't think I can use seesaw for this |
| 00:12 | tieTYT | if you assume that, how could I avoid the manual type-checking? |
| 00:13 | callen | tieTYT: that is very unfortunate. learn from seesaw then. |
| 00:13 | callen | tieTYT: learn more Clojure and you'll get your answers re: avoid manual type-checking. |
| 00:14 | tieTYT | callen: I've been reading seesaw source for days now |
| 00:15 | brehaut | tieTYT: is the purpose of the type check to ensure that its not nil or something? |
| 00:15 | brehaut | and if you want real type checking, theres a library for that |
| 00:15 | tieTYT | brehaut: it's to ensure that it is a JComponent. If it's not a JComponent, it won't have a getInputMap |
| 00:15 | callen | brehaut: (instance? ...) |
| 00:15 | tieTYT | and getComponents returns Component, not JComponent |
| 00:16 | brehaut | callen: obvious its instance at the moment, but i presume theres a reson for the check if its ported from java |
| 00:17 | tieTYT | if I don't do that check, it could try to call getInputMap on an instance that doesn't have that method |
| 00:23 | brehaut | well, if you need polymorphic functions, protocols are probably a better way to go about it |
| 00:23 | brehaut | you can implement protocols for nil or object if needed |
| 00:23 | brehaut | for your default behaviours |
| 00:23 | brehaut | this is assuming you are passing non-compliant objects into the function |
| 00:24 | tieTYT | i'm always passing a JComponent in |
| 00:24 | tieTYT | does that mean i shouldn't use protocols? |
| 00:25 | brehaut | if you always pass in something that supports that method then no protocols, no type checks |
| 00:25 | brehaut | just dont go passing the wrong thing in |
| 00:26 | tieTYT | line 11 may pass in a Component that's not a JComponent |
| 00:26 | tieTYT | i thought you meant me as in what the programmer passes in |
| 03:04 | noprompt | does anyone use pre/post conditions? |
| 03:05 | noprompt | i rarely see them used "in the wild" but the seem useful. |
| 03:06 | Raynes | noprompt: Not really. |
| 03:07 | murtaza52 | is it possible to short circuit a `reduce`, like what `some` does |
| 03:10 | Raynes | murtaza52: In Clojure 1.5 you can return (reduced) to stop the reduce. |
| 03:10 | Raynes | But only in 1.5+ |
| 03:11 | noprompt | Raynes: yeah. so i take it no one uses them. |
| 03:12 | noprompt | well, what's a clean way to assert arguments meet a certain criteria? |
| 03:12 | Raynes | &(doc assert) |
| 03:12 | lazybot | ⇒ "Macro ([x] [x message]); Evaluates expr and throws an exception if it does not evaluate to logical true." |
| 03:12 | Raynes | noprompt: But if you're gonna use assert, might as well use pre conditions and shit. |
| 03:12 | Raynes | I mean, just because nobody uses them doesn't mean they aren't perfect for your usecase. |
| 03:12 | Raynes | They were added for a reason. |
| 03:13 | Raynes | Very little is in Clojure that Rich didn't think was useful. |
| 03:14 | sw2wolf | Does Rich has id in this channel ? |
| 03:14 | noprompt | the AssertionError could be a bit cryptic though for a function in a public api. |
| 03:14 | tgoossens | sw2wolf: yes |
| 03:14 | sw2wolf | Is it Rich ? |
| 03:15 | sw2wolf | i just want to highlight it in my ERC configuration |
| 03:15 | Raynes | noprompt: Well, then throw ex-info instead. |
| 03:15 | Raynes | rhickey |
| 03:15 | tgoossens | I know that rich has been on IRC in the past. But I don't know about now |
| 03:15 | Raynes | He isn't here right now. Doesn't come very often. |
| 03:15 | Raynes | When he does it's rhickey. |
| 03:16 | tgoossens | whats with all the 'idiomatic'. I seriously never encountered a community that used the word 'idiomatic' so often |
| 03:16 | noprompt | Raynes: ex-info? |
| 03:16 | Raynes | &(doc ex-info) |
| 03:16 | sw2wolf | Now i have erc-pals '("Hindley" "rhickey") |
| 03:16 | lazybot | ⇒ "([msg map] [msg map cause]); Alpha - subject to change. Create an instance of ExceptionInfo, a RuntimeException subclass that carries a map of additional data." |
| 03:16 | Foxboron | tgoossens: you can't come from Python. |
| 03:16 | Raynes | You're not very good at this, are you noprompt? |
| 03:17 | Raynes | :p |
| 03:17 | Foxboron | tgoossens: the Python community uses "idiomatic" all the time. |
| 03:17 | Foxboron | "idiomatic python! idiomatic classes! idiomatic this and that!" |
| 03:17 | noprompt | tgoossens: so does the Ruby community too. |
| 03:17 | Foxboron | http://python.net/~goodger/projects/pycon/2007/idiomatic/handout.html |
| 03:17 | noprompt | Raynes: my brain is a little fried i guess. :/ |
| 03:18 | Raynes | noprompt: <3 |
| 03:18 | noprompt | i've been working on porting this legacy application at work to Clojure. |
| 03:18 | Raynes | &(throw. (ex-info {:some :data :about :the :exception}) |
| 03:18 | lazybot | java.lang.RuntimeException: Map literal must contain an even number of forms |
| 03:18 | Raynes | &(throw. (ex-info {:some :data :about :the :exception})) |
| 03:18 | lazybot | java.lang.RuntimeException: Map literal must contain an even number of forms |
| 03:18 | Raynes | FUUUU |
| 03:18 | Raynes | &(throw. (ex-info {:some :data :about :the :exception :okay})) |
| 03:18 | lazybot | java.lang.IllegalArgumentException: Unable to resolve classname: throw |
| 03:18 | Raynes | ffffffffffuuuuuuuuuu |
| 03:18 | Raynes | &(throw (ex-info {:some :data :about :the :exception :okay})) |
| 03:18 | lazybot | clojure.lang.ArityException: Wrong number of args (1) passed to: core$ex-info |
| 03:18 | noprompt | Raynes: that happened to me last week. :P |
| 03:19 | Raynes | &(throw (ex-info "Goddamn it." {:some :data :about :the :exception :okay})) |
| 03:19 | lazybot | clojure.lang.ExceptionInfo: Goddamn it. {:about :the, :some :data, :exception :okay} |
| 03:19 | Raynes | Thank you. |
| 03:19 | Raynes | &(try (throw (ex-info "Goddamn it." {:some :data :about :the :exception :okay})) (catch ExceptionInfo e (ex-data e))) |
| 03:19 | lazybot | java.lang.SecurityException: You tripped the alarm! catch is bad! |
| 03:19 | Raynes | Oh blow me lazybot. |
| 03:20 | noprompt | but gawd. the application is a maze of 6-year-old php and javascript (interleaved of course). |
| 03:20 | murtaza52 | I have a seq of vectors. I want to iterate through them. Modify only the first vector that meets a pred. Return back the coll with the modified vector. |
| 03:21 | Raynes | &(doc ex-data) |
| 03:21 | lazybot | ⇒ "([ex]); Alpha - subject to change. Returns exception data (a map) if ex is an ExceptionInfo. Otherwise returns nil." |
| 03:21 | murtaza52 | How do I do the above? bcoz all methods such as for and reduce will modify all vectors that meet the pred, while I want to modify only the first that meets the criteria. |
| 03:21 | Raynes | noprompt: So my code should work. As an example. |
| 03:21 | Raynes | noprompt: ExceptionInfo is basically an exception that doesn't suck and allows you to pass data out. |
| 03:21 | tgoossens | and with idiomatic i guess you mean "conventional" ? |
| 03:22 | noprompt | Raynes: that's neat-o. |
| 03:23 | noprompt | gonna try it out in the repl real quick. |
| 03:23 | itemad | http://www.youtube.com/watch?v=UrMWRAaFdIc&feature=youtu.be |
| 03:23 | itemad | ops! :-P |
| 03:26 | noprompt | hmm... i'm debating whether i should add a dependency, steal code, or hand-roll a color lib for garden. |
| 03:27 | tomoj | murtaza52: https://www.refheap.com/paste/7dc0b0d3e81f5ed63c7b4d589 hmm, surely there is a better way? |
| 03:27 | noprompt | aren't those always the choices? geeze. i think i need a drink... |
| 03:28 | Foxboron | tgoossens: idiomatic is an idiom. It could be obscure code which is widely known to be the "right" way. Think of it as language idioms. "Break a leg" is an idiom. |
| 03:28 | tomoj | I would like to write it as something like (update-in vecs [map (some pred)] f) |
| 03:29 | tomoj | (hypothetical) |
| 03:29 | tomoj | (.. and probably confusing because the names 'map and 'some are taken. ignore me) |
| 03:32 | noprompt | Raynes: i guess what i like about the pre conditions is that it can make something like (if (meets-criteria x) do-stuff (throw ...)) a bit cleaner. |
| 04:12 | Odinodin | Given I run lein test, when a test fails, the process just hangs and I have to manually stop it. Does anyone know if there is anything to get around that? |
| 04:13 | noprompt | /quit |
| 04:20 | noidi | Odinodin, maybe you have a thread that's still alive and blocking the app from exiting |
| 04:22 | noidi | I think you can use VisualVM to see what's going on while the process hangs http://docs.oracle.com/javase/6/docs/technotes/guides/visualvm/ |
| 04:23 | Odinodin | noidi: ah, thanks, that seems very probable. We have a jetty server running during the tests thats probably the culprit |
| 04:26 | nbeloglazov | What is the usage of symbols in edn format? I cannot find any real use case for them. |
| 04:29 | tomoj | datomic is an example where they are used |
| 04:30 | tomoj | the rest interface accepts queries like [:find ?x :where [?x :foo]] as edn |
| 04:33 | tomoj | I guess datomic shows two use cases: representing binding in edn, and referring to clojure vars |
| 04:37 | tomoj | my intuition is that the space of symbols in a language encoded in edn will tend to be more closed (less open) than the space of keywords |
| 04:38 | tomoj | hmm |
| 04:39 | tomoj | I guess the difference is really more just that keywords are supposed to mean themselves where symbols can be assigned particular meanings |
| 04:48 | nbeloglazov | tomoj: thank you |
| 05:09 | no7hing | does anybody know of a java/clojure lib similar to https://github.com/jubos/fake-s3 ? |
| 05:11 | jaley | no7hing: are you just trying to stub out an S3 server for testing purposes? |
| 05:11 | jaley | no7hing: jClouds' blobstore abstraction has a stub provider implementation, which can be useful for that |
| 05:12 | no7hing | @jaley yes |
| 05:12 | no7hing | @jaley i'll have a look at it, thanks |
| 05:16 | jaley | no7hing: if you depend on [org.jclouds/jclouds-blobstore "1.6.0"] in your project.clj |
| 05:17 | jaley | no7hing: you can then (:require [org.jclouds.blobstore2 :as blob]) and use (blobstore "transient" "" "") to get a fake instance |
| 05:17 | jaley | no7hing: all of the blob/put-blob blob/get-blob will work with it, storing entries in ram |
| 05:18 | jaley | no7hing: I believe there's also a filesystem implementation if you need it |
| 05:18 | no7hing | ram only sounds perfect for my needs |
| 05:19 | no7hing | i'll just pre-populate the blobstore with my data and don't need to tamper with the application code, as it's tested from another vm |
| 05:20 | jaley | no7hing: presumably you also want your code to actually talk to S3 later? |
| 05:20 | jaley | no7hing: when you want to plug into s3, you need to add a dependency on the s3 "blobstore" provider to your project and create an instance of that with (blobstore "aws-s3" "access-key" "secret-key") instead |
| 05:20 | no7hing | already doing it |
| 05:20 | jaley | no7hing: cool |
| 05:21 | no7hing | thanks for your help! |
| 05:21 | jaley | no7hing: no problem |
| 05:49 | nbeloglazov | Is there some clojure expression that is not valid edn expression? |
| 06:00 | tomoj | nbeloglazov: ::foo |
| 06:00 | tomoj | among others.. |
| 06:00 | tomoj | #(foo) |
| 06:00 | tomoj | @foo |
| 06:01 | tomoj | #'foo |
| 06:01 | nbeloglazov | :) Ok, thanks |
| 06:01 | tomoj | though |
| 06:01 | tomoj | those last ones are all sort of cheats |
| 06:01 | tomoj | (fn [] (foo))) and (deref foo) and (var foo) are all valid edn.. |
| 06:02 | tomoj | #java.net.URI["/foo"] |
| 08:48 | CookedGryphon | Hey all. So I don't much like the try/catch form in clojure. I find it always produces ugly, hard to follow, hard to re-use and hard to compose code. What i do instead is in this gist: https://gist.github.com/AdamClements/5488162 what do people think of this? I'm tempted to make it a library, but a dependency and a require feel like overkill for one/two macros! |
| 08:51 | clgv | CookedGryphon: probably, you do not know "dire" https://github.com/MichaelDrogalis/dire |
| 08:52 | clgv | CookedGryphon: that lib allows you to decouple error handlers from the functions they might appear in |
| 08:53 | clgv | CookedGryphon: as well as pre-/post-hooks |
| 08:53 | CookedGryphon | clgv: I do know dire, I find it's overkill for most of my use cases |
| 08:53 | CookedGryphon | and does var rebinding, which I don't really like |
| 08:54 | CookedGryphon | as it's all too easy to miss that your error handling is subverting your code path, making it hard to read |
| 08:55 | clgv | CookedGryphon: but you can really dcouple the handlers from code which is one step further than your macros |
| 08:55 | CookedGryphon | if you see (defn times [a b] ...) and then something which calls (times 2 3), you'd expect it to go straight into that function, which could lead to unpredictable behaviour if you've actually rebound the times var |
| 08:56 | CookedGryphon | I feel it's a step too far and has the potential to reduce readability, especially if you're reading someone else's code and aren't used to dealing with errors in that way |
| 08:56 | clgv | CookedGryphon: well, that's what documentation is for. if you have a coding guideline for error handlers of this kind in your project - you'll expect that those handlers will kick in |
| 08:57 | clgv | CookedGryphon: it is certainly a matter of personal taste. but I'd choose dire before those macros in the gist, since using them consistently also makes the code quiet complex. |
| 08:58 | CookedGryphon | my point is, someone's going to see this, think great, write a separate namespace for handlers (to keep similar things bundled together), gleefully rebind these variables. Someone else comes along and they're missing half the code but don't even realise it because there's no reference to the error stuff |
| 08:58 | clgv | CookedGryphon: but that is a documentation problem. |
| 08:59 | CookedGryphon | not really, it's an evident code problem |
| 08:59 | CookedGryphon | I don't want to have to read a manual on how this particular codebase handles errors, that sounds like the java way of doing things |
| 09:00 | Morgawr | what function can I use if I want to update all the values of a hashmap without touching the keys? |
| 09:00 | Morgawr | like a map but only on the values |
| 09:00 | clgv | Morgawr: there is none. you can build it via reduce-kv |
| 09:01 | Morgawr | I'll try, thanks |
| 09:01 | CookedGryphon | Morgawr: I believe there's something in the flatland/useful library which does that |
| 09:01 | Morgawr | CookedGryphon: I'm using ClojureScript so I can't really rely on external libraries |
| 09:02 | clgv | Morgawr: if you change all values you actually build a new map even if you use assoc. since there does not remain much for structural sharing |
| 09:02 | CookedGryphon | Morgawr: fair enough, you could copy the implementation though |
| 09:04 | Morgawr | clgv: the thing is, I have a hashmap that contains all filenames and I want to append a different extension at the end of said filenames (to distinguish between .mp3 and .ogg sounds depending on the browser) |
| 09:06 | clgv | Morgawr: (defn update-map-values [m f & args] (persistent! (reduce-kv (fn [r, k, v] (assoc! r k (apply f v args))) (transient {}) m))) |
| 09:06 | clgv | Morgawr: you might also add the key to the function invocation |
| 09:06 | Morgawr | oh wait |
| 09:07 | Morgawr | I found a much easier way |
| 09:07 | Morgawr | http://stackoverflow.com/questions/1676891/mapping-a-function-on-the-values-of-a-map-in-clojure this seems pretty good |
| 09:07 | Morgawr | and it works :) |
| 09:07 | clgv | Morgawr: yes that works. the reduce-kv is the faster approach in Clojure - dont know about ClojureScript |
| 09:09 | Morgawr | I don't really need speed at the moment though, it's a very simple function. Thanks either way :) |
| 09:11 | LiaoPengyu | Hello? |
| 09:11 | clojurebot | BUENOS DING DONG DIDDLY DIOS, fRaUline LiaoPengyu |
| 09:11 | LiaoPengyu | javadoc |
| 09:11 | LiaoPengyu | ToUpperCase |
| 09:51 | xeqi | Raynes: ping; what kind of info do you scrape off clojars for lazybot? |
| 09:57 | no7hing | is there a fast way to add a virtual host to ring/jetty? |
| 09:57 | weavejester | no7hing: A virtual host is just dispatching off the Host header |
| 09:58 | weavejester | In Compojure, you can write: (context "http://subdomain.example.com/" [] ...) |
| 09:59 | weavejester | At least in theory... |
| 09:59 | no7hing | @weavejester i didn't get them to show up in the app, but haven't gone for those context's though |
| 09:59 | weavejester | Actually, it would probably be better to write: |
| 09:59 | weavejester | (ANY "http://subdomain.example.com/" [] (routes …)) |
| 09:59 | weavejester | I know that one works |
| 09:59 | weavejester | Not sure about the context |
| 09:59 | no7hing | will try that, thanks |
| 10:00 | weavejester | But you can always dispatch off the (get-in request [:headers "host"]) anyway |
| 10:00 | no7hing | i understood them to be a way to bundle up handlers; |
| 10:00 | no7hing | but that's just e |
| 10:00 | no7hing | me |
| 10:00 | no7hing | was thinking too complicated. again. |
| 10:00 | weavejester | The context macro is a way to add a common prefix to a set of routes. |
| 10:01 | no7hing | what i thought |
| 10:01 | no7hing | but couldn't express |
| 10:08 | mefesto | any know if the docs for weavejester/{hiccup,compojure} currently in a transition? Seems like the links are broken and no css |
| 10:09 | mefesto | http://weavejester.github.io/hiccup |
| 10:09 | weavejester | mefesto: Looks like github.io domain shift broke the redirect |
| 10:10 | weavejester | http://weavejester.github.io/hiccup/ |
| 10:10 | weavejester | If you add an ending / it works |
| 10:10 | mefesto | weavejester: ahh thank you |
| 10:10 | weavejester | Not sure how to fix that for a static site... |
| 10:11 | weavejester | I guess I should alert github to the issue. "/foo" should redirect to "/foo/" |
| 10:12 | wink | yeah |
| 10:13 | Anderkent | technomancy: https://github.com/technomancy/leiningen/blob/master/src/leiningen/pom.clj#L234 |
| 10:13 | Anderkent | (if (seq extra-src) (add-test-sources)) ? :( |
| 10:13 | mefesto | weavejester: it loads the index page correctly but the resources within the page are relative (js/blah.js) whereas (/hiccup/js/blah.js) would fix it |
| 10:14 | weavejester | mefesto: Yes, but that would require the docs to know where they are being deployed to. |
| 10:14 | mefesto | maybe i shouldn't say `fix it` but work-around it |
| 10:14 | mefesto | weavejester: ah i see |
| 10:15 | weavejester | Ideally the docs should work as local files as well |
| 10:15 | weavejester | Which means relative links |
| 10:15 | mefesto | yeah definitely wouldn't want to sacrifice that. |
| 10:16 | mefesto | knowing to put a slash at the end is enough for me :) |
| 10:19 | kasterma | I just run into some confusing (for me) behaviour of equality. See https://gist.github.com/kasterma/5489015. It seems declared but unset symbols are treated specially for =. |
| 10:20 | kasterma | Is it that, or am I missing something in the behaviour of '? |
| 10:22 | clgv | kasterma: thats symbol versus variable value |
| 10:23 | kasterma | Could you explain a little more? |
| 10:23 | clgv | kasterma: those list constructions are not the same: (def x 42) (list x) => (42), '(x) => (x) |
| 10:25 | kasterma | (= (list |) dd) => true |
| 10:25 | kasterma | Ahh, but why did it work with a keyword? |
| 10:25 | clgv | keywords evaluate to themselves |
| 10:26 | kasterma | So in the equality test the content of the list is evaluated, and evaluating | doesn't work? |
| 10:27 | clgv | kasterma: in that expression you construct a list with a single element which is the value that is bound to | |
| 10:27 | kasterma | Which does not exist. |
| 10:28 | clgv | kasterma: | is unbound and thus returns an instance of clojure.lang.Var$Unbound which is an implementation detail |
| 10:29 | kasterma | clgv: thx, for the help. |
| 10:30 | mefesto | when using lein-ring and lein-cljsbuild is a typical workflow for generating a standalone jar something like the following or is there another way? lein cljsbuild prod && lein ring uberjar |
| 10:32 | mefesto | ideally, i'd like to only have to issue `lein ring uberjar` and have cljs build with all the optimizations for production |
| 10:35 | clgv | kasterma: a simple rule to remember: only use '(1 2 3 4 5) to construct list of constants |
| 10:35 | ucb | when I eval this I get :default, where am I going wrong? (condp <= 1 0xff "yes" 0xffff "no" :default) |
| 10:36 | clgv | ,(<= 1 0xffff) |
| 10:36 | clojurebot | true |
| 10:37 | kasterma | clgv: thx |
| 10:38 | ucb | ,(<= 1 0xff) |
| 10:38 | clojurebot | true |
| 10:38 | clgv | &(condp >= 1 0xff "yes" 0xffff "no" :default) |
| 10:38 | lazybot | ⇒ "yes" |
| 10:38 | akells` | Is a [B not a bytearray? I'm trying to call .length on something that is a [B and its telling me 'no matching field found: length for [B' |
| 10:38 | clgv | the application of arguments is the other way round in condp |
| 10:39 | clgv | quote: " & & & & & 0 & 0 & 1 & 0 & 0 & 0 & 0 & 1 & & & & \\" |
| 10:39 | clgv | oops |
| 10:39 | nDuff | akells`: there's an alength function |
| 10:39 | clgv | quote: "For each clause, (pred test-expr expr) is evaluated." |
| 10:39 | nDuff | akells`: ...Java exposing it as a field is syntactic sugar. |
| 10:39 | ucb | clgv: ooh, nice, thanks |
| 10:39 | ucb | clgv: totally misread that |
| 10:40 | akells` | nDuff: that seems to be working. is this the length, in bytes? |
| 10:40 | akells` | thank you very much, by the way |
| 10:40 | clgv | ucb: I would have guessed for (pred expr test-expr) as well |
| 10:40 | nDuff | akells`: number of array elements, so for a byte array, yes. |
| 10:40 | ucb | *nod* |
| 10:40 | akells` | much appreciated! |
| 11:26 | akells` | Is this going to actually concatenate these two byte arrays? Or is my repl misleading me a little bit by saying it returns one? (byte-array (concat (.getBytes "edf") (.getBytes "abc"))) |
| 11:33 | xeqi | (let [x 3 _ (println x) y (+ 1 2) _ (println y)] y) |
| 11:33 | xeqi | &(let [x 3 _ (println x) y (+ 1 2) _ (println y)] y) |
| 11:33 | lazybot | ⇒ 3 3 3 |
| 11:33 | gfredericks | (let [a (b), :do (things), c (d)] ...) |
| 11:33 | gfredericks | xeqi: yeah, I use that for debugging. feels to awkward to use for real code |
| 11:58 | dnolen | ibdknox: congrats on the latest release! |
| 11:59 | ibdknox | dnolen: thanks :) |
| 12:10 | seangrove | ibdknox: Yes, it seemed very well received on hn, great job |
| 12:10 | n_b | I'll second that! |
| 12:10 | n_b | It's helped get a few of my friends into Clojure :) |
| 12:43 | saolsen | that js integration is great, does it work that well for clojurescript? |
| 13:00 | dnolen | saolsen: LT is written entirely in ClojureScript as far as I know and I believe ibdknox uses LT to dev LT, so I imagine it works OK. Would like to see more docs on that tho. |
| 13:04 | ibdknox | saolsen: dnolen: because of the way cljs works, you'd have to do some weird things to get the same level of eval. For one, it requires replacing the source of a file, which means you'd have to completely recompile on every eval :/ |
| 13:05 | ibdknox | that being said, LT gets around this because of the BOT architecture - everything is late bound |
| 13:09 | dnolen | ibdknox: hmm, why do you need to re-compile the whole file if you just want to change a single def? |
| 13:09 | ibdknox | dnolen: because I need the complete output of bootstrap.js or whatever you call the cat'd source |
| 13:10 | dnolen | stuartsierra: can we do another CLJS at some point? It's been a while. Main changes would be Clojure 1.5.0 dependency and data.json 0.2.2 |
| 13:10 | stuartsierra | will do |
| 13:10 | stuartsierra | may need updating since Sonatype Nexus change — I'll look into it |
| 13:11 | dnolen | ibdknox: oh this is for dev'ing LT directly, I guess less a problem if you're using LT to dev your own CLJS stuff? |
| 13:11 | dnolen | stuartsierra: 1.5.1 I meant |
| 13:11 | stuartsierra | ok |
| 13:11 | ibdknox | dnolen: nope, this is for the VM patching for any CLJS. You can always do normal eval, which is actually more than enough in most cases for CLJS |
| 13:12 | ibdknox | dnolen: but to do the same things I was showing in the cube video, I have to replace the original source file with a new one and they have to be relatively similar - so I would need the new result of compilation to swap it out with |
| 13:21 | dnolen | ibdknox: hmm make some sense ... is there some way you see to make that process smoother? |
| 13:22 | wink | hm, anyone ever tried to put json into mysql via korma? looks like an encoding problem, but it's weird |
| 13:22 | saolsen | I've been working on a cljs game and that level of interaction with a threejs canvas would be the greatest thing ever |
| 13:40 | ibdknox | saolsen: depending on how you write your game, you may not need that stuff |
| 13:41 | ibdknox | dnolen: I haven't though through it too far yet. There may be something clever to do. |
| 13:54 | akells` | clojure.java.io/copy should be able to handle any byte array, correct? |
| 13:56 | amalloy | akells`: i doubt it |
| 13:57 | amalloy | well, i guess it does. it implicitly creates a Reader from it. okay |
| 13:57 | amalloy | er...an InputStream |
| 13:57 | akells` | I must be doing something else wrong. It works fine with a byte array from an image file |
| 13:57 | akells` | but it doesn't seem to be working quite the same with a byte array from a text/html file |
| 13:58 | akells` | well, its actually a byte array that is a concat of two other byte arrays. but it works fine for the concat that uses an image file's byte array, but not for the concat that uses a text/html file's byte array |
| 13:59 | amalloy | well that's obviously a red herring. the jvm doesn't remember where arrays came from |
| 14:00 | akells` | I just wanted to make sure clojure.java.io/copy should work in any case. sounds like I've got an issue somewhere else. this was helpful, thanks amalloy |
| 14:01 | _francis_ | I'm looking at this code https://www.refheap.com/paste/14081 and wondering why you would put a type in a function metadata - thoughts anyone? |
| 14:05 | arrdem | _francis_: one day god willing we will have optional typing able to take advantage of that data |
| 14:05 | _francis_ | arrdem: thanks |
| 14:06 | arrdem | _francis_: actually no. in this case you are type-hinting the function. |
| 14:06 | _francis_ | arrdem: I thought that type hints go in the arg list? |
| 14:07 | arrdem | _francis_: you can put them there too. |
| 14:07 | arrdem | _francis_: I'm not clear on the details, but I understand that it type-specializes the generated code. Used for performance and for Java interop. |
| 14:09 | _francis_ | arrdem: Are you certain that types in the metadata will be used for type-hinting? In this case the fn will return that type, but can accept several different types. |
| 14:09 | arrdem | _francis_: that's why I say I'm not sure. I' |
| 14:10 | arrdem | ve seen argument metadata used to clamp down the function dispatch time, but I'm not sure what effect typing the return value has. |
| 14:11 | _francis_ | Could you supply an example? |
| 14:12 | svedubois | In CLJS, how can I set some value inside a "doto". |
| 14:12 | svedubois | For example, I have this: |
| 14:12 | svedubois | (set! (.-color sphere) "red") |
| 14:12 | svedubois | And I would like to have something like this: |
| 14:12 | svedubois | (doto (sphere.) |
| 14:12 | svedubois | (.-color "red")) |
| 14:13 | dnolen | _francis_: the compiler will use that information, it makes interop less tedious |
| 14:14 | dnolen | _francis_: for example if you locally bind the result of invoking that function in let, that type hint will be propagated by the compiler |
| 14:14 | _francis_ | dnolen: Awesome. |
| 14:14 | arrdem | dnolen: thanks for the save :p, didn't know (let) could use type hinting |
| 14:15 | arrdem | _francis_: I can't find it ATM but I believe that the community matrix library is the last place I saw hinting in the wild. |
| 14:16 | dnolen | arrdem: most of binding forms really as they generally macro expand to let |
| 14:16 | matko | hi #clojure, I was wondering, in a multi-threaded environment, is it a bad thing to have many threads lying around that do nothing? For example, 5000 threads that mostly sleep but wake up now and then to update something? Or does this incur little cost? |
| 14:16 | dnolen | now that I think about it, I think all? |
| 14:17 | technomancy | matko: IIRC the primary cost there is creating and destroying threads; I think once they're around they're supposed to be cheap. but you might want to look into a thread pool anyway to avoid re-inventing the wheel |
| 14:17 | arrdem | dnolen: everything but def should macroexpand to a let at the end of the day |
| 14:17 | matko | technomancy: futures already use a threadpool right? |
| 14:17 | matko | I was thinking of using futures for this |
| 14:17 | n_b | futures use the agent thread pool I believe |
| 14:17 | matko | hm.. is that bad? |
| 14:17 | matko | I'd assume that means the send-off pool |
| 14:18 | n_b | That's my understanding |
| 14:18 | technomancy | matko: it just means you don't have a lot of control over it |
| 14:18 | technomancy | may or may not be a problem in practice |
| 14:18 | matko | ok, so startup is costly, but a sleeping thread is not a bad thing |
| 14:18 | matko | thank you :) |
| 14:18 | technomancy | well, not on a decently-sized linux system |
| 14:19 | matko | what about windows? |
| 14:19 | n_b | matko: I just did a pretty large threaded importer, and ended up using threadpools because I had tens of thousands of threads bein created when I just used futures |
| 14:19 | technomancy | matko: no idea about windows or mac |
| 14:19 | matko | ok |
| 14:19 | n_b | but it was a memory consumption issue due to my workload |
| 14:19 | matko | I'll have to test |
| 14:19 | technomancy | virtualized linux also might not be so hot |
| 14:19 | technomancy | you'll have to test anyway; don't trust random advice on IRC =) |
| 14:19 | matko | hahah, that's advice I will trust |
| 14:19 | stuartsierra | Futures use the Agent send-off thread pool. |
| 14:19 | n_b | Benchmark both ways, and remember IFn implements Runnable so you can always (.new (Thread. #(some_fn)) |
| 14:20 | matko | woah, I forgot about that |
| 14:20 | matko | thanks for reminding |
| 14:20 | stuartsierra | In Clojure 1.5 you can configure the thread pools, e.g. set bounds. |
| 14:20 | n_b | matko: It makes using Executors much easier :) |
| 14:20 | matko | does clojure come with libraries for thread pools? |
| 14:21 | n_b | matko: Outside the basic concurrency constructs, not to my knowledge. Using Java interop was very easy IME |
| 14:21 | stuartsierra | matko: java.util.concurrent |
| 14:22 | n_b | Though IRC did much to help fill the gaps in my knowledge of it |
| 14:22 | matko | stuartsierra: that's not clojure :) but sure that works |
| 14:22 | stuartsierra | Clojure generally makes little effort to hide details of its host platform. |
| 14:22 | antares_ | matko: agents use a thread pool and can be (ab)used very similarly to executes in j.u.c. |
| 14:23 | matko | j.u.c.? |
| 14:23 | technomancy | clojurebot: j.u.c? |
| 14:23 | clojurebot | Titim gan éirí ort. |
| 14:23 | matko | .... scary |
| 14:23 | technomancy | clojurebot: java.util.concurrent? |
| 14:23 | clojurebot | java.util.concurrent is "When I find myself in times of trouble / Prof. Doug Lea comes to me / Coding lines of wisdom / j.u.c." |
| 14:24 | matko | oh doh |
| 14:24 | nDuff | matko: RH has been pretty explicit about building Clojure's concurrency primitives to supplement, not replace, java.util.concurrent. |
| 14:24 | matko | cool, so I guess I'll prototype using futures. If it turns out to be problematic, I'll switch to a thread pool. either way should work fine for my purposes |
| 14:24 | tcrayford | man do I love that j.u.c. thing. That's cscotta or somebody like that originally? |
| 14:24 | technomancy | tcrayford: tnm |
| 14:26 | nDuff | matko: If a future isn't the right thing for the job, don't be shy about going straight to j.u.c. Clojure functions implement both Runnable and Callable; there's nothing at all difficult about using them with the Java APIs. |
| 14:27 | tcrayford | technomancy: oh, of course. I'm sad that dude deleted all his tweets, he was the best |
| 14:27 | technomancy | what; he did?! |
| 14:27 | matko | hm. I should have a good look at that library anyway. Guess I'll do so now |
| 14:27 | technomancy | weird |
| 14:27 | tcrayford | yeah :((( |
| 14:27 | technomancy | well it's immortalized in clojurebot now |
| 14:31 | matko | oh, I guess the thing I actually want is a scheduled thread pool. good thing I looked |
| 14:47 | xorola | is clojure strongly typed? i think so. |
| 14:47 | technomancy | xorola: yes |
| 14:49 | SegFaultAX | xorola: Java is strongly typed, yes. |
| 15:01 | ToBeReplaced | how can i extend the Closeable interface to an existing type i don't own? extend-type yells b/c Closeable is an interface, not protocol |
| 15:03 | ToBeReplaced | for personal use, of course... i want to take a jzmq context which has a .term destructor that matches libzmq and make it usable from clojure with with-open |
| 15:04 | xeqi | you can't directly. One option is (proxy Closeable ...) and decorate the object |
| 15:04 | gfredericks | hmm |
| 15:04 | gfredericks | promises can't act like futures by throwing exceptions on deref can they :/ |
| 15:04 | xeqi | hmm, I think I want reify there |
| 15:04 | xeqi | instead of proxy |
| 15:05 | xeqi | can never remember which until I try |
| 15:05 | gfredericks | oh nevermind I can combine futures and promises in a magical mystery way |
| 15:05 | ToBeReplaced | yeah reify would work, it would also muck with the type which might make reflections not happy, but i suppose that makes sense |
| 15:05 | ToBeReplaced | thanks |
| 15:25 | svedubois_ | I have a vector (def v ["a" "b" "c"]) |
| 15:25 | svedubois_ | And I would like to create a classname for each element in the vector in only one line. |
| 15:25 | svedubois_ | Is it possible, how? |
| 15:25 | svedubois_ | (def a (classname.)) |
| 15:26 | SegFaultAX | svedubois_: What do you mean create a classname? Why does it have to be one line? |
| 15:27 | svedubois_ | One global variable for each element in the vector |
| 15:28 | svedubois_ | With the vector ["a" "b" "c" ... ], create (def a (classname.)), def b ..., def c ... |
| 15:29 | SegFaultAX | svedubois_: Why do you want to do this? |
| 15:31 | amalloy | yeah, that is not a thing you want to do |
| 15:33 | matko | (map #(eval `(def ~(symbol %))) v) |
| 15:34 | gdev | ,(map class [0.07 "james" :bond]) |
| 15:34 | clojurebot | (java.lang.Double java.lang.String clojure.lang.Keyword) |
| 15:40 | svedubois_ | ClojureScript can list all files in a given directory? |
| 15:41 | gfredericks | probably in whatever manner you would normally do that in javascript |
| 15:41 | gfredericks | which is "no" in a traditional browser setting |
| 16:17 | arrdem | can I add hooks to a lein command? so "ring server" triggers "lessc" in my specific case. |
| 16:25 | technomancy | arrdem: :prep-tasks ["lessc"] will cause lessc to happen before any code runs inside a project |
| 16:25 | arrdem | technomancy: thanks |
| 16:25 | technomancy | lessc needs to be fast if there's no work to do, because it'll trigger on every repl, complie, test, etc |
| 16:26 | arrdem | it's pretty fast atm since it doesn't seem to be building my CSS files -_- |
| 16:26 | technomancy | fast is good |
| 16:26 | arrdem | silent failure is bad tho |
| 16:28 | wink | hmm. (clojure.java.io/copy (clojure.java.io/input-stream "http://...x.png") (clojure.java.io "/path/to/foo")) copies one image and not another. reproducably. any ideas? :) |
| 16:29 | wink | *add /output-stream ofc where needed |
| 16:42 | gdev | my eyes, they bleed, warning: java code https://www.refheap.com/paste/af945a051690ee85ec1d018cf |
| 16:43 | Raynes | gdev: This is beautiful code. |
| 16:43 | Raynes | I strive to write this kind of code in Clojure. |
| 16:44 | arrdem | Raynes: not sure if sarcasm |
| 16:44 | Raynes | arrdem: Sarcasm. |
| 16:44 | arrdem | gud |
| 16:44 | iwo | hey, does anyone know of an example on how to create a vector of keys that is compatible with get-in/assoc-in/update-in FROM a map? |
| 16:44 | mthvedt | clojure is not type-safe and enterprise-ready, it cannot make code that beautiful |
| 16:44 | Raynes | I think amalloy wrote something to do that. |
| 16:45 | amalloy | doesn't ring a bell, sorry |
| 16:45 | iwo | so i have a nested map structure - i'm trying to decide how I could navigate this map to create all valid keys for get-in |
| 16:45 | Raynes | amalloy: You wrote a function to get all possible keyseqs from a map. |
| 16:45 | Raynes | amalloy: I know you did because we discussed the implementation. |
| 16:45 | Raynes | Don't screw with me, bro. |
| 16:45 | amalloy | i write a lot of functions. i don't remember this one |
| 16:46 | gdev | L.A. GUI with an Oakland back end |
| 16:48 | amalloy | it's not hard to write, though |
| 16:48 | amalloy | https://www.refheap.com/paste/5823c0e842a3948b579c42cc5 |
| 16:49 | amalloy | modulo your decision about whether (:b) is a valid answer as well |
| 16:49 | Raynes | amalloy: I'm greping every piece of code you ever wrote until I find the one you wrote in the first place. |
| 16:51 | amalloy | it actually comes out a lot nicer if you're willing to count (:b) as a keyseq: https://www.refheap.com/paste/5885807c958f35ab9b80976c1 |
| 16:51 | Raynes | I can't remember the bloody project. |
| 16:51 | Raynes | Jiraph? Telemetry? BAH. |
| 16:51 | Raynes | This is going to haunt me. |
| 16:53 | arrdem | Raynes: you were right, noir -> compojure wasn't that bad at all. |
| 16:56 | Raynes | arrdem: Whoa, you just now did it? |
| 16:56 | arrdem | Raynes: yeah I just got the user facing parts of my site ported in the last two hours |
| 16:56 | ppppaul | i want to output a JSON stream from my ring endpoint (using cheshire, and can't really figure out how to get an input-stream form it's generate-stream fn |
| 16:56 | ppppaul | any help |
| 16:57 | ppppaul | :) |
| 16:57 | gfredericks | ppppaul: oh there was something for this |
| 16:58 | arrdem | Raynes: once I got about 15 github documentation pages open it was dead easy |
| 16:58 | Raynes | arrdem: Worth it! |
| 16:58 | arrdem | ppppaul: someone hacked this live here a few months ago.... |
| 16:58 | gfredericks | ppppaul: first find ring.util.io/piped-input-stream |
| 16:58 | ppppaul | gfredericks, i found some issues on cheshire and ring about this, but i'm looking for a hacked up solution now :) |
| 16:59 | ppppaul | i have the piped-input-stream src open... |
| 16:59 | gfredericks | then make your body (piped-input-stream (fn [out] (->> out (OutputStreamWriter.) (BufferedWriter.) (json/generate-stream data)))) |
| 16:59 | ppppaul | i know i'm going to use it, and i know where to use it, but the cheshire stuff is what i'm tripping over |
| 16:59 | ppppaul | gfredericks, woooooo thanks so much :D |
| 17:06 | ppppaul | this is now a part of my liberator fork |
| 17:06 | ppppaul | woot |
| 17:07 | ppppaul | never has seeing a data dump from datomic felt so good |
| 17:08 | ppppaul | feel like watermelon |
| 17:09 | gfredericks | :) |
| 17:09 | gfredericks | I should pass on credit to whoever gave me that snippet in the first place |
| 17:09 | gfredericks | I have no idea who that was |
| 17:09 | gfredericks | (inc anonymous) |
| 17:09 | lazybot | ⇒ 1 |
| 17:09 | arrdem | (inc clojure) ;; since gfredrics is passing |
| 17:09 | lazybot | ⇒ 11 |
| 17:10 | gdev | yay, this works, but it seems hacky and amateurish which is a good description of my coding style so not surprising https://www.refheap.com/paste/cbb89e7032d2418dc20d66c84 |
| 17:11 | gdev | gfredericks:) I'm still working on that database thing you helped me with; doseq on the update statement meant my update to database call was 1 to 1 |
| 17:12 | gfredericks | gdev: how do you do updates without that being the case? |
| 17:12 | gfredericks | I've often wanted that |
| 17:12 | gdev | gfredericks:) I'll let you know when I figure it out =) |
| 17:12 | gfredericks | ha |
| 17:13 | gdev | having the data pre-staged was half the battle |
| 17:15 | gfredericks | ppppaul: ha I started that issue |
| 17:15 | ppppaul | :) |
| 17:16 | gfredericks | somebody, I think weavejester, pointed out at some point that the ring spec might need some amending to handle cases like this |
| 17:17 | gfredericks | not basic json, but any kind of streaming that involves an open resource |
| 17:18 | asteve | a coworker is trying to pull in a clojure project and is getting checksum errors on com/google/guava; he is using leiningen 2.1.x and we tried remove ~/.m2 |
| 17:19 | asteve | 26 days ago the developers for guava claimed they pushed a corrected checksum and that it would propagate over the next few hours |
| 17:19 | asteve | any ideas? |
| 17:21 | stuartsierra | dnolen: FYI, ClojureScript release build will need some changes to accommodate new Sonatype Nexus version. |
| 17:21 | stuartsierra | I'm burnt out now but I'll try to get to it this week. |
| 17:29 | asteve | this is the exact problem a coworker was having earlier today http://stackoverflow.com/questions/15818219/failed-retrieving-guava-libs-from-maven |
| 17:29 | asteve | we tried lein clean and we tried removing ~/.m2 entirely |
| 17:30 | asteve | is there a way to download the dep manually? |
| 17:30 | arrdem | asteve: your best bet is probably gonna be to force lein to load without checks... |
| 17:30 | arrdem | asteve: not sure how to do that tho. |
| 17:31 | technomancy | asteve: you can always build from source |
| 17:31 | technomancy | mvn install or whatever |
| 17:31 | technomancy | turning off checksum checks is pretty sketchy |
| 17:31 | arrdem | oooh yeah |
| 17:31 | technomancy | would strongly not recommend leaving checksum checks off |
| 17:31 | gdev | gfredericks:) sorry, I didn't mean ratio of database calls to update statement, im still trying to figure out how to interpret this oracle database trace file |
| 17:31 | technomancy | maybe turn it off once, download the dep, and turn it back on |
| 17:31 | technomancy | asteve: sometimes bad checksums get stuck on a specific mirror |
| 17:32 | technomancy | so only users from certain geographic locations see them |
| 17:32 | asteve | ah |
| 17:32 | technomancy | anyway you should definitely continue to communicate with the maintainers |
| 17:32 | asteve | ok |
| 17:32 | technomancy | until it's resolved upstream all you have are workarounds |
| 17:38 | iwo | hey, is there a neat way to do 'cons if not nil' in clojure? |
| 17:38 | arrdem | ,(cons 1 nil) |
| 17:38 | clojurebot | (1) |
| 17:38 | iwo | basically: (if x (cons x l) l) |
| 17:39 | arrdem | oh identity over list? |
| 17:39 | iwo | i suppose i could do: (keep identity (cons x l)) |
| 17:39 | arrdem | ,(doc keep_ |
| 17:39 | clojurebot | #<RuntimeException java.lang.RuntimeException: EOF while reading> |
| 17:39 | iwo | but that's even less neat :) |
| 17:39 | arrdem | ,(doc keep) |
| 17:39 | clojurebot | "([f coll]); Returns a lazy sequence of the non-nil results of (f item). Note, this means false return values will be included. f must be free of side-effects." |
| 17:40 | arrdem | no that's neater, it's just not gonna do what you want. |
| 17:40 | iwo | ? |
| 17:41 | iwo | this would work: (keep identity (cons x l)) |
| 17:41 | iwo | i.e. cons regardless, but use keep identity to remove x if it was nil |
| 17:42 | iwo | what i'd really like is (if x (cons x l) l) |
| 17:42 | iwo | but in a single fn from clojure core :) |
| 17:42 | technomancy | iwo: useful's "fix" function might do that |
| 17:42 | technomancy | nothing in core though |
| 17:42 | amalloy | iwo: (keep identity (cons x l)) doesn't do what you want at all |
| 17:42 | amalloy | it will remove all the nils that were already in the list |
| 17:43 | sw2wolf | ,(doc identity) |
| 17:43 | clojurebot | "([x]); Returns its argument." |
| 17:43 | iwo | amalloy: not a problem for me, the list contains no nils |
| 17:43 | arrdem | amalloy: thanks, I didn't think it would behave but I wasn't sure what it _would_ do :p |
| 17:44 | iwo | technomancy: do you mean flatland/useful? |
| 17:44 | technomancy | iwo: yeah, but amalloy would know for sure |
| 17:44 | amalloy | fix can kinda do it, but it's awkward: (fix l x (partial cons x)) would work most of the time, or (fix l (not (nil? x)) (partial cons x)) to be careful |
| 17:45 | amalloy | i don't think i'd use fix for this |
| 17:45 | technomancy | yeah, it's an awkward request =) |
| 17:45 | amalloy | (concat (keep identity [x]) l)? |
| 17:45 | amalloy | but that's much harder than the simple (if x (cons x l) l) |
| 17:46 | amalloy | i think test-> in 1.5 does a decent job of it, doesn't it? |
| 17:47 | amalloy | (test-> l x (->> (cons x))) probably works |
| 17:47 | amalloy | ,(doc test->) |
| 17:47 | clojurebot | Gabh mo leithscéal? |
| 17:53 | iwo | i guess clojurebot doesn't speak 1.5 |
| 17:54 | iwo | (if x (cons x l) l) it is :) |
| 17:57 | mthvedt | is there a way to make a private defrecord, say Foo, and not have it expose ->Foo |
| 17:58 | gfredericks | mthvedt: you could muck with the var if you really wanted to |
| 17:59 | amalloy | mthvedt: this sounds like a great opportunity to use a hashmap instead of a record |
| 17:59 | gfredericks | haha |
| 17:59 | gfredericks | amalloy the hashmap salesman |
| 18:00 | amalloy | my hashmaps provide genuine, FDA-certified constant-time lookup time, won't you try one? |
| 18:01 | gfredericks | would "unused arguments" be a good kibit rule? |
| 18:01 | gdev | amalloy:) are they organic? |
| 18:01 | arrdem | amalloy: but can you optimize them out to structs at runtime? |
| 18:01 | amalloy | i was aiming more for the 1950s "door-to-door salesman" archetype, not the 2000s-era organic stuff |
| 18:01 | tcrayford | amalloy: I only use grass-fed, home grown vegan kosher paeleo primal hashmaps, you got any of those? |
| 18:02 | mthvedt | amalloy: can your hash maps implement protocols? :P |
| 18:02 | gdev | tcrayford:) lol at vegan paeleo |
| 18:02 | amalloy | use multimethods! technomancy is probably willing to put on an evangelism act to match my salesmanship, telling you how protocols are the devil |
| 18:03 | tcrayford | true story, I know a dude who's on something like that. Asking him "what he eats" leads to a pretty short list |
| 18:03 | technomancy | be free of their tyranny |
| 18:03 | PudgePacket | Hi, I'm having some trivial problems importing jara .jars for a clojure project. I'm not sure where to keep the .jar, and how the import should refer to it, I'm used to C++ style of using a filename! |
| 18:03 | mthvedt | they are not my protocols |
| 18:03 | amalloy | technomancy: i'm afraid to google "jack chick tract" |
| 18:03 | tcrayford | technomancy: I use a protocol for this core abstraction (of data storage) in my app. Please be mad |
| 18:03 | Glenjamin | amalloy: i can't seem to find test->, did you mean cond-> ? |
| 18:03 | technomancy | tcrayford: there is still hope for you |
| 18:03 | amalloy | ~repeatability |
| 18:03 | clojurebot | repeatability is crucial for builds, see https://github.com/technomancy/leiningen/wiki/Repeatability |
| 18:03 | tcrayford | how do I teach clojurebot shit? |
| 18:03 | tcrayford | ~amalloy |
| 18:04 | clojurebot | amalloy is the spotlight illuminating my dumb mistakes |
| 18:04 | arrdem | loooool |
| 18:04 | amalloy | Glenjamin: i probably do. i didn't pay attention to the renaming thing |
| 18:04 | gdev | ~nDuff |
| 18:04 | clojurebot | Please don't use pastebin.com: there are lots of annoying animated ads. Instead, try http://refheap.com, an ad-free pastebin written in Clojure. |
| 18:04 | arrdem | PudgePacket: amalloy is telling you to import your jars to maven and then make them lein deps |
| 18:04 | arrdem | PudgePacket: as of lein 2 lein no longer supports local non-maven jars |
| 18:05 | Glenjamin | ,(doc cond->) |
| 18:05 | clojurebot | "([expr & clauses]); Takes an expression and a set of test/form pairs. Threads expr (via ->) through each form for which the corresponding test expression is true. Note that, unlike cond branching, cond-> threading does not short circuit after the first true test expression." |
| 18:05 | PudgePacket | arrdem, can i just use maven commands in lein? I only have leiningen |
| 18:05 | arrdem | clojurebot: remember arrdem is about 85% corect |
| 18:05 | clojurebot | 'Sea, mhuise. |
| 18:05 | tcrayford | technomancy: also this app has a "util" namespace where I rewrote "keys" and "values" to be sane, also wrote get so it throws an exception if the key isn't there. Be more mad. |
| 18:05 | technomancy | tcrayford: non-nilling get is great |
| 18:05 | arrdem | PudgePacket: don't think so. you'll need maven to manipulate ~/.m2 in any reasonable way. |
| 18:05 | technomancy | but "util" is sad times |
| 18:06 | tcrayford | technomancy: I should just open up clojure.core right? |
| 18:06 | technomancy | totes |
| 18:06 | djwonk | I am using `bz2-reader` from http://www.paullegato.com/blog/reading-bzip2-files-clojure/ but I'm having a problem with it: https://gist.github.com/bluemont/8e8b717a732446fc9a8e#file-core-clj-L61 |
| 18:06 | tcrayford | realtalk, I wish nil didn't exist. Clojure doesn't technically need it except for interop |
| 18:07 | Glenjamin | what is a good way to deal with "util" aka random bucket of functions i wish were in core? |
| 18:07 | Glenjamin | also, what's so bad about Protocols? |
| 18:08 | arrdem | it's clojurebot: forget <phrase>, right? |
| 18:09 | tcrayford | clojurebot: forget forget |
| 18:09 | clojurebot | It's greek to me. |
| 18:12 | PudgePacket | arrdem, I've downloaded and got maven working, do i just perform a similar task to running a lein operation ? navigate to project directory then run the command? |
| 18:15 | arrdem | PudgePacket: http://www.pgrs.net/2011/10/30/using-local-jars-with-leiningen/ |
| 18:19 | PudgePacket | arrdem, it says there is no project object model in the directory, im running from the project directory, do i need to create a POM somehow? |
| 18:20 | Glenjamin | xeqi: am i missing something, or does kerodon not handle select elements? |
| 18:20 | SegFaultAX | PudgePacket: Probably a good idea to read a tutorial on Maven. |
| 18:21 | PudgePacket | SegFaultAx, i'm just trying to use a local .jar file in my clojure code, this seems a pretty ridiculous amount of fiddling to get something so trivial working :/ |
| 18:24 | technomancy | tcrayford: "except for interop" is kind of a really big thing though =( |
| 18:24 | technomancy | but I would love a nil-free clojure |
| 18:25 | tcrayford | ofc ;). In a modern dynamically typed lang, with Maybe supplied by the lang, there's no need for nil (in my book) |
| 18:26 | Glenjamin | is Maybe actually an improvement over nil? |
| 18:27 | Glenjamin | doesn't it just move the nil along to some point where you need a value? |
| 18:29 | tcrayford | it's different |
| 18:29 | tcrayford | Maybe as a return type says "this quite possibly will return nothing" |
| 18:29 | tcrayford | usually you have to dig in non-existent docs or read the code to find out if something can return nil |
| 18:30 | mthvedt | what's the point of maybe without type checking and/or pattern matching |
| 18:30 | Glenjamin | ^^ this |
| 18:30 | tcrayford | if you look at a function, and what you get out of it is a nil, then you know you have to handle the nil case |
| 18:31 | tcrayford | wheras if you look at a function, often you don't know if there is a nil case, then fail to handle it, then your program blows up in weird and wonderful ways |
| 18:31 | technomancy | it just forces awareness, right? |
| 18:31 | tcrayford | without pattern matching/monads/type checking, yeah |
| 18:31 | mthvedt | so, the point of maybe is to replace java annotations |
| 18:31 | mthvedt | got it |
| 18:33 | Glenjamin | but where do you write the Maybe return type in a dynamic language? |
| 18:34 | technomancy | docstring |
| 18:34 | technomancy | the point is, you can't not handle maybe |
| 18:34 | tcrayford | also, you'd see it when you called the function at the repl |
| 18:35 | Glenjamin | right, you have to unpack it |
| 18:35 | Glenjamin | i see |
| 18:35 | technomancy | like a reference type |
| 18:37 | SegFaultAX | "The point of maybe is to replace Java annotations" wut. |
| 18:38 | hiredman | if you fail to handle nil you aren't using mapcat enough |
| 18:41 | mthvedt | segfaultax: sarcasm |
| 18:41 | amalloy | (def easy-version-of-technomancy's-annoying-Maybe-fn (comp fromJust technomancy's-annoying-Maybe-fn)) ;; now i don't have to handle maybe anymore! |
| 18:42 | Anderkent | amalloy: fromJust throws on Nothing, surely |
| 18:42 | Anderkent | it wouldnt return nil |
| 18:43 | amalloy | Anderkent: of course, that's the joke. you're back to exceptions, just like you wanted |
| 18:43 | amalloy | not you specifically, of course |
| 18:45 | Glenjamin | xeqi: going to see if i can get dropdown support into kerodon, the enlive stuff is a bit black-magicky to me though - will send a PR if i get something reasonable |
| 18:46 | technomancy | I imagine haskell users look upon nil with the same disdain exception users look upon languages that use numeric error codes as return values |
| 18:47 | Anderkent | Sounds reasonable to me - I think nils are the source of more than half of the bugs i introduce |
| 18:48 | Anderkent | Oh, you forgot to initialize your map values to sets? Here, let me give you a nil so that you can conj onto it and break the code mysteriously 20 calls later :) |
| 18:49 | Glenjamin | isn't that basically what happens if you use Maybe with do notation in haskell? |
| 18:50 | Glenjamin | the Monad composition just shuffles the Nothing along? |
| 18:50 | Anderkent | sure, but that's not what my problem is |
| 18:50 | Anderkent | the problem is that conj eats the nil happily |
| 18:50 | Anderkent | and gives you back a list :) |
| 18:50 | SegFaultAX | Glenjamin: That's the whole /point/ of Maybe. |
| 18:50 | SegFaultAX | Anderkent: nil is the empty list. |
| 18:51 | Glenjamin | is there a conj-set ? |
| 18:51 | SegFaultAX | conj-set? |
| 18:51 | Anderkent | I know, that's why this problem exists? If conj threw up on nil, I'd get errors at the failure point. But it doesn't, so I only get errors in some random other place that expects a set but sees a list |
| 18:51 | Glenjamin | a conj that always gives you a set :p |
| 18:52 | SegFaultAX | Anderkent: conj is fine. You should be correctly checking for errors in your data. |
| 18:53 | Anderkent | I should have a map type that throws on non-existing keys, instead of silently pretending there was a nil in it |
| 18:54 | Glenjamin | or better yet, a map type that gives you empty sets on new keys |
| 18:54 | Anderkent | well not quite, because it's rare you'd want an empty set for every key |
| 18:54 | Anderkent | it's like |
| 18:54 | Glenjamin | in this case |
| 18:55 | Glenjamin | something like python's defaultdict, unsure if that fits the clojure model really |
| 18:55 | dnolen | And even tho the MLs got rid of null, ya still got the empty list to produce show stopping runtime errors - http://stackoverflow.com/questions/4883169/why-im-getting-exception-prelude-head-empty-list |
| 18:55 | Anderkent | you have some state, you store it as (def my-state (ref {:id-ste #{} :some-other-map {}})) and then somewhere else you have (update-in my-state [:id-set] conj new-id) |
| 18:56 | dnolen | c'est la vie |
| 18:56 | Anderkent | like what kind of idiom would prevent this from blowing up? |
| 18:56 | Anderkent | never conj in update-in? |
| 18:57 | SegFaultAX | Anderkent: Is it exceptional for the key to not be present? |
| 18:57 | hiredman | ,(doc fnil) |
| 18:57 | clojurebot | "([f x] [f x y] [f x y z]); Takes a function f, and returns a function that calls f, replacing a nil first argument to f with the supplied value x. Higher arity versions can replace arguments in the second and third positions (y, z). Note that the function f can take any number of arguments, not just the one(s) being nil-patched." |
| 18:57 | brehaut | dnolen: something something dependant types and total functions something *handwaves* solves that problem just fine |
| 18:58 | Anderkent | SegFaultAX: yes, the key is only not present because of the typo in original declaration |
| 18:58 | dnolen | brehaut: ;) |
| 18:58 | Glenjamin | oh, i see |
| 18:59 | Glenjamin | if all you're worried about is typos, you're probably ok |
| 19:00 | Anderkent | I don't think "don't make typos" is a solution |
| 19:01 | Glenjamin | write some tests to express behaviour, you'll catch them soon enough |
| 19:01 | Glenjamin | or take a typing class, i don't class typos as one of the major problems in software development |
| 19:08 | Anderkent | That was uncalled for. Whatever, I'm probably more likely to use something like (defn sget [map key] (when-not (contains? map key) (throw ...)) (map key)). I can imagine at least 2 ways in which even full test coverage wouldn't catch a similar update-in conj issue, but since it seems you never make mistakes I won't bother |
| 19:10 | SegFaultAX | Glenjamin: Humans are prone to typing errors. Some non-trivial percentage of programs are types by humans. Therefore some non-trivial percentage of programs are prone to typing errors. To categorically exclude typing errors as a source of bugs in software is utterly short-sighted. |
| 19:10 | Glenjamin | sorry, that came across as snarky, wasn't intended that way |
| 19:11 | Glenjamin | if you're concerned that typos will be a major source of bugs, then you probably want a statically typed language? |
| 19:11 | SegFaultAX | Glenjamin: Humans are the source of bugs. |
| 19:12 | Glenjamin | which is why we write automated tests, and abstractions :) |
| 19:12 | SegFaultAX | Glenjamin: Automated tests can only capture at most a certain subset of all possible errors. Likewise with static typing. There is no silver bullet. |
| 19:13 | Glenjamin | agreed |
| 19:14 | Glenjamin | i'm not claming i never make typos or introduce bugs |
| 19:14 | Glenjamin | i'm claiming that I don't introduce enough bugs from typos to change my entire approach to development to attempt to avoid them |
| 19:15 | Glenjamin | i feel like my tone isn't transferring very well though :( |
| 19:17 | brehaut | actually, you dont need static typing to catch typoes; clojure eliminates a large number of typo causing errors by requiring all symbols to be defined before they are reference lexically |
| 19:17 | SegFaultAX | Or at least declared. |
| 19:17 | brehaut | obviously whenever strings and keywords etc enter the mix, you reintroduce the potential for that type of typo |
| 19:18 | brehaut | yeah sorry |
| 19:18 | SegFaultAX | As is the case in lots of languages that have forward decls. |
| 19:18 | SegFaultAX | (Dynamic or otherwise) |
| 19:18 | brehaut | (yup |
| 19:19 | tieTYT2 | is there a function/library that takes a POJO and converts it into a clojure data structure? |
| 19:19 | SegFaultAX | On a related tangent, I've never really understood the justification for variable hoisting in JS. |
| 19:19 | brehaut | (clojure,set/subset? static-types static-analysis) |
| 19:19 | SegFaultAX | tieTYT2: Records are POJOs |
| 19:19 | tcrayford | dnolen: re the head of an empty list case, that's been a long complain of mine for haskell. Head should return a Maybe. |
| 19:20 | brehaut | also the bean function |
| 19:20 | tieTYT2 | SegFaultAX: my java pojo already exists. Is that an issue? |
| 19:20 | tieTYT2 | ooh bean function |
| 19:20 | SegFaultAX | tieTYT2: Oh then you'll probably have to write a converter for it. |
| 19:20 | SegFaultAX | pojo->map or something. |
| 19:20 | tieTYT2 | SegFaultAX: well it looks like bean would work? |
| 19:20 | brehaut | tieTYT: it creates a proxy thoguh, not a persistent structure |
| 19:20 | tieTYT2 | am I wrong? |
| 19:20 | tieTYT2 | aw |
| 19:21 | tieTYT2 | it says it's read-only |
| 19:22 | SegFaultAX | Plus the bean function is probably a lot more expensive than it's worth if you're converting a lot of these objects. |
| 19:23 | SegFaultAX | I don't really know anything about how HotSpot may or may not optimize lots of reflective calls. |
| 19:23 | tieTYT2 | k, i'll write my own converter |
| 19:25 | tieTYT2 | here's what I'm trying to do. I've got a list of this POJO. For shitty reasons, its equals() impl is worthless. I need to find instances in the list that are the same based off of specific fields and only keep the instance with the earliest date. Then I need to take the ones that are the same based on a DIFFERENT set of fields, copy the data (except for a primary key field) over to the |
| 19:25 | tieTYT2 | instance with a primary key... etc. |
| 19:26 | tieTYT2 | to me this sounds like a functional problem and it'd be easier to do in clojure. This is a javaee app and the class is an entity |
| 19:27 | Glenjamin | you might be as well just breaking into small functions for each step like you would in clojure, but staying on the java side |
| 19:28 | tieTYT2 | Glenjamin: it's really hard to do that without a useful equals(). The collections have to be mutated along the way |
| 19:28 | tieTYT2 | and it's hard to figure out what's going on |
| 19:28 | Glenjamin | are the fields public? |
| 19:28 | tieTYT2 | no, but you can get them through getters |
| 19:28 | hiredman | (->> objs (group-by identity-function) vals (map (partial sort-by date-of)) (map first) (group-by second identity) vals (map (partial apply merger))) |
| 19:28 | hiredman | that should be second-identity |
| 19:29 | Glenjamin | just have your service class define it's own domain specific equals() function |
| 19:29 | tieTYT2 | hiredman: yeah that's a shitload of code in java IMO |
| 19:29 | hiredman | and there is no need to make maps |
| 19:30 | Glenjamin | that certainly looks better than my idea :) |
| 19:30 | tieTYT2 | hiredman: are you advocating what Glenjamin's suggesting with your comment? |
| 19:31 | hiredman | I dunno, I have Glenjamin on ignore |
| 19:31 | Glenjamin | :( |
| 19:31 | tieTYT2 | sounds like a no |
| 19:34 | tieTYT2 | hiredman: why'd you mention the maps thing? |
| 19:34 | tieTYT2 | did you mean no need for a converter? |
| 19:35 | hiredman | yes |
| 19:35 | tieTYT2 | ah, cool |
| 19:35 | tieTYT2 | i'll try it out, thanks |
| 19:37 | Glenjamin | i take it all back, i just got a mysterious null pointer error from deep in the stack :( |
| 19:40 | amalloy | check for typos |
| 19:41 | Glenjamin | heh, forgot to save a file :( |
| 19:42 | Raynes | I read "heh, forgot to save a life :(" |
| 19:43 | tieTYT2 | is this out of date? The second one looks like what I want to do |
| 19:43 | tieTYT2 | http://stackoverflow.com/questions/2181774/calling-clojure-from-java |
| 19:43 | tieTYT2 | it says: No need to call RT.init() anymore |
| 19:43 | tieTYT2 | but it only works if I do |
| 19:44 | djwonk | My bzip2 problem was that I needed to use the second constructor form. Groan: http://www.paullegato.com/blog/reading-bzip2-files-clojure/ |
| 19:44 | djwonk | Who knew that bzip2 files could be concatenated anyways? |
| 19:45 | tieTYT2 | gives me this: java.lang.ExceptionInInitializerError at clojure.lang.Compiler.<clinit>(Compiler.java:47) |
| 19:45 | djwonk | Making the default be false, which breaks stuff when you don't expect it, is crazytown. |
| 20:22 | gdev | ,(#(* %)#_(if youre happy and you know it print a one)(*)) |
| 20:22 | clojurebot | 1 |
| 20:22 | ToxicFrog | MY BRAIN |
| 20:22 | gdev | your braine on drugs |
| 20:24 | tomoj | holy crap, pst takes a depth |
| 20:26 | tomoj | now I can stop lein-swanking instead of jacking-in just to be able to see .printStackTrace |