#clojure logs

2012-07-17

00:00dsrguruso lets walk through evaluating this
00:00dsrguruoh btw
00:00dsrguruyou should set acc to 1
00:00dsrgurunot 0
00:00dsrgurusince 0! = 1
00:01dsrguruotherwise each time you multiply by n
00:01dsrguruyou're still at 0 :)
00:01dsrguruso acc just means
00:01iDesperadOacc is accumulation of the current factorial..
00:01dsrguruthis is the ultimate return value
00:01dsrgurubut what we've accumulated so far
00:01dsrguruyes
00:01dsrguruso
00:01iDesperadOi get it
00:01dsrgurugood
00:01dsrguruand trace it out
00:02dsrguruyou'll see that (fact 2) -> (recur (dec 2) (* 2 1))
00:02dsrguru-> (recur 1 (* 2 1)) -> (recur 0 (* 1 (* 2 1)))
00:02dsrguruand now that (= n 0)
00:03dsrguru(recur 0 (* 1 (* 2 1))) just equals (* 1 (* 2 1))
00:03iDesperadOok
00:03dsrguruwhich evaluates to 2
00:03dsrguruso to make something tail recursive
00:03dsrguruor the clojure equivalent at least
00:03iDesperadO(defn rrgcd [a b] (loop [a a b b] (if (= a 0) b (recur (rrgcd (rem b a) a)))))
00:03dsrguruwhat you want to do is have all the operations
00:03dsrguruthat get you closer to the base case
00:03dsrgurutake place inside the recursive call
00:03dsrgurunot outside
00:04dsrgurui.e. (recur (bla...) (bla...)) not (bla (recur 2)...
00:04dsrguruif you look at a few examples online
00:04iDesperadOah...
00:05dsrguruthe pattern will be very clear
00:09iDesperadO (defn rrgcd [a b] (loop [a a b b] (if (= a 0) b (recur (rrgcd (rem b a) a)))))
00:09iDesperadOthis definition is still not right
00:09iDesperadOMismatched argument count to recur, expected: 2 args, got: 1
00:10dsrgurucheck your parens
00:10dsrguruoh nvm
00:10iDesperadOi'm afraid the parens are right...
00:11dsrguruyou don't also include rrgcd
00:11dsrguruit should be (defn rrgcd [a b] (loop [a a b b] (if (= a 0) b (recur (rem b a) a))))
00:11iDesperadO?
00:11iDesperadOwhy there's no rrgcd there?
00:11dsrguruloop and recur work together
00:11dsrguruloop isn't just a let statement
00:11dsrguruit also sets the boundary of a new function
00:12dsrguruthat can be recursively called
00:12dsrguruwith TCO
00:12dsrguru(tail call optimization)
00:12dsrguruwhen you call recur
00:12dsrguruso recur says
00:12dsrgurucall the function I just defined by loop
00:12dsrguruand in your case
00:12dsrguruit happens to have the same parameters as the outer function rrgcd
00:13dsrgurubut that's unusual
00:13dsrguruthat's why I showed you the factorial case first
00:13dsrguruwhere it was clear
00:13dsrguruthat the loop expression was autonymous
00:13dsrguruso in this case (loop [a a b b] (if (= a 0) b (recur (rem b a) a)))
00:13iDesperadOso (loop [a a b b] ...) is a function?
00:13dsrgurudefines an anonymous function
00:13dsrguruyes
00:13dsrguruexactly
00:13dsrguruexcept
00:14dsrguruit doesn't define it
00:14dsrguruit calls it in place
00:14dsrguruit's like ((fn [a b] ...) a b)
00:14iDesperadOah
00:14dsrgurusorry I should have explained that at the beginning!
00:15iDesperadOif the loop part is an anonymous function then this function body is just [a a b b] ???
00:15lazybotiDesperadO: Oh, absolutely.
00:15dsrgurudo triple question marks trigger lazybot ???
00:15lazybotdsrguru: Oh, absolutely.
00:16iDesperadOoh
00:16iDesperadOso..?
00:16dsrgurusorry had to test that
00:16dsrguruI'm not sure I get your question
00:16dsrgurulet me give you two examples
00:17dsrguruone with loop/recur
00:17dsrguruone with a named fn
00:17dsrguruso you can see how they map up
00:17iDesperadOif the loop is a anonymous function, then it must have a function body, which i guess is [a a b b]
00:17dsrgurualthough remember that loop/recur will run faster
00:17dsrguruor at least conserve space in the call stack
00:17dsrgurubtw a named fn is the same as a regular anonymous fn except it temporarily has a name for purposes of recursion
00:17dsrguruso:
00:18dsrguru(fn rgcd [a b] (if (= a 0) b (rgcd (rem b a) a)))
00:18dsrguruis the same as:
00:18dsrguruwait
00:19dsrguru((fn rgcd [a b] (if (= a 0) b (rgcd (rem b a) a))) 3 4)
00:19dsrguruis the same as:
00:19dsrguru(loop [a 3 b 4] (if (= a 0) b (recur (rem b a) a)))
00:19dsrguruexcept for efficiency
00:19iDesperadOah
00:19dsrgurudoes that help?
00:20wingyfinally
00:20wingycljs worked!
00:20iDesperadOhelps a lot !
00:20wingyhttps://github.com/emezeske/lein-cljsbuild was really great
00:20wingymuch better than clojurescriptone if you wanna get started
00:21iDesperadOloop defines a function, binds the parameters and then call the function...
00:21dsrguruiDesperadO: or at least I'm assuming that's true because that's how the equivalent works in Scheme!
00:21dsrguruyes
00:21dsrguruand it does one more thing
00:22iDesperadOfor recur to rebind the parameters
00:22dsrguruyes
00:22iDesperadOthanks, dsrguru, you are sooooooooooo helpful
00:24dsrguruiDesperadO: 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:26iDesperadOi'm a c++ programming by profession, but now I'm amazed by clojure...
00:26iDesperadOprogrammer
00:27iDesperadOa clojure's function can do so much more than a c++'s class...haha~~~
00:28dsrguruhaha yup LISPs are so expressive
00:47wingyiDesperadO: lisp is the best thing after sliced bread
00:48iDesperadOwingy: hahahahaha...
00:48wingyone thing bad though is the jvm startup time in lein
00:48wingyi wish they can move to node.js instead for lein .. isn't cljs designed for running cli tools
00:48wingytechnomancy: ^ :)
00:52yonataneHi wingy, do you ever sleep? ;)
00:52wingyyonatane: couldn't sleep since i couldn't get cljs working
00:52wingybut now its fixed
00:52wingyso now i have to play with it some more before i sleep
00:53wingyyonatane: have you been stalking me?
00:53ivantechnomancy might think about it after you port 20MB of Java to CLJS
00:54wingyivan: :/
00:55wingyit's using a lot of java libs?
00:55ivantake a look inside leiningen's jar
00:55ivanit's got all that maven stuff
00:55wkellyand ant stuff
00:56wingyplan b … let's just kill the startup time
02:42iDesperadOhi, `lein search` always returns with exception with clj-http: status-404
02:42iDesperadOI use a vpn to get access to the repo
03:00wingyhow do i add a css file in hiccup?
03:01wingythe api doesnt mention css files http://weavejester.github.com/hiccup/hiccup.element.html
03:03wingyoh: http://weavejester.github.com/hiccup/hiccup.page.html
03:08ro_stwhat do you think of hiccup so far, wingy?
03:11akhudekI greatly prefer enlive
03:11ro_stthey do different things, don't they? enlive is more for parsing/scraping?
03:11akhudekro_st: not really, enlive is great for templating
03:12ro_sti'm planning on using enlive/enfocus with a common set of templates
03:12akhudekthe big deal with enlive is that a designer can give you pure html and you don't need to modify it directly
03:12ro_stallow the server to render pages, but also allow the client to re-render them or parts of them
03:12akhudekthat's a good idea
03:12akhudekwas thinking of something similar myself
03:13akhudekwe use a lot of enlive at my work
03:13ro_stpart of my app is a store, i'm planning to do what the new basecamp does
03:13ro_stwith pjax
03:13ro_stwhere it only loads the 'center' on page nav
03:14ro_stmakes it really fast
03:14akhudekI'm not very familiar with basecamp sadly, but enlive on both server + ajax client seems pretty natural
03:14ro_stwhat i like about the enlive/enfocus strategy is i don't need to decide where things get rendered
03:14ro_stand i can change my mind easily once i do
03:14akhudekI've found cljs to be very undocumented this point overall
03:14ro_stmakes things a lot more manageable
03:14ro_styeah
03:15ro_stcljsbuild's crossover feature is great
03:15akhudekthere are a number of places where I could also see cljs and clj sharing code directly
03:16ro_sti'm doing all my 'model' code in clj and testing with midje and midje-mode
03:16akhudekenfocuse/enlive templates and snippets, and also validation/state control code
03:16ro_stand it's auto compiling all those ns's to js as well
03:16akhudekhuh, so you do share code between client and server?
03:16ro_stso hopefully i'll only need to actually develop the glue and service layer code in cljs directly
03:17ro_sti'll be able to build all my templates in the repl with enlive
03:17ro_styes
03:17ro_stit's very easy to configure
03:17akhudeknice, 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:18ro_sti'm re-doing a google closure javascript codebase as cljs
03:18ro_sti'm coming out at less than a 1/6th of the code, including tests :-)
03:18akhudekour client code is jquery, which makes it a bit more painful to move over… maybe
03:19ro_stmy advantage is that i'm already familiar with the closure compiler and library
03:19ro_stour CI et al already has all that set up
03:20akhudeknice, that seems like it would make it a bit easier
03:20ro_stdefinitely
03:20akhudekdo you know if closure provides multiple file upload in IE8?
03:20ro_sti don't, sorry
03:21akhudekdarn, no worries. IE8 is very annoying.
03:21ro_stindeed
03:21ro_stunfortunately it accounts for close to a third of our userbase
03:21ro_stthankfully ie6/7 are less than 1% combined
03:21akhudeksame or worse here :-(
03:22akhudekwe don't support 6/7
03:22akhudekalthough I think 7 still mostly works last I checked
03:24ro_stwhat's the simplest way to find the index of an item in a set?
03:24akhudekset's have no numerical index
03:24akhudekor any index really
03:24akhudekthey compare on the items they contain directly
03:25ro_stoh, my mistake. index of an item in a vector
03:25ro_stin this case, i know for sure the vector only contains one copy of each item in it
03:26malcolmsparks(just a test)
03:26akhudekI can't think of any easy way outside of combining map and some
03:27ro_sti'm using seq-utils' positions fn now
03:27ro_stbut 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:29akhudekisn't seq-utils deprecated?
03:30akhudekeasiest direct way I can see right now is
03:30akhudek,(let [items (map vector (iterate inc 0) [:a :b :c :d])] (some (fn [[i v]] (if (= v :c) i)) items))
03:30clojurebot2
03:30akhudekcould make it into a function easily enough
03:31akhudekor just copy the seq-util function if it works for you
03:31ro_sti guess it takes that much code because of the lazy nature?
03:31ro_styeah i copied it
03:31ro_stit's not much: https://www.refheap.com/paste/3638
03:32hiredman,(doc keep-indexed)
03:32clojurebot"([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:32amalloyyou want ##(doc keep-indexed), but really if your code needs the index of something you're usually doing something wrong
03:32lazybot⇒ ------------------------- 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:33ro_stwell, 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:33ro_stand 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:34ro_stgood ole imperative style. i'm very keen to use a better method if one exists
03:34ro_sti 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:34akhudekhow many elements are in this vector?
03:35ro_sttens at most
03:35akhudekunless you have millions of queries per second, I wouldn't worry too much about performance here
03:35ro_stanother constraint: this code runs in cljs primarily
03:36ro_stoh, indeed. showing intent in the code clearly is my main concern
03:36akhudekdrop-while + fnext
03:37akhudekuse let-if or similar if you want to check the case where there is no next
03:37ro_stum, 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:38ro_stedge 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:38akhudek,(fnext (drop-while #(not= :c %) [:a :b :c :d]))
03:38clojurebot:d
03:39hiredmanro_st: keep :c and :c's index in the ref, and then just inc :c's index
03:39ro_stoh right. drop-while finds the ref, and fnext grabs the next one
03:39akhudek,(fnext (drop-while #(not= :c %) [:a :b :c]))
03:39clojurebotnil
03:39ro_stthat's very elegant, akhudek!
03:40akhudekif you need to check that no :d exists, just do if-let
03:40ro_sthiredman: that has the problem of me needing to determine the index, which i've been told is Naughty :-)
03:40hiredmanro_st: how do you not know the index? do you not start at 0?
03:42akhudekI'm off to sleep, night ro_st
03:42ro_stthe fn returns the element, which is then kept elsewhere. the next time the fn is used, i pass in the previously returned element
03:42ro_stsleep well
03:43ro_stso using index is adding complexity. akhudek's drop-while + fnext solution works a charm
03:43hiredmanro_st: if you need the index, why not pass it around?
03:43ro_sti don't need the index :-) i need the element
03:43ro_sti was using the index before because that's how my n00b imperative brain said i should do it
03:44hiredmanso why are you using a vector?
03:44ro_stthat's how it comes off the wire
03:44ro_stdeserialised json
03:45hiredmanthere is nothing imperative about indexed access
03:47ro_stok :-) 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:47ro_stthat's imperative-y
03:47hiredmanit is not
03:47ro_stoh
03:47wingyro_st: hiccup is nice
03:47ro_st-writes that down-
03:48ro_st-grin-
03:48wingyare you using enlive?
03:48ro_sti plan to, yes
03:48ro_sthaven't gotten there yet
03:48wingyhmm .. im going to use bootstrap
03:49ro_stwingy: http://lightglitch.github.com/bootstrap-xtra/
03:49wingyand thinking that writing HTML directly is more compatible with bootstrap
03:49wingywow
03:49ro_stsome nice stuff in this one
03:50wingyro_st: is it maintained?
03:50wingy8 months from last activity
03:50ro_stdoesn't look like it :-(
03:51wingysuch projects are risky
03:51ro_stagreed
03:52ro_st,(if nil 1 2)
03:52clojurebot2
03:53wingyanyway .. 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:53ro_stweird. i had (if var-name (stuff) (things)) where var-name is nil and (stuff) got called
03:53ro_stswitching to (if-not (nil? var-name) (…)) worked
03:53ro_stbootstrap is predominantly css and js, isn't it?
03:55wingyhavent used it yet but yeah its heavy in css
03:55ro_stwingy, check kibit out
03:55wingyand using jquery for animations
03:57wingyhttps://github.com/jonase/kibit/
03:57ro_styup
03:57wingywhat about it?
03:57ro_stit analyzes your code and tells you where you can simplify things
03:57wingyi see
03:57wingycool
03:57wingydoes it work?
03:58ro_steg, instead of (map #(:id %) […]), it'll tell you to use (map :id […])
03:58wingycool
03:58ro_stor (= (:id foo) =) -> (zero? (:id foo))
03:58ro_ststuff like that
03:58ro_stsorry
03:58wingyneat
03:58ro_st(= (:id foo) 0) -> (zero? (:id foo))
04:02wingyro_st: (when (System/getenv "PORT") (Integer. (System/getenv "PORT"))) instead of: (if (System/getenv "PORT") (Integer. (System/getenv "PORT")) nil)
04:02wingyso cool :)
04:02wingyi have to play with core.logic myself when everything is setup
04:03ro_stdid you watch edmund jackson's intro to core.logic?
04:03ro_stsearch vimeo for clojure and sort by date. bottom of page 1
04:04ro_streally cool talk
04:04wingythe guy who talked really fast?
04:04wingyand something asked him to slow down at the beginning?
04:04ro_stthat's the one
04:04ro_stwith the south african accent
04:04wingyyeah ive seen it
04:05wingyclojure.core seems to allow us to code in a different way
04:05wingyin a very declarative way
04:05ro_stit's very interesting. definitely an area i want to play around in
04:05wingyyeah i hope i can use it heavily in my app
04:05malcolmsparksit was funny because there were a lot of europeans in the room who were really struggling with the speed of English
04:06malcolmsparksone German guy stood up and put both hands up pleading with the speaker to slow down :)
04:06wingyOTOH he talked really fast :)
04:06ro_stthey can watch it on vimeo now and slow it down
04:06wingymalcolmsparks: you were there?
04:06malcolmsparksbut it was a superb talk - hopefully someone can make a transcript one day
04:06malcolmsparksyes
04:06wingycool
04:06ro_sti kept up ok, but that's because i'm used to that accent. my own is quite similar to his
04:06wingymalcolmsparks: how many people were there?
04:07malcolmsparksyou don't see the baffled audience from the video :)
04:07malcolmsparksalmost 200
04:08ro_sti would love to have been there
04:09ro_sti can count the number of clojure folks in cape town that i know of on one hand!
04:09malcolmsparksanyone know of a Midje talk? I'm really enjoying it - only just starting playing with it - it's very cool
04:09wingyhttp://www.hackerne.ws/item?id=2683007 read ynniv's post
04:09ro_sthave you seen marick's vids, malcolmsparks?
04:09malcolmsparksno - guess I should have googled before chatting
04:09malcolmsparksI'll look them up tonight
04:10ro_stare you using emacs, malcolmsparks?
04:10malcolmsparksnever really used midje before, didn't realise how powerful it was
04:10clgvmalcolmsparks: the midje wiki is quite good in explaining
04:10ro_stit ROCKS. i'm doing TDD with it
04:10malcolmsparksah, train in - gotta go
04:17wingywow .. bootstrap is really simple to use
04:17wingyalways used big frameworks like extjs/sproutcore to make good looking buttons and now it's just a html class i need to add :)
04:17wingytowards simplicity like clj!
04:20clgvbootstrap?
04:20wingytwitter bootstrap
04:21wingyhttp://twitter.github.com/bootstrap/components.html
04:21clgvah ok. read that before
04:22wingydo you guys feel that html should be html and not in clj like hiccup is doing?
04:23ro_stlong term, i think it's good to keep the markup separate from the logic
04:23wingyyeah
04:24ro_sthiccup 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:25wingygood analysis
04:25ro_stlots of designers use (barf) dreamweaver or similar to accomplish tasks like that. it's nice to be able to keep that ability
04:26wingyro_st: OTOH is it really desired to have pure designers doing HTML?
04:26wingyisn't it something a clojure dev can do
04:26wingyhe knows the logic and display
04:26ro_stdo you want to pay a clojure dev to do something a markup monkey can?
04:26ro_stno disrespect to markup monkeys -grin-
04:27ro_stwhat do you gain by using hiccup over raw html and enlive?
04:27wingysince im doing the markup atm i get joy :)
04:27ro_stis that gain worth losing the flexibility of pure html throughout your dev lifecycle?
04:27wingyi guess not
04:28wingyyeah
04:28ro_stthe thing about code is you want as little of it as possible
04:28ro_sthiccup is code, it's not markup
04:28wingyright
04:28ro_stthat's what makes enlive great. your code is just a set of transformations, which is much easier to test
04:29wingyand being able to use pure HTML is kinda neat
04:29wingyyou know what is going on
04:30ro_stalso, pure html/css is much easier to work with in chrome
04:30ro_styou can even use chrome dev tools' save-file features
04:30wingybut then you could say that about js vs cljs :)
04:31ro_stchrome dev tools get thoroughly spanked by emacs+repl
04:31ro_stwhen it comes to logic stuff
04:31ro_stthats just my opinion, of course :-)
04:32ro_stbut it's one formed from experience of both worlds
04:33ro_sti wonder if cljs supports source maps
04:33wingyyeah i also think that writing pure html is better for long term maintenance
04:33ro_stchrome dev tools has excellent support for it. shows you your source language (ie, cljs) right there in the scripts panel
04:33clgvro_st: they are working on source maps as far as I heard
04:34wingywhen will that be ready you think?
04:34ro_stno clue
04:35wingyok new policy
04:35wingy"close to the metal"
04:35ro_styes
04:36wingyhtml, css, cljs but using js libs without transformations, clj using java libs without tranformations
04:36wingy;)
04:37ro_stdo you use a css pre-processor?
04:38wingyno .. im not that great in styling
04:38wingybootstrap is using less
04:38wingybut i dont think i will have to style that much
04:38wingyhttps://wrapbootstrap.com/
04:39ro_stoh wow, nice resource
04:39wingyhttp://bootswatch.com/
04:39wingyi feel this is way better than styling manually
04:39wingywe use bootstrap .. and everyone can provide styling template
04:40wingythey could open a new market
04:41ro_stboth great resources. bootswatch is realy nice
04:41wingyro_st: now i recall what rich hickey said about complecting
04:42wingyperhaps having logic and presentation in one is complecting things
04:42wingyjust like you dont want to have logic and data as one like in OOP
04:42ro_styes, exactly
04:44ro_stohpauleez did something interesting in his demo-shoreleave-findit project
04:45ro_sthe uses erb (from ruby) and rake to pre-compile static html pages, using layouts and partials
04:45ro_stthen cljs uses enfocus to munge that markup clientside
04:45ro_sthe could just as easily have used enlive to do the partials work, actually
04:53pyrmorning
04:54pyrcan members be removed from a clojars group ?
04:54pyr(from clojars i mean)
05:00clgvpyr: I only see an "add member" button over there
05:02pyrclgv: yup, me too
05:05kralnamaste
05:08ro_sttashi delek!
05:34augustlare there any solutions to have "lein test" keep a JVM running and automatically reload changed files, for faster test runs?
05:37ro_stlazytest
05:37twhumeI'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:37ro_stare you using clojure.test or midje, augustl?
05:38augustlro_st: clojure.test
05:39augustlmostly because of use-fixtures with :once, haven't found an equivalent for midje
05:39ro_sti'm using lein-midje with lazytest, which auto-runs when tests or the files the tests load change
05:39ro_stmidje has the background macro
05:41ro_sthttps://github.com/marick/Midje/wiki/Setup%2C-Teardown%2C-and-State
05:42ro_stfor example: https://www.refheap.com/paste/3639
05:42ro_stthis runs all the facts inside the binding, so that the production code being tested uses the test database instead of the production one
05:43ro_stand it only loads the fixtures once
05:43ro_styou can use :facts instead of :contents if you want the work to be performed per fact
05:43augustla fact is a test?
05:43ro_styes
05:44augustland :contents is one test namespace?
05:44augustlor the entire run?
05:44ro_stone test namespace
05:44augustlis there a way to run some code before and after the entire test suite?
05:44ro_stas with everything in clojure, it's all namespace bound
05:44augustlcurrently 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:45ro_styou could probably use a separate namepsace and memoize the calls
05:45augustlgood point
05:45ro_stso first calls do the work, subsequent calls just return whatever work was done the first time
05:45ro_stif you use emacs, there's midje-mode too
05:46augustlwhat does it do?
05:46ro_strun individual facts right there in your buffer
05:46ro_stit pastes the output as comments above the fact
05:46ro_stit uses your active repl
05:46augustlah
05:46ro_stthe 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:47ro_stlazytest helps with regression testing when i refactor stuff
05:47augustltypically memoization is done via function calls I suppose?
05:47augustlwhich checks a ref for nil etc
05:47ro_styup. i've not done memoization with clojure before, but the concept is pretty simple
05:48augustlperhaps there's something built-in
05:48ro_sthttp://blog.fogus.me/2012/07/13/announcing-core-memoize-version-0-5-2/
05:48ro_streading the tests for this code should give you a thorough background on the topic
05:53ro_stso 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:54ro_stright now the file has (def name {…}) in it, and i'm using load-file
05:56vijaykiranhttps://github.com/technomancy/leiningen/blob/master/leiningen-core/src/leiningen/core/user.clj#L25
05:56vijaykiranro_st: something like that ^ ?
05:56ro_stsuperduper!
05:57vijaykiranleiningen loads user.clj profile, I guess that's something similar to what you are looking for
05:57ro_stit's precisely what i'm after, thanks very much
05:57vijaykiranyw
05:59augustlro_st: I see, thanks
06:02ro_stheck i should really make a screencast showing all this working together
06:08twhumeAnyone know why this code should lead to high CPU usage? (deref (future (loop[a 1] (recur a)) :done!) 1000 :impatient!)
06:11cshellinfinite llop?
06:11cshellinfinite loop?
06:11ro_stthe loop recur is infinite
06:11ro_strecur should be wrapped inside a conditional that checks whether recur should happen or not
06:12cshellit needs to increment the a value
06:12cshellor do something with it
06:13ro_st'(loop [a 1] (if (< a 3) (recur (inc a)) a))
06:13ro_st,(loop [a 1] (if (< a 3) (recur (inc a)) a))
06:13clojurebot3
06:17augustlit would seem that irccloud.com just died :)
06:17cshellyep
06:17twhumeshell, 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:17twhumes/shell/cshell/
06:17ro_sti just got a pingdom alert for my vps as well
06:18twhumeIn 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:20ro_stright
06:20ro_sti've no experience with futures, i'm afraid
06:24augustlro_st: are you using lein 1.x and lein-midje?
06:24augustlseems I need lein-midje both as a plugin and dev-dependency
06:25augustlalso, is there a way to run midje tests with "lein test", or make "lein test" throw errors?
06:26Fossithey will be run
06:26Fossidon't know what you mean with "errors"
06:26Fossilike a negativ return code?
06:27ro_sti'm using lein2 for midje, augustl
06:28ro_staugustl: https://www.refheap.com/paste/3640
06:28augustlFossi, 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:28ro_stwith that in place, i can run lein2 midje —lazytest
06:29ro_sti believe midje will run any existing clojure.test tests as well
06:29ro_stso transitioning is easy
06:30Fossiyes
06:30Fossiand you can use midje tests with lein test as well
06:30Fossiat least with the version/setup we are using
06:31Fossinot sure what that includes though
06:31Fossibeen a while since i touched it ;)
06:31Fossiafair lein midje is just nicer output
06:31ro_styeah
06:32ro_stthe 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:32Fossinice
06:32ro_stso even with a massive suite, the testing is still fast
06:36augustlro_st: how would you do this with midje? http://pastie.org/4270944
06:36augustlseems midje doesn't have a concept of "tests"
06:37augustlmy 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:38augustlthese 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:39ro_sthttps://www.refheap.com/paste/3641
06:41augustlro_st: so I can have anything I want inside a "fact"?
06:41augustllet, if-let, nested lets, etc?
06:42ro_styup :)
06:42augustlnot sure if I like the => syntax.. It's not very lispy
06:42ro_stit grows on you
06:42augustl'foo operator bar' that is
06:43ro_stin emacs, it's bright red, so it's easy to distinguish tested code vs checker code
06:43augustlthe only thing I like is the checkers :)
06:44augustlperhaps there's a more generic collection assertion library I can use
06:44augustllike "vector contains {:foo 123}" and so on
06:51augustlro_st: do you know if midje supports a more traditional syntax?
06:52augustlI'd prefer (=> foo bar) to foo => bar
06:54ro_sti don't think so
06:54ro_st-shrug- i like it the way it is
06:58ro_staugustl: i suggest scanning through the midje wiki to get a sense of why brian did it they way he did
06:58ro_sthe provides a rationale and lots of great docs as well
07:07augustlro_st: I see, thanks :)
07:08ro_stalso, midje-mode #justsaying
07:08ro_stwww.youtube.com/watch?v=HK2HG9U3anA
07:44ro_sti 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:44ro_stdisj then conj?
07:46clgvro_st: yes.
07:46clgvro_st: for a map you could use update-in, but in a set you can not specifically adresse one of its elements
07:50ro_stlike this? https://www.refheap.com/paste/3643
07:50ro_sti realised the set won't be able to remove the node if i only give it the updated version
07:53clgvseems to do the job.
07:54clgvbut are you sure that the set is the right datastructure in this case?
07:54ro_sti plan to use sorted-set-by and provide a custom sorting fn
07:55ro_sthaving it sorted in a particular fashion is a User Story
07:55ro_sti definitely have only one of each element in the structure, so a sorted-set seemed the right fit
07:56clgvthere is also sorted-map-by where you could directly address elements via a key (e.g. id)
07:56ro_sti want to be able to throw nodes at it and let the sorting fn figure out what the order should be
07:56ro_sti 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:59clgvro_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:00ro_sti guess with sorted-map-by i can use update-in instead of disj-then-conj
08:00clgvright
08:03ro_stsorted-map-by seems to pass the keys to the comparator?
08:05clgvro_st: oh right. I would have assumed that you get both
08:05ro_stlemme just set a breakpoint and see
08:06clgv&(sorted-map-by (fn [x, y] (println "x =" x "y =" y) (compare x y)) :bla 10 :blubb 20)
08:06lazybot⇒ x = :blubb y = :bla {:bla 10, :blubb 20}
08:11mikemI 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:12ro_st(apply fn (take 7 (constantly anything)))
08:12ro_st*shoots from the hip*
08:13mikemro_st: haha, epic fail :-)
08:13mikemdidn't work
08:14ro_st,(take 3 (constantly "five"))
08:14clojurebot#<ExecutionException java.util.concurrent.ExecutionException: java.lang.IllegalArgumentException: Don't know how to create ISeq from: clojure.core$constantly$fn__2351>
08:14ro_stdamnit. i thought i understood constantly :)
08:16ro_stif 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:16ro_stlemme know when you find out how :-)
08:17vijaykiran,(take 3 (repeatedly (constantly "five")))
08:17clojurebot("five" "five" "five")
08:17vijaykiran:)
08:17ro_strepeatedly!
08:17ro_st(apply fn (take 7 (repeatedly (constantly anything))))
08:17ro_stthat should do it
08:18ro_stalthough that's almost as long as
08:18ro_stanything anything anything anything anything anything anything
08:18ro_st:)
08:20mikemvijaykiran, ro_st: that doesn't actually work, midje explodes with a StackOverflowError
08:20mikembut, valiant effort!
08:21vijaykiransorry, I didn't know the context - just trying to give a fix for exception that clojurebot threw
08:21ro_sthe has (fn-name <7 anythings in a row>) and wants to know if he can instead programmatically generate 7 anythings
08:22ro_stand pass them as args to fn-name
08:22clgvmikem: there are aliases for "anything", I would use the shortest one, if the amount to write is a problem
08:23mikemthe catch is it's in a (provided) block in Midje
08:23mikemclgv: oh, what are the aliases?
08:23clgvshould be in the wiki
08:24y3didisclojure hiatus is depressing =/
08:25ro_stclgv, mikem: only synomym is 'irrelevant'
08:25ro_sthttps://github.com/marick/Midje/wiki/Checkers
08:25clgvdamn
08:25ro_stnothing stopping you making your own :)
08:25clgv"any" or "_" would be good ^^
08:25clojurebotCool story bro.
08:25ro_st(def :P anything)
08:26clgvthat wont work because :P is not a symbol :P
08:26ro_stworth a try
08:26ro_stlooks like sorted-map-by's comparator only takes the keys as args
08:27mikemI guess I was thinking more of a catch-all which means any number of arguments and anything
08:27mikemin case the function gains or loses arguments in the future
08:27clgvro_st: yep, that was the point of the above example with sorted-map-by ;)
08:27ro_stthat sucks. i need to be able to sort based on data in the values
08:28ro_stlooks like sorted-set is the way, then
08:28clgvro_st: well, do you need to keep the container sorted or is sorting when accessing all elements an option?
08:29ro_sti'd like to keep the container sorted
08:29ro_stbecause 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:30ro_stsorted-set-by's comparator receives the values, which works for me
08:39cshellDo you ugys find it easier or harder to code/develop with music on or off?
08:40ro_stdepends on the music i guess. sometimes i must have silence. other times, jazz is great
08:40Bronsaprog metal is good too
08:40ro_stand the inception soundtrack is awesome if you want to feel like you're saving the world
08:40Bronsageneraly everything with very little to no lyrics at all
08:41mprenticeclassical instrument covers of rock == great coding music
08:41mprenticevitamin string quartet, apocalyptico
08:41cshellYeah, 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:42cshellinteresting, thanks guys!
08:42ro_stoo nice mprentice
08:43ro_sti tried to grab some classical but it's always such a mixed bag
08:43ro_stdon't want hectic, jarring music. i find that the mellow stuff is mixed in with the crazy stuff
08:44mprentice:D
08:44ro_stthese guys? http://coda.fm/artists/143
08:44cshellI also find that if I know the cd by heart I can focus, but new songs with lyrics seems to distract me
08:44ro_stsame here. i can code to coldplay no problem cos i know it all so well
08:45cshellprobably because the intervals/changes are expected by our brain
08:45cshelland new music surprises our brain
08:57edoloughlinI 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:02cshellDo all namespaces in the application get compiled or do they only get loaded when accessed?
09:02lnostdalwhat kind of music?
09:02lnostdal..music with lyrics ruins everything for me for sure
09:03cshellme too
09:06vijaykiranhmm . interesting - http://faculty.nipissingu.ca/stange/courses/P2267/BackgroundMusic.pdf
09:06augustlhmm, 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:06vijaykiran"The effect of background music and background noise on the task performance of introverts and extraverts"
09:10cshellaugustl: You can write your functions to take whatever comes out of the library
09:10cshelli use congo mongo and what comes out is just a map
09:11cshelland I pass that map in when I want to do a search
09:21jolyvijaykiran: I'm having trouble reading that article because of too much background noise. :P
09:23augustlcshell: I'm talking about the db operations, the connection is implicit
09:23augustlyou call connect! one time and then all future calls will use that connection
09:23cshellah, I don't do that with congo-mongo
09:24cshellI call make-connection and bind it to a var
09:24goodieboyanyone 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:24augustlcshell: what's the API for passing that connection to queries? a with-connection like thing?
09:27pyri 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:27pyri see the class in the jar, and when manually pulling the jar in eclipse to try out i see the class correctly
09:27clgvpyr: you have to load the namespace in advance
09:28clgvpyr: provided it was not AOT-compiled
09:30pyrclgv: the namespace in which the records are defined is aot compiled
09:30duck11231goodieboy: If you have a file in resources/ (on your classpath) you can call getSystemResourceAsStream on the classloader
09:31clgvpyr: humm, do you see the class files in filesystem or in the dependency-jar?
09:31goodieboyduck11231: OK, thanks. How can I access the classloader?
09:31pyrclgv: yes
09:31clgvpyr: you used Class.forName?
09:32pyrnope, it breaks at import
09:32pyrwhen i say import 'org.something.namespace.RecordName'
09:32pyri get 'cannot find symbol'
09:33pyrsymbol: RecordName
09:33pyrclass: org.something.namespace
09:33pyrs,class,location
09:33duck1123,(Thread/currentThread)
09:33clojurebot#<Thread Thread[Thread-55,5,main]>
09:34duck1123,(.getContextClassLoader (Thread/currentThread))
09:34clojurebot#<AccessControlException java.security.AccessControlException: access denied ("java.lang.RuntimePermission" "getClassLoader")>
09:34duck1123goodieboy: that works if you're not in a sandbox
09:34goodieboyduck1123: cool thanks!
09:35duck1123there may be a better way
09:35clgvpyr: weird.
09:36pyrclgv: indeed, will dig further
09:36uvtcWould you recommend a Clojure novice use Noir, or straight Ring + Compojure?
09:36uvtcAlso, good morning, #clojure. :)
09:37uvtcEr,... good *, for folks in different timezones.
09:38clgvuvtc: as far as the advertisement says Noir is on a higher level above Ring + Compojure
09:38uvtcweavejester: is it common to write web apps using just Compojure, rather than a "framework" built atop it?
09:39luciani tend to take all the help i can get
09:40duck1123All 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:40cshelluvtc I just started with noir
09:40cshellit has a lot of helper methods that you would need for ring and compojure
09:42uvtcMm. Thank you.
10:02sh10151Any thoughts on when to use bindings/vars and when to use explicit function parameters?
10:03sh10151use case is an xslt transform function -- (transform stylesheet input output)
10:03sh10151need to provide an interface for xsl:param and the like
10:11sprocIf I have two loops, nested, and I am in the inner loop, how can I recur back to the "parent" loop?
10:12sh10151I don't think you want to do that...
10:12tmciversproc: you can't in Clojure
10:12sh10151do you have some code to paste?
10:13sh10151Generally you don't want to write recur at all
10:13sh10151the higher-order functions take care of nearly all use cases
10:13sprocI'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:14sprocBut I need that processed data in the larger loop.
10:14sh10151it sounds like you may need to use reduce then
10:14sh10151it's hard to say without any code
10:15sh10151or for example http://clojure.github.com/clojure/clojure.core-api.html#clojure.core/iterate
10:17goodieboyduck1123: 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:19sprocsh10151: http://pastebin.com/ji5V01ig
10:20sh10151yea, i think a reduce is the right way to go
10:20sh10151the accumulator value is the {:col-widths :current-col} tuple or something
10:22sprocYeah, there is a column loop within a row loop, so :col-widths accumulated that while :current-col tracked which column to process next
10:22sh10151shouldn't even need the current-col?
10:22sh10151that kind of iteration should be taken care of by map/reduce/for whatever
10:22sh10151main thing is to build up the col-widths map
10:23sprocI used it so I could use the ResultSetMetaData.getColumnName function
10:23sproc(which requires the index)
10:24sh10151sure but use map-indexed for that
10:25sh10151(map-indexed (fn [i thing] (str i " is " thing)) ["a" "b" "c"])
10:25sh10151("0 is a" "1 is b" "2 is c")
10:25sh10151there are other functions like that too but i can never keep them straight among python scheme and clojure
10:26sprocAh, I see; that will be nice. I am new to Clojure and wasn't aware of that
10:26sh10151it's ok
10:26sh10151main thing to remember is that you almost never need to write loop/recur yourself
10:27sprocI was looking at loop/recur like using auxiliary/helper recursive functions
10:27sh10151Sure, but the recursions themselves have already been written for you
10:27sh10151the big ones to understand are map and reduce
10:28sh10151if you can start looking at nested loops as combinations of those, it should come quickly
10:28sh10151frankly I found it easiest to learn that with Haskell since it's very difficult to really do it another way :)
10:28duck1123clojureatlas.com is a good resource for when you know what type of function you need, but not what it's called
10:29sprocAlright, thanks. That will give me some good stuff to think about
10:30sh10151Anytime. Do you program JavaScript? There's actually map/reduce functions in most JS libraries
10:30sh10151my frontend code bears an (un?)fortunate resemblance to Lisp nowadays
10:32sprocThe 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:32sh10151is that the server-side framework?
10:33sh10151my work is all JVM all the time pretty much :(
10:33_nmmnnode.js is massive jungle of callbacks and js caveats, imo
10:33sprocYeah, it's neat because it serves requests in a non-blocking way and eliminates the need for multithreading for lots of requests
10:34duck1123you could also use Aleph with Clojure for that
10:34sh10151pretty sure nginx does that too :)
10:35pipelineyou mean sproc
10:35pipelinenode.js only gives you a single thread
10:35pipelineso you had BETTER damn well write non-blocking code
10:35_nmmntrue
10:35pipelineor else your app stops working
10:35_nmmni think its similar fab as ruby
10:35pipelinebelieve it or not this is a trivial model to handle in any language
10:35sh10151If you do Perl this is a pretty good book on functional programming/higher order functions: http://hop.perl.plover.com/book/
10:35pipelinejust don't call fork() haha
10:35pipelineperl makes the whole non-blocking event-based apps easy as hell, and has done for 10+ years: POE
10:36pipelinethis is not a new model of development
10:36pipelineit's just that node.js gives new freedom to people who were once relegated to "front end" development
10:36sprocI 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:36pipelinethere 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_nmmntrue
10:36sh10151select() has been around since early BSD
10:36_nmmnstill im keeping myself from js as far as possible =]
10:36sprocIn languages without closures it can be done but would seem to be more painful.
10:37pipeline(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:37sprocYeah, there are problems getting helpful stack traces
10:37sh10151prototype.js :(
10:45cshell_Can you extend a protocol on a def record?
10:54sprocduck1123: Neat site
10:56duck1123It'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:56kreig1earthlings!
11:09gfrederickscshell_: I should think so
11:25dsevillaall
11:25dsevillaI'm searching for an introductory slides on core.logic that I found the other day, but I don't remember where
11:25dsevillathey start comparing functions with relations
11:26dsevillafunctions only return one value
11:26dsevillarelations relate different input parameters and result values
11:26dsevillaI searched euroclojure, clojure/conj, etc., but now I can't find them
11:26dsevillaany of you would remember that one?
11:27woodzHere? https://github.com/ejackson/EuroClojure-2012-Talk
11:27pyrtechnomancy: around ?
11:27scriptordsevilla: this one https://github.com/relevance/clojure-conj/blob/master/2011-slides/ambrose-bonnaire-sergeant-introduction-to-logic-programming.pdf
11:27dsevillawoodz: Yes, I found those, nice slides, but these were not
11:27scriptoryou'll have to download the pdf, but I'm pretty sure it's that one
11:28sprocWhy doesn't (get 1 {1 2 3 4}) return 2 instead of nil?
11:28dsevillascriptor: ahhhhhh these are!
11:28scriptor,(get {1 2 3 4} 1)
11:28clojurebot2
11:28dsevillascriptor: thanks!
11:28scriptordsevilla: no prob
11:28dsevillawoodz: thaks to you too
11:29scriptorsproc: the arguments go the other way http://clojuredocs.org/clojure_core/clojure.core/get
11:29dsevillavery nice talk, btw
11:48technomancypyr: sure
11:49technomancyaugustl: you can alias "test" to "midje" in project.clj
12:07pyrtechnomancy: i'm trying to build java + clj projects
12:07pyrtechnomancy: where the java part loads classes defined in the clj files
12:07pyrtechnomancy: and this with leiningen, goes without saying
12:08pyrtechnomancy: i'm using lein2 and i am seeing a few weird behaviors
12:09pyrtechnomancy: 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:10pyrtechnomancy: then i was never able to load a class defined through deftype in the java source code
12:10technomancyyeah, out of the box leiningen assumes you are going to compile java first
12:10technomancybecause the java parts of a project are typically the legacy ones
12:10pyrtechnomancy: which makes snese
12:10technomancyyou can change it with :prep-tasks; lemme see
12:10pyrsense
12:10technomancy:prep-tasks ^:replace ["compile" "javac"] ; <- in project.clj should work
12:11pyrok
12:11pyri will start by trying that out
12:23technomancyI actually had never tried changing :prep-tasks like that; always nice when I see something like that work the way it should =)
12:33m0smithhi all
12:34m0smithI 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:35m0smithany hints on how to find out what the real problem is
12:35m0smith?
12:36S11001001m0smith: I'd start with the line numbers in the stacktrace that are actually in your code
12:36m0smithThe compiler is not spitting out a stack trace
12:37m0smithI am compiling in emacs using clojure-jack-in
12:37m0smithCc-Ck
12:37S11001001m0smith: then use C-c C-l instead
12:37m0smithok
12:44m0smithThat 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:46S11001001m0smith: compiler failures also have source location
12:49harjaHello, 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:51harjaI 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:51harjawould a def:d vector be fine?
12:53joegalloharja: 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:54harjaah the parens :) https://gist.github.com/2a31909da1ff277a8384
12:54scriptorharja: so in your example, use-it should get the data returned by get-stuff?
12:54harjathat's a part of a quil script
12:54S11001001harja: I would use fewer intermediate bindings
12:54S11001001in fact, I would use only two in your example, harja
12:55joegalloharja: generally you just use arguments to functions to hold that stuff, nothing global. (do-some-with (this-value-im-generating-right-now))
12:55scriptorwhat's wrong with the intermediate bindings?
12:55harjajoegallo: yeah, but how do I make the framework call on the (draw) method with my stuff in it?
12:56harjanormally I would have done it using args and recursion
12:56joegalloharja: close over the results. hand them a function or whatever that will do the whole thing.
12:56S11001001scriptor: draw binds *everything* to be passed as an arg; has same problem as comments that narrate code directly
12:56joegallo(.setIntoBlah some-framework-class #(do-something-with (this-value-im-generating-right-now)))
12:57harjaokay, got it. is there a way to do it in quil?
12:57joegalloclojure'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:58joegalloharja: 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:59scriptorS11001001: those comments are considered bad because they're superfluous, since the code should say what it does
13:00scriptorin this case, that's what the code's doing
13:00scriptorI guess canvas-center-x and y aren't strictly necessary, but they make it more readable, don't they?
13:00harjajoegallo: 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:00harjaand if I'm "forced" to use such things, what would be the best option
13:01joegallofor $5 i'll let you use a global data structure. but you have to pay each time. :D
13:01S11001001scriptor: no
13:03scriptorwhy not?
13:03harjajoegallo: 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:04harjait would be fairly trivial if I had the execution path in my hands but it's not
13:04harjanot even fairly, but very trivial :)
13:04harjaby execution path I mean the order things are evaluated as the program progresses on
13:04joegalloharja: you can just magic functions up at any time with (fn [] ...)...
13:04harjayes, I'm familiar with that
13:05S11001001scriptor: every name introduces an indirection you have to follow. The expressive value of the binding has to exceed that cost
13:06nDuffharja: 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:07scriptorS11001001: 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:08S11001001scriptor: ok
13:08scriptorotherwise, you run into the indirection of trying to figure out what width and height are referring to
13:08harjanDuff: I have the data when the function is invoked so I don't need promises here
13:08nDuffAhh; I misunderstood the question, then.
13:12harjanDuff: 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:12harjaso, 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:13sridtechnomancy: 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:13technomancysrid: oh no kidding; that's cool =)
13:14joegalloharja: in your gist, which functions are the things you're talking about? i think we're talking past each other.
13:14technomancythis brings me one step closer to having all my ~/src dir be OSS
13:14nDuffharja: ...so, as long as the function is in a closure with access to the atom/ref/whatnot pointing to the data......
13:15harjajoegallo: 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:16technomancysrid: you work for activestate?
13:16harjanDuff: Exactly. My original question was, what is the idiomatic way to do this in Clojure
13:16joegallookay. now i think i get it.
13:16harjasince I'm very new to this language
13:17sridtechnomancy: 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:18nDuffharja: ...well, I think I answered -- close over the ref.
13:18m0smiths11001001: thanks. I used lein compile and it is giving much more helpful messages
13:18joegalloright, i agree with nDuff.
13:18technomancysrid: ah, too bad; that can be a hard sell sometimes
13:18S11001001m0smith: no prob, but that was all you I think :)
13:19m0smiths11001001: I wonder if swank is using a different clojure version
13:20technomancym0smith: swank uses clj-stacktrace; in a few cases there are problems where generating the stack trace causes another exception =(
13:20harjanDuff: 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:20S11001001m0smith: if you use jack-in, compiler should be running at whatever you have set in project.clj
13:20m0smiththanks techomancy: I'll keep that in mind
13:21harjaso basically am I closed under a script file
13:24harjacan I just do (def data (ref [])) and access that in both of those functions?
13:24harjaIt seems to work
13:24joegalloyou could.
13:24harjaand use @data and updating in dosync
13:24harjathat seems to be working the way I want to
13:24harjais that a good way to do it?
13:24joegallodepends on the size of the program.
13:25joegallosmall programs get more leniency than large ones.
13:25harjayeah, this one is easilly under 1k lines
13:25joegalloyou're probably fine
13:25harjaif i'd need to do a bigger program, how would this be accomplished then?
13:26joegallothe 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:26joegalloand then that ref isn't defined globally, just in that other function-generating-function.
13:26joegallowhich is what nDuff meant by closing.
13:26harjayeah
13:26harjathat's exactly my follow-up question
13:27harjaso I need to explicitly close, there is no global namespace-closure, a script file closure or anything like that
13:27joegalloi'm not quite sure i know what you mean, but i think the answer is yes
13:28harjawell, you can always think a namespace could have an implicit scope it could use "internally"
13:28harjaor a script file for that matter
13:28joegalloi mean, you can always just bang on the map that *is* the namespace, but i think that's generally frowned on.
13:29harjaOkay, so it's possible but not recommended :)
13:30harjaBut, 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:34joegalloenough of those, and the sky's the limit.
13:35Roey_Hello, does anyone here have experience with the Monger clojure lib for MongoDB?
13:36gtrakyes, not me, but I'm sure someone does
13:44sh10151is there any downside to using local function definitions in a let?
13:48technomancysh10151: could be harder to test in isolation
13:50ToxicFrogsh10151: I haven't seen any so far, and I've been doing it a lot
13:50ToxicFrogSince I don't like the aesthetics of letfn, especially when there's already a normal let
13:52duck1123Roey_: What's your question?
14:03sh10151these are pretty straightforward
14:03sh10151they're in a let
14:04sh10151another style question, is it bad to rely too much on dynamic vars?
14:05sh10151specifically the way CL uses special variables for parameterization
14:05technomancysh10151: it's bad to write an API that forces callers to use dynamic variables
14:06technomancybuild around lexical scope first and add dynamic scope once you have it working if the lexical version is cumbersome
14:06sh10151specifically this is for the mess of attributes/parameters/error listeners/URI resolvers/etc. that XSL processors make optional
14:07gfrederickscemerick spent a lot of effort back in the day on designing an interface that could be used either way
14:07gfredericksI'm not sure if it ended up being worth the effort/complexity
14:07sh10151to avoid the mutating setFoo setBar etc. would require either dynamic vars changed with binding
14:07sh10151or 10-argument functions
14:08gfrederickssh10151: maybe condense a lot of the args to a map?
14:08technomancytake a map and bind the default that you use if a given value isn't in the map
14:08sh10151there's a map for attributes
14:08sh10151a map for parameters
14:08sh10151a map for features
14:08gfredericksa map for maps!
14:08sh10151and a variable for error listener and a variable for uri resolver
14:09sh10151so it's still preferable to pass in one big config-type map in this case?
14:12gtraksh10151: you could parameterize the building of the map with another api
14:19sh10151well, the use case is, 90% of the time it will contain nothing
14:19sh10151then occasionally one or two customizations will be needed
14:20sh10151or xsl-params are provided
14:20sh10151that's really the most common case
14:33pyrc/lear
14:40harjawhat's the Common LISP progn equivalent in Clojure?
14:41arrdemharja: (do) if I remember correctly
14:41arrdem,(doc do)
14:41clojurebotGabh mo leithsc?al?
14:41harjayeah, found it :)
14:42harjaarrdem: thanks!
14:43arrdem(doc do)
14:43clojurebotI don't understand.
14:43arrdemtechnomancy: first it speaks Irish and now it's retarded. a little help here?
14:58twhumeI'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:59twhumeRight 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:01wingy_how do i get lein server to allow connections from the outside world?
15:15neotykdnolen: ping
15:15dnolenneotyk: pong
15:16neotykdnolen: do you know the reason for using CrossPageChannel in BrowserREPL?
15:17dnolenneotyk: 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:18neotykdnolen: sorry, didn't notice your reply
15:20nDuffWhich list was this? I don't see the thread on clojure-dev
15:21neotykdnolen: 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:21neotyknDuff: clojure-users
15:22dnolenneotyk: yes.
15:22augustlis there a way to force leiningen to download the latest snapshots?
15:22dnolenneotyk: if it's there I'm sure a lot of people would leverage it too.
15:22neotykdnolen: let me follow up on it than
15:23dnolenneotyk: CrossPageChannel is slow.
15:24neotykhow do I make lein-cljsbuild run against local cljs build?
15:24dnolenneotyk: checkouts
15:25dnolenneotyk: I'm pretty sure lein-cljsbuild mentions this.
15:27emezeskeneotyk: https://github.com/emezeske/lein-cljsbuild/wiki/Using-a-Git-Checkout-of-the-ClojureScript-Compiler
15:28neotykemezeske: just reading it, thanks
15:32augustldoes "lein deploy" also update ~/.m2 for snapshots? Or does it just upload to the repo?
15:33augustlseems 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:40uvtcWhat else do I need to use sqlite from Clojure aside from clojure.java.jdbc? Which driver is the canonical one for sqlite?
15:41metajackorg.xerial/sqlite-jdbc is the one i use
15:42metajacki use it with korma and it works out of the box.
15:42uvtcmetajack: That's the one I see mentioned in the CP-oreilly book, but clojars has listed sqlitejdbc (zentus).
15:42uvtcOh.
15:43duck11231uvtc: http://mvnrepository.com/artifact/org.xerial/sqlite-jdbc/3.7.2
15:43metajackit's not in clojars :)
15:43hiredmanI'd recommend derby or h2 over sqlite, unless you specificly need sqlite
15:43metajackmost of the java libs come from maven central
15:43metajackhiredman: why is that?
15:44hiredmanmetajack: because derby and h2 are both "native" to the jvm
15:44uvtcmetajack: Whoops. I just realized --- it's a java lib, since it's for Java's jdbc to talk to sqlite.
15:45hiredmanthe 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:45uvtchiredman: 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:45metajackuvtc: 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:45hiredmanhttp://www.zentus.com/sqlitejdbc/
15:45clojurebotdakrone maintains clj-http
15:45hiredmanhttp://nestedvm.ibex.org/
15:46metajackhiredman: 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:47uvtchiredman: I've got sqlite3 (and libsqlite3-0) installed (on GNU/Linux).
15:47augustltechnomancy: "17:52 < technomancy> augustl: you can alias "test" to "midje" in project.clj" - thanks, didn't notice until now :)
15:47clojurebotI'm no man, and she's no lady!
15:48hiredmanuvtc: so?
15:48uvtchiredman: You'd mentioned what happens if the JVM fails to load the native library.
15:48duck11231uvtc: you also have a ~/.m2, so having one of the others is a lein deps away
15:50hiredmanhttp://database-management-systems.findthebest.com/compare/6-16-53/Apache-Derby-vs-H2-vs-SQLite
15:51hiredmanalthough, that seems suspect, I am pretty sure derby supports indices
15:51augustltechnomancy: 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:51uvtchiredman: reading about derby and h2. Thanks for the recommendations.
15:52duck11231augustl: lein midje also runs normal tests
15:54augustlduck1123: right, I want "lein test" to run midje tests though
15:54augustloh, I think I see what you mean
15:55augustlanyways, the output is different from "lein test" and "lein midje" when I alias test to midje
15:56augustlhttps://www.refheap.com/paste/3656 for an example
15:56augustl(prompt at line 16)
15:57duck1123augustl: yeah, that second one is definitely lein midje
15:57augustlduck1123: right, but there's some additional output there too
15:57augustlplain clojure.test output
15:57augustlwhich isn't present witih "lein midje"
15:58augustlso it's kind of weird that it is, since "lein test" is an alias to "lein midje" in this paste
15:59duck1123augustl: you're right, it looks like your alias isn't working
16:00duck1123midje 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:01augustlduck1123: it does kind of work though :)
16:01augustl"lein test" without the alias doesn't run midje tests
16:01augustloh wait, never mind, it does :)
16:01aibcan anyone help me get penumbra to run? http://paste.ubuntu.com/1097213/
16:01augustlshould have checked that
16:02augustlthat is, it contains the "WORK TO DO" calls as they probably print immediately
16:02augustlduck1123: so it's the alias that simply isn't working
16:02augustlperhaps aliases is a lein 2 thing
16:02duck1123augustl: that's what it looks like
16:03amalloyaib: you really want to use leiningen; it will stop you from getting the classpath wrong (which is what's happened)
16:04amalloyspecifically, -jar ignores classpath settings, assuming the jar you pointed at has all the classes it needs
16:04aibahh
16:05aibthis is my first (2nd?) time using clojure/lein. Any reading material would be appreciated
16:05amalloyto do it manually (which, again, i don't recommend) you need the classpath to include the jar and run clojure.main or something
16:05amalloy~leiningen
16:05clojurebothttp://github.com/technomancy/leiningen
16:08aibah, 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:10aibin which case, https://github.com/ztellman/penumbra/wiki/getting-started - how do I run the REPL after 'lein deps' and 'lein compile' ?
16:12aiboh no. there's a 'lein repl', isn't there?
16:12aibof course there is.
16:31wingyi feel that we should pay the maintainers of a project even if it's OS
16:31devnhello clojurians
16:31wingyto have high quality libs
16:32Rayneswingy: Those are called donations.
16:33wingythey shouldn't be donations
16:33wingythey should be earnings
16:33RaynesI'll be expecting a paycheck in the mail.
16:33wingyyou pay a carpenter making a chair for you
16:34wingyif someone is making a good lib and you need features added and maintenance you should pay for it
16:34wingyor the project might die put
16:34wingyout
16:34emezeskewingy: You can't make a perfect copy of a chair for less than one cent of electricity, though :)
16:35wingykinda like ExtJS .. they started from just a lib and charged money
16:35nDuffwingy: You first.
16:35wingynow they are big .. and the thing is they can make it better
16:35wingyjust saying
16:35wingyim not a lib maker
16:35nDuffwingy: ...or, better, you could start by reading CatB and its kin, on how and why OSS works in practice.
16:35duck1123So if you're forced to pay for open source software...
16:35wingynothing wrong to charge for things .. if they need to make a living they wont have time to fix the libs
16:36wingyfulltime
16:36nDuffwingy: 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:37nDuffwingy: 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:37wingythere is a diff between pet projects and actual production ready projects with high doc and support quality
16:37emezeskewingy: 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:37wingyemezeske: yes
16:38nDuffwingy: "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:39technomancythe software I love using most is generally written because the author couldn't not write it
16:39wingyi 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:39nDuff*sigh*.
16:39emezesketechnomancy: That is a great indicator! :)
16:39nDuffwingy: again, you're assuming this silly dichotomy that anything that isn't work-for-hire is a "pet project". It's frankly insulting.
16:40wingynDuff: no .. i meant terse doc .. no maintenance
16:40wingyjust saying you may have the skills and knowledge but you need the fuel
16:41wingyjust another ingredience
16:41nDuffwingy: I've pointed you at some essays on how and why the ecosystem works. Please read them before continuing this conversation.
16:41wingybe good at development, be good at business
16:41wingythe market needs it
16:43emezeskewingy: Keep in mind that some people are motivated by things other than money, though.
16:43wingywell we all know why Ubuntu is getting more popular than Debian … they know business as well
16:43hiredmannot I, money money money
16:44wingyemezeske: cant agree more .. im not talking about we do it for money..im talking about money can help
16:44emezeskehiredman: I guess that's why you're "hiredman" instead of "volunteerman" :)
16:44wingyand not trying to start a flame war but we do have to agree a lot of potential projects could be more solid
16:45technomancythe original meaning of the word "amateur" actually comes from the root "amor"; in other words, done out of love.
16:45emezeskewingy: Sure, but money isn't always a fix
16:45mattmossThrowing money at things is not an automatic win.
16:45wingyemezeske: didnt say that .. it helps
16:45clojurebotPardon?
16:45mattmossHowever, throwing money at me is a wonderful thing.
16:45wingymattmoss: i agree .. throw it on top devs coding for love
16:45emezeskeHeh, it sometimes helps.
16:46wingybut they need to make a salary as well
16:46emezesketechnomancy: Interesting fact!
16:46wingynot everyone wants to use java/php at their job
16:46mattmosswingy: What if they're already salaried? You seem to have ignored nDuff's points.
16:46duck1123throw money at me and I consider it a win. Just not pennies, those hurt
16:46technomancyemezeske: call me a professional amateur =)
16:46mattmossPennies aren't worth anything anyway.... except for making large penny pyramids.
16:47emezesketechnomancy: Same here!
16:47wingymattmoss: not everyone works on the thing they really want to work on
16:47wingymattmoss: some work for money only, no love at jobs
16:48mattmossYou seem to be conflating a few different arguments. Perhaps sticking to one at a time?
16:48wingymattmoss: i dont get what you mean .. everything is connected?
16:48mattmossEverything is connected? I highly doubt that.
16:49wingyyou do what you love .. you make a living out of it .. you can throw more resources at it .. KISS people
16:49technomancyeverything is intertwigled
16:49wingynot saying money is everything so stop throwing that at me
16:49duck1123mattmoss: You've obviously never taken acid
16:49mattmossComplected?
16:49mattmossduck1123: That's true.
16:49mattmossDid you hear the one about the Buddist in New York City who asked a hot dog vendor, "Make me one with everything." ?
16:50technomancyI'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:51wingytechnomancy: yes
16:51wingyi mean .. my parents sell food for just a small town .. they make more money than 10 developers in total
16:51wingyone dev makes a lib 500-1000 people are using .
16:52wingyi 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:53wingyif devs know how to take charge i think the OS market would be more solid and with good quality, doc, testing etc
16:53technomancyyou 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:54aaelonyyou need a pipeline of work or a rainmaker :)
16:54wingytechnomancy: you make what you love at freetime as you always do and then take charge for it when you have > 300 users
16:55wingymore than 300 users using your thing .. yeah that is a product you have
16:55uvtcmattmoss: 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:55duck1123There 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:56mattmossuvtc: Good one.
16:56wingyim 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:56wingythe OS projects could definitely be charged as apps
16:57technomancyI'll happily pay for software as long as it's open source
16:57wingyme 2
16:58mattmosswingy: It's not an evil cult, no, but your "i pay you..." statement comes off as a demand, not a request.
16:59joegalloi wonder how that model is working out for the itext guy.
16:59mattmossGreat thing about open-source... fork and improve.
16:59uvtc... and send pull-request. :)
17:01wingymattmoss: didn't solve the resource problem
17:01mattmosswingy: What resource problem?
17:01wingy:/
17:02mattmossThe resources necessary for developing software are human effort.
17:02mattmossOne way to acquire that is through money to an interested developer, but is hardly the only way.
17:02kreig1wingy: can you guess why I am skeptical of your perspective on open-source software and what goes into the process of making software?
17:03mattmossThe developer you are demanding write docs in exchange for $$$ may be more interested in throwing around the football with his kids...
17:03mattmoss...meanwhile another developer who likes writing docs (if there is such a thing) would happily fork and improve the project if asked.
17:03wingymattmoss: what a company does with their money i cannot control .. but i think we all we'll see the outcome for each version
17:04mattmossOr a company decides it is in their best interests to hire/pay for those docs.
17:04kreig1and whose to say the best part of software production is the software?
17:04wingyand i doubt that passionate devs would wanna kill their baby project
17:04wingyit's their life
17:04nDuffwingy: ...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:04nDuffeatures, etc.
17:04mattmosswingy: You are making many unfounded assertions.
17:05nDuffwingy: ...so, you're actively advocating a model that would make my life worse by increasing the range of Stuff I Can't Use.
17:05wingynDuff: 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:06wingynDuff: well if you put it in that way i can't argue anymore
17:06kreig1hehe
17:06kreig1good, then stop
17:06kreig1so, how about those macros
17:08scriptorthere was an article about how soldiers reacted when the red cross started charging for formerly free donuts
17:09scriptornot sure how relevant it is, but it's interesting to think of the psychology
17:09technomancygratis donuts, you mean
17:09scriptordonuts libre
17:09technomancythe soldiers weren't improving the donut recipe as they ate them, though that would be awesome if they could
17:10kreig1according to e. coli they were
17:10technomancy"hm; have you considered what a little nutmeg would do to the flavor profile here?"
17:10scriptormore like, "this donut doesn't work horribly unformatted donut-mulch attached plz fix thx"
17:10mattmossMmm, donuts libre. *drool*
17:11technomancythe red cross is all "HAVE YOU SIGNED PAPERWORK"
17:12mattmossCurious 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:13mattmossLike... (defn create-foo [a b] (Foo. a b)) vs. (defn create-foo [a b] {:instance (Foo. a b)})
17:25gfredericksmattmoss: 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:27duck1123It really depends on how close to the line you're working
17:27mattmossgfredericks: 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:27mattmossThe former seems cleaner, "nicer", Clojure code... hiding away the "nasty" details of POJOs.
17:28mattmossBut I may just be needlessly worrying.
17:37nDuffI'm interested in temporarily disabling watches on a known list of atoms during test setup/teardown. Is a mechanism available?
17:38technomancynDuff: can you just with-redefs the associated vars to (constantly true)
17:38technomancyI guess that only works if you pass the var in as the watcher, not the function itself
17:40nDuff...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:41wingydo you guys use a statechart/statemachine in frontend cljs when coding? if not, how do you usually organize your code?
17:44sisciaaaelony, thank you also for jiraph ;-D
17:44duck1123wingy: Have you seen Waltz?
17:45duck1123I just refactored some of my code this past weekend to use that, seems pretty nice so far
17:49wingyduck1123: ill give it a try .. seems to be the most popular one in cljs land
17:50wingyin worse case scenario if that won't cut it I see if I can use http://stativ.us/ with cljs
17:51wingyif the oop style would work nicely
17:51duck1123wingy: Heres what I did with Waltz. https://github.com/duck1123/jiksnu/blob/dev/src-cljs/jiksnu/websocket.cljs
17:52duck1123still a WIP, obviously
17:52hiredmanb
17:53aaelonysiscia: thank flatland folks... who are awesome to the hilt
17:54wingyduck1123: great i can use your project as a template for frontend :)
17:54duck1123And on that note, I'm out of here. Time to get home and trade in my Java and js for Clojure and cljs.
17:54wingyhaha
17:54duck1123wingy: have at it. Share and enjoy
17:55Raynesamalloy: Here that, Alan? To the hilt.
17:55RaynesHear, even.
17:55RaynesHere, there, whatever.
17:55fsmunozIf 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:56RaynesClojure rocks! I sampled everything in the medicine cabinet for comparison, but I think that this euphoria is the Clojure.
17:56technomancyfsmunoz: 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:57emezeskeRaynes: Nice, you got your doctor to write you a clojure-script?
17:58aperiodic(inc emezeske)
17:58lazybot⇒ 1
17:58fsmunoztechnomancy, Raynes: heheh
18:04SegFaultAX|work2The documentation format for special-forms and macros kinda sucks.
18:05SegFaultAX|work2(fn name? ([params* ] exprs*)+) <- it's like a weird mixture of ad-hoc sexp and regex.
18:06TimMcIt's more like BNF, really.
18:06SegFaultAX|work2TimMc: Except for not.
18:06SegFaultAX|work2TimMc: But if I squint really hard, I see your point.
18:07SegFaultAX|work2TimMc: Either way, the usage of ? + and * (and the implied meaning of each) makes it look more like a syntax based on regex.
18:07clojurebotthe best way to represent X is as a regular clojure map. (for most values of x)
18:07TimMcLike BNF that has been condensed. You can do that more easily with languages whose syntax is close to their AST.
18:08fsmunozspeaking 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:08TimMcclojurebot: We value your input. Please wait for the next available logger.
18:08clojurebotIt's greek to me.
18:08SegFaultAX|work2TimMc: 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:09TimMcfsmunoz: I could come up with philosophical reasons re: doc-driven development, but the real answer probably lies somewhere in the multi-arity syntax.
18:09SegFaultAX|work2That would be my guess as well.
18:09fsmunozTimMc: yes, that was what I was suspecting
18:09fsmunozty
18:11TimMcIt's easy to accidentally write (defn foo [args] \n "docstring but not really" ...) and have a fake docstring. :-/
18:11TimMcAnyone know if ibit catches that?
18:11TimMc*kibit
18:11SegFaultAX|work2TimMc: Is that a clojure linter
18:11SegFaultAX|work2?
18:12SegFaultAX|work2Ah, static code analysis.
18:19wingywhat do you think about http://emberjs.com/documentation/ for frontend with cljs .. it's using MVC/OOP approach
18:19wingystatemachine is one of the things included
18:21SegFaultAX|work2wingy: I like backbone. Ember is pretty heavy for what I'm usually looking for.
18:21SegFaultAX|work2wingy: Just my $0.02
18:21wingySegFaultAX|work2: but is using a MVC/OOP framework OK even for a FP lang?
18:21wingymixing 2 different paradigms
18:22SegFaultAX|work2wingy: Those don't really have anything to do with each other.
18:22wingySegFaultAX|work2: now you have to put your maps/vectors into their models i guess?
18:22SegFaultAX|work2wingy: 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:24wingyyeah i know, was curious about if that would break something important now when I think data and logic should be kept separate
18:24fsmunozI think that they can match well, especially if one considers that the view is mostly about side-effects
18:25SegFaultAX|work2wingy: That isn't really related to MVC, so you're probalby good there if that pattern matches your problem.
18:25fsmunozand the model can be thus more "pure", containing the actual logic and not polluted by (doto (.JFrame)...)
18:25fsmunoz(or whatever it is really like)
18:25wingyok
18:25wingyseems that we are all green to go
18:26wingythat'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:26SegFaultAX|work2fsmunoz: 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:26wingywithout wrappers
18:26SegFaultAX|work2fsmunoz: After all, it's up to the models to transform application state.
18:27fsmunozSegFaultAX|work2: quite right, haven't thought of it that way
18:27wingyyay . so now we have bootstrap and emberjs including a statechart for free
18:27SegFaultAX|work2fsmunoz: In other words, unless the data layer is abstracted away, models will necessarily be side-effecting.
18:39SegFaultAX|work2I need to interop with git, what's a good library to do that with?
18:40Raynesclojure.java.shell
18:40Raynes;)
18:40technomancythere are a couple jgit wrappers; don't use the one from seajure as it was a swarm-coding exercise and not further maintained
18:41SegFaultAX|work2Actually maybe just writing a wrapper for working with git from the shell wouldn't be so bad.
18:42technomancyjgit is great for reading; I haven't used it for commits and push/pull stuff
18:42SegFaultAX|work2technomancy: This would be read-only.
18:42amalloywrite a wrapper for working with git from the shell? isn't that just git?
18:42technomancygit's CLI is beyond awful though
18:43amalloywhaaaat
18:43SegFaultAX|work2technomancy: I use it everyday.
18:43SegFaultAX|work2technomancy: I don't find it that bad.
18:43amalloyget out of my channel, technomancy
18:43technomancyit's bad!
18:43technomancyit just is.
18:43amalloythere are some bad things for sure
18:43technomancyit overloads commands to do like five different operations
18:43technomancyit calls the staging area the "index"
18:44technomancyyou learn about how it's bad, and you stop noticing it if you use it every day
18:45technomancyevery time I have to drop out of magit and use regular git it just feels so backwards
18:45SegFaultAX|work2technomancy: 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:46technomancyI agree; I still use git. I just think you can do better if you're going to wrap it.
18:46SegFaultAX|work2Which commands do you feel are too heavily overloaded?
18:46technomancy"checkout" is the most obvious one
18:46SegFaultAX|work2Why do you think that?
18:46technomancybecause it's used for switching branches as well as discarding changes to the working copy and a few other things
18:47technomancythere's no conceptual coherence to it
18:47gtrakyou're not 'discarding changes', that's just a side-effect
18:47technomancythe 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:47SegFaultAX|work2It does exactly 1 thing, it changes your working directory based on a commit-ish.
18:47SegFaultAX|work2That's all.
18:47technomancyno, it creates new branches too
18:48SegFaultAX|work2technomancy: No it doesn't. git-checkout -b does.
18:48technomancyyes?
18:48clojurebotyes isn't is
18:48technomancyalso: IIRC git branch creates a branch without switching to it; wtf
18:48technomancyno one has ever wanted to do that
18:48SegFaultAX|work2technomancy: Because all its doing under the hood is associating a ref with a commit-ish.
18:49gtrakI 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:49technomancySegFaultAX|work2: who cares what's happening under the hood?
18:49SegFaultAX|work2Sure they do. Before a rebase operation you might make a "backup" by using git-branch.
18:49technomancyit's ignoring the perspective of a user
18:49SegFaultAX|work2Which really means "I don't want to look through the reflog if I fuck this up"
18:49gtrakmercurial's user philosophy is supposed to be better
18:49technomancyI've forgotten most of my other complaints because luckily I can most things done with magit these days
18:49gtrakgit's user experience was never its selling point
18:50SegFaultAX|work2technomancy: The problem is you don't grok git.
18:50SegFaultAX|work2technomancy: Remembering that it started as a collection of tools instead of one big application helps.
18:50technomancySegFaultAX|work2: the problem is you have to understand irrelevant details to use it effectively
18:50SegFaultAX|work2technomancy: Perhaps.
18:50technomancyoh, 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:51technomancysince pull ignores certain aspects of the remote IIRC
18:51SegFaultAX|work2technomancy: What are the subtle details you're thinking of?
18:51SegFaultAX|work2technomancy: It doesn't.
18:51technomancyI sort of wish I could remember, but on the other hand I'm also kind of glad I've forgotten =)
18:51SegFaultAX|work2technomancy: But you can certainly get weird issues if your refspecs are configured improperly, I'll give you that.
18:52hiredmantechnomancy: push pushes everything if you don't give it a branch?
18:53SegFaultAX|work2I'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:54technomancyhiredman: that's a fun one too
18:54technomancythe 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:55technomancyhahaha: "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:56technomancyreset is another example of a single command that has many different purposes
18:57SegFaultAX|work2technomancy: Sorry, my connection died.
18:57SegFaultAX|work2technomancy: What were you saying?
18:57amalloyyeah, reset is poorly named
18:58RaynesSegFaultAX|work2: He was saying whinewhinewimperbitchblaaaahblurggitsucks.
18:58SegFaultAX|work2Haha.
18:58technomancySegFaultAX|work2: "reset is another example of a single command that has many different purposes"
18:58SegFaultAX|work2amalloy: reset is easily one of the more complicated features of git.
18:58technomancyI like it as an API, but it leaves a lot to be desired as an application
18:58SegFaultAX|work2amalloy: It allows you to interact with the tree, index, and working directory all in one.
18:58technomancyand usually I don't have to use it as an application, so I'm fairly happy
18:59SegFaultAX|work2technomancy: I agree to a certain extent that reset is overloaded. But understanding how it /actually/ works really helps.
19:00technomancywell-designed applications allow users to learn gradually
19:00SegFaultAX|work2technomancy: Most new or mid-level users of git have only a basic understanding of how git-reset operates.
19:00amalloySegFaultAX|work2: i don't know why you're telling me this. i like reset
19:01SegFaultAX|work2amalloy: Awesome! All I got was that it's poorly named. :)
19:01amalloywell, it is
19:01SegFaultAX|work2amalloy: Dunno what else I'd call it.
19:01amalloyi'm very comfortable with git; i don't need evangelizing :P
19:02SegFaultAX|work2"ref-sync" maybe.
19:03RaynesI'd call it reset.
19:03RaynesThat's much better than reset.
19:03SegFaultAX|work2:)
19:04gtrakgit reset --hard just makes me feel lika a badass
19:04amalloyand then usually an idiot, right?
19:04SegFaultAX|work2gtrak: git reset --hard && git clean -df
19:04SegFaultAX|work2gtrak: Like a boss.
19:04gtrakwhat's that do?
19:04Raynestechnomancy: You should use mercurial.
19:04SegFaultAX|work2gtrak: Also removed everything untracked.
19:04amalloytechnomancy: 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:04gtrakamalloy: haven't blown my foot off with that yet
19:05technomancyRaynes: magit solves all my problems
19:05SegFaultAX|work2amalloy: Some people say the same thing about vim. I think most complex tools get that wrap.
19:05gtrakI want your hardest reset, git... don't hold back
19:05technomancygit reset --hard --with-a-vengeance
19:06duck1123you have to pass --hard to get the special ending
19:06SegFaultAX|work2technomancy: Does that null out the sectors on my hdd before it resets?
19:06SegFaultAX|work2duck1123: No one likes it --soft.
19:14wingyi need to dig deeper into git
19:15jballancQuestion 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:15jballancright now I'm using println and clojure.string/join with "\n"…but it feels wrong
19:16emezeskejballanc: What feels wrong about that?
19:17jballancI 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:17jballancfor example, if it were Ruby, I'd finish with "filtered_list.each { |elem| puts elem }"
19:18emezeskeWell, you could (doseq [elem elems] (println elem))
19:18jballancbut, everything I try, I just keep ending up with more lazy-seqs
19:18jballancah, doseq will realize the lazy-seq?
19:18gtrakjballanc: (apply println seq?)
19:18emezeskegtrak: Isn't apply lazy?
19:18gtrak,(apply println [1 2 3 4 5])
19:18clojurebot1 2 3 4 5
19:19gtrakemezeske: the realization is lazy, but the invocation isn't
19:19gtrakerrr...
19:20gtrakit's not curried, so I'm not sure why it would be lazy
19:20emezeskejballanc: Yes, doseq's purpose is to be un-lazy
19:20emezeskejballanc: I should say, it's purpose is for side-effects
19:20jballancah, yes…that works perfectly
19:21jballancthanks, emezeske!
19:21gtrak,(let [_ (apply println [1 2 3 4 5]) _ (println "should happen second")] nil)
19:21clojurebot1 2 3 4 5
19:21clojurebotshould happen second
19:21gtrakemezeske: ^
19:21emezeskegtrak: At any rate, that's not what jballanc is trying to do
19:22gtrakwhy not?
19:22emezeskeSee his original example, he is printing each element on a separate line
19:22gtrakjballanc: if you want to make it feel nicer, try interpose and I think there's a \newline
19:22jballanchmm…hadn't seen interpose
19:22jballancah, but still lazy
19:23gtrakuntil you do it
19:23gtrakthat's kinda the point of laziness
19:23emezeskejballanc: Just use doseq, that's exactly what it's made for
19:23jballancright…so, to give more context, this is reading a file in the context of a with-open
19:24jballancit'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:25gtrakjballanc: yea, you need to do something to actually realize it, doseq, mapv, into
19:26jballancgot it
19:26jballancI'm still learning, but I actually rather like this aspect of clojure
19:31gtrakjballanc: 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:35jballancgtrak: 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:36gtrakjballanc: sure, if you're doing that you want to use a countdownlatch or something
19:36gtrakbut then what if it isn't fully realized?
19:37gtrakbut yea, that's the secret, contain as a value everything that the value depends on
19:37jballancyes, not at all an easy task…in any language, I think
19:53wingywhat is the reason for this inconsistent naming in cljs: (array) for creating an array and (js-obj) for creating an object?
19:54gtrakwingy: inconsistent how?
19:54wingywhy not js-array or obj
19:55gtrak(def js-array array) ; mm feels so much better ;-)
19:56kreig1array is a shared type, js-obj is a jscript specific type?
19:56kreig1hmm, no, not tit
19:57RaynesAlways tit.
19:57kreig1there are not arrays in cljs, don't have a repl open to confirm tho
19:57emezeskekreig1: There are arrays in cljs
19:57kreig1vectors tho right?
19:57emezeskekreig1: https://github.com/clojure/clojurescript/blob/master/src/cljs/cljs/core.cljs#L78
19:59wingygtrak: ...
19:59kreig1I know that, but it's not a native clojure type, but I have a hunch that distinction is in my head only
20:00gtrakI was looking for a all? instead of an every? the other day... I think it just happens sometimes
20:00gtrakthankfully it's not that big a deal
20:02wingyhi there, I'm a such mature person who talks inbetween the lines all the time since i find it's contributing
20:03wingyinstead of trying to help to answer the question i make a fool of them so they find them self in shame
20:03gtrakwingy: sorry I don't know the answer, it doesn't seem to me like it's intentional either way
20:37bloudermilkThis 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:37kennethhey is there a way to use stuff in /usr/share/java in my class path with lein
20:38bloudermilkSuch as environment differences?
20:38aperiodicbloudermilk: yes; the REPL forces evaluation of lazy sequences
20:38gtrakbloudermilk: the repl does bind some vars that aren't there otherwise
20:39technomancybloudermilk: the repl also pulls in a few dependencies needed for clojuredocs etc.
20:39technomancyand nrepl
20:39bloudermilkAh that seems like a likely source of the problem
20:39gtrakaperiodic: I think I've been hit by that one
20:40bloudermilkaperiodic: pretty sure that's what I'm experiencing
20:40technomancykenneth: short answer: no, it needs to pull from a real repository in order to avoid certain kinds of problems
20:40technomancy~repeatability
20:40clojurebotrepeatability is crucial for builds, see https://github.com/technomancy/leiningen/wiki/Repeatability
20:40aperiodicbloudermilk: check out doall, dorun, and doseq
20:40bloudermilkaperiodic: Will do. Shouldn't calling map on a set evaluate it though?
20:41emezeskebloudermilk: map is lazy.
20:42bloudermilkA hah!
20:42technomancyclojurebot: map?
20:42clojurebotmap is lazy
20:42aperiodicbloudermilk: the set will be evaluated, but the lazy sequence produced by map may not have its elements realized without something that forces it
20:42kennethtechnomancy: what's the traditional way of dealing with JNI jars?
20:42technomancyweeping and gnashing of teeth
20:42technomancykenneth: seriously though; generally people include statically-compiled binaries inside jars
20:43technomancydocs are a bit slim on this; best to follow the example of some of the existing native libs
20:43kennethi'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:43technomancywhat's the library?
20:43bloudermilkaperiodic: 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:43kennethjzmq
20:44technomancythere are working versions of jzmq; you don't need to roll your own
20:44technomancyI'm not sure which they are though
20:44aperiodicbloudermilk: i'd use (doseq [elem set] ...)
20:45aperiodicbloudermilk: but yeah, if you want side effects, don't use map
20:45kennethtechnomancy: i've spent literally days trying to get jzmq to work, and only got it to work by compiling it myself
20:46bloudermilkaperiodic: 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:47aperiodicbloudermilk: sure, you can build stuff up lazily with map and then force side effects with dorun
20:48duck1123So 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:48bloudermilkaperiodic: Appreciate the help. Thanks
20:52hiredmanduck1123: depends on the optimization level
20:53hiredmanduck1123: I believe if you have adavanced opts on everything get's mangled and doing repl stuff will be very painful
20:55duck1123I don't have any optimization
20:56duck1123whitespace and pretty-print
20:56hiredmanyou may need to refer cljs.core or something, if require is undefined
20:57duck1123It seems that I can refer to the functions directly (ie. jayq.core/$)
20:57hiredmanwhat happens if you use (cljs.core/require ...) instead of (require ...)
20:58duck1123same
21:14gfredericksI wouldn't think require would ever be defined in cljs
21:14gfredericksunless something has changed
21:15duck1123so you're saying that I can't require namespaces from the repl? Or I should be able to
21:15duck1123I'm just trying to avoid needing to fully qualify everything
21:15gfredericksafaik you can only do it within a (ns ...)
21:16duck1123that makes cljs repl severely less useful
21:16gfredericksyeps
21:27arrdemis there a way I can have multiple (:use :as ) statements with the same :as?
21:29emezeskearrdem: You're, like, trying to combine multiple namespaces into a single alias?
21:31emezeskearrdem: 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:31arrdememezeske: 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:31arrdemso yes... I guess I want to merge namespaces.
21:32emezeskeThat 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:32emezeskeWhereas if you start combining namespaces, you don't know where a form came from
21:32emezeskeAnyway, I am pretty sure you can't do that with :use :as
21:34arrdememezeske: 's ok. I'll just ditch the :as and bring it all into my local ns. %s/"bd/"/""/g and done.
21:34arrdem*db/
21:34amalloyemezeske: that's true of :require/:as; :use/:as is generally a bad idea
21:35emezeskeamalloy: Oh, I totally had :require/:as in my head
21:35emezeskeDerp
22:08clj_newb_2057290what happened to rule based programming langauges?
22:08clj_newb_2057290why have none of them ever taken off?
22:14nicholasfhow are people using leiningen for scripting tasks?
22:15technomancynicholasf: what are you trying to do?
22:16nicholasfhi technomancy - I want to drop a database after a test run
22:16technomancycan you use test fixtures for that?
22:16nicholasfin this case, we have a convention that we need this scripted (for a continuous delivery system to call)
22:16technomancymeaning I think it should be done at runtime, not at build time
22:17nicholasfyeh, but regardless of the problem, how do I script a task with leiningen?
22:17nicholasfis there a way people generally do it?
22:17technomancyusually you use a plugin that already exists =)
22:18technomancybut if you need to write your own, the plugin guide explains how: https://github.com/technomancy/leiningen/blob/master/doc/PLUGINS.md
22:18nicholasfthanks mate
22:18technomancysure
22:50amalloyunlink: 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:27gnarmisis anyone aware of efforts to write a lang level for clojure in racket, so we can use the awesome dr racket?
23:29yonataneCan I add to an existing multimethod from somewhere else?
23:29yonatanelike from another namespace, to some multimethod that a third-party defined?
23:31gfredericksyes
23:31gfredericksyou can
23:31gfredericksthat's most of the motivation for multimethods I think
23:32yonatanegfredericks: so i can just hook my code to a third-party without dependency injection like that?
23:33gfredericks...sure?
23:33yonataneif the caller used to invoke the default, it will now invoke my code if i configured it correctly?
23:34gfrederickssounds right
23:34gfredericksyou should be able to experiment with that in the repl
23:35gfredericksput a (defmulti) in one namespace and a (defmethod) in another
23:35gfredericksI'm doing this right now because I've never tried it
23:36gfredericksand it worked perfectly