2012-07-17
| 00:00 | dsrguru | so lets walk through evaluating this |
| 00:00 | dsrguru | oh btw |
| 00:00 | dsrguru | you should set acc to 1 |
| 00:00 | dsrguru | not 0 |
| 00:00 | dsrguru | since 0! = 1 |
| 00:01 | dsrguru | otherwise each time you multiply by n |
| 00:01 | dsrguru | you're still at 0 :) |
| 00:01 | dsrguru | so acc just means |
| 00:01 | iDesperadO | acc is accumulation of the current factorial.. |
| 00:01 | dsrguru | this is the ultimate return value |
| 00:01 | dsrguru | but what we've accumulated so far |
| 00:01 | dsrguru | yes |
| 00:01 | dsrguru | so |
| 00:01 | iDesperadO | i get it |
| 00:01 | dsrguru | good |
| 00:01 | dsrguru | and trace it out |
| 00:02 | dsrguru | you'll see that (fact 2) -> (recur (dec 2) (* 2 1)) |
| 00:02 | dsrguru | -> (recur 1 (* 2 1)) -> (recur 0 (* 1 (* 2 1))) |
| 00:02 | dsrguru | and now that (= n 0) |
| 00:03 | dsrguru | (recur 0 (* 1 (* 2 1))) just equals (* 1 (* 2 1)) |
| 00:03 | iDesperadO | ok |
| 00:03 | dsrguru | which evaluates to 2 |
| 00:03 | dsrguru | so to make something tail recursive |
| 00:03 | dsrguru | or the clojure equivalent at least |
| 00:03 | iDesperadO | (defn rrgcd [a b] (loop [a a b b] (if (= a 0) b (recur (rrgcd (rem b a) a))))) |
| 00:03 | dsrguru | what you want to do is have all the operations |
| 00:03 | dsrguru | that get you closer to the base case |
| 00:03 | dsrguru | take place inside the recursive call |
| 00:03 | dsrguru | not outside |
| 00:04 | dsrguru | i.e. (recur (bla...) (bla...)) not (bla (recur 2)... |
| 00:04 | dsrguru | if you look at a few examples online |
| 00:04 | iDesperadO | ah... |
| 00:05 | dsrguru | the pattern will be very clear |
| 00:09 | iDesperadO | (defn rrgcd [a b] (loop [a a b b] (if (= a 0) b (recur (rrgcd (rem b a) a))))) |
| 00:09 | iDesperadO | this definition is still not right |
| 00:09 | iDesperadO | Mismatched argument count to recur, expected: 2 args, got: 1 |
| 00:10 | dsrguru | check your parens |
| 00:10 | dsrguru | oh nvm |
| 00:10 | iDesperadO | i'm afraid the parens are right... |
| 00:11 | dsrguru | you don't also include rrgcd |
| 00:11 | dsrguru | it should be (defn rrgcd [a b] (loop [a a b b] (if (= a 0) b (recur (rem b a) a)))) |
| 00:11 | iDesperadO | ? |
| 00:11 | iDesperadO | why there's no rrgcd there? |
| 00:11 | dsrguru | loop and recur work together |
| 00:11 | dsrguru | loop isn't just a let statement |
| 00:11 | dsrguru | it also sets the boundary of a new function |
| 00:12 | dsrguru | that can be recursively called |
| 00:12 | dsrguru | with TCO |
| 00:12 | dsrguru | (tail call optimization) |
| 00:12 | dsrguru | when you call recur |
| 00:12 | dsrguru | so recur says |
| 00:12 | dsrguru | call the function I just defined by loop |
| 00:12 | dsrguru | and in your case |
| 00:12 | dsrguru | it happens to have the same parameters as the outer function rrgcd |
| 00:13 | dsrguru | but that's unusual |
| 00:13 | dsrguru | that's why I showed you the factorial case first |
| 00:13 | dsrguru | where it was clear |
| 00:13 | dsrguru | that the loop expression was autonymous |
| 00:13 | dsrguru | so in this case (loop [a a b b] (if (= a 0) b (recur (rem b a) a))) |
| 00:13 | iDesperadO | so (loop [a a b b] ...) is a function? |
| 00:13 | dsrguru | defines an anonymous function |
| 00:13 | dsrguru | yes |
| 00:13 | dsrguru | exactly |
| 00:13 | dsrguru | except |
| 00:14 | dsrguru | it doesn't define it |
| 00:14 | dsrguru | it calls it in place |
| 00:14 | dsrguru | it's like ((fn [a b] ...) a b) |
| 00:14 | iDesperadO | ah |
| 00:14 | dsrguru | sorry I should have explained that at the beginning! |
| 00:15 | iDesperadO | if the loop part is an anonymous function then this function body is just [a a b b] ??? |
| 00:15 | lazybot | iDesperadO: Oh, absolutely. |
| 00:15 | dsrguru | do triple question marks trigger lazybot ??? |
| 00:15 | lazybot | dsrguru: Oh, absolutely. |
| 00:16 | iDesperadO | oh |
| 00:16 | iDesperadO | so..? |
| 00:16 | dsrguru | sorry had to test that |
| 00:16 | dsrguru | I'm not sure I get your question |
| 00:16 | dsrguru | let me give you two examples |
| 00:17 | dsrguru | one with loop/recur |
| 00:17 | dsrguru | one with a named fn |
| 00:17 | dsrguru | so you can see how they map up |
| 00:17 | iDesperadO | if the loop is a anonymous function, then it must have a function body, which i guess is [a a b b] |
| 00:17 | dsrguru | although remember that loop/recur will run faster |
| 00:17 | dsrguru | or at least conserve space in the call stack |
| 00:17 | dsrguru | btw a named fn is the same as a regular anonymous fn except it temporarily has a name for purposes of recursion |
| 00:17 | dsrguru | so: |
| 00:18 | dsrguru | (fn rgcd [a b] (if (= a 0) b (rgcd (rem b a) a))) |
| 00:18 | dsrguru | is the same as: |
| 00:18 | dsrguru | wait |
| 00:19 | dsrguru | ((fn rgcd [a b] (if (= a 0) b (rgcd (rem b a) a))) 3 4) |
| 00:19 | dsrguru | is the same as: |
| 00:19 | dsrguru | (loop [a 3 b 4] (if (= a 0) b (recur (rem b a) a))) |
| 00:19 | dsrguru | except for efficiency |
| 00:19 | iDesperadO | ah |
| 00:19 | dsrguru | does that help? |
| 00:20 | wingy | finally |
| 00:20 | wingy | cljs worked! |
| 00:20 | iDesperadO | helps a lot ! |
| 00:20 | wingy | https://github.com/emezeske/lein-cljsbuild was really great |
| 00:20 | wingy | much better than clojurescriptone if you wanna get started |
| 00:21 | iDesperadO | loop defines a function, binds the parameters and then call the function... |
| 00:21 | dsrguru | iDesperadO: or at least I'm assuming that's true because that's how the equivalent works in Scheme! |
| 00:21 | dsrguru | yes |
| 00:21 | dsrguru | and it does one more thing |
| 00:22 | iDesperadO | for recur to rebind the parameters |
| 00:22 | dsrguru | yes |
| 00:22 | iDesperadO | thanks, dsrguru, you are sooooooooooo helpful |
| 00:24 | dsrguru | iDesperadO: np I've been pestering the good people on this channel enough in the last couple days as I too am starting to use clojure, so I'm only happy to help |
| 00:26 | iDesperadO | i'm a c++ programming by profession, but now I'm amazed by clojure... |
| 00:26 | iDesperadO | programmer |
| 00:27 | iDesperadO | a clojure's function can do so much more than a c++'s class...haha~~~ |
| 00:28 | dsrguru | haha yup LISPs are so expressive |
| 00:47 | wingy | iDesperadO: lisp is the best thing after sliced bread |
| 00:48 | iDesperadO | wingy: hahahahaha... |
| 00:48 | wingy | one thing bad though is the jvm startup time in lein |
| 00:48 | wingy | i wish they can move to node.js instead for lein .. isn't cljs designed for running cli tools |
| 00:48 | wingy | technomancy: ^ :) |
| 00:52 | yonatane | Hi wingy, do you ever sleep? ;) |
| 00:52 | wingy | yonatane: couldn't sleep since i couldn't get cljs working |
| 00:52 | wingy | but now its fixed |
| 00:52 | wingy | so now i have to play with it some more before i sleep |
| 00:53 | wingy | yonatane: have you been stalking me? |
| 00:53 | ivan | technomancy might think about it after you port 20MB of Java to CLJS |
| 00:54 | wingy | ivan: :/ |
| 00:55 | wingy | it's using a lot of java libs? |
| 00:55 | ivan | take a look inside leiningen's jar |
| 00:55 | ivan | it's got all that maven stuff |
| 00:55 | wkelly | and ant stuff |
| 00:56 | wingy | plan b … let's just kill the startup time |
| 02:42 | iDesperadO | hi, `lein search` always returns with exception with clj-http: status-404 |
| 02:42 | iDesperadO | I use a vpn to get access to the repo |
| 03:00 | wingy | how do i add a css file in hiccup? |
| 03:01 | wingy | the api doesnt mention css files http://weavejester.github.com/hiccup/hiccup.element.html |
| 03:03 | wingy | oh: http://weavejester.github.com/hiccup/hiccup.page.html |
| 03:08 | ro_st | what do you think of hiccup so far, wingy? |
| 03:11 | akhudek | I greatly prefer enlive |
| 03:11 | ro_st | they do different things, don't they? enlive is more for parsing/scraping? |
| 03:11 | akhudek | ro_st: not really, enlive is great for templating |
| 03:12 | ro_st | i'm planning on using enlive/enfocus with a common set of templates |
| 03:12 | akhudek | the big deal with enlive is that a designer can give you pure html and you don't need to modify it directly |
| 03:12 | ro_st | allow the server to render pages, but also allow the client to re-render them or parts of them |
| 03:12 | akhudek | that's a good idea |
| 03:12 | akhudek | was thinking of something similar myself |
| 03:13 | akhudek | we use a lot of enlive at my work |
| 03:13 | ro_st | part of my app is a store, i'm planning to do what the new basecamp does |
| 03:13 | ro_st | with pjax |
| 03:13 | ro_st | where it only loads the 'center' on page nav |
| 03:14 | ro_st | makes it really fast |
| 03:14 | akhudek | I'm not very familiar with basecamp sadly, but enlive on both server + ajax client seems pretty natural |
| 03:14 | ro_st | what i like about the enlive/enfocus strategy is i don't need to decide where things get rendered |
| 03:14 | ro_st | and i can change my mind easily once i do |
| 03:14 | akhudek | I've found cljs to be very undocumented this point overall |
| 03:14 | ro_st | makes things a lot more manageable |
| 03:14 | ro_st | yeah |
| 03:15 | ro_st | cljsbuild's crossover feature is great |
| 03:15 | akhudek | there are a number of places where I could also see cljs and clj sharing code directly |
| 03:16 | ro_st | i'm doing all my 'model' code in clj and testing with midje and midje-mode |
| 03:16 | akhudek | enfocuse/enlive templates and snippets, and also validation/state control code |
| 03:16 | ro_st | and it's auto compiling all those ns's to js as well |
| 03:16 | akhudek | huh, so you do share code between client and server? |
| 03:16 | ro_st | so hopefully i'll only need to actually develop the glue and service layer code in cljs directly |
| 03:17 | ro_st | i'll be able to build all my templates in the repl with enlive |
| 03:17 | ro_st | yes |
| 03:17 | ro_st | it's very easy to configure |
| 03:17 | akhudek | nice, I was hoping that it was possible. Our project hasn't incorporated any cljs yet, but I've been starting to look into it |
| 03:18 | ro_st | i'm re-doing a google closure javascript codebase as cljs |
| 03:18 | ro_st | i'm coming out at less than a 1/6th of the code, including tests :-) |
| 03:18 | akhudek | our client code is jquery, which makes it a bit more painful to move over… maybe |
| 03:19 | ro_st | my advantage is that i'm already familiar with the closure compiler and library |
| 03:19 | ro_st | our CI et al already has all that set up |
| 03:20 | akhudek | nice, that seems like it would make it a bit easier |
| 03:20 | ro_st | definitely |
| 03:20 | akhudek | do you know if closure provides multiple file upload in IE8? |
| 03:20 | ro_st | i don't, sorry |
| 03:21 | akhudek | darn, no worries. IE8 is very annoying. |
| 03:21 | ro_st | indeed |
| 03:21 | ro_st | unfortunately it accounts for close to a third of our userbase |
| 03:21 | ro_st | thankfully ie6/7 are less than 1% combined |
| 03:21 | akhudek | same or worse here :-( |
| 03:22 | akhudek | we don't support 6/7 |
| 03:22 | akhudek | although I think 7 still mostly works last I checked |
| 03:24 | ro_st | what's the simplest way to find the index of an item in a set? |
| 03:24 | akhudek | set's have no numerical index |
| 03:24 | akhudek | or any index really |
| 03:24 | akhudek | they compare on the items they contain directly |
| 03:25 | ro_st | oh, my mistake. index of an item in a vector |
| 03:25 | ro_st | in this case, i know for sure the vector only contains one copy of each item in it |
| 03:26 | malcolmsparks | (just a test) |
| 03:26 | akhudek | I can't think of any easy way outside of combining map and some |
| 03:27 | ro_st | i'm using seq-utils' positions fn now |
| 03:27 | ro_st | but i'm using it in a crossover (clj + cljs) ns. so i guess i'll have to yank it out into a util.clj in my own crossover folder |
| 03:29 | akhudek | isn't seq-utils deprecated? |
| 03:30 | akhudek | easiest direct way I can see right now is |
| 03:30 | akhudek | ,(let [items (map vector (iterate inc 0) [:a :b :c :d])] (some (fn [[i v]] (if (= v :c) i)) items)) |
| 03:30 | clojurebot | 2 |
| 03:30 | akhudek | could make it into a function easily enough |
| 03:31 | akhudek | or just copy the seq-util function if it works for you |
| 03:31 | ro_st | i guess it takes that much code because of the lazy nature? |
| 03:31 | ro_st | yeah i copied it |
| 03:31 | ro_st | it's not much: https://www.refheap.com/paste/3638 |
| 03:32 | hiredman | ,(doc keep-indexed) |
| 03:32 | clojurebot | "([f coll]); Returns a lazy sequence of the non-nil results of (f index item). Note, this means false return values will be included. f must be free of side-effects." |
| 03:32 | amalloy | you want ##(doc keep-indexed), but really if your code needs the index of something you're usually doing something wrong |
| 03:32 | lazybot | ⇒ ------------------------- clojure.core/keep-indexed ([f coll]) Returns a lazy sequence of the non-nil results of (f index item). Note, this means false return values will be included. f must be free of side-effects. nil |
| 03:33 | ro_st | well, i have a ref to a unique element, and i want to get the very next element in the vector after this element i have a reference to |
| 03:33 | ro_st | and so i'm using positions to get the index of the element i have, adding 1, and checking bounds, and if that passes, fetching it out |
| 03:34 | ro_st | good ole imperative style. i'm very keen to use a better method if one exists |
| 03:34 | ro_st | i can't modify the source vector, though. i can pre-process it to make it a sorted-set or something if that's more appropriate |
| 03:34 | akhudek | how many elements are in this vector? |
| 03:35 | ro_st | tens at most |
| 03:35 | akhudek | unless you have millions of queries per second, I wouldn't worry too much about performance here |
| 03:35 | ro_st | another constraint: this code runs in cljs primarily |
| 03:36 | ro_st | oh, indeed. showing intent in the code clearly is my main concern |
| 03:36 | akhudek | drop-while + fnext |
| 03:37 | akhudek | use let-if or similar if you want to check the case where there is no next |
| 03:37 | ro_st | um, so say i have a ref to :c, and a vector, [:a :b :c :d]. using :c, i want to get :d. how would i use drop-while in this case? |
| 03:38 | ro_st | edge cases are that a nil ref should fetch back :a, and a :d ref should fetch back nil. those are easy once the main case is working, of course |
| 03:38 | akhudek | ,(fnext (drop-while #(not= :c %) [:a :b :c :d])) |
| 03:38 | clojurebot | :d |
| 03:39 | hiredman | ro_st: keep :c and :c's index in the ref, and then just inc :c's index |
| 03:39 | ro_st | oh right. drop-while finds the ref, and fnext grabs the next one |
| 03:39 | akhudek | ,(fnext (drop-while #(not= :c %) [:a :b :c])) |
| 03:39 | clojurebot | nil |
| 03:39 | ro_st | that's very elegant, akhudek! |
| 03:40 | akhudek | if you need to check that no :d exists, just do if-let |
| 03:40 | ro_st | hiredman: that has the problem of me needing to determine the index, which i've been told is Naughty :-) |
| 03:40 | hiredman | ro_st: how do you not know the index? do you not start at 0? |
| 03:42 | akhudek | I'm off to sleep, night ro_st |
| 03:42 | ro_st | the fn returns the element, which is then kept elsewhere. the next time the fn is used, i pass in the previously returned element |
| 03:42 | ro_st | sleep well |
| 03:43 | ro_st | so using index is adding complexity. akhudek's drop-while + fnext solution works a charm |
| 03:43 | hiredman | ro_st: if you need the index, why not pass it around? |
| 03:43 | ro_st | i don't need the index :-) i need the element |
| 03:43 | ro_st | i was using the index before because that's how my n00b imperative brain said i should do it |
| 03:44 | hiredman | so why are you using a vector? |
| 03:44 | ro_st | that's how it comes off the wire |
| 03:44 | ro_st | deserialised json |
| 03:45 | hiredman | there is nothing imperative about indexed access |
| 03:47 | ro_st | ok :-) as i mentioned before, i was a) finding the index of the element i had b) incrementing it c) testing that value against the length of the vector d) if in bounds, returning vector[next-index] e) or if not, nil |
| 03:47 | ro_st | that's imperative-y |
| 03:47 | hiredman | it is not |
| 03:47 | ro_st | oh |
| 03:47 | wingy | ro_st: hiccup is nice |
| 03:47 | ro_st | -writes that down- |
| 03:48 | ro_st | -grin- |
| 03:48 | wingy | are you using enlive? |
| 03:48 | ro_st | i plan to, yes |
| 03:48 | ro_st | haven't gotten there yet |
| 03:48 | wingy | hmm .. im going to use bootstrap |
| 03:49 | ro_st | wingy: http://lightglitch.github.com/bootstrap-xtra/ |
| 03:49 | wingy | and thinking that writing HTML directly is more compatible with bootstrap |
| 03:49 | wingy | wow |
| 03:49 | ro_st | some nice stuff in this one |
| 03:50 | wingy | ro_st: is it maintained? |
| 03:50 | wingy | 8 months from last activity |
| 03:50 | ro_st | doesn't look like it :-( |
| 03:51 | wingy | such projects are risky |
| 03:51 | ro_st | agreed |
| 03:52 | ro_st | ,(if nil 1 2) |
| 03:52 | clojurebot | 2 |
| 03:53 | wingy | anyway .. i thought i im using enlive/enfocus i can do separate logic with template in HTML and that would be better when using Bootstrap |
| 03:53 | ro_st | weird. i had (if var-name (stuff) (things)) where var-name is nil and (stuff) got called |
| 03:53 | ro_st | switching to (if-not (nil? var-name) (…)) worked |
| 03:53 | ro_st | bootstrap is predominantly css and js, isn't it? |
| 03:55 | wingy | havent used it yet but yeah its heavy in css |
| 03:55 | ro_st | wingy, check kibit out |
| 03:55 | wingy | and using jquery for animations |
| 03:57 | wingy | https://github.com/jonase/kibit/ |
| 03:57 | ro_st | yup |
| 03:57 | wingy | what about it? |
| 03:57 | ro_st | it analyzes your code and tells you where you can simplify things |
| 03:57 | wingy | i see |
| 03:57 | wingy | cool |
| 03:57 | wingy | does it work? |
| 03:58 | ro_st | eg, instead of (map #(:id %) […]), it'll tell you to use (map :id […]) |
| 03:58 | wingy | cool |
| 03:58 | ro_st | or (= (:id foo) =) -> (zero? (:id foo)) |
| 03:58 | ro_st | stuff like that |
| 03:58 | ro_st | sorry |
| 03:58 | wingy | neat |
| 03:58 | ro_st | (= (:id foo) 0) -> (zero? (:id foo)) |
| 04:02 | wingy | ro_st: (when (System/getenv "PORT") (Integer. (System/getenv "PORT"))) instead of: (if (System/getenv "PORT") (Integer. (System/getenv "PORT")) nil) |
| 04:02 | wingy | so cool :) |
| 04:02 | wingy | i have to play with core.logic myself when everything is setup |
| 04:03 | ro_st | did you watch edmund jackson's intro to core.logic? |
| 04:03 | ro_st | search vimeo for clojure and sort by date. bottom of page 1 |
| 04:04 | ro_st | really cool talk |
| 04:04 | wingy | the guy who talked really fast? |
| 04:04 | wingy | and something asked him to slow down at the beginning? |
| 04:04 | ro_st | that's the one |
| 04:04 | ro_st | with the south african accent |
| 04:04 | wingy | yeah ive seen it |
| 04:05 | wingy | clojure.core seems to allow us to code in a different way |
| 04:05 | wingy | in a very declarative way |
| 04:05 | ro_st | it's very interesting. definitely an area i want to play around in |
| 04:05 | wingy | yeah i hope i can use it heavily in my app |
| 04:05 | malcolmsparks | it was funny because there were a lot of europeans in the room who were really struggling with the speed of English |
| 04:06 | malcolmsparks | one German guy stood up and put both hands up pleading with the speaker to slow down :) |
| 04:06 | wingy | OTOH he talked really fast :) |
| 04:06 | ro_st | they can watch it on vimeo now and slow it down |
| 04:06 | wingy | malcolmsparks: you were there? |
| 04:06 | malcolmsparks | but it was a superb talk - hopefully someone can make a transcript one day |
| 04:06 | malcolmsparks | yes |
| 04:06 | wingy | cool |
| 04:06 | ro_st | i kept up ok, but that's because i'm used to that accent. my own is quite similar to his |
| 04:06 | wingy | malcolmsparks: how many people were there? |
| 04:07 | malcolmsparks | you don't see the baffled audience from the video :) |
| 04:07 | malcolmsparks | almost 200 |
| 04:08 | ro_st | i would love to have been there |
| 04:09 | ro_st | i can count the number of clojure folks in cape town that i know of on one hand! |
| 04:09 | malcolmsparks | anyone know of a Midje talk? I'm really enjoying it - only just starting playing with it - it's very cool |
| 04:09 | wingy | http://www.hackerne.ws/item?id=2683007 read ynniv's post |
| 04:09 | ro_st | have you seen marick's vids, malcolmsparks? |
| 04:09 | malcolmsparks | no - guess I should have googled before chatting |
| 04:09 | malcolmsparks | I'll look them up tonight |
| 04:10 | ro_st | are you using emacs, malcolmsparks? |
| 04:10 | malcolmsparks | never really used midje before, didn't realise how powerful it was |
| 04:10 | clgv | malcolmsparks: the midje wiki is quite good in explaining |
| 04:10 | ro_st | it ROCKS. i'm doing TDD with it |
| 04:10 | malcolmsparks | ah, train in - gotta go |
| 04:17 | wingy | wow .. bootstrap is really simple to use |
| 04:17 | wingy | always used big frameworks like extjs/sproutcore to make good looking buttons and now it's just a html class i need to add :) |
| 04:17 | wingy | towards simplicity like clj! |
| 04:20 | clgv | bootstrap? |
| 04:20 | wingy | twitter bootstrap |
| 04:21 | wingy | http://twitter.github.com/bootstrap/components.html |
| 04:21 | clgv | ah ok. read that before |
| 04:22 | wingy | do you guys feel that html should be html and not in clj like hiccup is doing? |
| 04:23 | ro_st | long term, i think it's good to keep the markup separate from the logic |
| 04:23 | wingy | yeah |
| 04:24 | ro_st | hiccup is fun, but to be able to do pure css work on that markup, you need a running ring server and a knowledge of clojure sufficient to do hiccup changes to be able to complete work |
| 04:25 | wingy | good analysis |
| 04:25 | ro_st | lots of designers use (barf) dreamweaver or similar to accomplish tasks like that. it's nice to be able to keep that ability |
| 04:26 | wingy | ro_st: OTOH is it really desired to have pure designers doing HTML? |
| 04:26 | wingy | isn't it something a clojure dev can do |
| 04:26 | wingy | he knows the logic and display |
| 04:26 | ro_st | do you want to pay a clojure dev to do something a markup monkey can? |
| 04:26 | ro_st | no disrespect to markup monkeys -grin- |
| 04:27 | ro_st | what do you gain by using hiccup over raw html and enlive? |
| 04:27 | wingy | since im doing the markup atm i get joy :) |
| 04:27 | ro_st | is that gain worth losing the flexibility of pure html throughout your dev lifecycle? |
| 04:27 | wingy | i guess not |
| 04:28 | wingy | yeah |
| 04:28 | ro_st | the thing about code is you want as little of it as possible |
| 04:28 | ro_st | hiccup is code, it's not markup |
| 04:28 | wingy | right |
| 04:28 | ro_st | that's what makes enlive great. your code is just a set of transformations, which is much easier to test |
| 04:29 | wingy | and being able to use pure HTML is kinda neat |
| 04:29 | wingy | you know what is going on |
| 04:30 | ro_st | also, pure html/css is much easier to work with in chrome |
| 04:30 | ro_st | you can even use chrome dev tools' save-file features |
| 04:30 | wingy | but then you could say that about js vs cljs :) |
| 04:31 | ro_st | chrome dev tools get thoroughly spanked by emacs+repl |
| 04:31 | ro_st | when it comes to logic stuff |
| 04:31 | ro_st | thats just my opinion, of course :-) |
| 04:32 | ro_st | but it's one formed from experience of both worlds |
| 04:33 | ro_st | i wonder if cljs supports source maps |
| 04:33 | wingy | yeah i also think that writing pure html is better for long term maintenance |
| 04:33 | ro_st | chrome dev tools has excellent support for it. shows you your source language (ie, cljs) right there in the scripts panel |
| 04:33 | clgv | ro_st: they are working on source maps as far as I heard |
| 04:34 | wingy | when will that be ready you think? |
| 04:34 | ro_st | no clue |
| 04:35 | wingy | ok new policy |
| 04:35 | wingy | "close to the metal" |
| 04:35 | ro_st | yes |
| 04:36 | wingy | html, css, cljs but using js libs without transformations, clj using java libs without tranformations |
| 04:36 | wingy | ;) |
| 04:37 | ro_st | do you use a css pre-processor? |
| 04:38 | wingy | no .. im not that great in styling |
| 04:38 | wingy | bootstrap is using less |
| 04:38 | wingy | but i dont think i will have to style that much |
| 04:38 | wingy | https://wrapbootstrap.com/ |
| 04:39 | ro_st | oh wow, nice resource |
| 04:39 | wingy | http://bootswatch.com/ |
| 04:39 | wingy | i feel this is way better than styling manually |
| 04:39 | wingy | we use bootstrap .. and everyone can provide styling template |
| 04:40 | wingy | they could open a new market |
| 04:41 | ro_st | both great resources. bootswatch is realy nice |
| 04:41 | wingy | ro_st: now i recall what rich hickey said about complecting |
| 04:42 | wingy | perhaps having logic and presentation in one is complecting things |
| 04:42 | wingy | just like you dont want to have logic and data as one like in OOP |
| 04:42 | ro_st | yes, exactly |
| 04:44 | ro_st | ohpauleez did something interesting in his demo-shoreleave-findit project |
| 04:45 | ro_st | he uses erb (from ruby) and rake to pre-compile static html pages, using layouts and partials |
| 04:45 | ro_st | then cljs uses enfocus to munge that markup clientside |
| 04:45 | ro_st | he could just as easily have used enlive to do the partials work, actually |
| 04:53 | pyr | morning |
| 04:54 | pyr | can members be removed from a clojars group ? |
| 04:54 | pyr | (from clojars i mean) |
| 05:00 | clgv | pyr: I only see an "add member" button over there |
| 05:02 | pyr | clgv: yup, me too |
| 05:05 | kral | namaste |
| 05:08 | ro_st | tashi delek! |
| 05:34 | augustl | are there any solutions to have "lein test" keep a JVM running and automatically reload changed files, for faster test runs? |
| 05:37 | ro_st | lazytest |
| 05:37 | twhume | I'm having a bit of NotFun with futures. Could anyone explain to me why this code seems to run correctly, but then drives CPU usage for the Java process to 90%+, and stays there forever? I think the future I create is being terminated correctly, but it appears not… https://gist.github.com/3124000 |
| 05:37 | ro_st | are you using clojure.test or midje, augustl? |
| 05:38 | augustl | ro_st: clojure.test |
| 05:39 | augustl | mostly because of use-fixtures with :once, haven't found an equivalent for midje |
| 05:39 | ro_st | i'm using lein-midje with lazytest, which auto-runs when tests or the files the tests load change |
| 05:39 | ro_st | midje has the background macro |
| 05:41 | ro_st | https://github.com/marick/Midje/wiki/Setup%2C-Teardown%2C-and-State |
| 05:42 | ro_st | for example: https://www.refheap.com/paste/3639 |
| 05:42 | ro_st | this runs all the facts inside the binding, so that the production code being tested uses the test database instead of the production one |
| 05:43 | ro_st | and it only loads the fixtures once |
| 05:43 | ro_st | you can use :facts instead of :contents if you want the work to be performed per fact |
| 05:43 | augustl | a fact is a test? |
| 05:43 | ro_st | yes |
| 05:44 | augustl | and :contents is one test namespace? |
| 05:44 | augustl | or the entire run? |
| 05:44 | ro_st | one test namespace |
| 05:44 | augustl | is there a way to run some code before and after the entire test suite? |
| 05:44 | ro_st | as with everything in clojure, it's all namespace bound |
| 05:44 | augustl | currently integration testing a SSO system so I would like to boot 3 jetty servers. Currently doing that for each test namespace, so it's kind of slow |
| 05:45 | ro_st | you could probably use a separate namepsace and memoize the calls |
| 05:45 | augustl | good point |
| 05:45 | ro_st | so first calls do the work, subsequent calls just return whatever work was done the first time |
| 05:45 | ro_st | if you use emacs, there's midje-mode too |
| 05:46 | augustl | what does it do? |
| 05:46 | ro_st | run individual facts right there in your buffer |
| 05:46 | ro_st | it pastes the output as comments above the fact |
| 05:46 | ro_st | it uses your active repl |
| 05:46 | augustl | ah |
| 05:46 | ro_st | the way i work is to have lein2 midje —lazytest running in a shell, and then code tdd style in emacs, using C-c . to run individual facts as i go |
| 05:47 | ro_st | lazytest helps with regression testing when i refactor stuff |
| 05:47 | augustl | typically memoization is done via function calls I suppose? |
| 05:47 | augustl | which checks a ref for nil etc |
| 05:47 | ro_st | yup. i've not done memoization with clojure before, but the concept is pretty simple |
| 05:48 | augustl | perhaps there's something built-in |
| 05:48 | ro_st | http://blog.fogus.me/2012/07/13/announcing-core-memoize-version-0-5-2/ |
| 05:48 | ro_st | reading the tests for this code should give you a thorough background on the topic |
| 05:53 | ro_st | so i have a .clj with plain clojure data in it. how do i read it off disk and assign that map into a ns-bound var? |
| 05:54 | ro_st | right now the file has (def name {…}) in it, and i'm using load-file |
| 05:56 | vijaykiran | https://github.com/technomancy/leiningen/blob/master/leiningen-core/src/leiningen/core/user.clj#L25 |
| 05:56 | vijaykiran | ro_st: something like that ^ ? |
| 05:56 | ro_st | superduper! |
| 05:57 | vijaykiran | leiningen loads user.clj profile, I guess that's something similar to what you are looking for |
| 05:57 | ro_st | it's precisely what i'm after, thanks very much |
| 05:57 | vijaykiran | yw |
| 05:59 | augustl | ro_st: I see, thanks |
| 06:02 | ro_st | heck i should really make a screencast showing all this working together |
| 06:08 | twhume | Anyone know why this code should lead to high CPU usage? (deref (future (loop[a 1] (recur a)) :done!) 1000 :impatient!) |
| 06:11 | cshell | infinite llop? |
| 06:11 | cshell | infinite loop? |
| 06:11 | ro_st | the loop recur is infinite |
| 06:11 | ro_st | recur should be wrapped inside a conditional that checks whether recur should happen or not |
| 06:12 | cshell | it needs to increment the a value |
| 06:12 | cshell | or do something with it |
| 06:13 | ro_st | '(loop [a 1] (if (< a 3) (recur (inc a)) a)) |
| 06:13 | ro_st | ,(loop [a 1] (if (< a 3) (recur (inc a)) a)) |
| 06:13 | clojurebot | 3 |
| 06:17 | augustl | it would seem that irccloud.com just died :) |
| 06:17 | cshell | yep |
| 06:17 | twhume | shell, ro_st: yes, it's an infinite loop (it's not the actual code I want to run, but the actual code may or may not contain such a loop - hence the need for a timeout). But surely it should stop running once the future is cancelled whatever? |
| 06:17 | twhume | s/shell/cshell/ |
| 06:17 | ro_st | i just got a pingdom alert for my vps as well |
| 06:18 | twhume | In practice I'm going to want to run short sequences of arbitrary bytecode inside this future, some of which may contain such loops. I've stuck a recur in there so I can be testing with the worst possible case... |
| 06:20 | ro_st | right |
| 06:20 | ro_st | i've no experience with futures, i'm afraid |
| 06:24 | augustl | ro_st: are you using lein 1.x and lein-midje? |
| 06:24 | augustl | seems I need lein-midje both as a plugin and dev-dependency |
| 06:25 | augustl | also, is there a way to run midje tests with "lein test", or make "lein test" throw errors? |
| 06:26 | Fossi | they will be run |
| 06:26 | Fossi | don't know what you mean with "errors" |
| 06:26 | Fossi | like a negativ return code? |
| 06:27 | ro_st | i'm using lein2 for midje, augustl |
| 06:28 | ro_st | augustl: https://www.refheap.com/paste/3640 |
| 06:28 | augustl | Fossi, ro_st: the issue is that "lein test" is still present, and it doesn't run the midje tests, so some devs (me included) might forget about it and think they ran the tests when they did "lein test" |
| 06:28 | ro_st | with that in place, i can run lein2 midje —lazytest |
| 06:29 | ro_st | i believe midje will run any existing clojure.test tests as well |
| 06:29 | ro_st | so transitioning is easy |
| 06:30 | Fossi | yes |
| 06:30 | Fossi | and you can use midje tests with lein test as well |
| 06:30 | Fossi | at least with the version/setup we are using |
| 06:31 | Fossi | not sure what that includes though |
| 06:31 | Fossi | been a while since i touched it ;) |
| 06:31 | Fossi | afair lein midje is just nicer output |
| 06:31 | ro_st | yeah |
| 06:32 | ro_st | the lazytest reloading stuff is great too. it knows how to reload changed files and all the files that depend on those changes, but only those files |
| 06:32 | Fossi | nice |
| 06:32 | ro_st | so even with a massive suite, the testing is still fast |
| 06:36 | augustl | ro_st: how would you do this with midje? http://pastie.org/4270944 |
| 06:36 | augustl | seems midje doesn't have a concept of "tests" |
| 06:37 | augustl | my tests typically do a lot of stuff, so it makes sense to reset the db between each test in clojure.test. Doesn't seem to make sense to reset the db between each fact in midje, since a fact seems to be 1:1 with assertions |
| 06:38 | augustl | these particular tests only contain one assertion but I might want to have a bunch of them, do a couple of more HTTP requests, etc |
| 06:39 | ro_st | https://www.refheap.com/paste/3641 |
| 06:41 | augustl | ro_st: so I can have anything I want inside a "fact"? |
| 06:41 | augustl | let, if-let, nested lets, etc? |
| 06:42 | ro_st | yup :) |
| 06:42 | augustl | not sure if I like the => syntax.. It's not very lispy |
| 06:42 | ro_st | it grows on you |
| 06:42 | augustl | 'foo operator bar' that is |
| 06:43 | ro_st | in emacs, it's bright red, so it's easy to distinguish tested code vs checker code |
| 06:43 | augustl | the only thing I like is the checkers :) |
| 06:44 | augustl | perhaps there's a more generic collection assertion library I can use |
| 06:44 | augustl | like "vector contains {:foo 123}" and so on |
| 06:51 | augustl | ro_st: do you know if midje supports a more traditional syntax? |
| 06:52 | augustl | I'd prefer (=> foo bar) to foo => bar |
| 06:54 | ro_st | i don't think so |
| 06:54 | ro_st | -shrug- i like it the way it is |
| 06:58 | ro_st | augustl: i suggest scanning through the midje wiki to get a sense of why brian did it they way he did |
| 06:58 | ro_st | he provides a rationale and lots of great docs as well |
| 07:07 | augustl | ro_st: I see, thanks :) |
| 07:08 | ro_st | also, midje-mode #justsaying |
| 07:08 | ro_st | www.youtube.com/watch?v=HK2HG9U3anA |
| 07:44 | ro_st | i have an atom which contains a sorted-set of maps. i want to alter a value in one of these maps. what's the best way to update the sorted-set with the new map that update-in returns? |
| 07:44 | ro_st | disj then conj? |
| 07:46 | clgv | ro_st: yes. |
| 07:46 | clgv | ro_st: for a map you could use update-in, but in a set you can not specifically adresse one of its elements |
| 07:50 | ro_st | like this? https://www.refheap.com/paste/3643 |
| 07:50 | ro_st | i realised the set won't be able to remove the node if i only give it the updated version |
| 07:53 | clgv | seems to do the job. |
| 07:54 | clgv | but are you sure that the set is the right datastructure in this case? |
| 07:54 | ro_st | i plan to use sorted-set-by and provide a custom sorting fn |
| 07:55 | ro_st | having it sorted in a particular fashion is a User Story |
| 07:55 | ro_st | i definitely have only one of each element in the structure, so a sorted-set seemed the right fit |
| 07:56 | clgv | there is also sorted-map-by where you could directly address elements via a key (e.g. id) |
| 07:56 | ro_st | i want to be able to throw nodes at it and let the sorting fn figure out what the order should be |
| 07:56 | ro_st | i guess. it'll be easy to refactor to sorted-map-by if i find that i need to. i'm going to see how far i can get without having to use ids |
| 07:59 | clgv | ro_st: but you already did a first work-around with your two functions for updating an element, so that might be an indicator that a set is not the best approach there |
| 08:00 | ro_st | i guess with sorted-map-by i can use update-in instead of disj-then-conj |
| 08:00 | clgv | right |
| 08:03 | ro_st | sorted-map-by seems to pass the keys to the comparator? |
| 08:05 | clgv | ro_st: oh right. I would have assumed that you get both |
| 08:05 | ro_st | lemme just set a breakpoint and see |
| 08:06 | clgv | &(sorted-map-by (fn [x, y] (println "x =" x "y =" y) (compare x y)) :bla 10 :blubb 20) |
| 08:06 | lazybot | ⇒ x = :blubb y = :bla {:bla 10, :blubb 20} |
| 08:11 | mikem | I have a function which takes 7 arguments. I'm "stubbing" it in Midje with provided and specifying 7 anythings, one in place of each argument. Is there a way to achieve the same without being so repetitive? |
| 08:12 | ro_st | (apply fn (take 7 (constantly anything))) |
| 08:12 | ro_st | *shoots from the hip* |
| 08:13 | mikem | ro_st: haha, epic fail :-) |
| 08:13 | mikem | didn't work |
| 08:14 | ro_st | ,(take 3 (constantly "five")) |
| 08:14 | clojurebot | #<ExecutionException java.util.concurrent.ExecutionException: java.lang.IllegalArgumentException: Don't know how to create ISeq from: clojure.core$constantly$fn__2351> |
| 08:14 | ro_st | damnit. i thought i understood constantly :) |
| 08:16 | ro_st | if you can find a way to make an infinite sequence of 'anything's, you can use take 7 to bite off 7 and use apply to pass em in |
| 08:16 | ro_st | lemme know when you find out how :-) |
| 08:17 | vijaykiran | ,(take 3 (repeatedly (constantly "five"))) |
| 08:17 | clojurebot | ("five" "five" "five") |
| 08:17 | vijaykiran | :) |
| 08:17 | ro_st | repeatedly! |
| 08:17 | ro_st | (apply fn (take 7 (repeatedly (constantly anything)))) |
| 08:17 | ro_st | that should do it |
| 08:18 | ro_st | although that's almost as long as |
| 08:18 | ro_st | anything anything anything anything anything anything anything |
| 08:18 | ro_st | :) |
| 08:20 | mikem | vijaykiran, ro_st: that doesn't actually work, midje explodes with a StackOverflowError |
| 08:20 | mikem | but, valiant effort! |
| 08:21 | vijaykiran | sorry, I didn't know the context - just trying to give a fix for exception that clojurebot threw |
| 08:21 | ro_st | he has (fn-name <7 anythings in a row>) and wants to know if he can instead programmatically generate 7 anythings |
| 08:22 | ro_st | and pass them as args to fn-name |
| 08:22 | clgv | mikem: there are aliases for "anything", I would use the shortest one, if the amount to write is a problem |
| 08:23 | mikem | the catch is it's in a (provided) block in Midje |
| 08:23 | mikem | clgv: oh, what are the aliases? |
| 08:23 | clgv | should be in the wiki |
| 08:24 | y3di | disclojure hiatus is depressing =/ |
| 08:25 | ro_st | clgv, mikem: only synomym is 'irrelevant' |
| 08:25 | ro_st | https://github.com/marick/Midje/wiki/Checkers |
| 08:25 | clgv | damn |
| 08:25 | ro_st | nothing stopping you making your own :) |
| 08:25 | clgv | "any" or "_" would be good ^^ |
| 08:25 | clojurebot | Cool story bro. |
| 08:25 | ro_st | (def :P anything) |
| 08:26 | clgv | that wont work because :P is not a symbol :P |
| 08:26 | ro_st | worth a try |
| 08:26 | ro_st | looks like sorted-map-by's comparator only takes the keys as args |
| 08:27 | mikem | I guess I was thinking more of a catch-all which means any number of arguments and anything |
| 08:27 | mikem | in case the function gains or loses arguments in the future |
| 08:27 | clgv | ro_st: yep, that was the point of the above example with sorted-map-by ;) |
| 08:27 | ro_st | that sucks. i need to be able to sort based on data in the values |
| 08:28 | ro_st | looks like sorted-set is the way, then |
| 08:28 | clgv | ro_st: well, do you need to keep the container sorted or is sorting when accessing all elements an option? |
| 08:29 | ro_st | i'd like to keep the container sorted |
| 08:29 | ro_st | because i need to be able to process delta updates in the view (so that the entire view doesn't need to be re-rendered whenever something changes) |
| 08:30 | ro_st | sorted-set-by's comparator receives the values, which works for me |
| 08:39 | cshell | Do you ugys find it easier or harder to code/develop with music on or off? |
| 08:40 | ro_st | depends on the music i guess. sometimes i must have silence. other times, jazz is great |
| 08:40 | Bronsa | prog metal is good too |
| 08:40 | ro_st | and the inception soundtrack is awesome if you want to feel like you're saving the world |
| 08:40 | Bronsa | generaly everything with very little to no lyrics at all |
| 08:41 | mprentice | classical instrument covers of rock == great coding music |
| 08:41 | mprentice | vitamin string quartet, apocalyptico |
| 08:41 | cshell | Yeah, for me if I'm thinking of a solution to a problem i need silence, if I know what I'm coding, music helps |
| 08:42 | cshell | interesting, thanks guys! |
| 08:42 | ro_st | oo nice mprentice |
| 08:43 | ro_st | i tried to grab some classical but it's always such a mixed bag |
| 08:43 | ro_st | don't want hectic, jarring music. i find that the mellow stuff is mixed in with the crazy stuff |
| 08:44 | mprentice | :D |
| 08:44 | ro_st | these guys? http://coda.fm/artists/143 |
| 08:44 | cshell | I also find that if I know the cd by heart I can focus, but new songs with lyrics seems to distract me |
| 08:44 | ro_st | same here. i can code to coldplay no problem cos i know it all so well |
| 08:45 | cshell | probably because the intervals/changes are expected by our brain |
| 08:45 | cshell | and new music surprises our brain |
| 08:57 | edoloughlin | I read an article a few years ago (don't think I can find it again) where people were given logic/math problems to solve with/without background music. Everyone solved the problems but those listening to music failed to spot threads/themes that were common to all of the problems. |
| 09:02 | cshell | Do all namespaces in the application get compiled or do they only get loaded when accessed? |
| 09:02 | lnostdal | what kind of music? |
| 09:02 | lnostdal | ..music with lyrics ruins everything for me for sure |
| 09:03 | cshell | me too |
| 09:06 | vijaykiran | hmm . interesting - http://faculty.nipissingu.ca/stange/courses/P2267/BackgroundMusic.pdf |
| 09:06 | augustl | hmm, the singleton-ness of the mongodb libraries for clojure bothers me. I wonder why they all seem to prefer an implicit singleton connection somewhere, instead of just passing a connection descriptor to all queries |
| 09:06 | vijaykiran | "The effect of background music and background noise on the task performance of introverts and extraverts" |
| 09:10 | cshell | augustl: You can write your functions to take whatever comes out of the library |
| 09:10 | cshell | i use congo mongo and what comes out is just a map |
| 09:11 | cshell | and I pass that map in when I want to do a search |
| 09:21 | joly | vijaykiran: I'm having trouble reading that article because of too much background noise. :P |
| 09:23 | augustl | cshell: I'm talking about the db operations, the connection is implicit |
| 09:23 | augustl | you call connect! one time and then all future calls will use that connection |
| 09:23 | cshell | ah, I don't do that with congo-mongo |
| 09:24 | cshell | I call make-connection and bind it to a var |
| 09:24 | goodieboy | anyone know if it's possible to access the resources of a dependency? For example, I have a jar that I've deployed that contains stuff in it's "resources" dir. My parent project needs to access that stuff, how to do this? |
| 09:24 | augustl | cshell: what's the API for passing that connection to queries? a with-connection like thing? |
| 09:27 | pyr | i must be doing things wrong, but while trying to load a class defined through a defrecord in a java project i get errors saying the class cannot be found (the dependency was pulled through maven) |
| 09:27 | pyr | i see the class in the jar, and when manually pulling the jar in eclipse to try out i see the class correctly |
| 09:27 | clgv | pyr: you have to load the namespace in advance |
| 09:28 | clgv | pyr: provided it was not AOT-compiled |
| 09:30 | pyr | clgv: the namespace in which the records are defined is aot compiled |
| 09:30 | duck11231 | goodieboy: If you have a file in resources/ (on your classpath) you can call getSystemResourceAsStream on the classloader |
| 09:31 | clgv | pyr: humm, do you see the class files in filesystem or in the dependency-jar? |
| 09:31 | goodieboy | duck11231: OK, thanks. How can I access the classloader? |
| 09:31 | pyr | clgv: yes |
| 09:31 | clgv | pyr: you used Class.forName? |
| 09:32 | pyr | nope, it breaks at import |
| 09:32 | pyr | when i say import 'org.something.namespace.RecordName' |
| 09:32 | pyr | i get 'cannot find symbol' |
| 09:33 | pyr | symbol: RecordName |
| 09:33 | pyr | class: org.something.namespace |
| 09:33 | pyr | s,class,location |
| 09:33 | duck1123 | ,(Thread/currentThread) |
| 09:33 | clojurebot | #<Thread Thread[Thread-55,5,main]> |
| 09:34 | duck1123 | ,(.getContextClassLoader (Thread/currentThread)) |
| 09:34 | clojurebot | #<AccessControlException java.security.AccessControlException: access denied ("java.lang.RuntimePermission" "getClassLoader")> |
| 09:34 | duck1123 | goodieboy: that works if you're not in a sandbox |
| 09:34 | goodieboy | duck1123: cool thanks! |
| 09:35 | duck1123 | there may be a better way |
| 09:35 | clgv | pyr: weird. |
| 09:36 | pyr | clgv: indeed, will dig further |
| 09:36 | uvtc | Would you recommend a Clojure novice use Noir, or straight Ring + Compojure? |
| 09:36 | uvtc | Also, good morning, #clojure. :) |
| 09:37 | uvtc | Er,... good *, for folks in different timezones. |
| 09:38 | clgv | uvtc: as far as the advertisement says Noir is on a higher level above Ring + Compojure |
| 09:38 | uvtc | weavejester: is it common to write web apps using just Compojure, rather than a "framework" built atop it? |
| 09:39 | lucian | i tend to take all the help i can get |
| 09:40 | duck1123 | All noir is really doing is abstracting away some things and providing helpers for others. If you like those abstractions and they fit with what you want to do, then use it. But you can certainly get by without. |
| 09:40 | cshell | uvtc I just started with noir |
| 09:40 | cshell | it has a lot of helper methods that you would need for ring and compojure |
| 09:42 | uvtc | Mm. Thank you. |
| 10:02 | sh10151 | Any thoughts on when to use bindings/vars and when to use explicit function parameters? |
| 10:03 | sh10151 | use case is an xslt transform function -- (transform stylesheet input output) |
| 10:03 | sh10151 | need to provide an interface for xsl:param and the like |
| 10:11 | sproc | If I have two loops, nested, and I am in the inner loop, how can I recur back to the "parent" loop? |
| 10:12 | sh10151 | I don't think you want to do that... |
| 10:12 | tmciver | sproc: you can't in Clojure |
| 10:12 | sh10151 | do you have some code to paste? |
| 10:13 | sh10151 | Generally you don't want to write recur at all |
| 10:13 | sh10151 | the higher-order functions take care of nearly all use cases |
| 10:13 | sproc | I'm trying to process data in functional style. I am doing work recursively in an inner loop, but if I exit that form I "lose" the data in the loop variables. |
| 10:14 | sproc | But I need that processed data in the larger loop. |
| 10:14 | sh10151 | it sounds like you may need to use reduce then |
| 10:14 | sh10151 | it's hard to say without any code |
| 10:15 | sh10151 | or for example http://clojure.github.com/clojure/clojure.core-api.html#clojure.core/iterate |
| 10:17 | goodieboy | duck1123: dang, i can't get this resource loading to work, hmm. I can see the resources in my dependency jar, i just can't access them in my parent project. I guess it's time for me to read up on class loaders! |
| 10:19 | sproc | sh10151: http://pastebin.com/ji5V01ig |
| 10:20 | sh10151 | yea, i think a reduce is the right way to go |
| 10:20 | sh10151 | the accumulator value is the {:col-widths :current-col} tuple or something |
| 10:22 | sproc | Yeah, there is a column loop within a row loop, so :col-widths accumulated that while :current-col tracked which column to process next |
| 10:22 | sh10151 | shouldn't even need the current-col? |
| 10:22 | sh10151 | that kind of iteration should be taken care of by map/reduce/for whatever |
| 10:22 | sh10151 | main thing is to build up the col-widths map |
| 10:23 | sproc | I used it so I could use the ResultSetMetaData.getColumnName function |
| 10:23 | sproc | (which requires the index) |
| 10:24 | sh10151 | sure but use map-indexed for that |
| 10:25 | sh10151 | (map-indexed (fn [i thing] (str i " is " thing)) ["a" "b" "c"]) |
| 10:25 | sh10151 | ("0 is a" "1 is b" "2 is c") |
| 10:25 | sh10151 | there are other functions like that too but i can never keep them straight among python scheme and clojure |
| 10:26 | sproc | Ah, I see; that will be nice. I am new to Clojure and wasn't aware of that |
| 10:26 | sh10151 | it's ok |
| 10:26 | sh10151 | main thing to remember is that you almost never need to write loop/recur yourself |
| 10:27 | sproc | I was looking at loop/recur like using auxiliary/helper recursive functions |
| 10:27 | sh10151 | Sure, but the recursions themselves have already been written for you |
| 10:27 | sh10151 | the big ones to understand are map and reduce |
| 10:28 | sh10151 | if you can start looking at nested loops as combinations of those, it should come quickly |
| 10:28 | sh10151 | frankly I found it easiest to learn that with Haskell since it's very difficult to really do it another way :) |
| 10:28 | duck1123 | clojureatlas.com is a good resource for when you know what type of function you need, but not what it's called |
| 10:29 | sproc | Alright, thanks. That will give me some good stuff to think about |
| 10:30 | sh10151 | Anytime. Do you program JavaScript? There's actually map/reduce functions in most JS libraries |
| 10:30 | sh10151 | my frontend code bears an (un?)fortunate resemblance to Lisp nowadays |
| 10:32 | sproc | The Javascript I've done has all been pretty trivial. I am starting to read about Node though and think about ways I might want to use that |
| 10:32 | sh10151 | is that the server-side framework? |
| 10:33 | sh10151 | my work is all JVM all the time pretty much :( |
| 10:33 | _nmmn | node.js is massive jungle of callbacks and js caveats, imo |
| 10:33 | sproc | Yeah, it's neat because it serves requests in a non-blocking way and eliminates the need for multithreading for lots of requests |
| 10:34 | duck1123 | you could also use Aleph with Clojure for that |
| 10:34 | sh10151 | pretty sure nginx does that too :) |
| 10:35 | pipeline | you mean sproc |
| 10:35 | pipeline | node.js only gives you a single thread |
| 10:35 | pipeline | so you had BETTER damn well write non-blocking code |
| 10:35 | _nmmn | true |
| 10:35 | pipeline | or else your app stops working |
| 10:35 | _nmmn | i think its similar fab as ruby |
| 10:35 | pipeline | believe it or not this is a trivial model to handle in any language |
| 10:35 | sh10151 | If you do Perl this is a pretty good book on functional programming/higher order functions: http://hop.perl.plover.com/book/ |
| 10:35 | pipeline | just don't call fork() haha |
| 10:35 | pipeline | perl makes the whole non-blocking event-based apps easy as hell, and has done for 10+ years: POE |
| 10:36 | pipeline | this is not a new model of development |
| 10:36 | pipeline | it's just that node.js gives new freedom to people who were once relegated to "front end" development |
| 10:36 | sproc | I was thinking the creator chose JS because its clojures allow you to declare several nested callback functions that have access to enclosing variables; I suppose any language supporting closures could do that |
| 10:36 | pipeline | there is an entire generation of developers who came out of design and ux backgrounds, and node.js gives these guys a server side that they are comfortable with |
| 10:36 | _nmmn | true |
| 10:36 | sh10151 | select() has been around since early BSD |
| 10:36 | _nmmn | still im keeping myself from js as far as possible =] |
| 10:36 | sproc | In languages without closures it can be done but would seem to be more painful. |
| 10:37 | pipeline | (unfortunately node.js carries with it a lot of the problems you find in frontend development circa 2005: bad/no debugging, awful garbage 3rd party libraries, etc) |
| 10:37 | sproc | Yeah, there are problems getting helpful stack traces |
| 10:37 | sh10151 | prototype.js :( |
| 10:45 | cshell_ | Can you extend a protocol on a def record? |
| 10:54 | sproc | duck1123: Neat site |
| 10:56 | duck1123 | It's great for "I need to do something to this var. Oh what's that function called again?" Also good for exploring new fns |
| 10:56 | kreig1 | earthlings! |
| 11:09 | gfredericks | cshell_: I should think so |
| 11:25 | dsevilla | all |
| 11:25 | dsevilla | I'm searching for an introductory slides on core.logic that I found the other day, but I don't remember where |
| 11:25 | dsevilla | they start comparing functions with relations |
| 11:26 | dsevilla | functions only return one value |
| 11:26 | dsevilla | relations relate different input parameters and result values |
| 11:26 | dsevilla | I searched euroclojure, clojure/conj, etc., but now I can't find them |
| 11:26 | dsevilla | any of you would remember that one? |
| 11:27 | woodz | Here? https://github.com/ejackson/EuroClojure-2012-Talk |
| 11:27 | pyr | technomancy: around ? |
| 11:27 | scriptor | dsevilla: this one https://github.com/relevance/clojure-conj/blob/master/2011-slides/ambrose-bonnaire-sergeant-introduction-to-logic-programming.pdf |
| 11:27 | dsevilla | woodz: Yes, I found those, nice slides, but these were not |
| 11:27 | scriptor | you'll have to download the pdf, but I'm pretty sure it's that one |
| 11:28 | sproc | Why doesn't (get 1 {1 2 3 4}) return 2 instead of nil? |
| 11:28 | dsevilla | scriptor: ahhhhhh these are! |
| 11:28 | scriptor | ,(get {1 2 3 4} 1) |
| 11:28 | clojurebot | 2 |
| 11:28 | dsevilla | scriptor: thanks! |
| 11:28 | scriptor | dsevilla: no prob |
| 11:28 | dsevilla | woodz: thaks to you too |
| 11:29 | scriptor | sproc: the arguments go the other way http://clojuredocs.org/clojure_core/clojure.core/get |
| 11:29 | dsevilla | very nice talk, btw |
| 11:48 | technomancy | pyr: sure |
| 11:49 | technomancy | augustl: you can alias "test" to "midje" in project.clj |
| 12:07 | pyr | technomancy: i'm trying to build java + clj projects |
| 12:07 | pyr | technomancy: where the java part loads classes defined in the clj files |
| 12:07 | pyr | technomancy: and this with leiningen, goes without saying |
| 12:08 | pyr | technomancy: i'm using lein2 and i am seeing a few weird behaviors |
| 12:09 | pyr | technomancy: first thing, even though i seem to use the correct :aot configuration the java source will never compile unless i move it elsewhere, compile my clojure classes a first time then put the java files back |
| 12:10 | pyr | technomancy: then i was never able to load a class defined through deftype in the java source code |
| 12:10 | technomancy | yeah, out of the box leiningen assumes you are going to compile java first |
| 12:10 | technomancy | because the java parts of a project are typically the legacy ones |
| 12:10 | pyr | technomancy: which makes snese |
| 12:10 | technomancy | you can change it with :prep-tasks; lemme see |
| 12:10 | pyr | sense |
| 12:10 | technomancy | :prep-tasks ^:replace ["compile" "javac"] ; <- in project.clj should work |
| 12:11 | pyr | ok |
| 12:11 | pyr | i will start by trying that out |
| 12:23 | technomancy | I actually had never tried changing :prep-tasks like that; always nice when I see something like that work the way it should =) |
| 12:33 | m0smith | hi all |
| 12:34 | m0smith | I am getting the dreaded: error: java.lang.IllegalArgumentException: No single method: display of interface: crossfire.protocol.peg.Peg found for function: display of protocol: Peg |
| 12:35 | m0smith | any hints on how to find out what the real problem is |
| 12:35 | m0smith | ? |
| 12:36 | S11001001 | m0smith: I'd start with the line numbers in the stacktrace that are actually in your code |
| 12:36 | m0smith | The compiler is not spitting out a stack trace |
| 12:37 | m0smith | I am compiling in emacs using clojure-jack-in |
| 12:37 | m0smith | Cc-Ck |
| 12:37 | S11001001 | m0smith: then use C-c C-l instead |
| 12:37 | m0smith | ok |
| 12:44 | m0smith | That does spit a stack trace but none of my code is in the stack trace, as expected because it is the compiler throwing the error |
| 12:46 | S11001001 | m0smith: compiler failures also have source location |
| 12:49 | harja | Hello, I'm pretty new to this clojure-stuff. What is the most idiomatic way to get input from user in a function and provide the output to another function that is called asynchronously by a framework? |
| 12:51 | harja | I mean something in the lines of (defn get-stuff [] (let [stuff-one (get-input) stuff-two (get-second-input)] (make-profit)) (defn use-it [] (let [stuff-from (get-stuff-added)] (profit)) |
| 12:51 | harja | would a def:d vector be fine? |
| 12:53 | joegallo | harja: suggest you gist your example code so it's more understandable. as it is, you don't have enough closing parens, so it's hard to tell quite what you mean. |
| 12:54 | harja | ah the parens :) https://gist.github.com/2a31909da1ff277a8384 |
| 12:54 | scriptor | harja: so in your example, use-it should get the data returned by get-stuff? |
| 12:54 | harja | that's a part of a quil script |
| 12:54 | S11001001 | harja: I would use fewer intermediate bindings |
| 12:54 | S11001001 | in fact, I would use only two in your example, harja |
| 12:55 | joegallo | harja: generally you just use arguments to functions to hold that stuff, nothing global. (do-some-with (this-value-im-generating-right-now)) |
| 12:55 | scriptor | what's wrong with the intermediate bindings? |
| 12:55 | harja | joegallo: yeah, but how do I make the framework call on the (draw) method with my stuff in it? |
| 12:56 | harja | normally I would have done it using args and recursion |
| 12:56 | joegallo | harja: close over the results. hand them a function or whatever that will do the whole thing. |
| 12:56 | S11001001 | scriptor: draw binds *everything* to be passed as an arg; has same problem as comments that narrate code directly |
| 12:56 | joegallo | (.setIntoBlah some-framework-class #(do-something-with (this-value-im-generating-right-now))) |
| 12:57 | harja | okay, got it. is there a way to do it in quil? |
| 12:57 | joegallo | clojure's anonymous functions are runnables, for instance. if one of the interfaces that clojure's functions implement isn't workable for your case, you could reify or proxy to some other interface, with basically the same effect. |
| 12:58 | joegallo | harja: be more specific, please. perhaps if you explain what it is you're trying to do, we could give better advice. as it is, this is all pretty generic. for instance, in your gist, i can't quite see what's missing... |
| 12:59 | scriptor | S11001001: those comments are considered bad because they're superfluous, since the code should say what it does |
| 13:00 | scriptor | in this case, that's what the code's doing |
| 13:00 | scriptor | I guess canvas-center-x and y aren't strictly necessary, but they make it more readable, don't they? |
| 13:00 | harja | joegallo: Basically I understood your advice that I should somehow re-set the draw function to the framework I am using to use an anonymous function that does not take any arguments hence making it compatible with the type of function it is expecting. My question is that if this is not possible, when am I allowed to use global data structures, if ever? |
| 13:00 | harja | and if I'm "forced" to use such things, what would be the best option |
| 13:01 | joegallo | for $5 i'll let you use a global data structure. but you have to pay each time. :D |
| 13:01 | S11001001 | scriptor: no |
| 13:03 | scriptor | why not? |
| 13:03 | harja | joegallo: is there somekind if idiomatic way of providing these new functions to frameworks? or do I have to study every one of them if I want to use them |
| 13:04 | harja | it would be fairly trivial if I had the execution path in my hands but it's not |
| 13:04 | harja | not even fairly, but very trivial :) |
| 13:04 | harja | by execution path I mean the order things are evaluated as the program progresses on |
| 13:04 | joegallo | harja: you can just magic functions up at any time with (fn [] ...)... |
| 13:04 | harja | yes, I'm familiar with that |
| 13:05 | S11001001 | scriptor: every name introduces an indirection you have to follow. The expressive value of the binding has to exceed that cost |
| 13:06 | nDuff | harja: Going back to your original question -- might a promise be an appropriate tool to represent the user input you're waiting for in this case? If it's something provided only once and reused multiple times... |
| 13:07 | scriptor | S11001001: in this case it's not obvious that width and height refer to the canvas's width and height, rather than something else's, so I'd probably agree with you if that was clearer given the rest of the code |
| 13:08 | S11001001 | scriptor: ok |
| 13:08 | scriptor | otherwise, you run into the indirection of trying to figure out what width and height are referring to |
| 13:08 | harja | nDuff: I have the data when the function is invoked so I don't need promises here |
| 13:08 | nDuff | Ahh; I misunderstood the question, then. |
| 13:12 | harja | nDuff: Yeah, basically I'd just need a way to pass stuff to a function whose execution is handled by the framework I am using (quil) |
| 13:12 | harja | so, given that a user drags the mouse around, I'd be happy to add the x and y coordinates to a vector and draw lines between the successive points in the draw function |
| 13:13 | srid | technomancy: http://blog.heroku.com/archives/2012/7/17/buildpacks/ <- FYI, it was me who added buildpack support to stackato :-) i have always been a heroku fan, especially their willing use of varied technologies (go, clojure, etc..) |
| 13:13 | technomancy | srid: oh no kidding; that's cool =) |
| 13:14 | joegallo | harja: in your gist, which functions are the things you're talking about? i think we're talking past each other. |
| 13:14 | technomancy | this brings me one step closer to having all my ~/src dir be OSS |
| 13:14 | nDuff | harja: ...so, as long as the function is in a closure with access to the atom/ref/whatnot pointing to the data...... |
| 13:15 | harja | joegallo: i get (mouse-x) and (mouse-y) in the (defn mouse-dragged [] ...) function. I need to "store those" and use them in the (defn draw [] ...) method |
| 13:16 | technomancy | srid: you work for activestate? |
| 13:16 | harja | nDuff: Exactly. My original question was, what is the idiomatic way to do this in Clojure |
| 13:16 | joegallo | okay. now i think i get it. |
| 13:16 | harja | since I'm very new to this language |
| 13:17 | srid | technomancy: yup, and we met briefly at clojure/conj last year. ghoseb introduced me to you, if you remember. i tried using clojure to write stackato admin UI, but it was rejected, so open sourced - https://github.com/srid/horizon |
| 13:18 | nDuff | harja: ...well, I think I answered -- close over the ref. |
| 13:18 | m0smith | s11001001: thanks. I used lein compile and it is giving much more helpful messages |
| 13:18 | joegallo | right, i agree with nDuff. |
| 13:18 | technomancy | srid: ah, too bad; that can be a hard sell sometimes |
| 13:18 | S11001001 | m0smith: no prob, but that was all you I think :) |
| 13:19 | m0smith | s11001001: I wonder if swank is using a different clojure version |
| 13:20 | technomancy | m0smith: swank uses clj-stacktrace; in a few cases there are problems where generating the stack trace causes another exception =( |
| 13:20 | harja | nDuff: Okay, what is considered a closure in Clojure. Is it a context defined within a let, a namespace or something else? Can I just make the ref available in the script file I am writing or do I need to do a "global closure"? |
| 13:20 | S11001001 | m0smith: if you use jack-in, compiler should be running at whatever you have set in project.clj |
| 13:20 | m0smith | thanks techomancy: I'll keep that in mind |
| 13:21 | harja | so basically am I closed under a script file |
| 13:24 | harja | can I just do (def data (ref [])) and access that in both of those functions? |
| 13:24 | harja | It seems to work |
| 13:24 | joegallo | you could. |
| 13:24 | harja | and use @data and updating in dosync |
| 13:24 | harja | that seems to be working the way I want to |
| 13:24 | harja | is that a good way to do it? |
| 13:24 | joegallo | depends on the size of the program. |
| 13:25 | joegallo | small programs get more leniency than large ones. |
| 13:25 | harja | yeah, this one is easilly under 1k lines |
| 13:25 | joegallo | you're probably fine |
| 13:25 | harja | if i'd need to do a bigger program, how would this be accomplished then? |
| 13:26 | joegallo | the alternative is to generate both the draw and the mouse-dragged function from a place where they have access to the same original ref. |
| 13:26 | joegallo | and then that ref isn't defined globally, just in that other function-generating-function. |
| 13:26 | joegallo | which is what nDuff meant by closing. |
| 13:26 | harja | yeah |
| 13:26 | harja | that's exactly my follow-up question |
| 13:27 | harja | so I need to explicitly close, there is no global namespace-closure, a script file closure or anything like that |
| 13:27 | joegallo | i'm not quite sure i know what you mean, but i think the answer is yes |
| 13:28 | harja | well, you can always think a namespace could have an implicit scope it could use "internally" |
| 13:28 | harja | or a script file for that matter |
| 13:28 | joegallo | i mean, you can always just bang on the map that *is* the namespace, but i think that's generally frowned on. |
| 13:29 | harja | Okay, so it's possible but not recommended :) |
| 13:30 | harja | But, the original question is now answered and I get to add data to my vector and consume it. Fantastic! An epsilon-sized step, but still.. |
| 13:34 | joegallo | enough of those, and the sky's the limit. |
| 13:35 | Roey_ | Hello, does anyone here have experience with the Monger clojure lib for MongoDB? |
| 13:36 | gtrak | yes, not me, but I'm sure someone does |
| 13:44 | sh10151 | is there any downside to using local function definitions in a let? |
| 13:48 | technomancy | sh10151: could be harder to test in isolation |
| 13:50 | ToxicFrog | sh10151: I haven't seen any so far, and I've been doing it a lot |
| 13:50 | ToxicFrog | Since I don't like the aesthetics of letfn, especially when there's already a normal let |
| 13:52 | duck1123 | Roey_: What's your question? |
| 14:03 | sh10151 | these are pretty straightforward |
| 14:03 | sh10151 | they're in a let |
| 14:04 | sh10151 | another style question, is it bad to rely too much on dynamic vars? |
| 14:05 | sh10151 | specifically the way CL uses special variables for parameterization |
| 14:05 | technomancy | sh10151: it's bad to write an API that forces callers to use dynamic variables |
| 14:06 | technomancy | build around lexical scope first and add dynamic scope once you have it working if the lexical version is cumbersome |
| 14:06 | sh10151 | specifically this is for the mess of attributes/parameters/error listeners/URI resolvers/etc. that XSL processors make optional |
| 14:07 | gfredericks | cemerick spent a lot of effort back in the day on designing an interface that could be used either way |
| 14:07 | gfredericks | I'm not sure if it ended up being worth the effort/complexity |
| 14:07 | sh10151 | to avoid the mutating setFoo setBar etc. would require either dynamic vars changed with binding |
| 14:07 | sh10151 | or 10-argument functions |
| 14:08 | gfredericks | sh10151: maybe condense a lot of the args to a map? |
| 14:08 | technomancy | take a map and bind the default that you use if a given value isn't in the map |
| 14:08 | sh10151 | there's a map for attributes |
| 14:08 | sh10151 | a map for parameters |
| 14:08 | sh10151 | a map for features |
| 14:08 | gfredericks | a map for maps! |
| 14:08 | sh10151 | and a variable for error listener and a variable for uri resolver |
| 14:09 | sh10151 | so it's still preferable to pass in one big config-type map in this case? |
| 14:12 | gtrak | sh10151: you could parameterize the building of the map with another api |
| 14:19 | sh10151 | well, the use case is, 90% of the time it will contain nothing |
| 14:19 | sh10151 | then occasionally one or two customizations will be needed |
| 14:20 | sh10151 | or xsl-params are provided |
| 14:20 | sh10151 | that's really the most common case |
| 14:33 | pyr | c/lear |
| 14:40 | harja | what's the Common LISP progn equivalent in Clojure? |
| 14:41 | arrdem | harja: (do) if I remember correctly |
| 14:41 | arrdem | ,(doc do) |
| 14:41 | clojurebot | Gabh mo leithsc?al? |
| 14:41 | harja | yeah, found it :) |
| 14:42 | harja | arrdem: thanks! |
| 14:43 | arrdem | (doc do) |
| 14:43 | clojurebot | I don't understand. |
| 14:43 | arrdem | technomancy: first it speaks Irish and now it's retarded. a little help here? |
| 14:58 | twhume | I'm having trouble getting futures to cancel; future-cancel returns true, but CPU usage goes through the roof, so I think my function is still running. Any ideas? I've written up the issue and had a couple of responses at http://stackoverflow.com/questions/11520394/why-do-cancelled-clojure-futures-continue-using-cpu |
| 14:59 | twhume | Right now I'm thinking of going in and doing it all myself, but I know that's exactly the kind of thing I should avoid doing if possible... |
| 15:01 | wingy_ | how do i get lein server to allow connections from the outside world? |
| 15:15 | neotyk | dnolen: ping |
| 15:15 | dnolen | neotyk: pong |
| 15:16 | neotyk | dnolen: do you know the reason for using CrossPageChannel in BrowserREPL? |
| 15:17 | dnolen | neotyk: I responded on the ML, it works everywhere back o IE6, we're not going to replace it. If you want another transport give us a patch to support alternate transports. |
| 15:18 | neotyk | dnolen: sorry, didn't notice your reply |
| 15:20 | nDuff | Which list was this? I don't see the thread on clojure-dev |
| 15:21 | neotyk | dnolen: I've seen stuff in clojure.browser.net, but only now it appeared to me that there is still a websocket stuff that was enabled by recent closure |
| 15:21 | neotyk | nDuff: clojure-users |
| 15:22 | dnolen | neotyk: yes. |
| 15:22 | augustl | is there a way to force leiningen to download the latest snapshots? |
| 15:22 | dnolen | neotyk: if it's there I'm sure a lot of people would leverage it too. |
| 15:22 | neotyk | dnolen: let me follow up on it than |
| 15:23 | dnolen | neotyk: CrossPageChannel is slow. |
| 15:24 | neotyk | how do I make lein-cljsbuild run against local cljs build? |
| 15:24 | dnolen | neotyk: checkouts |
| 15:25 | dnolen | neotyk: I'm pretty sure lein-cljsbuild mentions this. |
| 15:27 | emezeske | neotyk: https://github.com/emezeske/lein-cljsbuild/wiki/Using-a-Git-Checkout-of-the-ClojureScript-Compiler |
| 15:28 | neotyk | emezeske: just reading it, thanks |
| 15:32 | augustl | does "lein deploy" also update ~/.m2 for snapshots? Or does it just upload to the repo? |
| 15:33 | augustl | seems like it's the latter. Had some problems with a new snapshot (my own internal lib) not being available, deleting ~/.m2 fixed it though |
| 15:40 | uvtc | What else do I need to use sqlite from Clojure aside from clojure.java.jdbc? Which driver is the canonical one for sqlite? |
| 15:41 | metajack | org.xerial/sqlite-jdbc is the one i use |
| 15:42 | metajack | i use it with korma and it works out of the box. |
| 15:42 | uvtc | metajack: That's the one I see mentioned in the CP-oreilly book, but clojars has listed sqlitejdbc (zentus). |
| 15:42 | uvtc | Oh. |
| 15:43 | duck11231 | uvtc: http://mvnrepository.com/artifact/org.xerial/sqlite-jdbc/3.7.2 |
| 15:43 | metajack | it's not in clojars :) |
| 15:43 | hiredman | I'd recommend derby or h2 over sqlite, unless you specificly need sqlite |
| 15:43 | metajack | most of the java libs come from maven central |
| 15:43 | metajack | hiredman: why is that? |
| 15:44 | hiredman | metajack: because derby and h2 are both "native" to the jvm |
| 15:44 | uvtc | metajack: Whoops. I just realized --- it's a java lib, since it's for Java's jdbc to talk to sqlite. |
| 15:45 | hiredman | the sqlite driver, last I heard tries to load a native library, and if that fails falls back to emmulating a risc cpu on the jvm (which sounds so crazy it makes me want to google it and make sure) |
| 15:45 | uvtc | hiredman: I don't specifically need sqlite. I'm familiar with it, and like that it's small, fast, and simple though. Have not looked into derby or h2. |
| 15:45 | metajack | uvtc: I was in the same position the other day. I found it by typing "!mvn sqlite" into my search bar, which uses duckduckgo's redirection to get me to maven's search page |
| 15:45 | hiredman | http://www.zentus.com/sqlitejdbc/ |
| 15:45 | clojurebot | dakrone maintains clj-http |
| 15:45 | hiredman | http://nestedvm.ibex.org/ |
| 15:46 | metajack | hiredman: I'll keep those in mind for future projects, although I do like the ability to use the sqlite3 commandline tool to poke and prod the database. |
| 15:47 | uvtc | hiredman: I've got sqlite3 (and libsqlite3-0) installed (on GNU/Linux). |
| 15:47 | augustl | technomancy: "17:52 < technomancy> augustl: you can alias "test" to "midje" in project.clj" - thanks, didn't notice until now :) |
| 15:47 | clojurebot | I'm no man, and she's no lady! |
| 15:48 | hiredman | uvtc: so? |
| 15:48 | uvtc | hiredman: You'd mentioned what happens if the JVM fails to load the native library. |
| 15:48 | duck11231 | uvtc: you also have a ~/.m2, so having one of the others is a lein deps away |
| 15:50 | hiredman | http://database-management-systems.findthebest.com/compare/6-16-53/Apache-Derby-vs-H2-vs-SQLite |
| 15:51 | hiredman | although, that seems suspect, I am pretty sure derby supports indices |
| 15:51 | augustl | technomancy: weird, `:aliases {"test" "midje"}` seems to run _both_ `lein test` and `lein midje` when I run `lein test`. Both midje and clojure.test output is there. |
| 15:51 | uvtc | hiredman: reading about derby and h2. Thanks for the recommendations. |
| 15:52 | duck11231 | augustl: lein midje also runs normal tests |
| 15:54 | augustl | duck1123: right, I want "lein test" to run midje tests though |
| 15:54 | augustl | oh, I think I see what you mean |
| 15:55 | augustl | anyways, the output is different from "lein test" and "lein midje" when I alias test to midje |
| 15:56 | augustl | https://www.refheap.com/paste/3656 for an example |
| 15:56 | augustl | (prompt at line 16) |
| 15:57 | duck1123 | augustl: yeah, that second one is definitely lein midje |
| 15:57 | augustl | duck1123: right, but there's some additional output there too |
| 15:57 | augustl | plain clojure.test output |
| 15:57 | augustl | which isn't present witih "lein midje" |
| 15:58 | augustl | so it's kind of weird that it is, since "lein test" is an alias to "lein midje" in this paste |
| 15:59 | duck1123 | augustl: you're right, it looks like your alias isn't working |
| 16:00 | duck1123 | midje runs it's tests when they're evaluated, so if you have facts in your test nses, they'll be run, but unless you've wrapped them, they won't be reported on |
| 16:01 | augustl | duck1123: it does kind of work though :) |
| 16:01 | augustl | "lein test" without the alias doesn't run midje tests |
| 16:01 | augustl | oh wait, never mind, it does :) |
| 16:01 | aib | can anyone help me get penumbra to run? http://paste.ubuntu.com/1097213/ |
| 16:01 | augustl | should have checked that |
| 16:02 | augustl | that is, it contains the "WORK TO DO" calls as they probably print immediately |
| 16:02 | augustl | duck1123: so it's the alias that simply isn't working |
| 16:02 | augustl | perhaps aliases is a lein 2 thing |
| 16:02 | duck1123 | augustl: that's what it looks like |
| 16:03 | amalloy | aib: you really want to use leiningen; it will stop you from getting the classpath wrong (which is what's happened) |
| 16:04 | amalloy | specifically, -jar ignores classpath settings, assuming the jar you pointed at has all the classes it needs |
| 16:04 | aib | ahh |
| 16:05 | aib | this is my first (2nd?) time using clojure/lein. Any reading material would be appreciated |
| 16:05 | amalloy | to do it manually (which, again, i don't recommend) you need the classpath to include the jar and run clojure.main or something |
| 16:05 | amalloy | ~leiningen |
| 16:05 | clojurebot | http://github.com/technomancy/leiningen |
| 16:08 | aib | ah, I did compile the project using "lein deps" + compile. the getting-started file then told me to run some clojure commands, that's why I did java -jar, which was probably wrong, in retrospect |
| 16:10 | aib | in which case, https://github.com/ztellman/penumbra/wiki/getting-started - how do I run the REPL after 'lein deps' and 'lein compile' ? |
| 16:12 | aib | oh no. there's a 'lein repl', isn't there? |
| 16:12 | aib | of course there is. |
| 16:31 | wingy | i feel that we should pay the maintainers of a project even if it's OS |
| 16:31 | devn | hello clojurians |
| 16:31 | wingy | to have high quality libs |
| 16:32 | Raynes | wingy: Those are called donations. |
| 16:33 | wingy | they shouldn't be donations |
| 16:33 | wingy | they should be earnings |
| 16:33 | Raynes | I'll be expecting a paycheck in the mail. |
| 16:33 | wingy | you pay a carpenter making a chair for you |
| 16:34 | wingy | if someone is making a good lib and you need features added and maintenance you should pay for it |
| 16:34 | wingy | or the project might die put |
| 16:34 | wingy | out |
| 16:34 | emezeske | wingy: You can't make a perfect copy of a chair for less than one cent of electricity, though :) |
| 16:35 | wingy | kinda like ExtJS .. they started from just a lib and charged money |
| 16:35 | nDuff | wingy: You first. |
| 16:35 | wingy | now they are big .. and the thing is they can make it better |
| 16:35 | wingy | just saying |
| 16:35 | wingy | im not a lib maker |
| 16:35 | nDuff | wingy: ...or, better, you could start by reading CatB and its kin, on how and why OSS works in practice. |
| 16:35 | duck1123 | So if you're forced to pay for open source software... |
| 16:35 | wingy | nothing wrong to charge for things .. if they need to make a living they wont have time to fix the libs |
| 16:36 | wingy | fulltime |
| 16:36 | nDuff | wingy: Nonsense. If your software is useful enough, companies will pay people to improve it in their own self-interest. That's not theory, it's actual practice. |
| 16:37 | nDuff | wingy: I've spent a damn lot of time fixing up OSS code while on salary, as do most people here. If that isn't paying to fund software development, what is? |
| 16:37 | wingy | there is a diff between pet projects and actual production ready projects with high doc and support quality |
| 16:37 | emezeske | wingy: I totally agree that there's nothing wrong with charging. I do think for certain projects, though, the "payment" can be in terms of bug reports, bug fixes, extra eyeballs, patches, etc |
| 16:37 | wingy | emezeske: yes |
| 16:38 | nDuff | wingy: "pet project" something someone is doing only because they choose to. I'm talking, again, about people doing work on payroll with authorization, but without their employer receiving direct remuneration for that effort. |
| 16:39 | technomancy | the software I love using most is generally written because the author couldn't not write it |
| 16:39 | wingy | i don't think a person chooses doing pet projects .. he just doesn't have the resource making it better and going all in for it |
| 16:39 | nDuff | *sigh*. |
| 16:39 | emezeske | technomancy: That is a great indicator! :) |
| 16:39 | nDuff | wingy: again, you're assuming this silly dichotomy that anything that isn't work-for-hire is a "pet project". It's frankly insulting. |
| 16:40 | wingy | nDuff: no .. i meant terse doc .. no maintenance |
| 16:40 | wingy | just saying you may have the skills and knowledge but you need the fuel |
| 16:41 | wingy | just another ingredience |
| 16:41 | nDuff | wingy: I've pointed you at some essays on how and why the ecosystem works. Please read them before continuing this conversation. |
| 16:41 | wingy | be good at development, be good at business |
| 16:41 | wingy | the market needs it |
| 16:43 | emezeske | wingy: Keep in mind that some people are motivated by things other than money, though. |
| 16:43 | wingy | well we all know why Ubuntu is getting more popular than Debian … they know business as well |
| 16:43 | hiredman | not I, money money money |
| 16:44 | wingy | emezeske: cant agree more .. im not talking about we do it for money..im talking about money can help |
| 16:44 | emezeske | hiredman: I guess that's why you're "hiredman" instead of "volunteerman" :) |
| 16:44 | wingy | and not trying to start a flame war but we do have to agree a lot of potential projects could be more solid |
| 16:45 | technomancy | the original meaning of the word "amateur" actually comes from the root "amor"; in other words, done out of love. |
| 16:45 | emezeske | wingy: Sure, but money isn't always a fix |
| 16:45 | mattmoss | Throwing money at things is not an automatic win. |
| 16:45 | wingy | emezeske: didnt say that .. it helps |
| 16:45 | clojurebot | Pardon? |
| 16:45 | mattmoss | However, throwing money at me is a wonderful thing. |
| 16:45 | wingy | mattmoss: i agree .. throw it on top devs coding for love |
| 16:45 | emezeske | Heh, it sometimes helps. |
| 16:46 | wingy | but they need to make a salary as well |
| 16:46 | emezeske | technomancy: Interesting fact! |
| 16:46 | wingy | not everyone wants to use java/php at their job |
| 16:46 | mattmoss | wingy: What if they're already salaried? You seem to have ignored nDuff's points. |
| 16:46 | duck1123 | throw money at me and I consider it a win. Just not pennies, those hurt |
| 16:46 | technomancy | emezeske: call me a professional amateur =) |
| 16:46 | mattmoss | Pennies aren't worth anything anyway.... except for making large penny pyramids. |
| 16:47 | emezeske | technomancy: Same here! |
| 16:47 | wingy | mattmoss: not everyone works on the thing they really want to work on |
| 16:47 | wingy | mattmoss: some work for money only, no love at jobs |
| 16:48 | mattmoss | You seem to be conflating a few different arguments. Perhaps sticking to one at a time? |
| 16:48 | wingy | mattmoss: i dont get what you mean .. everything is connected? |
| 16:48 | mattmoss | Everything is connected? I highly doubt that. |
| 16:49 | wingy | you do what you love .. you make a living out of it .. you can throw more resources at it .. KISS people |
| 16:49 | technomancy | everything is intertwigled |
| 16:49 | wingy | not saying money is everything so stop throwing that at me |
| 16:49 | duck1123 | mattmoss: You've obviously never taken acid |
| 16:49 | mattmoss | Complected? |
| 16:49 | mattmoss | duck1123: That's true. |
| 16:49 | mattmoss | Did you hear the one about the Buddist in New York City who asked a hot dog vendor, "Make me one with everything." ? |
| 16:50 | technomancy | I'm all for contributing money to oss projects, but the idea that the devs can use their donations to work on their projects full-time only works with very high-profile projects |
| 16:51 | wingy | technomancy: yes |
| 16:51 | wingy | i mean .. my parents sell food for just a small town .. they make more money than 10 developers in total |
| 16:51 | wingy | one dev makes a lib 500-1000 people are using . |
| 16:52 | wingy | i say that is not that hard as we have seen, but no money in? makes me wonder .. money isn't evil..taking charge somehow can be good for everyone, the users especially |
| 16:53 | wingy | if devs know how to take charge i think the OS market would be more solid and with good quality, doc, testing etc |
| 16:53 | technomancy | you have to have a lot of money (and a predictable stream of it) before you can quit your job to do something full time |
| 16:54 | aaelony | you need a pipeline of work or a rainmaker :) |
| 16:54 | wingy | technomancy: you make what you love at freetime as you always do and then take charge for it when you have > 300 users |
| 16:55 | wingy | more than 300 users using your thing .. yeah that is a product you have |
| 16:55 | uvtc | mattmoss: the customer paid for the hot dog with a 10, but the vendor didn't give him any change. When the customer asked for his change, the hot dog vendor said, "Change comes from within." |
| 16:55 | duck1123 | There was a site I saw that let you set Bitcoin bounties for checking in passing commits or fixing bugs, but I can't seem to find the original link |
| 16:56 | mattmoss | uvtc: Good one. |
| 16:56 | wingy | im not the "i need to charge guy" im the "i pay you just make good docs and better features so I feel happier" .. that's what we are used to when buying iphone/android apps .. pay a small fee for something you want .. you are not participating in an evil cult |
| 16:56 | wingy | the OS projects could definitely be charged as apps |
| 16:57 | technomancy | I'll happily pay for software as long as it's open source |
| 16:57 | wingy | me 2 |
| 16:58 | mattmoss | wingy: It's not an evil cult, no, but your "i pay you..." statement comes off as a demand, not a request. |
| 16:59 | joegallo | i wonder how that model is working out for the itext guy. |
| 16:59 | mattmoss | Great thing about open-source... fork and improve. |
| 16:59 | uvtc | ... and send pull-request. :) |
| 17:01 | wingy | mattmoss: didn't solve the resource problem |
| 17:01 | mattmoss | wingy: What resource problem? |
| 17:01 | wingy | :/ |
| 17:02 | mattmoss | The resources necessary for developing software are human effort. |
| 17:02 | mattmoss | One way to acquire that is through money to an interested developer, but is hardly the only way. |
| 17:02 | kreig1 | wingy: can you guess why I am skeptical of your perspective on open-source software and what goes into the process of making software? |
| 17:03 | mattmoss | The developer you are demanding write docs in exchange for $$$ may be more interested in throwing around the football with his kids... |
| 17:03 | mattmoss | ...meanwhile another developer who likes writing docs (if there is such a thing) would happily fork and improve the project if asked. |
| 17:03 | wingy | mattmoss: what a company does with their money i cannot control .. but i think we all we'll see the outcome for each version |
| 17:04 | mattmoss | Or a company decides it is in their best interests to hire/pay for those docs. |
| 17:04 | kreig1 | and whose to say the best part of software production is the software? |
| 17:04 | wingy | and i doubt that passionate devs would wanna kill their baby project |
| 17:04 | wingy | it's their life |
| 17:04 | nDuff | wingy: ...so, just took you off ignore to explain something. You gave ExtJS as an example of a project "doing it right". For me, it's an example of a project I can't use commercially, because my employers (the last several of them!) won't touch software with for-cost licensing, no matter how useful it is, period -- and that hurts the project, because I contribute real, useful things -- well-researched bug reports, fixes, new f |
| 17:04 | nDuff | eatures, etc. |
| 17:04 | mattmoss | wingy: You are making many unfounded assertions. |
| 17:05 | nDuff | wingy: ...so, you're actively advocating a model that would make my life worse by increasing the range of Stuff I Can't Use. |
| 17:05 | wingy | nDuff: first of all i didn't ignore anything .. if there is something i didn't address just ask again .. its a quite broad discussion |
| 17:06 | wingy | nDuff: well if you put it in that way i can't argue anymore |
| 17:06 | kreig1 | hehe |
| 17:06 | kreig1 | good, then stop |
| 17:06 | kreig1 | so, how about those macros |
| 17:08 | scriptor | there was an article about how soldiers reacted when the red cross started charging for formerly free donuts |
| 17:09 | scriptor | not sure how relevant it is, but it's interesting to think of the psychology |
| 17:09 | technomancy | gratis donuts, you mean |
| 17:09 | scriptor | donuts libre |
| 17:09 | technomancy | the soldiers weren't improving the donut recipe as they ate them, though that would be awesome if they could |
| 17:10 | kreig1 | according to e. coli they were |
| 17:10 | technomancy | "hm; have you considered what a little nutmeg would do to the flavor profile here?" |
| 17:10 | scriptor | more like, "this donut doesn't work horribly unformatted donut-mulch attached plz fix thx" |
| 17:10 | mattmoss | Mmm, donuts libre. *drool* |
| 17:11 | technomancy | the red cross is all "HAVE YOU SIGNED PAPERWORK" |
| 17:12 | mattmoss | Curious if anyone is doing heavy Java interop... I'm split over passing around lots of POJOs vs. wrapping them in maps (with extra info at times). |
| 17:13 | mattmoss | Like... (defn create-foo [a b] (Foo. a b)) vs. (defn create-foo [a b] {:instance (Foo. a b)}) |
| 17:25 | gfredericks | mattmoss: I don't think it'd be idiomatic to wrap them except for the purpose of the extra info; i.e., not for its own sake |
| 17:27 | duck1123 | It really depends on how close to the line you're working |
| 17:27 | mattmoss | gfredericks: I suppose what I was mulling over was passing around maps of things and shoving them into POJOs at the point of a Java call, or requiring use of POJOs spread throughout the clojure code. |
| 17:27 | mattmoss | The former seems cleaner, "nicer", Clojure code... hiding away the "nasty" details of POJOs. |
| 17:28 | mattmoss | But I may just be needlessly worrying. |
| 17:37 | nDuff | I'm interested in temporarily disabling watches on a known list of atoms during test setup/teardown. Is a mechanism available? |
| 17:38 | technomancy | nDuff: can you just with-redefs the associated vars to (constantly true) |
| 17:38 | technomancy | I guess that only works if you pass the var in as the watcher, not the function itself |
| 17:40 | nDuff | ...so, I could see doing that to just put in entirely new atoms, but the effects of the watches are a big part of what I want to test during operation. |
| 17:41 | wingy | do you guys use a statechart/statemachine in frontend cljs when coding? if not, how do you usually organize your code? |
| 17:44 | siscia | aaelony, thank you also for jiraph ;-D |
| 17:44 | duck1123 | wingy: Have you seen Waltz? |
| 17:45 | duck1123 | I just refactored some of my code this past weekend to use that, seems pretty nice so far |
| 17:49 | wingy | duck1123: ill give it a try .. seems to be the most popular one in cljs land |
| 17:50 | wingy | in worse case scenario if that won't cut it I see if I can use http://stativ.us/ with cljs |
| 17:51 | wingy | if the oop style would work nicely |
| 17:51 | duck1123 | wingy: Heres what I did with Waltz. https://github.com/duck1123/jiksnu/blob/dev/src-cljs/jiksnu/websocket.cljs |
| 17:52 | duck1123 | still a WIP, obviously |
| 17:52 | hiredman | b |
| 17:53 | aaelony | siscia: thank flatland folks... who are awesome to the hilt |
| 17:54 | wingy | duck1123: great i can use your project as a template for frontend :) |
| 17:54 | duck1123 | And on that note, I'm out of here. Time to get home and trade in my Java and js for Clojure and cljs. |
| 17:54 | wingy | haha |
| 17:54 | duck1123 | wingy: have at it. Share and enjoy |
| 17:55 | Raynes | amalloy: Here that, Alan? To the hilt. |
| 17:55 | Raynes | Hear, even. |
| 17:55 | Raynes | Here, there, whatever. |
| 17:55 | fsmunoz | If you allow an external observation, you clojure guys seem permanently in a state of bliss. Every time I read the buffer it's all about people saying nice things about the language, the libs, the weather. |
| 17:56 | Raynes | Clojure rocks! I sampled everything in the medicine cabinet for comparison, but I think that this euphoria is the Clojure. |
| 17:56 | technomancy | fsmunoz: just wait; we've overdue for someone to announce their independent re-invention of "lisp without parens, to make it easier for newbies" on the mailing list |
| 17:57 | emezeske | Raynes: Nice, you got your doctor to write you a clojure-script? |
| 17:58 | aperiodic | (inc emezeske) |
| 17:58 | lazybot | ⇒ 1 |
| 17:58 | fsmunoz | technomancy, Raynes: heheh |
| 18:04 | SegFaultAX|work2 | The documentation format for special-forms and macros kinda sucks. |
| 18:05 | SegFaultAX|work2 | (fn name? ([params* ] exprs*)+) <- it's like a weird mixture of ad-hoc sexp and regex. |
| 18:06 | TimMc | It's more like BNF, really. |
| 18:06 | SegFaultAX|work2 | TimMc: Except for not. |
| 18:06 | SegFaultAX|work2 | TimMc: But if I squint really hard, I see your point. |
| 18:07 | SegFaultAX|work2 | TimMc: Either way, the usage of ? + and * (and the implied meaning of each) makes it look more like a syntax based on regex. |
| 18:07 | clojurebot | the best way to represent X is as a regular clojure map. (for most values of x) |
| 18:07 | TimMc | Like BNF that has been condensed. You can do that more easily with languages whose syntax is close to their AST. |
| 18:08 | fsmunoz | speaking of weird, is there a reason why the doc string is before the args? It looks weird to me, but I suppose there is a language feature that makes this sensible? |
| 18:08 | TimMc | clojurebot: We value your input. Please wait for the next available logger. |
| 18:08 | clojurebot | It's greek to me. |
| 18:08 | SegFaultAX|work2 | TimMc: Except for BNF has the descriptive power of telling me exactly valid and invalid syntaxes. This format is only approximate and doesn't really describe anything about the form in any detail. |
| 18:09 | TimMc | fsmunoz: I could come up with philosophical reasons re: doc-driven development, but the real answer probably lies somewhere in the multi-arity syntax. |
| 18:09 | SegFaultAX|work2 | That would be my guess as well. |
| 18:09 | fsmunoz | TimMc: yes, that was what I was suspecting |
| 18:09 | fsmunoz | ty |
| 18:11 | TimMc | It's easy to accidentally write (defn foo [args] \n "docstring but not really" ...) and have a fake docstring. :-/ |
| 18:11 | TimMc | Anyone know if ibit catches that? |
| 18:11 | TimMc | *kibit |
| 18:11 | SegFaultAX|work2 | TimMc: Is that a clojure linter |
| 18:11 | SegFaultAX|work2 | ? |
| 18:12 | SegFaultAX|work2 | Ah, static code analysis. |
| 18:19 | wingy | what do you think about http://emberjs.com/documentation/ for frontend with cljs .. it's using MVC/OOP approach |
| 18:19 | wingy | statemachine is one of the things included |
| 18:21 | SegFaultAX|work2 | wingy: I like backbone. Ember is pretty heavy for what I'm usually looking for. |
| 18:21 | SegFaultAX|work2 | wingy: Just my $0.02 |
| 18:21 | wingy | SegFaultAX|work2: but is using a MVC/OOP framework OK even for a FP lang? |
| 18:21 | wingy | mixing 2 different paradigms |
| 18:22 | SegFaultAX|work2 | wingy: Those don't really have anything to do with each other. |
| 18:22 | wingy | SegFaultAX|work2: now you have to put your maps/vectors into their models i guess? |
| 18:22 | SegFaultAX|work2 | wingy: MVC is a design pattern for separation of concerns. In a nutshell: Models are for application state and business logic, views are for UI/UX, and controllers are a bridge between them. |
| 18:24 | wingy | yeah i know, was curious about if that would break something important now when I think data and logic should be kept separate |
| 18:24 | fsmunoz | I think that they can match well, especially if one considers that the view is mostly about side-effects |
| 18:25 | SegFaultAX|work2 | wingy: That isn't really related to MVC, so you're probalby good there if that pattern matches your problem. |
| 18:25 | fsmunoz | and the model can be thus more "pure", containing the actual logic and not polluted by (doto (.JFrame)...) |
| 18:25 | fsmunoz | (or whatever it is really like) |
| 18:25 | wingy | ok |
| 18:25 | wingy | seems that we are all green to go |
| 18:26 | wingy | that's is one of the selling point to clj/cljs to me that it's pragmatic to leverage the current libs/frameworks in the host env |
| 18:26 | SegFaultAX|work2 | fsmunoz: Maybe if you separate models from persistence (eg Models & Repositories) but when those two concepts are coupled (which they often are) then both can be heavily side-effecting. |
| 18:26 | wingy | without wrappers |
| 18:26 | SegFaultAX|work2 | fsmunoz: After all, it's up to the models to transform application state. |
| 18:27 | fsmunoz | SegFaultAX|work2: quite right, haven't thought of it that way |
| 18:27 | wingy | yay . so now we have bootstrap and emberjs including a statechart for free |
| 18:27 | SegFaultAX|work2 | fsmunoz: In other words, unless the data layer is abstracted away, models will necessarily be side-effecting. |
| 18:39 | SegFaultAX|work2 | I need to interop with git, what's a good library to do that with? |
| 18:40 | Raynes | clojure.java.shell |
| 18:40 | Raynes | ;) |
| 18:40 | technomancy | there are a couple jgit wrappers; don't use the one from seajure as it was a swarm-coding exercise and not further maintained |
| 18:41 | SegFaultAX|work2 | Actually maybe just writing a wrapper for working with git from the shell wouldn't be so bad. |
| 18:42 | technomancy | jgit is great for reading; I haven't used it for commits and push/pull stuff |
| 18:42 | SegFaultAX|work2 | technomancy: This would be read-only. |
| 18:42 | amalloy | write a wrapper for working with git from the shell? isn't that just git? |
| 18:42 | technomancy | git's CLI is beyond awful though |
| 18:43 | amalloy | whaaaat |
| 18:43 | SegFaultAX|work2 | technomancy: I use it everyday. |
| 18:43 | SegFaultAX|work2 | technomancy: I don't find it that bad. |
| 18:43 | amalloy | get out of my channel, technomancy |
| 18:43 | technomancy | it's bad! |
| 18:43 | technomancy | it just is. |
| 18:43 | amalloy | there are some bad things for sure |
| 18:43 | technomancy | it overloads commands to do like five different operations |
| 18:43 | technomancy | it calls the staging area the "index" |
| 18:44 | technomancy | you learn about how it's bad, and you stop noticing it if you use it every day |
| 18:45 | technomancy | every time I have to drop out of magit and use regular git it just feels so backwards |
| 18:45 | SegFaultAX|work2 | technomancy: Your first point is somewhat true. Second one is irrelevant. As for the third, well you learn to live with the warts of any tool if it helps you Get Shit Done (tm) |
| 18:46 | technomancy | I agree; I still use git. I just think you can do better if you're going to wrap it. |
| 18:46 | SegFaultAX|work2 | Which commands do you feel are too heavily overloaded? |
| 18:46 | technomancy | "checkout" is the most obvious one |
| 18:46 | SegFaultAX|work2 | Why do you think that? |
| 18:46 | technomancy | because it's used for switching branches as well as discarding changes to the working copy and a few other things |
| 18:47 | technomancy | there's no conceptual coherence to it |
| 18:47 | gtrak | you're not 'discarding changes', that's just a side-effect |
| 18:47 | technomancy | the underlying model of storage is very good, which is the only reason tools with a good UX like magit can be built on top of it |
| 18:47 | SegFaultAX|work2 | It does exactly 1 thing, it changes your working directory based on a commit-ish. |
| 18:47 | SegFaultAX|work2 | That's all. |
| 18:47 | technomancy | no, it creates new branches too |
| 18:48 | SegFaultAX|work2 | technomancy: No it doesn't. git-checkout -b does. |
| 18:48 | technomancy | yes? |
| 18:48 | clojurebot | yes isn't is |
| 18:48 | technomancy | also: IIRC git branch creates a branch without switching to it; wtf |
| 18:48 | technomancy | no one has ever wanted to do that |
| 18:48 | SegFaultAX|work2 | technomancy: Because all its doing under the hood is associating a ref with a commit-ish. |
| 18:49 | gtrak | I just saw in mercurial yesterday, hg resolve discards local changes and pulls up a merge tool... hg resolve -m says you've already resolved it |
| 18:49 | technomancy | SegFaultAX|work2: who cares what's happening under the hood? |
| 18:49 | SegFaultAX|work2 | Sure they do. Before a rebase operation you might make a "backup" by using git-branch. |
| 18:49 | technomancy | it's ignoring the perspective of a user |
| 18:49 | SegFaultAX|work2 | Which really means "I don't want to look through the reflog if I fuck this up" |
| 18:49 | gtrak | mercurial's user philosophy is supposed to be better |
| 18:49 | technomancy | I've forgotten most of my other complaints because luckily I can most things done with magit these days |
| 18:49 | gtrak | git's user experience was never its selling point |
| 18:50 | SegFaultAX|work2 | technomancy: The problem is you don't grok git. |
| 18:50 | SegFaultAX|work2 | technomancy: Remembering that it started as a collection of tools instead of one big application helps. |
| 18:50 | technomancy | SegFaultAX|work2: the problem is you have to understand irrelevant details to use it effectively |
| 18:50 | SegFaultAX|work2 | technomancy: Perhaps. |
| 18:50 | technomancy | oh, the other big thing was that everyone says "git pull is the same thing as git fetch plus git merge" but there are subtle details between the two, and fetch+merge is pretty much always what you want |
| 18:51 | technomancy | since pull ignores certain aspects of the remote IIRC |
| 18:51 | SegFaultAX|work2 | technomancy: What are the subtle details you're thinking of? |
| 18:51 | SegFaultAX|work2 | technomancy: It doesn't. |
| 18:51 | technomancy | I sort of wish I could remember, but on the other hand I'm also kind of glad I've forgotten =) |
| 18:51 | SegFaultAX|work2 | technomancy: But you can certainly get weird issues if your refspecs are configured improperly, I'll give you that. |
| 18:52 | hiredman | technomancy: push pushes everything if you don't give it a branch? |
| 18:53 | SegFaultAX|work2 | I'm not a git evangelist. I just hear a lot of people bitch about git without having meaningful arguments against it. "It's harder" is a fine argument all by itself which most folks won't disagree with. |
| 18:54 | technomancy | hiredman: that's a fun one too |
| 18:54 | technomancy | the problem is that git devs claim that git is both porcelain and plumbing, but it's really all just plumbing with various levels of polish applied |
| 18:55 | technomancy | hahaha: "Git refers to implementation details as “plumbing” and the user interface as “porcelain”, in order to make it clear that git’s designers think of git with the same reverence I think of the instrument that handles the organic waste that my body produces." |
| 18:56 | technomancy | reset is another example of a single command that has many different purposes |
| 18:57 | SegFaultAX|work2 | technomancy: Sorry, my connection died. |
| 18:57 | SegFaultAX|work2 | technomancy: What were you saying? |
| 18:57 | amalloy | yeah, reset is poorly named |
| 18:58 | Raynes | SegFaultAX|work2: He was saying whinewhinewimperbitchblaaaahblurggitsucks. |
| 18:58 | SegFaultAX|work2 | Haha. |
| 18:58 | technomancy | SegFaultAX|work2: "reset is another example of a single command that has many different purposes" |
| 18:58 | SegFaultAX|work2 | amalloy: reset is easily one of the more complicated features of git. |
| 18:58 | technomancy | I like it as an API, but it leaves a lot to be desired as an application |
| 18:58 | SegFaultAX|work2 | amalloy: It allows you to interact with the tree, index, and working directory all in one. |
| 18:58 | technomancy | and usually I don't have to use it as an application, so I'm fairly happy |
| 18:59 | SegFaultAX|work2 | technomancy: I agree to a certain extent that reset is overloaded. But understanding how it /actually/ works really helps. |
| 19:00 | technomancy | well-designed applications allow users to learn gradually |
| 19:00 | SegFaultAX|work2 | technomancy: Most new or mid-level users of git have only a basic understanding of how git-reset operates. |
| 19:00 | amalloy | SegFaultAX|work2: i don't know why you're telling me this. i like reset |
| 19:01 | SegFaultAX|work2 | amalloy: Awesome! All I got was that it's poorly named. :) |
| 19:01 | amalloy | well, it is |
| 19:01 | SegFaultAX|work2 | amalloy: Dunno what else I'd call it. |
| 19:01 | amalloy | i'm very comfortable with git; i don't need evangelizing :P |
| 19:02 | SegFaultAX|work2 | "ref-sync" maybe. |
| 19:03 | Raynes | I'd call it reset. |
| 19:03 | Raynes | That's much better than reset. |
| 19:03 | SegFaultAX|work2 | :) |
| 19:04 | gtrak | git reset --hard just makes me feel lika a badass |
| 19:04 | amalloy | and then usually an idiot, right? |
| 19:04 | SegFaultAX|work2 | gtrak: git reset --hard && git clean -df |
| 19:04 | SegFaultAX|work2 | gtrak: Like a boss. |
| 19:04 | gtrak | what's that do? |
| 19:04 | Raynes | technomancy: You should use mercurial. |
| 19:04 | SegFaultAX|work2 | gtrak: Also removed everything untracked. |
| 19:04 | amalloy | technomancy: i guess i would say that the git cli has the same problem emacs does: it's not very discoverable, but it's powerful and usable |
| 19:04 | gtrak | amalloy: haven't blown my foot off with that yet |
| 19:05 | technomancy | Raynes: magit solves all my problems |
| 19:05 | SegFaultAX|work2 | amalloy: Some people say the same thing about vim. I think most complex tools get that wrap. |
| 19:05 | gtrak | I want your hardest reset, git... don't hold back |
| 19:05 | technomancy | git reset --hard --with-a-vengeance |
| 19:06 | duck1123 | you have to pass --hard to get the special ending |
| 19:06 | SegFaultAX|work2 | technomancy: Does that null out the sectors on my hdd before it resets? |
| 19:06 | SegFaultAX|work2 | duck1123: No one likes it --soft. |
| 19:14 | wingy | i need to dig deeper into git |
| 19:15 | jballanc | Question on idiomatic clojure: if I have a filter of a lazy-seq, and I want to print all of the matching entries, what's the best way? |
| 19:15 | jballanc | right now I'm using println and clojure.string/join with "\n"…but it feels wrong |
| 19:16 | emezeske | jballanc: What feels wrong about that? |
| 19:17 | jballanc | I just feel like I should be able to pass println to the seq, instead of having to join the seq and pass to println |
| 19:17 | jballanc | for example, if it were Ruby, I'd finish with "filtered_list.each { |elem| puts elem }" |
| 19:18 | emezeske | Well, you could (doseq [elem elems] (println elem)) |
| 19:18 | jballanc | but, everything I try, I just keep ending up with more lazy-seqs |
| 19:18 | jballanc | ah, doseq will realize the lazy-seq? |
| 19:18 | gtrak | jballanc: (apply println seq?) |
| 19:18 | emezeske | gtrak: Isn't apply lazy? |
| 19:18 | gtrak | ,(apply println [1 2 3 4 5]) |
| 19:18 | clojurebot | 1 2 3 4 5 |
| 19:19 | gtrak | emezeske: the realization is lazy, but the invocation isn't |
| 19:19 | gtrak | errr... |
| 19:20 | gtrak | it's not curried, so I'm not sure why it would be lazy |
| 19:20 | emezeske | jballanc: Yes, doseq's purpose is to be un-lazy |
| 19:20 | emezeske | jballanc: I should say, it's purpose is for side-effects |
| 19:20 | jballanc | ah, yes…that works perfectly |
| 19:21 | jballanc | thanks, emezeske! |
| 19:21 | gtrak | ,(let [_ (apply println [1 2 3 4 5]) _ (println "should happen second")] nil) |
| 19:21 | clojurebot | 1 2 3 4 5 |
| 19:21 | clojurebot | should happen second |
| 19:21 | gtrak | emezeske: ^ |
| 19:21 | emezeske | gtrak: At any rate, that's not what jballanc is trying to do |
| 19:22 | gtrak | why not? |
| 19:22 | emezeske | See his original example, he is printing each element on a separate line |
| 19:22 | gtrak | jballanc: if you want to make it feel nicer, try interpose and I think there's a \newline |
| 19:22 | jballanc | hmm…hadn't seen interpose |
| 19:22 | jballanc | ah, but still lazy |
| 19:23 | gtrak | until you do it |
| 19:23 | gtrak | that's kinda the point of laziness |
| 19:23 | emezeske | jballanc: Just use doseq, that's exactly what it's made for |
| 19:23 | jballanc | right…so, to give more context, this is reading a file in the context of a with-open |
| 19:24 | jballanc | it's annoying that if the expressions all evaluate lazily until you finish the with-open form, you get a Exception in thread "main" (java.io.IOException: Stream closed) |
| 19:25 | gtrak | jballanc: yea, you need to do something to actually realize it, doseq, mapv, into |
| 19:26 | jballanc | got it |
| 19:26 | jballanc | I'm still learning, but I actually rather like this aspect of clojure |
| 19:31 | gtrak | jballanc: I like to think about it like lazy seqs are reified computations in value-land, and side-effects aren't compatible with that notion. What's the conceptual value of that item if it depends on a resource having not been closed yet? |
| 19:35 | jballanc | gtrak: it's a good question but, if I may be so bold, couldn't closing the stream be done lazily when the list is fully realized? |
| 19:36 | gtrak | jballanc: sure, if you're doing that you want to use a countdownlatch or something |
| 19:36 | gtrak | but then what if it isn't fully realized? |
| 19:37 | gtrak | but yea, that's the secret, contain as a value everything that the value depends on |
| 19:37 | jballanc | yes, not at all an easy task…in any language, I think |
| 19:53 | wingy | what is the reason for this inconsistent naming in cljs: (array) for creating an array and (js-obj) for creating an object? |
| 19:54 | gtrak | wingy: inconsistent how? |
| 19:54 | wingy | why not js-array or obj |
| 19:55 | gtrak | (def js-array array) ; mm feels so much better ;-) |
| 19:56 | kreig1 | array is a shared type, js-obj is a jscript specific type? |
| 19:56 | kreig1 | hmm, no, not tit |
| 19:57 | Raynes | Always tit. |
| 19:57 | kreig1 | there are not arrays in cljs, don't have a repl open to confirm tho |
| 19:57 | emezeske | kreig1: There are arrays in cljs |
| 19:57 | kreig1 | vectors tho right? |
| 19:57 | emezeske | kreig1: https://github.com/clojure/clojurescript/blob/master/src/cljs/cljs/core.cljs#L78 |
| 19:59 | wingy | gtrak: ... |
| 19:59 | kreig1 | I know that, but it's not a native clojure type, but I have a hunch that distinction is in my head only |
| 20:00 | gtrak | I was looking for a all? instead of an every? the other day... I think it just happens sometimes |
| 20:00 | gtrak | thankfully it's not that big a deal |
| 20:02 | wingy | hi there, I'm a such mature person who talks inbetween the lines all the time since i find it's contributing |
| 20:03 | wingy | instead of trying to help to answer the question i make a fool of them so they find them self in shame |
| 20:03 | gtrak | wingy: sorry I don't know the answer, it doesn't seem to me like it's intentional either way |
| 20:37 | bloudermilk | This is a very broad question and I apologize for that, but is there any reason a function would behave differently in the REPL than when running lein run? |
| 20:37 | kenneth | hey is there a way to use stuff in /usr/share/java in my class path with lein |
| 20:38 | bloudermilk | Such as environment differences? |
| 20:38 | aperiodic | bloudermilk: yes; the REPL forces evaluation of lazy sequences |
| 20:38 | gtrak | bloudermilk: the repl does bind some vars that aren't there otherwise |
| 20:39 | technomancy | bloudermilk: the repl also pulls in a few dependencies needed for clojuredocs etc. |
| 20:39 | technomancy | and nrepl |
| 20:39 | bloudermilk | Ah that seems like a likely source of the problem |
| 20:39 | gtrak | aperiodic: I think I've been hit by that one |
| 20:40 | bloudermilk | aperiodic: pretty sure that's what I'm experiencing |
| 20:40 | technomancy | kenneth: short answer: no, it needs to pull from a real repository in order to avoid certain kinds of problems |
| 20:40 | technomancy | ~repeatability |
| 20:40 | clojurebot | repeatability is crucial for builds, see https://github.com/technomancy/leiningen/wiki/Repeatability |
| 20:40 | aperiodic | bloudermilk: check out doall, dorun, and doseq |
| 20:40 | bloudermilk | aperiodic: Will do. Shouldn't calling map on a set evaluate it though? |
| 20:41 | emezeske | bloudermilk: map is lazy. |
| 20:42 | bloudermilk | A hah! |
| 20:42 | technomancy | clojurebot: map? |
| 20:42 | clojurebot | map is lazy |
| 20:42 | aperiodic | bloudermilk: the set will be evaluated, but the lazy sequence produced by map may not have its elements realized without something that forces it |
| 20:42 | kenneth | technomancy: what's the traditional way of dealing with JNI jars? |
| 20:42 | technomancy | weeping and gnashing of teeth |
| 20:42 | technomancy | kenneth: seriously though; generally people include statically-compiled binaries inside jars |
| 20:43 | technomancy | docs are a bit slim on this; best to follow the example of some of the existing native libs |
| 20:43 | kenneth | i'm compiling the JNI using an automated build script and placing the jar in /usr/share/java because the one published on clojars is broken |
| 20:43 | technomancy | what's the library? |
| 20:43 | bloudermilk | aperiodic: If I just want to call a function on all the elements in a set without caring about the return values, should I be using something other than map? Or is it a combination of do* and map |
| 20:43 | kenneth | jzmq |
| 20:44 | technomancy | there are working versions of jzmq; you don't need to roll your own |
| 20:44 | technomancy | I'm not sure which they are though |
| 20:44 | aperiodic | bloudermilk: i'd use (doseq [elem set] ...) |
| 20:45 | aperiodic | bloudermilk: but yeah, if you want side effects, don't use map |
| 20:45 | kenneth | technomancy: i've spent literally days trying to get jzmq to work, and only got it to work by compiling it myself |
| 20:46 | bloudermilk | aperiodic: Thanks, will do. I imagine this is something I should use sparingly? I have three functions in this chain. Maybe just the outer-most function? |
| 20:47 | aperiodic | bloudermilk: sure, you can build stuff up lazily with map and then force side effects with dorun |
| 20:48 | duck1123 | So just to clarify, If I connect to a browser repl, then I *should* be able to require my code and dependencies, correct? All I get is this. https://gist.github.com/3133277 |
| 20:48 | bloudermilk | aperiodic: Appreciate the help. Thanks |
| 20:52 | hiredman | duck1123: depends on the optimization level |
| 20:53 | hiredman | duck1123: I believe if you have adavanced opts on everything get's mangled and doing repl stuff will be very painful |
| 20:55 | duck1123 | I don't have any optimization |
| 20:56 | duck1123 | whitespace and pretty-print |
| 20:56 | hiredman | you may need to refer cljs.core or something, if require is undefined |
| 20:57 | duck1123 | It seems that I can refer to the functions directly (ie. jayq.core/$) |
| 20:57 | hiredman | what happens if you use (cljs.core/require ...) instead of (require ...) |
| 20:58 | duck1123 | same |
| 21:14 | gfredericks | I wouldn't think require would ever be defined in cljs |
| 21:14 | gfredericks | unless something has changed |
| 21:15 | duck1123 | so you're saying that I can't require namespaces from the repl? Or I should be able to |
| 21:15 | duck1123 | I'm just trying to avoid needing to fully qualify everything |
| 21:15 | gfredericks | afaik you can only do it within a (ns ...) |
| 21:16 | duck1123 | that makes cljs repl severely less useful |
| 21:16 | gfredericks | yeps |
| 21:27 | arrdem | is there a way I can have multiple (:use :as ) statements with the same :as? |
| 21:29 | emezeske | arrdem: You're, like, trying to combine multiple namespaces into a single alias? |
| 21:31 | emezeske | arrdem: I don't think you can do that, because :as is probably implemented via refer, which doesn't create a new ns, just an alias |
| 21:31 | arrdem | emezeske: to be specific, I'm using congomongo :as db and it needs a global *mongo-config* which is __not__ in somnium.congomongo, it's in config. as a result I would like to :only import the var to db |
| 21:31 | arrdem | so yes... I guess I want to merge namespaces. |
| 21:32 | emezeske | That seems like a bad idea to me; the nice thing about :use :as is that you can look at a form and trace it back to a single namespace |
| 21:32 | emezeske | Whereas if you start combining namespaces, you don't know where a form came from |
| 21:32 | emezeske | Anyway, I am pretty sure you can't do that with :use :as |
| 21:34 | arrdem | emezeske: 's ok. I'll just ditch the :as and bring it all into my local ns. %s/"bd/"/""/g and done. |
| 21:34 | arrdem | *db/ |
| 21:34 | amalloy | emezeske: that's true of :require/:as; :use/:as is generally a bad idea |
| 21:35 | emezeske | amalloy: Oh, I totally had :require/:as in my head |
| 21:35 | emezeske | Derp |
| 22:08 | clj_newb_2057290 | what happened to rule based programming langauges? |
| 22:08 | clj_newb_2057290 | why have none of them ever taken off? |
| 22:14 | nicholasf | how are people using leiningen for scripting tasks? |
| 22:15 | technomancy | nicholasf: what are you trying to do? |
| 22:16 | nicholasf | hi technomancy - I want to drop a database after a test run |
| 22:16 | technomancy | can you use test fixtures for that? |
| 22:16 | nicholasf | in this case, we have a convention that we need this scripted (for a continuous delivery system to call) |
| 22:16 | technomancy | meaning I think it should be done at runtime, not at build time |
| 22:17 | nicholasf | yeh, but regardless of the problem, how do I script a task with leiningen? |
| 22:17 | nicholasf | is there a way people generally do it? |
| 22:17 | technomancy | usually you use a plugin that already exists =) |
| 22:18 | technomancy | but if you need to write your own, the plugin guide explains how: https://github.com/technomancy/leiningen/blob/master/doc/PLUGINS.md |
| 22:18 | nicholasf | thanks mate |
| 22:18 | technomancy | sure |
| 22:50 | amalloy | unlink: a week or so ago you mentioned having some troubles with slingshot - you might be interested in https://github.com/scgilardi/slingshot/issues/24, which explained to me why i was having trouble with it |
| 23:27 | gnarmis | is anyone aware of efforts to write a lang level for clojure in racket, so we can use the awesome dr racket? |
| 23:29 | yonatane | Can I add to an existing multimethod from somewhere else? |
| 23:29 | yonatane | like from another namespace, to some multimethod that a third-party defined? |
| 23:31 | gfredericks | yes |
| 23:31 | gfredericks | you can |
| 23:31 | gfredericks | that's most of the motivation for multimethods I think |
| 23:32 | yonatane | gfredericks: so i can just hook my code to a third-party without dependency injection like that? |
| 23:33 | gfredericks | ...sure? |
| 23:33 | yonatane | if the caller used to invoke the default, it will now invoke my code if i configured it correctly? |
| 23:34 | gfredericks | sounds right |
| 23:34 | gfredericks | you should be able to experiment with that in the repl |
| 23:35 | gfredericks | put a (defmulti) in one namespace and a (defmethod) in another |
| 23:35 | gfredericks | I'm doing this right now because I've never tried it |
| 23:36 | gfredericks | and it worked perfectly |