#clojure logs

2013-05-09

00:00xeqiadd a BufferedReader. to the end of your reader building
00:00tomojisn't that what io/reader does?
00:01shriphanibut i have a bufferedreader
00:01shriphaniand an io/reader both in there...
00:01shriphaniand I still cannot read past the 4300th line.
00:02tomojI don't see the BufferedReader. - did you change the code?
00:02tomojI tried your refheap with a million lines of "yes" and got a million lines
00:02tomojprobably a bad test case..
00:02shriphanitomoj: https://www.refheap.com/paste/14333
00:03xeqitomoj: ah, your right
00:03tomojyeah that gives me 1000000 too
00:03xeqiit is what io/reader does
00:04xeqishriphani: are you reading with the right encoding?
00:04mthvedtit does seem problematic that you sometimes need to construct java readers to use clojure stuff that is supposed to abstract those
00:04shriphanixeqi, I am guessing no at this point.
00:04shriphaniI didn't specify one while writing to the file.
00:05shriphanibut the lines it reads in are ok...
00:06tomojmthvedt: there is no abstraction, clojure.java.io just has some helpers
00:06tomojof course it doesn't have every conceivable helper..
00:06shriphaniso it possibly reads EOF somewhere where zcat doesn't….
00:06mthvedtwell, s/abstraction/more accurate word
00:07tomojso what seems problematic, that clojure.java.io doesn't contain every conceivable java.io.* helper? O_o
00:08mthvedtthat some helpers produce stuff that can't be consumed by other helpers
00:08mthvedtwithout doing the appropriate java rain dance
00:09tomojlike what?
00:09shriphaniand unix tells me line #4301 is not unnatural.
00:10brehautmthvedt: it is java.io, expectations of being java-free are based on incorrect fact gahter
00:10brehautgathering*
00:10mthvedti'm not talking about java-free
00:13mthvedtsay you open a file with io/reader
00:13mthvedtthen you try to use 'read on the result
00:13mthvedtClassCastException java.io.BufferedReader cannot be cast to java.io.PushbackReader
00:14hiredmanpushbackreaders can by their nature be problematic
00:14brehautback up a moment, read is core, not java.io. a) read isnt a helper b) its in a different module
00:14hiredmanthey can end up reading a character then pushing it back in to an internal buffer, so if you auto wrap with pushback readers you can lose a character
00:15tomojshriphani: I got no clue, I've never had trouble with code like that..
00:16tomoj(without the BufferedReader. since io/reader already returns one)
00:16hiredmanshriphani: I'd suggest taking a step back and starting from scratch verifying each step
00:17shriphanihiredman… I only have 1 function that I am calling from a repl….
00:17hiredmanwe use clojure and gzipinputstreams and gzipoutputstreams and clojure.java.io extensively at work
00:17hiredmanso I know they work fine, so the only variable is your setup
00:17shriphaniI guess my file is corrupt in some way
00:18hiredmanshriphani: have you restarted your repl? do you have some bogus state in there somewhere?
00:18shriphanihiredman, yes
00:18hiredmanshriphani: gzip can be a little more tolerant of errors than the stream classes, but in my experience in prints warnings if that is the case
00:18shriphaniso I ran it on another file and it returned with the right number of lines.
00:19shriphanithat one had 316k lines in it.
00:19shriphaniit is just the 8 million lines file that claims it has 4300...
00:19shriphaniand throws no errors..
00:20hiredmanshriphani: have you checked the result when the file is uncompressed?
00:21shriphaniI'm trying that right now.
00:24shriphanihiredman, so that gzip file was obtained by doing a cat on two gzip files. I ran a cat the other way round and tried the routine on it and it reports 3200 lines on that one.
00:25shriphanii.e. instead of cat file1.gz file2.gz I did cat file2.gz file1.gz > test_out.gz and I get 3200 on that one… so the files are wonky and hit some odd edge case.
00:33tomojshriphani: hmm, that doesn't work
00:33shriphanitomoj ?
00:33tomojGZIPInputStream doesn't expect multiple concatenated gzip streams
00:34shriphanitomoj… I the cat of two gzip files is a valid gzip file...
00:35tomoj`cat file1 file2 | gzip > test_out.gz` should work
00:36shriphanitomoj, this is from the gzip manpage: ADVANCED USAGE
00:36shriphani Multiple compressed files can be concatenated. In this case, gunzip will extract all members at once. For example:
00:36tomojyeah I'm looking at that too
00:36tomoj`gzip -c file1 file2 > foo.gz` is also readable by GZIPInputStream
00:36tomojjust not `cat file1.gz file2.gz > foo.gz`
00:36shriphani....
00:37shriphaniwow...
00:37tomoj(which I don't see in the manpage despite the "Multiple compressed files can be concatenated"
00:38tomojhttp://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4691425
00:40shriphaniumm that bug report says Resolved...
00:40shriphaniso they just closed the ticket ?
00:40tomojwell as a wontfix..
00:40shriphanifantastic.
00:40tomojhttp://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4763158
00:40tomojthat being the 'real bug'
00:40shriphaniThis assumption isn't documented within any of the J2SE documentation as far as I can tell.....
00:41shriphaniman that is just so awesome...
00:47logenIn order to update a session in ring, I have to pass the request into my view function and assoc my values back into the :session keyword, right?
00:49tomojso, uh, speaking of IO abstractions
00:49tomojrich has said "we need reducible IO" or something
00:50tomojconsider ZipInputStream
00:50tomojmost natural thing that fell out when I started writing was a reducer where the values are the ZipEntry's
00:50Apage43logen: yep
00:50Apage43if you're using the session middleware that ships with ring
00:51tomojwell, clearly that won't work if all we have is a ZipInputStream
00:51hiredmantomoj: that doesn't track
00:52logenApage43: I keep ending up needing stuff in the request object...is it bad form to just pass the whole request into view functions?
00:52tomojif we have a ZipFile we can get a reducer of entries and use the entries to get whatever an InputStream is as a reducer
00:52tomojhiredman: track?
00:53hiredmanno
00:53hiredmanyou can get entries from a zipinputstream
00:54Apage43logen: well it won't break anything. Depends on how concerned you are about separation of concerns. Is there a particular subset of things you tend to need or could it be anything?
00:55tomojyeah, but then you have to have the ZIS still around (and not disturbed further) to read the actual contents of the entry?
00:55hiredmanwhich you can do just fine
00:55hiredmanin fact, it is that kind of resource handling that makes reducers based io appealing
00:56logenApage43: I need to know if the user is logged in, in order to show a Log In link or show their username if already logged in. POSTs need post params. It seems like most of my view functions end up needing the request.
00:56hiredmanhttps://gist.github.com/hiredman/4075459
00:56shriphanitomoj, was that ZIJ comment for me ?
00:56tomojshriphani: nope
00:56shriphaniah.
00:56Apage43logen: sounds like they typically want :session and :params
00:57logenApage43: true, but both are already in request.
00:57tomojhiredman: ByteSource makes sense to me
00:57hiredmantomoj: so you would do the same thing with an zipinputstream
00:57hiredmanZipEntrySource or what have you
00:58Apage43well yes that's where you'd get them. Passing in the request isn't a big deal, as long as you're passing them to something you wouldn't expect to want to ever use outside of that context
00:58tomojso the user of the ZipEntrySource must have a reference to the ZipInputStream
00:59shriphaniI am surprised.. with the number of sugar daddies that java has, how does it still manage to not have the resources to fix such bugs ?
00:59hiredmantomoj: ideally the user would have see the zis
00:59Apage43if you wanted to be able to separately test those fns with different sessions/params, it could get bothersome later if you have to construct a whole request map to do that
00:59hiredmanjust create a zipentrysource and reduce over it
00:59tomojgetting ZipEntry values which are useless?
00:59hiredmanthey are not useless
01:00logenApage43: Thanks. I'm trying to learn and do at the same time. The docs for ring + sessions is sparse.
01:00hiredmantomoj: if you r/map over them that r/map happens while the stream is still open
01:00Apage43logen: mhm. I often just go look at the code https://github.com/mmcgrana/ring/blob/master/ring-core/src/ring/middleware/session.clj :)
01:00tomojbut you have to have to see the ZIS to use them
01:00tomoj..I assumed you meant "should not have to see the ZIS"
01:00Apage43ah wait
01:00Apage43https://github.com/ring-clojure/ring/blob/master/ring-core/src/ring/middleware/session.clj
01:01Apage43the mmcgrana repo is old, don't look at that one
01:01hiredmantomoj: ok, so you don't return a entry exactly, you return something like an entry with its own internal reference
01:02tomojand now the 'values' coming out of the reducer self-destruct
01:02hiredmanin what way?
01:02tomojif you don't use it and save it away instead, it's now broken
01:02hiredmanit isn't
01:02tomojlike if you did (into [] the-reducer-of-entry-like-things)
01:03tomojwell it can either read all of the contents for you and save them away so that there's no problem
01:03hiredmanyes
01:03tomojor it lets you decide which entries' contents to read, in which case you're fucked
01:03hiredmanor you can just hand on to the unreduced reducer
01:03hiredmanwhich is a promise to do the work, and manage the resources when you want it
01:03logen Apage43: Yeah, a lot of time it would just be quicker to read the source than google and find a bunch of old blog posts. I'm trying to get to the point where source doesn't send me off consulting clojure docs every other line.
01:04hiredmantomoj: if you run r/filter the filtering happens while the zis is still open
01:05tomojright, OK, so the ZipEntrySource's values contain like byte-arrays with the entire contents of each entry, and you skip the ones you don't care about?
01:05hiredmanmaybe, maybe not depending on what you want and how you do it
01:06tomojwhat I'm trying to avoid is the requirement that a value coming out of the reducer be used during the reduction
01:07tomojonly seemingly sane way I can see so far (besides always reading everything into memory) is to have the reducer make a copy of the input stream in a temp file so that we can go back and to the entries later
01:07Apage43logen: if you're using an editor with some integration, having hotkeys for jump to the source of this function and show me the docs for this function makes exploring much nicer
01:07hiredmanyou can do it in stages (r/map make-valuies (r/filter values-i-want zip-entry-source))
01:08tomojyeah, but only if you have a ZipFile, afaict
01:08tomojrather than just a ZipInputStream
01:08hiredmanno, that is just not correct
01:08tomojoh, right, your example works
01:09hiredmanand you can even do more transforms on the results there
01:09tomojbut say (into [] (r/filter non-values-i-want zip-entry-source))
01:09tomojthose aren't values, right?
01:09hiredmanit depends on how you do it, but sure they may not be
01:10hiredmanthe source has a lot of control, for example it could look at the result and reify it as a value on the way out
01:11tomojoh, interesting. I hadn't thought of that, will take me a while to process I think. thanks
01:12hiredmanhmmm, I dunno if that is practical though
01:12hiredmanthat could get really nasty fast
01:13tomojI don't see what you mean actually - 'result' here is a reducef return value?
01:14hiredmanyes
01:14hiredmanyou would have to walk the value
01:14hiredman"that could get really nasty fast"
01:15tomojI suspect my (still nebulous) goals probably cannot be satisfied without saving the input somewhere
01:20totimkopfdo most web frameworks extend ring?
01:22tomojI wonder what rich meant, we need impure reducer IO?
01:24tomojI guess for now I'll ignore the impurity since it should work OK. but that can't be what we need..
01:24tomojI mean, sometimes maybe, but that's not what I want to work with most of the time
01:27dpwrighthello, can somebody point me in the right direction of a more idiomatic approach to building up a list from repeated calls to a function
01:27dpwrightBasically, I have a function (lanterna.screen/get-key) which returns the last pressed key if there was one, or nil otherwise
01:28dpwrightright now I'm using loop/recur with an accumulator to put all these keys into a list and drop out when it returns nil
01:28dpwrightbut I feel like there must already be a function which does that -- runs a function repeatedly, conj/consing the result into an accumulator, until some predicate has been met
01:30tomoj(->> f repeatedly (take-while (complement pred))) ?
01:32dpwrighttomoj: Ooh, a couple of things I didn't know about there.. I've used -> but not ->>, and I've not used take-while
01:32tomojyou successfully decoded the ->> I guess?
01:32dpwrightsame as -> but at the end?
01:32tomojindeed
01:33tomojlanterna.screen/get-key sounds sorta insane
01:34tomojI mean what does (take-while (complement pred) (repeatedly lanterna.screen/get-key)) even mean
01:34tomojer, (take-while identity ..)
01:35tomojit's something like "if the user is pressing keys faster than I can handle them, keep adding to this seq I'm building, otherwise the seq ends"?
01:35dpwrightyeah, or pressing two keys at once
01:36dpwrightalthough I'm not actually sure whether it does work like that
01:36dpwrightit's last key pressed, not all keys currently down
01:37tomojoh, and, I see, it's buffering them up instead of just dropping them
01:37dpwrightbut yeah, I suppose if you were to press two keys precisely simultaneously they'd come in at the same time
01:38dpwrightwell... actually I'm not sure that it is doing that, heh
01:38dpwrightthat's what I wanted it to be doing
01:38dpwrightbut looking back at the documentation, it might not be doing that
01:38tomojI just read "Each call to get-key pops one character off the input buffer and returns it. If there isn't anything on the buffer, it returns nil."
01:39tomojwhich makes me not quite want to say 'insane' but still seems nuts
01:39dpwrightoh good, I'm not going mad though
01:40dpwrightit makes sense if you want to treat each key as an event and act on it straight away, I suppose
01:40dpwrightprobably not all that "functional"?
01:42dpwrightthis question in particular was more general anyway -- this is not the first time I've used loop/recur in this way... it seems quite common that there's some non-pure function that is pulling in outside information, like new keypresses or incoming network packets or whatever, and I just want to buffer them up
01:47tomojlooks like it's lanterna's fault (not clojure-lanterna's)
01:47tomojreminds me of datomics tx-report-queue though which apparently stu and rich are fine with (?!)
01:49dpwrightwould you mind explaining why it's nuts? I feel like I'm missing something obvious
01:52tomojseems like you have to have exactly one place in your program which reads input
01:52tomojand then distributes that input out to the multiple places that need it
01:52dpwrightah
01:53tomojor you just go full imperative style and write get-key all over the place - then how do you make sure you don't consume an input someone else wants?
01:53dpwrightyeah, that is why I'm having to do this pulling it into a list thing
01:54tomojI guess a counterargument is that get-key and tx-report-queue are more raw, and they couldn't make the right choice for everyone, so you just suck it up and make the right choice for you in that one place in your program..
01:55dpwrightbut... what's the alternative? otherwise you'd have to have some way of, I don't know, clearing it or something.. or putting timestamp information along with the keypress so you can work out if it's interesting to you or done with, or...
01:55tomojyeah the alternative I really want doesn't belong in lanterna nor datomic (this is why the counterargument occurred to me)
01:56tomoja more lightweight and common alternative would be like (add-input-listener! terminal (fn [char] ...)) or something
01:56dpwrightah right, yeah
01:57dpwrightI guess as you say, that's slightly higher level and easy enough to implement on top of lanterna/whatever yourself
01:58tomojyeah I wouldn't expect rich to put that in datomic!
02:00dpwrightanyway, thanks -- rephrasing the loop/recur into a combination of repeatedly and take-while works and makes the code a lot nicer to read too :-)
02:02tomojactually though
02:02tomojit does belong in datomic
02:03tomojhopefully in 1.6
02:37tomojhiredman: https://www.refheap.com/paste/c85b347e704d5d6ce70a31bef :/
02:44tomojhttps://www.refheap.com/paste/caa9c0785111b142ae1c81e91
02:45tomojseems pretty weird
04:30tomojshould r/map preserve metadata?
05:56rodnaphi'm having a strange problem where on my build server leiningen isn't fetching a plugin dependency (lein-bin). it seems to fetch all the others... i'm stumped as to how to debug it, can anyone help?
05:57rodnaphfine locally, fine on a VM image which should (should) be identical. but not on the server. it's running inside a mock RPM build root.
06:06broquaintIs something purporting to satisfy the lein-bin dependency and thereby obviating lein from pulling it down?
06:08rodnaphbroquaint: hmm... possibly, how could i check? and why would it work in one env and not another?
06:10broquaintI'm not sure, rodnaph, if you open a mock shell you can poke around and see what's what.
06:10broquaintThat's my usual approach anyway :)
06:11rodnaphok, i'll see if i can get in. thanks
06:11noidi_rodnaph, do you have a ~/.lein/profiles.clj on either machine?
06:12rodnaphthere shouldn't be... if lein-bin was specified in there would it not get pulled down?
06:12noidi_I don't know, that's just the first thing that came to my mind that might be different between the Leiningen installations
06:13noidi_there's also the #leiningen channel, maybe someone over there can help you
06:15rodnaphyah will check now (it's usually the same ppl in #leiningen as #clojure though, hehe)
06:22tomojI wonder why the pedestal app model has both :value and :attrs
06:22tomojis :attrs analogous to metadata?
06:23tomojif not, why isn't the :value just a map instead?
06:23sveduboisDo you know any "hello world" tutorial about Prismatic/dommy?
06:36tomojhttps://github.com/pedestal/samples/blob/master/square-root/src/square_root.clj how does this even?
06:37tomoj{:fn sum :input #{:guess :divide}} {:fn half :input #{:sum}}
06:37tomoj(defn sum [state inputs] ...)
06:37tomoj(defn half [state input-name old new] ...)
06:44tomojhttps://github.com/pedestal/pedestal/blob/master/app/src/io/pedestal/app/util/adapters.clj#L42
06:44tomojOK, so that's deprecated. good.
06:47tomojhttps://github.com/pedestal/pedestal/blob/master/app/test/clj/io/pedestal/test/app.clj#L476
06:54noidi_Pedestal seems quite daunting at a first glance
06:56noidithere's a lot to more to take in than in a typical "data goes in, data comes out" Clojure library
07:07callennoidi: seems like a big prank being pulled on the clojure web community.
07:07callen"snicker snicker, lets see if they actually think this stuff is good. snicker snicker"
07:43Okasucallen: What stuff?
07:44muhooit feels to me like there's a better way to do this: (assoc m :durations (-> m :durations duration-fix*))
07:44TimMccallen: Shush, unless you're going to give an actual critique.
07:45muhooi want to swap the value of :durations with the application of a function to it
07:46muhooi am golfing tho. this is prolly fine
07:50Anderkentmuhoo: (update-in m [:durations] duration-fix*)
07:50muhooupdate-in, of course, thanks
07:51tomojdpwright: I think I stumbled upon what you were talking about earlier
07:51tomojhmm, nevermind
08:03muhooheh, and after no sleep, i write stuff like this (apply cons ((juxt (comp keys first) (partial map vals)) ms))
08:04learnerHello Gurus. A newbie question here. I am reading Clojure STM stuff and I understand a transaction is retried if there is a state change. Is there any way I can print a simple println statement everytime a transaction is retried due to a conflict/state change? Thanks for your help in advance. cheers
08:05TimMclearner: Sure, just throw a (println "whoops!") at the top of the dosync.
08:09learnerTimMc: Hmm, it gets printed for every run even though there is no conflict. Isn't it?
08:14TimMcDerp. Yeah, it does. Uhh... you'll need an atom or something.
08:15TimMc(let [tries (atom 0)] (dosync (when-not (zero? @tries) (println ...)) (swap! tries inc) ...))
08:15TimMcThat works if there isn't a containing dosync.
08:35learnerTimMC: I slightly modified example given @ http://clojure.org/refs by adding new atom and printing the total count at the end. And I can see the diff. Thanks for the hint. cheers
08:35learnerTimMc: I slightly modified example given @ http://clojure.org/refs by adding new atom and printing the total count at the end. And I can see the diff. Thanks for the hint. cheers
09:47SpindleyQIs it just me, or is there no clojure function or library for writing EDN?
09:49bbloomSpindleyQ: pr and prn will do it, but you just need to validate yourself that the output will be EDN: you can do that with = and clojure.edn/read
09:51SpindleyQbbloom: but I'd like to use tagged elements to eg. serialize a queue
09:53bbloomSpindleyQ: for your own types, you can override the printing mechanisms, but you shouldn't do that for other people's types. beyond that: i agree, it's a problem that tagged literals came after all the core print methods were already defined
09:53SpindleyQbbloom: afaict the way to override pr for different types is with print-dup? But print-dup with even a simple map gets me things like "#=(clojure.lang.PersistentArrayMap/create {:x 3})" which is not helpful
09:54bbloomyou can defmethod print-method, but you really should not change the print behavior for queue or anything like that
09:54bbloomfor your own types, you can just define print-method & it will work
09:58jtoyif i have code in project and i want to make a version that is a standalone dameon and a version that runs in a batch mode, would i use the same project? or seperate them?
09:58jtoyso basically build 2 different executables
09:58tcrayfordjtoy: imo that's purely up to you. You could use lein's profiles to build two different executable uberjars
09:59jtoytcrayford: ah ok, my confusion was how would i build 2 seperate jars, i didnt know about lein profiles, ill try to use that
10:00tcrayfordsee https://github.com/technomancy/leiningen/blob/stable/doc/PROFILES.md for more on that
10:01bbloomjtoy: do you really need to separate jars and two separate builds?
10:01bbloomjtoy: could you just have one jar with two different bash scripts to start different main functions?
10:02tcrayfordjtoy: alternatively you could use a command line switch with your main function
10:02jtoybbloom: yeah, i could do that, i've never written java before clojure though, so im not sure how all the jva parts work
10:02bbloomjtoy: in general, java doesn't really like to be run as a normal unix process
10:02tcrayfordjtoy: if you don't need different jars, I would say just one build with a bash script makes more sense
10:03jtoyi dont really need different jars, i could use the same one
10:03bbloomjtoy: when you run java code, you tell it which class to look in for the main function. jars can specify in metadata where to look for that
10:04bbloomjtoy: you can either compile two main functions or compile one main function that switches on command line parameters
10:04bbloomthe lein folks would need to weigh in on if/how you can get that to play nice with `lein run`, since i haven't messed with that before
10:11Anderkentbbloom: you can always lein run -m main.namespace , or give a default main and declare some alias in the project.clj
10:11bbloomjtoy: ^^ yeah what Anderkent said
10:11Anderkent:run-aliases {:alt [alternative.namespace "arg1" "arg2"]}
10:43shriphanihi. I have a question about doall. I have a large file that I read in line-by-line and then apply a function to each line. I currently do: (doall (map f (line-seq in))). Now, is there a way to not force the entire list to be evaluated in case I just need something like (first (routine-that-reads-line-by-line …)) i.e. eval lazily.
10:50jjttjjshriphani: can't you just take off the doall?
10:50shriphanijjttjj, what if I want the first 100 lines ?
10:51shriphaniwon't in close ?
10:51tcrayfordshriphani: combining laziness and io is typically a bad idea
10:51tcrayfordand it might well close ;)
10:52shriphanitcrayford, I just want to be able to do (first *sequence-of-processed-strings*) and not have to wait 20 mins...
10:54tcrayfordshriphani: yeah, that's actually a hard problem. Ensuring the file isn't closed with laziness in the picture is somewhat tricky.
10:55tcrayfordI'm assuming from what you said above that this is a *very* large file, such that you can't just read it into a string?
10:56tcrayford(that's a dumb solution, but it can work in some cases)
10:56shriphanitcrayford, yes.
10:57tcrayfordyeah, you're pretty fucked if you wanna use first and have laziness and file closing. In haskell I could point you at like 6 competing libraries that solve this problem, but they don't exist in clojure (and afaik on the jvm)
10:58mmitchellleiningen question -- anyone know if it's possible to set the active "profile" with a plugin? I'd like to hook into an existing task (lein mijde), and set the project profile to "test" -- doable?
10:58tgoossensIf I would like to ask rhickey a question. What medium should I use. (It's not urgent at all (ie: i am not planning to spam). I would just like to ask him some questions about his study (I'm about to choose my masters degree) ) ? If I get no answer, then that's also okay.
11:03Anderkentmmitchell: not sure if you can do that with a plugin, but if you're making a custom task you can do it easily - just look at what with-profile does, and do the same thing
11:07mmitchellAnderkent: ok thanks, i'll do that
11:12shriphanitcrayford, so if you had to implement the unix head command in clojure, you would need to load the entire file ?
11:13tcrayfordshriphani: I'd be kind tempted to do head completely imperatively, if I was doing that. You don't need to load the entire file, it's just if you want laziness in there and streaming, and good resource finalization, you need something more complex.
11:13justin_smithshriphani: I don't think it is that bad, the problem is that if you want to use the file handle to generate a lazy structure, you need to have a strictness boundary before you leave the scope of the file being open
11:14jtoyif i am making a basic server that gets a request and spits out json, what server would you use?
11:14justin_smithlaziness and resource handling can be a tricky combo in general
11:14jtoyi want something very small and simple
11:14justin_smithsimple in its implementation, or simple for you to use?
11:15jtoysimple for me to use
11:15Anderkentjtoy I think ring + compojure is probably your best bet
11:15justin_smithring is straightforward for that
11:15justin_smithyeah
11:15Anderkentassuming you're talking http
11:15jtoyi dont have to talk http, but that probably is the easiest?
11:15tcrayfordyeah, I'd say so
11:16jtoythe server is only serving one request, so i dont a full web service framework
11:16justin_smithOSC is easier, but not everything talks OSC :)
11:16jtoywhat is OSC? open soud control
11:16justin_smithyeah
11:16justin_smithsends arbitrary structured data over udp
11:17justin_smithvery simple
11:17justin_smithbut it is udp, so it is also lossy
11:17justin_smith(potentially - I trust it over a wire but not on wifi)
11:18AnderkentSo guys - I have a server running somewhere and a repl on it. Some other threads have defined functions there and are using it. I want to modify one of these, so that the modification propagates to all the threads. Do I use alter-var-root? Do I just do (defn function-name ...)?
11:19shriphanijustin_smith, how about I ditch with-open and open and close the handles myself ?
11:19shriphaniI tried doing a .close on the reader and it complained....
11:20justin_smithshriphani: I think it would require using java interop
11:20justin_smithbut then you have some trouble getting a lazy structure out?
11:21justin_smithshriphani: one option is to explicitly leave the scope of the with-open
11:21shriphanijustin_smith, how do I do that (sorry - I'm a noob).
11:22justin_smith(with-open ... (for [...] ...)) for has ways of describing an "exit condition", so you have for drive the reading of the data, and tell for you are done and have it return the accumulated data when apropriate
11:23shriphaniah.
11:23shriphanibut then say I do (nth (get-lines-lazy …) 5).
11:24justin_smithyou could similarly use take-while
11:24justin_smithany construction that goes through a part of a lazy seq then returns
11:25TimMccemerick: Will you be at the Boston Clojure Meetup tonight? If so, would you mind exchanging key signatures?
11:25cemerickTimMc: Nope, missing this one.
11:25shriphanijustin_smith, I meant how versatile would the code be if I had to express an :exit condition.
11:26justin_smithshriphani: I think the trick would be to put the function that actually decides how much of the lazy seq you want directly inside the with-open
11:26shriphanione sec. if my :exit did a readline and got a nil and I checked and finished on that condition, would I still be able to do first, nth etc. with it ?
11:27justin_smithit would return a lazy seq up to the point you said it was done
11:27justin_smithunless you tell for not to collect the results somehow
11:27justin_smitherm... maybe not lazy? ugh
11:27shriphaniand I could obviously do first, nth etc and only a partial amount of the file would be read in right ?
11:28justin_smith(with-open "file" (doall (for ...))) would be the safe bet, dunno how strict for is off the top of my head
11:28shriphanijustin_smith, wouldn't doall force eval?
11:28shriphanii.e. wouldn't it cause the entire list to be loaded ?
11:28shriphaniI am not opposed to using interop.
11:28justin_smithshriphani: yes, the trick is that for is deciding how much to generate
11:30justin_smitheasier example than for: (with-open [rd (io/reader "file")] (take 10 (line-seq rd)))
11:30justin_smiththat is unix head
11:30justin_smithor a simplified version
11:30justin_smithit only ever reads 10 lines
11:31justin_smiththe trick is that you need to know, before exiting the with-open block, how many lines to read
11:31shriphaniyeah. I will probably use interop for this.
11:31justin_smithbut with (for ...) you can decide which line is the last
11:32justin_smithnotice how with-open uses (io/reader ...) - can't you just directly call io/reader and close the result when done with it?
11:32justin_smithor did you say that already failed to work?
11:33shriphanijustin_smith, I found something on s/o that used a lazy-seq to recursive read lines and called .close at the end.
11:33justin_smithcool
11:34shriphanibut it gave me this: No matching field found: close for class clojure.lang.LazySeq%
11:34shriphaniso I will probably need to avoid using lazy-seq
11:34Anderkentyou must call .close on the input stream, not on the lazy seq that is returned
11:34shriphaniyeah I figured.
11:34justin_smithshriphani: even if you use a lazy-seq to read from, don't you still have the value returned by io/reader?
11:35justin_smithI really don't think you need to use java primitives for this
11:35shriphanijustin_smith, yes.
11:35Anderkentaren't java streams closed on garbage collection anyway?
11:36Anderkentyou could just figure that since the file is private to the lazy seq, it will be closed eventually once the lazy seq is used and discarded. As long as you're only reading, that shouldn't be an issue?
11:36justin_smith(def rd (io/reader "project.clj")) (take 1 (line-seq rd)) ...
11:37justin_smith(.close rd)
11:37justin_smithworks!
11:37shriphaniyeah.
11:37shriphaniactually can I wrap this in a macro myself?
11:37justin_smithshriphani: those three calls are all you need (plus some looping logic I imagine)
11:37Anderkentwell if you know how many lines to take you can just do (with-open [rd (io/reader filename)] (doall (take n (line-seq rd)))
11:38justin_smithhe was looking for something more flexible than with-open
11:38TimMccemerick: Won't somebody think of the children^Wweb of trust!
11:40justin_smithshriphani: also, repeated calls to (take n (line-seq rd)) return the next n lines
11:41Anderkentany convenient way to read all the content from a inputstream/reader?
11:41justin_smithAnderkent: line-seq will try to return the whole thing if you don't use take to restrict it
11:42Anderkentas multiple strings though
11:42Anderkenti just want the contents of a stream
11:42justin_smithslurp
11:42Anderkentthat's on file not stream?
11:42justin_smithslurp works on anything returned by io/resource in my experience
11:42justin_smithwhich is not neccissarily a file
11:43Anderkentoh, thanks
11:43shriphanijustin_smith, I finally have: https://www.refheap.com/paste/14348
11:43justin_smithit calls reader on the arg, so you can see clojure.java.io/reader to see what args work with it
11:44shriphanithere is a recursive call there. would that be a problem (i.e result in stack-overflow if I read a lot of lines?)
11:44justin_smithshriphani: well you could refactor to a version that can use recur
11:45arrdem /join #libcello
11:45justin_smithby adding an accumulator argument to the function, so that call can be a tail call
11:45shriphaniok done.
11:45justin_smithshriphani: also, (.close rdr) already returns nil, no need for a do there
11:46justin_smithalso, I think io/resource can get you a stream from a gzipped file, and would be much simpler
11:47justin_smithI know I use it to open files inside zips transparently
11:47justin_smith(inside file.zip, not clojure zippers)
11:48justin_smithso lazy-file-lines always returns all the lines of the file, correct?
11:50shriphanijustin_smith, yeah
11:50shriphanibut it isn't eager.
11:51justin_smiththen you could do (with-open [rdr (io/reader (io/resource "something.gz")) rdr] (line-seq rdr))
11:52justin_smithif you only read 3 elements of the list, it would only read 3 lines of the file
11:52justin_smiththen the file would be closed
11:52justin_smithI thought you were doing something more complex
11:53justin_smitherr.
11:53justin_smithnever mind!
11:53justin_smithI see the problem now
11:53justin_smithhah
11:53shriphanijustin_smith, did I do something stupid…..
11:54justin_smithno, I did!@
11:54justin_smithI now realize, laziness makes that not work
11:54justin_smithyou need to know, inside the with-open, how many lines you need
11:54shriphanialso, recur expects 0 args here: https://www.refheap.com/paste/14349 …. why is that
11:55justin_smithzero args? that is weird
11:55shriphaniCompilerException java.lang.IllegalArgumentException: Mismatched argument count to recur, expected: 0 args, got: 2, compiling:(reddit_crawler/read_posts.clj:16)...
11:56justin_smithI would imagine some weird macro interaction
11:56justin_smithwhere that is actually inside a hidden zero arg function
11:57justin_smith,(macroexpand '(lazy-seq (+ 1 1)))
11:57clojurebot(new clojure.lang.LazySeq (fn* [] (+ 1 1)))
11:57justin_smithsee, lazy-seq creates a thunk
11:57justin_smithso recur is not possible there
11:59shriphaniI am not even sure how to debug some of the things I see….
12:00justin_smiththat hidden function call thing makes more sense when you start writing macros
12:00justin_smithas does the instinct to check macroexpand
12:00shriphaniso I can't use recur there ?
12:01justin_smithit will need to be refactored in order to be able to recur
12:02shriphaniugh..
12:02justin_smithmaybe it could be turned into reduce?
12:02bbloomshriphani: you need to realize that recur compiles down to a loop. if you have laziness, you need to break out of evaluation, so recur can't jump back into a loop
12:02bbloomshriphani: you can use explicit recursion, which doesn't have the memory guarentees as recur
12:03justin_smithyeah, my suggestion of using recur was off base here, sorry!
12:03edbondshriphani, you are trying to get lines from gzipped file?
12:03shriphaniedbond, yeah...
12:03bbloomshriphani: but that's OK, b/c the explicit recursion will be inside a thunk, so the stack won't nest, some calling code walk the lazy seq and evaluate the thunks in a flat manner, so the stack won't blow up
12:04bbloomso in that paste you made, just replace recur with helper
12:04shriphaniok.
12:04shriphaniI was thinking otherwise to do a (take-while identity (.readLine rdr)).
12:05bbloomthere is almost always a general function for any major use of lazy-seq you can think of
12:05shriphaniumm (repeatedly $(.readLine rdr)).
12:06bbloomgenerally, i like to avoid laziness in my IO code....
12:06shriphaniuh-oh that is not lazy anymore..
12:06justin_smithshriphani: how does (repeatedly #(.readLine rdr)) differ from (line-seq rdr)
12:07shriphaniit doesn't..
12:08shriphanibbloom, If I move the helper call to a non-tail position, it will still be evaluated without a stack-overflow ?
12:10edbondshriphani, see https://www.refheap.com/paste/14350
12:10bbloomshriphani: without looking at your particular example: laziness involves replacing tail positions with thunks and then letting somebody else execute those thunks. when that happens, the tail position returns a Seq object with the thunk in it and that somebody else is going to execute that thunk in a different stack context. if that thunk then produces ANOTHER thunk, it's not nested in the first one… so there is no stack overflow possibl
12:13shriphaniedbond, that works….
12:14justin_smiththat relies on gc to close the fd, correct?
12:14shriphaniyes I think so.
12:15irctc092I have a problem which matches the bin packing problem - http://en.wikipedia.org/wiki/Bin_packing_problem . Can anyone help me translate this into a clojure algo ?
12:15justin_smithyou could easily modify it to return the handle for further usage or closing
12:17justin_smithirctc092: which algo?
12:17justin_smithfirst fit, best fit decreasting, first fit decreasing?
12:17justin_smithI would reduce, with an array of objects and an array of bins
12:19justin_smithan object being a number (size) a bin being an arry, with (apply + array) telling you its current volume
12:19justin_smithwell I guess you need hashes, since you also want to know a max capacity
12:19justin_smith(apply + (map :capacity bin))
12:19irctc092best fit decreasing is what I am looking for
12:20justin_smithso, each bin should be something like {:capacity 100 :contents [1 2 3]}
12:20justin_smithwhere contents are the sizes of the objects it has in it
12:21irctc092yup and also the objects themselves
12:21justin_smithso (apply + (:contents bin)) tells you how much it has in it and (:capacity bin) tells you how much it can hold
12:21justin_smiththen your objects are an array of numbers
12:22irctc092so :contents [ [3 "abc"] ...] , where 3 is the volume
12:22justin_smiththen you reduce across the array of objects/numbers with the bins as your accumulator
12:22justin_smithoh, you could do {:size 3 :id "abc"} for the objects
12:22justin_smithyeah
12:24justin_smithso (reduce (fn [bins object] ...) [{:capacity 100 :contents []} {:capacity 44 :contents []}] [{:size 6 :name "abc"} {:size 33 :name "hugo"}])
12:24justin_smithnow you just want to add the object to a bin, and return the new set of bins, in the reducer function
12:25justin_smithoh, and best fit decreasing (reverse (sort-by :size objects))
12:26irctc092how does sorting them by size help ?
12:26justin_smiththat is how you do best fit decreasing
12:27justin_smithbefore iterating on them you sort reverse size
12:27justin_smithso you find places for biggest first
12:28justin_smith(reduce (fn [bins object] ...) [{:capacity 100 :contents []} ...] (reverse (sort-by :size [{size 6 :name "abc"} ...])))
12:28justin_smithright?
12:28clojurebotflatten |is| rarely the right answer. What if your "base type" is a list
12:30irctc092so if I have added a number of items to the bin, and it still has some space left. Now comes another item which does not fit bcoz its vol is greater than that left. However if I manually look at the bin, I can replace one of the items and have an exact fit for my volume, how do I aceieve that?
12:31justin_smithsounds like you would need a loop with object and bins as args
12:31justin_smithif you find a potential swap, you recur with the current obj swapped out with an element from one of the bins
12:32justin_smiththe trick being how do you make sure that loop does not keep swapping objs out of bins indefinitely?
12:32irctc092yup that is what I am struggling with ?
12:33irctc092I assume this should be an algo / pattern which is established, but cant find one ...
12:33justin_smithmaybe you only do a swap if obj swapped in is larger than the one you are swapping out? that will stop eventually
12:34justin_smithbecause the obj swapped will be smaller every time
12:34justin_smithbase case smallest object has no home
12:35irctc092didnt understand the base case
12:35justin_smithso the danger of infinite recursion is if you just keep swapping because there is no fit findable by the algo
12:35justin_smithif you only swap with a smaller object, the smallest object will not recur
12:36irctc092yup that should work ... let me code that
12:36irctc092thanks justin
12:36justin_smithnp!
12:36justin_smithmore fun than stinky orm web ui crap I should be doing
12:36justin_smithlol
12:45edoloughlinIs it possible to use type hints to help destructring for multiple function bodies? https://gist.github.com/edoloughlin/5548643
12:46edoloughlinI get an error: " Unable to resolve symbol: & in this context"
12:47hiredmanedoloughlin: because you aren't doing multiple function bodies correctly
12:47edoloughlinoh.
12:47hiredmanedoloughlin: keep in mind, destructure is not pattern matching, the only thing that determines which body you get is arity
12:48edoloughlinok. thanks. Will read more...
12:48hiredmanyour function wouldn't work if it had the correct syntax because the last arity can accept the same number of args as the first
12:49edoloughlinSo, there's no way to do what I want?
12:49hiredmana good rule of thumb is "varargs, every function gets one"
12:49bbloomedoloughlin: you're trying to accomplish overloading by type?
12:50edoloughlinI just want a different body executed if I have a Throwable in there
12:50hiredmanedoloughlin: in computer programming there is always a way to get what you want, the real question is "is it worth it?"
12:50edoloughlinGuess I'll take the path of least resistance. Thanks.
12:50bbloomedoloughlin: so clojure can only dispatch on normal functions by arity
12:51edbonduse (if (instance? <class> <obj))
12:51bbloomedoloughlin: there are more complex dispatch strategies, but none that directly match the optional infix argument switched by type
12:51bbloomedoloughlin: so yeah, the simplest thing to do is to have the signature [error-key & args] and then parse args
12:52edoloughlinOk. Thanks. Will do.
12:52bbloom(let [[cause & args] (if (exception? (first args)) args (cons nil args)))
12:52bbloomsomething like that
12:52edoloughlinThanks. Gotta run.
13:06justin_smithis there a way to introspect on an fn and see its source? we have a hash of hooks and want to verify the contents at runtime
13:07bbloomjustin_smith: not generally
13:08bbloomjustin_smith: the `source macro can show you code as declared in files, but it won't work for local functions or ones entered at the repl or what not
13:09justin_smithbut if it was an anonymous fn from a file, would source help there?
13:09bbloom,(source source) ; it's not as scary as it looks :-)
13:09clojurebotSource not found\n
13:10bbloomheh. well that works in a real repl
13:10justin_smithwhat namespace is source in?
13:10justin_smithit is not bound here
13:10bbloomclojure.repl
13:10bbloomshould be loaded by default by lein
13:10justin_smithok, I did not have clojure.repl loaded
13:11justin_smithI am running swank manually from inside a webapp request handler thread
13:11dabdhow can I translate the following imperative idiom to functional clojure? https://gist.github.com/anonymous/5548875. The first 'for' computes some values of an array but it stops as soon as somePred returns false. But the values of the array are used in the following for cycle. It seems clear I need to use reduce to accumulate the array but how do I make it stop as soon as somePred returns false?
13:11bbloomeasier to just dig into ##(-> #'clojure.repl/source meta :file)
13:11lazybot⇒ "clojure/repl.clj"
13:11justin_smithso clojure.repl is not there automatically
13:12bbloomdabd: ##(doc reduced)
13:12lazybotjava.lang.RuntimeException: Unable to resolve var: reduced in this context
13:12bbloomshesh, lazybot is not cooperating with me today
13:12bbloom,(doc reduced)
13:12clojurebot"([x]); Wraps x in a way such that a reduce will terminate with the value x"
13:12bbloomthat's the most general answer
13:13bbloombut you can map & take-while
13:13justin_smithor (take-while ... (reductions ...))
13:13bbloom,(->> (range 10) (map dec) (take-while #(< % 5)))
13:13clojurebot(-1 0 1 2 3 ...)
13:14bbloomdamn print limit… i am sucking at clojure bots today
13:14bbloom,(->> (range 10) (map dec) (take-while #(< % 2)))
13:14clojurebot(-1 0 1)
13:15bbloomand then if you want to index into that value, use a vector:
13:15bbloom,(->> (range 10) (map dec) (take-while #(< % 2)) vec)
13:15clojurebot[-1 0 1]
13:15justin_smith,(take-while (partial < -20) (reductions - (range)))
13:15clojurebot(0 -1 -3 -6 -10 ...)
13:15justin_smiththat would have ended at -15
13:15bbloomnow you can index into it: ##([-1 0 1] 0)
13:15lazybot⇒ -1
13:15bbloomnow you can index into it: ##([-1 0 1] 2)
13:15lazybot⇒ 1
13:16dabdok thanks for the ideas, i can't find how to use reduced
13:16dabdout of curiosity it seems interesting
13:16bbloomdabd: reduced is new in 1.5
13:16bbloomdabd: forget i mentioned it :-P
13:18justin_smithyou can use reductions exactly the way you would reduce (it just returns a lazy seq rather than the final result, last element of that seq is the result)
13:22edbonddabd, take a look at http://stackoverflow.com/questions/15625341/reduce-a-lazy-sequence-like-a-loop-with-a-condition-in-clojure for reduced example
13:23dabdedbond: thanks!
13:24irctc260(def items (take 20 (repeat {:desc "abc" :weight (int (rand 100))})))
13:25dabdreduced seems the simplest solution and apparently it is faster in 1.5 too
13:25irctc260I am trying to create a list of 20 diff items, however the above returns a list of 20 same items
13:26irctc260(def items (take 20 (repeat {:desc "abc" :weight (int (rand 100))})))
13:26justin_smiththat only calculates the rand once
13:26justin_smithyou want repeatedly with a thunk
13:27justin_smith(def items (take 20 (repeatedly (fn [] {:desc "abc" :weight (int (rand 100))}))))
13:28gfredericks"the heap of flour fell to the ground repeatedly with a thunk"
13:28justin_smithheh
13:29irctc260yup thanks
13:31irctc260justin_smith: why doesnt this work ? (def items (take 20 (repeatedly #({:desc "abc" :weight (int (rand 100))}))))
13:31gfredericksyou're calling the map
13:31justin_smiththat tries to call the map as an fn
13:31gfredericksthe #() syntax is bad for returning a literal
13:31justin_smiththere is #(do ...)
13:32edbond#(hash-map :a 4)
13:32justin_smithbut (fn [] is only one extra char
13:32justin_smiththat is even more extra chars!
13:32gfredericksthere's like 4 ways to do it, and (fn []) is probably the one that takes the least thought and indicates intent the clearest
13:32edbond:)
13:33irctc260yup that makes sense...
13:33dabdanyone knows why nrepl-quit won't kill the java processes on win?
13:42sritchiedo you guys have any suggestions for a directed graph library in clojure?
13:42sritchiebacwn and contrib.datalog both have the same graph.clj file,
13:42sritchiebut I'm hesitant to lift the thing out...
13:44bbloomsritchie: depends on what you want to do with it
13:44sritchiebbloom: I'm rewriting the cascalog datalog implementation
13:45sritchieso, I want to compile a set of datalog rules down into a directed graph of computations that I'll feed into MapReduce
13:45sritchieinto Cascading, specifically
13:45bbloomsritchie: without knowing anything about cascalog's datalog impl….. do you need a large library of graph functions? or are there a particular small number of algorithms you need?
13:45bbloomconsidering how easy it is to represent a graph with a clojure data, it seems unwise to bring in a large/complex library of representations
13:46amalloybbloom: it's not *that* easy to represent a graph in clojure, if you want to have any cycles
13:47arrdemamalloy: use node ids and that's easy
13:47bbloomamalloy: it's pretty easy to represent any graph as a spanning tree if you assign names/identities to nodes
13:47sritchieI don't need much, just a few functions for getting inbound edges, outbound edges, etc -- it's easy to code, but if a small library existed I wanted to avoid the duplication
13:47amalloyi know. but that's another layer of indirection you'd rather the graph library deal with
13:48arrdemsritchie: there's loom on github, I can vouch for the fact that it works and is pretty usable
13:48sritchiehere's the bacwn graph file, lifted from the old contrib datalog: https://github.com/fogus/bacwn/blob/master/src/clojure/fogus/datalog/bacwn/impl/graph.clj
13:48amalloywait, how do spanning trees enter into it, bbloom?
13:49sritchiearrdem: great, good tip
13:49irctc260I want to sort these - (def items (take 20 (repeatedly (fn [] {:desc "abc" :weight (int (rand 100))})))). (sort :weight items) doesnt work. How do I define a java.util.comparator ?
13:49bbloomamalloy: you flatten your graph into a tree… that tree touches all the vertexes of the graph
13:49arrdemsritchie: used it to build a type hierarchy so I only really touched the directed graph parts of it, not sure how well the weighted graph bits work tho
13:49justin_smithirctc260: you want sort-by, not sort
13:50justin_smithsort-by takes :weight from each of the two, and does a standard comparison
13:50justin_smithsort, as you notice, needs a true comparitor (taking two objs, returning -1 0 or 1)
13:50irctc260thanks
13:50amalloybbloom: i know what a spanning tree is. turning a graph into a spanning tree either loses a lot of information, or makes it very hard to work with, if you want to do general graph stuff to it
13:52bbloomamalloy: ok maybe spanning tree isn't precisely the right thing to call it when you flatten all the vertices into a list
13:52bbloomamalloy: you got a better name?
13:53arrdembbloom: how are you representing edges in this structure?
13:54amalloyarrdem: the same way you suggested, he's just not very good at verbalizing it :)
13:54bbloomarrdem: depends on if you need to to associate data with your edges. depends on if your edges are directed. depends on if they can be traversed in both directions
13:54arrdemamalloy: ah. yeah that's how loom does it, but it makes sense for clojure especially
13:55bbloomi'm sorta anti-graph-library b/c there are too many representational considerations that by the time you've picked all the choices, you might as well have written the 5 functions you needed for your use case
13:56bbloomand i don't think that it's a good idea to always go with the most general version; something like a graph database with propertied nodes & edges
13:59hugodbbloom: what are your plans regarding a fipp release? I used it here https://github.com/pallet/robot-crab/blob/master/src/robot/crab/print.clj and was thinking about how to get my project released.
13:59bbloomhugod: you just need a non snapshot release?
14:00hugodbbloom: right
14:00hugodI only saw snapshots on clojars
14:00bbloomwhat version are you using now?
14:00bbloomif you say it works, i'll consider that good enough and release a version :-)
14:01hugodhey! "0.3.0-SNAPSHOT" from a few of days ago
14:01justin_smithI have a hobby project to take declarative data structure describing a dag and translating that to a running synthesizer via csound
14:01justin_smithI should look into one of those proper graph libs
14:02justin_smithnodes = modules, edges = patch cables
14:02bbloomhugod: i'll make a 0.3.0 release
14:03hugodbbloom: thanks! no hurry
14:03bbloomoh now i remember why i didnt
14:03bbloomapparently to make a non snapshot release, you need to set up gpg and all that jazz
14:03bbloom:-/
14:04hugodI think signing is still optional
14:04bbloomis there a way to bypass it it quickly?
14:04arrdembbloom: no
14:04technomancyyes
14:04justin_smithgpg is easy to set up
14:04technomancybut yeah, if you're going to be releasing software you really should learn this
14:05bbloomtechnomancy: *sigh* fiiiiiiinnneeeee
14:05bbloomhugod: you'll have to wait until i figure that out
14:08hugodbbloom: np
14:09justin_smithgpg --gen-key
14:09justin_smithit is interactive
14:10technomancy`lein help gpg` too
14:11bbloomthanks guys. i've got phone meetings until 4pm… if i have the energy i'll try it then :-)
14:17irctc260justin_smith : how do I write the fn to decide which item to swap from the bin ? Given a bin {:capacity 100 :items [ {:w 20} {:w 30} {:w 40}] } and an item {:w 50} f(bin, item) => {:w 40}
14:26dabdafter trying to use compare on a lazyseq i got an error ClassCastException clojure.lang.LazySeq cannot be cast to java.lang.Comparable clojure.lang.Util.compare (Util.java:153)
14:26dabdHow do i convert a lazy seq to a seq that can be used with compare?
14:26edbondirctc260, isn't this a knapsack problem? http://rosettacode.org/wiki/Knapsack_problem/0-1#Clojure maybe you can get some ideas there.
14:27edbonddabd, how do you want to compare sequences?
14:28dabdhow to compare lexicographically two sequences (compare [1 2] [1 3])
14:28dabdI want to compare*
14:28dabdthe problem is that the sequences i am giving to compare are lazyseqs and it complains
14:29dabda simple solution is to use (vec s) but isn't this O(n)?
14:30amalloydabd: overly simple answer, but...write a function to do it. that's really all there is. walk the two sequences, and stop when you see a difference
14:31dabdso using (vec s) is inefficient?
14:31dabd(compare (vec s1) (vec s2))
14:35Pupnik-(compare (count s1) (count s2)) should give the same behavior as that
14:35Pupnik-which saves you from allocating new vecs probably, im no clojure expert
14:35Pupnik-,(compare [1 2 3] [5 6])
14:35clojurebot1
14:36Pupnik-,(compare (count [1 2 3]) (count [5 6]))
14:36clojurebot1
14:37matthavenercomparing the counts?
14:37dabdi want to compare the sequences lexicographically, comparing the counts doesn't make sense
14:37matthavenerif they're the same length you can do something like (every? #(apply = %) (map vector list1 list2))
14:37Pupnik-in that case you cant use the first one either
14:37Pupnik-because thats what compare does with vecs
14:37SegFaultAXPupnik-: You didn't read what he asked for.
14:38matthavenercompare with vecs just compares the length?
14:38matthaveneroh, you want the lexographic -1, 0, 1 output?
14:39SegFaultAXmatthavener: No, I don't think it does.
14:40justin_smith(any > v1 v2) ?
14:40amalloyit *starts* by comparing the length
14:40justin_smithI mean some
14:40Pupnik-(map compare s1 s2) ?
14:40Pupnik-,(map compare [1 2 3] [2 1 9])
14:40clojurebot(-1 1 -1)
14:41amalloy,(map compare [1 1 1] [1 1 1 2])
14:41clojurebot(0 0 0)
14:41SegFaultAXThe problem isn't comparing vecs or lists, the problem is he's trying to comapre a partially realized lazy seq.
14:42justin_smith(some #{1} (map compare v1 v2)) will stop comparing as soon as one element in v1 is greater than the corresponding in v2
14:43SegFaultAXVectors already short circuit during comparison.
14:44matthaveneryeah if you know they're the same length (or will eventually be unequal), you could do (first (drop-while #{0} (map compare l1 l2)))
14:44justin_smithactually make that some #{-1 1} - then it returns the comparator, and short circuits
14:44dabdwhat is the meaning of #{1}?
14:44matthavenerjustin_smith: or that, yeah
14:44justin_smithreturns nil if input is not 1
14:44matthavenerdabd: its a set that contains one element, 1
14:44SegFaultAXdabd: A set with a single element 1
14:44justin_smith#{-1 1} returns nil if input is not in the set, otherwise that element
14:45dabdok
14:45dabda set is also a function
14:45justin_smithyes
14:45SegFaultAXdabd: As are hashs, vectors, keywords, etc.
14:47dabdbut it won't work in the case ,(some #{-1 1} (map compare [1 2] [1 2]))
14:47dabd ,(some #{-1 1} (map compare [1 2] [1 2]))
14:47clojurebotnil
14:47SegFaultAXdabd: Use ## for in-line forms
14:47dabdty
14:47SegFaultAXJust coalesce the value to 0
14:47clojurebotGabh mo leithscéal?
14:48dabdwhat do you mean?
14:48SegFaultAX,(or (some #{-1 1} (map compare [1 2] [1 2])) 0)
14:48clojurebot0
14:48justin_smith(or ,(some #{-1 1} (map compare [1 2] [1 2])) 0)
14:48justin_smithoops!
14:48justin_smithhe beat me to it anyway
14:48amalloyfwiw, guys, IMO (-> (some #{-1 1} (map compare [1 2] [1 2])) (or 0)) is a bit easier on the eyes, since it keeps the 0 together with the or
14:49justin_smithamalloy: excellent point
14:49amalloy<3 ->
14:50dabdi need to start learning how to use the threading macros
14:50SegFaultAX(fn lazy-compare [& s] (-> (apply map compare s) (or 0)))
14:50justin_smith,(->> (map compare [1 2] [1 2]) (some #{-1 1}) (or 0)) ; is even better imho
14:50clojurebot0
14:50SegFaultAXProbably could use a when in there to make sure they're all seqs or something.
14:50amalloyjustin_smith: aside from not working at all, it's fine
14:51justin_smithoh, oops
14:51amalloythat will return 0 on any arguments at all, even non-collections
14:51justin_smiththe or 0
14:51SegFaultAXOh whoops
14:51justin_smithyeah
14:51SegFaultAXPasted the wrong code
14:51justin_smithdefining lazy-compare is better anyway
14:52amalloyalso, so far nobody has proposed a solution that handles collections of different lengths
14:52SegFaultAX(fn lazy-compare [& s] (-> (some #{-1 1} (apply map compare s)) (or 0)))
14:53SegFaultAXamalloy: This wouldn't be an issue at all if we already knew the length.
14:53SegFaultAXSince vectors already short circuit during comparison.
14:53SegFaultAX(And use count)
14:53SegFaultAXamalloy: I think the OP was asking about comparing a lazy seq.
14:54amalloyhe was...so you have to handle lengths properly. i don't see what you're getting at
14:55amalloyhe wants a function that acts like strcmp for sequences. you can't just ignore lengths
14:56justin_smithamalloy: does that mean forgoing map for an explicit loop?
14:56SegFaultAXamalloy: I don't think he wanted to realize the entire seq up front.
14:57SegFaultAXOtherwise, I agree with you.
14:57dabdthis issue came when trying to translate python code to clojure, since python < operator works on sequences
14:57SegFaultAXOh I see, nevermind. You're 100% correct
14:58dabdif one sequence is shorter it compares only up to the shorter sequence
14:58Pupnik-what if you convert the sequences to string then use compare?
14:58SegFaultAXPupnik-: Wut.
14:58slagyrI'm seeing some weird behavior with Var binding in Clojure 1.5.1:
14:58slagyrspeclj.config/*parent-description*: #<Unbound Unbound: #'speclj.config/*parent-description*>
14:58slagyr(bound? #'speclj.config/*parent-description*): true
14:58slagyr(thread-bound? #'speclj.config/*parent-description*): true
14:58slagyr(.getThreadBinding #'speclj.config/*parent-description*): #<TBox clojure.lang.Var$TBox@769a90b9>
14:59SegFaultAX~refheap
14:59clojurebotrefheap is forget ~paste
14:59SegFaultAX~paste
14:59clojurebotpaste is not gist.github.com
14:59SegFaultAXslagyr: Please refheap multi-line pastes.
14:59slagyrAnyone got a clue why the value of the var is Unbound, yet bound? returns true?
14:59dabdactually i am wrong is one sequence is shorter it does not evaluate up to the shorter sequence
14:59dabdif one*
15:00ppppaul,(doc ->>O)
15:00hiredmansure
15:00ppppaul,(doc ->>)
15:00clojurebotIt's greek to me.
15:00clojurebot"([x form] [x form & more]); Threads the expr through the forms. Inserts x as the last item in the first form, making a list of it if it is not a list already. If there are more forms, inserts the first form as the last item in second form, etc."
15:00ppppaul,(doc :>>)
15:00clojurebot#<ClassCastException java.lang.ClassCastException: clojure.lang.Keyword cannot be cast to clojure.lang.Symbol>
15:00hiredman(declare x) (def *parent-description* x)
15:00slagyrSegFailtAX: Sorry. https://www.refheap.com/paste/14358
15:00ppppaulcan someone explain this example to me? http://clojuredocs.org/clojure_core/clojure.core/condp#example_44
15:00ppppaulwtf is :>>
15:00ppppauli tried it in my repl and it works
15:01SegFaultAXppppaul: A man with 2 beards.
15:01amalloyslagyr: one way you could get into that scenario is (def ^:dynamic foo) (binding [foo foo] ...)
15:01justin_smithppppaul: a magic keyword in condp
15:01amalloyppppaul: (doc condp)
15:01ppppaulSegFaultAX, its
15:01ppppaulmagic keywords
15:01ppppaulmagic
15:01ppppaulmagnets
15:02ppppauli guess i should have looked at the source first
15:08Pupnik-,(compare (str [1]) (str [1 1]))
15:08clojurebot61
15:08Raynes@fogus on twitter: "OOP does model the real world! Things at the top of the hierarchy seemingly do nothing but tell those at the bottom what do do."
15:09RaynesFogus gold!
15:16mpenetnice
15:25gfredericksis there anything smelly about creating a background query function with java.jdbc that returns a lazy-seq that is eagerly realized in a background thread as the resultset is read?
15:26amalloygfredericks: i guess the only smelly thing is that you're not just using seque
15:27gfredericksthat thing I haven't remembered about for a year at least?
15:27amalloyi'm not actually sure if it would be easy to apply here
15:27amalloybut it sounds like the right ballpark
15:28gfredericksthe docs aren't clear about what the 1-arg version does
15:28gfrederickshow does "up to n items" apply if there is no n?
15:28amalloy&(doc seque)
15:28lazybot⇒ "([s] [n-or-q s]); Creates a queued seq on another (presumably lazy) seq s. The queued seq will produce a concrete seq in the background, and can get up to n items ahead of the consumer. n-or-q can be an integer n buffer size, or an instance of java.util.concur... https://www.refheap.com/paste/14361
15:28gfredericksalso I'm not sure how well that would fit with the "I have to close the resultset" paradigm
15:30SegFaultAXamalloy: I didn't even know that was a thing. Thanks!
15:30amalloySegFaultAX: i was recently accused of breaking it, so it's fresh in my mind :P
15:31gfredericksthe background is single-threaded, eh?
15:31SegFaultAXWill the seque always try and keep the buffer filled?
15:32SegFaultAXLike if I give it 10 then consume 5 items, will it produce another 5 in the background?
15:38dabdcould someone help me translate the following python function to clojure? https://gist.github.com/anonymous/5549946 I'm having a hard time with the recursion since there is a 'del' instruction after the recursive call.
15:39SegFaultAXdabd: This is only called for its side effects.
15:40dabdyes i tried to emulate the for with a map over to lists (range start 52) (iterate butlast cards) but it is not working
15:40dabdtwo lists*
15:40SegFaultAXThe issue here isn't really recursion. It's that you're mutating some global state.
15:41SegFaultAXAlso, you're mutating a list that you're iterating over which is universally considered an awful idea.
15:41SegFaultAXIn Python or otherwise.
15:42SegFaultAXOh I take that back, you're just pushing it on and popping it off repeatedly.
15:43edbonddabd, is't this just a combinations? http://clojure.github.io/math.combinatorics/#clojure.math.combinatorics/combinations
15:43amalloySegFaultAX: yes, it does try to keep the buffer filled
15:44dabdedbond the whole code is here: http://stackoverflow.com/questions/3829457/generating-all-5-card-poker-hands
15:44SegFaultAXamalloy: Hmm, maybe I don't understand. It appears to return the rest of the seq if the blocking queue will block.
15:45amalloySegFaultAX: fill returns the seq, yes, but that's just what goes into the agent
15:45dabdedbond: it's the code from the second answer. It is generating all isomorphic combinations of 5 card poker hands
15:46amalloythen next time you try to realize an element, you call drain, which starts the agent up again on the leftover seq, and it .offer()s again
15:46SegFaultAXAh, cool!
15:47slagyramalloy: Thanks for the help. The var was indeed being bound to itself.
15:47edbonddabd, implement canonical and filter (filter canonical (combinations cards 5))
15:48Bronsaheh
15:48Bronsathen you can do @@@@@@@@@var
15:48amalloy&(binding [*out* #'*out*] @@@@@@@@@*out*)
15:48lazybotjava.lang.SecurityException: You tripped the alarm! pop-thread-bindings is bad!
15:49gfredericksBronsa: that was the conclusion I was just coming to
15:49amalloywell, whatever. also, if you bind it to itself while it's unbound, you get the funny behavior slagyr asked about
15:49dabdi managed to translate the function but it is awfully slow and ugly. Any suggestions for improvement? https://gist.github.com/anonymous/5550022
15:50edbonddabd, I'm not good in cards ;)
15:51dabdedbond filter canonical combination is the way to go! the power of lazy evaluation
15:53edbonddabd, I would try to translate rules from comments and skip python version.
15:53edbondI mean doesn't translate word to word
15:53dabdit's done already. The key is the canonical? function. https://gist.github.com/anonymous/5550057
15:54dabdSegFaultAX: I stole your lazy-compare :-)
15:54justin_smith,(def cards (set (for [suit [:hearts :clubs :spades :diamonds] face (concat [:ace :jack :queen :king] (map inc (range 10)))] [suit face])))
15:54clojurebot#<Exception java.lang.Exception: SANBOX DENIED>
15:54justin_smith(take 5 (shuffle cards))
15:54justin_smithdone
15:55justin_smitherr, it should not be a set, but...
15:55dabdjustin_smith it's not that simple read the link to understand why some poker hands are isomorphic
15:57Pupnik-which part is making it slow dabd ?
15:58dabdthe last version i posted seems to be ok but i'm sure canonical? can be improved
15:59justin_smithdabd: sorry, I should have actually looked at the link
15:59justin_smiththe shuffle pun was too good to resist though
16:12dabdis there any way to make this faster? https://gist.github.com/anonymous/5550057 The python version is so much faster
16:22justin_smithdabd: you could use bit opts like they do, bit twiddling can be ugly but it is fast
16:23dabdthe correct solution is the answer no2 and there is no bit twiddling
16:25dabdi think the problem is that the python solution generates only the isomorphs while clojure generates all combinations and filters isomorphs
16:26dabdthis is lazy (filter canonical? (c/combinations (range 52) n)) but it still has to test all combinations right?
16:27gazboxThat's better :)
16:27dnolendabd: what n are you passing to generate isomorphs?
16:27dnolendabd: yes
16:27dabdthe number of cards
16:28dnolendabd: but what specific n?
16:28dabdif i want to generate 5 card poker hands i pass 5, if i want 2 cards i pass 2 :-)
16:28gazboxHi, I'm a new clojure programmer and I have some trouble understanding something
16:28gazboxI have a test case on pastebin
16:28gazboxI'll paste it :D
16:28gazboxhttp://pastebin.com/SZ8NAar6
16:28dnolendabd: you have to test 2,598,960 possibilities for n=5
16:28dabddnolen: yes that is the problem
16:29gazboxI'm trying to use iterate to produce a function that's called recursively to n deep
16:29justin_smithbut the ranking follows rules, so you could generate the valid rankings from the input set without iterating every possibility
16:29gazboxNot call the function but create an instance of it from an infinite set
16:30gazboxsequence I mean
16:30dabdgenerating only isomorphs is a bit more complicated i've read a bit about it
16:30AimHeregazbox > every time you call 'op', it just calls itself indefinitely
16:31gazboxdoesn't op return an lambda?
16:31AimHereerm, oops, maybe so
16:31dnolendabd: if you have the python code it shouldn't be hard to translate
16:31gazbox:D
16:31gazboxthe code runs in the repl
16:32gazboxjust does't do what I expect it to
16:32justin_smithgazbox: just a pedantic point, there is no such thing as a "pointer to a function" in clojure, it is just a function
16:32gfredericksexcept in the sense that near everything on the jvm is a pointer
16:32gazboxjustin_smith: I thought someone would say that :D I'm a c++ coder originally :D
16:32gazboxI'm getting over it though ;)
16:32mthvedta lot of people use pointer and reference interchangeably talking about the jvm
16:33justin_smithbut is #() a reference?
16:33justin_smithit is a clojure function
16:33gazboxyeah true, the function would be constructed
16:34gazboxif that's the right terminology :)
16:34gdevcan't core.logic-koans to run in windows; i think the bat file isn't concatenating the classpath correctly and its looking in .\lib for jars despite there not beng a lib folder
16:34gdev*can't get
16:34gazboxbut yeah the code I posted doesn't ever call fun
16:35gazboxand I thought the (m) bit would
16:35gazboxcall op five times and then call fun
16:36gdevit was saying it couldn't find clojure.main so I hardcoded the classpath in the bat file and now it is saying it can't find the koan engine
16:36justin_smithgazbox: there is no situation where op would call its arg as you have defined it
16:37gazboxoh it should return the function and call it first>
16:37justin_smithall it does is pass the arg - it never calls or returns it
16:37callenjustin_smith: are you from Ohio?
16:37justin_smithno
16:37callengood.
16:37justin_smithwhy?
16:37clojurebotwhy is the ram gone is <reply>I blame UTF-16. http://www.tumblr.com/tagged/but-why-is-the-ram-gone
16:38callenjustin_smith: I knew an awful person by your name from Ohio.
16:38justin_smiththere are lots of us
16:38justin_smithlol
16:38justin_smith(awful justin smiths from various places)
16:39gazboxgot it working :D
16:39gazboxCheers terrible people fron ohio :D
16:40gazboxI'm really enjoying clojure, managed to get a nice setup where I live code in emacs. It's amazing
16:42justin_smithemacs is a process of continuous discovery
16:42justin_smithtoday I discoverd C-u M-x vc-diff
16:42justin_smithshows diff of current file in two arbitrary branches
16:42justin_smith(neither has to be current)
16:42gazboxI've been in Sublime for ages and had to take the plunge so I could use nrepl
16:43gazboxlearning curve like a cliff but it's pretty cool
16:43callenvc-annotate is my preferred prelude to murder.
16:43justin_smithso, gazbox was your goal to make a function that called itself recursively 5 times and then evaluated its argument?
16:44gazboxyeah, the op thing will be calling stuff to set the OGL matricies
16:45gazboxso I can do some recursive geometry stuff
16:47muhooi find it frightening not only that i wrote this, but that it worked on the second try, and that i understand it: https://www.refheap.com/paste/14366 is that too obtuse? am i getting too golf-y?
16:49justin_smithgolfier- switch out sort #(compare ... with (sort-by :date
16:49justin_smithwell, shorter but actually more readable too
16:50justin_smithmuhoo: not too golfy, dense but not obfuscated imho
16:51muhoooh, i'd forgotten about sort-by, thanks
16:52gazboxThe only thing I find hard about clojure so far is there's not a lot of filler
16:53gazboxevery line counts
16:53gazboxyou have to concentrate a bit more :)
16:53gfrederickstype less think more
16:53gazboxyup
16:53gfredericksgood for your fingers
16:53gazboxwell
16:53gazboxI do a lot of deleting :D
16:53gdevi tap my fingers when i think so it's a zero-sum game for them
16:57bbloomgazbox: that's why people often think lisp is hard to read
16:57bbloomi argue that it's actually EASIER to read in that you gain more knowledge per unit of time & require less total time for more total knowledge
16:57justin_smithwell that is half of it, also you have to learn how not to read parens
16:57bbloombut it means you read much slower in terms of lines per unit of time
16:58justin_smithinformation theory tells us there is some optimal measure of redundency for optimum communication, the parens provide the redundancy :)
16:58Glenjaminhrm, thats an interesting idea
16:58Glenjaminshannon entropy to measure language expressiveness
16:59gfredericksjust gzip it and see how well it does :)
16:59justin_smithyup! as a language gets more powerful, it gets harder to tell a bug from an interesting but obscure construct
16:59bbloom& hence you need more documentation… and no javadoc style per function comments do not count
16:59lazybotjava.lang.RuntimeException: Unable to resolve symbol: hence in this context
17:00rbxbxha
17:00gfredericks&(hence soforth wherewithal)
17:00lazybotjava.lang.RuntimeException: Unable to resolve symbol: hence in this context
17:03gfredericksI'm having issues with my tests hanging
17:03gfredericksthere's a thread-pool thing I'm doing, and the tests only hang if I do it at least three times or something bizarre like that
17:04gfrederickstesting any single namespace finishes successfully o_O
17:04justin_smithmy solution to race conditions is get a healthy head start so I win
17:04justin_smith:P
17:04hiredmangfredericks: have you tried testing all the namespaces in random orders
17:05gfrederickshiredman: not sure how to do that with clojure.test?
17:05hiredman`lein test` then a shuffled list of test namespaces
17:05gfredericksah very good
17:05gfredericksI'm on it
17:07hiredmanclojure.test can also behave very oddly if if you do something bad with fixtures, I am trying to remember what, I forget if the symptoms are anything like tests hanging though
17:07gfredericksdefinitely using fixtures
17:08justin_smithexample of entropic terseness in clojure code: a controller helper in a webapp that extracts the id of the current user's permission role: (defn role-id [{{{role-id :role-id} :user} :session}] role-id)
17:08justin_smithfour of the size names in that definition are the same
17:08justin_smith*six
17:09gfrederickshiredman: still hangs on first random run
17:10gfredericksthe idea is to check if the hangin is caused by running A before B?
17:10hiredmanyeah
17:10gfredericksI guess I should reverse it then rather than doing more randoms
17:10hiredmanmaybe you shutdown a threadpool and don't restart it or something
17:11gfrederickshmmm...that one hung early o_O
17:13rodnaph_hey - i'm thinking of using core.cache in my application - does anyone have experience, and can give some pros/cons? cheers
17:13hiredmangfredericks: the with fixtures is due to the way they compose, if you swallow exceptions in a fixture thinking "oh, I never care about exceptions here" you can endup swallowing excetions from fixtures you care about
17:13hiredmanmaybe not relevant here
17:14hiredmanthe thing with
17:15justin_smithcode that unexpectedly catches my exceptions bedevils me
17:15hiredmanyes, it can be a bit of a bugger
17:17Glenjaminjustin_smith: isn't that example an example of too much entropy in the code?
17:17justin_smithyeah I think so!
17:17Glenjamin(defn role-id [req] (get-in req [:session :user :role-id]))
17:17justin_smithI would not have called it entropic if it was ideal
17:17gfrederickshiredman: okay, I don't think I expect any exceptions in my fixtures
17:17justin_smithyeah, I like destructuring, but I overdo it
17:18Glenjamin,((defn role-id [req] (get-in req [:session :user :role-id])) {:session {:user {:role-id 1}}})
17:18clojurebot#<Exception java.lang.Exception: SANBOX DENIED>
17:18Glenjamin,((fn [req] (get-in req [:session :user :role-id])) {:session {:user {:role-id 1}}})
17:18clojurebot1
17:18justin_smithyeah
17:18gfredericks,(assoc-in {} [:session :user :role-id] 1)
17:18clojurebot{:session {:user {:role-id 1}}}
17:18justin_smithwhat I like about destructing is that you can read it backwards to see the structure the funciton needs
17:19gfredericks,(assoc-in {} (repeat 10 :x) :y)
17:19clojurebot{:x {:x {:x {:x {:x {:x {:x {:x {:x {:x :y}}}}}}}}}}
17:19Glenjaminheh
17:21Glenjamin,((fn role-id [{{{role-id :role-id} :user} :session}] role-id) nil)
17:21clojurebotnil
17:25mabesit doesn't look like nrepl.el/ritz has a trace function helper like the swank version had.. is that right, or have I missed it?
17:37Glenjaminbah, why does get-in work on vectors, but not lists
17:37gfredericksvectors are peculiarly map-like. lists are not at all.
17:37gfredericksget-in is for mappy things, same as get
17:37Glenjaminmm, i guess i was cheating a bit
17:38Glenjaminhad a seq with one deep map
17:38Glenjaminwas trying to do get-in [0 :key :key2]
17:38Glenjamininstead of first (get-in [:key :key2]
17:38gfredericksyou could also (-> % first :key :key2)
17:39Glenjaminmm, but that's not null-safe
17:39Glenjaminand this lib has back-compat to 1.3, so i can't use some->
17:39gfredericksnot null-safe?
17:39gfredericks,(-> nil first :key :key2)
17:39clojurebotnil
17:39Glenjaminoh right
17:39gfredericksor your keys are nil?
17:39Glenjamini dunno why i thought that
17:40Glenjaminmuch better, thanks
17:52shriphanihi. Is there a way to pipe output to less (or something like that) in a repl? pprinting leads to something that can't fit in 1 screen-buffer.
17:57rlbShould (set-stroke chart :width 5) affect a bar chart in incanter when going to pdf?
17:59vijaykiranshriphani: not aware of anything like that - may be you should write the pprint to a tempfile?
18:00amalloyor use something smarter than a command-line repl, like an emacs nrepl connection
18:02n_bshriphani: Not from the default clj REPL; either spit it out and view it in your editor or switch to emacs/vimclojure/what-have-you
18:03shriphaniamalloy, the repl is running on a remote machine and I am using sshfs.
18:04vijaykirantramp using emacs
18:24Glenjamincan you increase the screen buffer?
18:29justin_smithshriphani: another option is the script command, makes everything you do in the shell also print out to a file
18:29justin_smithscript is a shell command you would run before opening the repl
18:32gfredericksI have three namespaces such that `lein test A B C` hangs but removing any of A, B, or C completes
18:32RaynesI tend to break leiningen.test.
18:33RaynesIf I broke this it must have been broken for quite a long time.
18:34_{^_^}_when do you guys decide to use a n-tuple to represent an entity vs a hashmap? e.g. {:name "tyler" :age 29} vs ["tyler" 29]
18:35gfredericksonly when haxing
18:42Apage43_{^_^}_: I tend to only do 2-tuples
18:42Apage43once I get to 3 I start forgetting which element is which too often
18:42Apage43and i have to debug less if I just give them names
18:43Apage43I get them mixed up often enough with 2-tuples, but if I'm just playing around and trying to bang something out quick i do it to save typing
18:44Apage43but you can use https://github.com/Prismatic/plumbing and nearly get the best of both worlds
18:47omacielgiven the following sequence ("Blue" "Yellow" "Red") how do I check if a "Blue" is in this sequence?
18:48amalloy~contains
18:48clojurebotcontains is gotcha
18:48amalloywell, true enough. don't use contains
18:48justin_smith,(some #{"Blue"} ["Blue" "Yellow" "Red"])
18:48clojurebot"Blue"
18:48omacielhmmmm
18:48hiredmanamalloy: you can use the java method just fine
18:49hiredmanthe real question is, shouldn't you be using a set instead?
18:49omacielis it possible to get back a boolean?
18:49omacielwait
18:49omacielI don't have a vector
18:49justin_smith,(some #{"Blue"} '("Blue" "Yellow" "Red"))
18:49clojurebot"Blue"
18:50hiredmanomaciel: why don't you keep the colors in a set instead?
18:50omaciel,(some #{"Black"} '("Blue" "Yellow" "Red"))
18:50clojurebotnil
18:50omaciel,(boolean (some #{"Black"} '("Blue" "Yellow" "Red")))
18:50clojurebotfalse
18:50hiredmansets are much better for membership testing
18:50omaciel,(boolean (some #{"Blue"} '("Blue" "Yellow" "Red")))
18:50clojurebottrue
18:51omacielhiredman: hmmm I may change the function that is returning that seq then
18:51justin_smith,(boolean ((set '("Blue" "Yellow" "Red")) "Blue"))
18:51clojurebottrue
18:51hiredman:(
18:52patchworkBest practice: iterate over a string or split it with #"" ?
18:52hiredmandon't build a set out of a list just for that
18:52patchwork(to do something to each char in the string)
18:52justin_smithhiredman: yeah, good point
18:52omacielhiredman: what do you recommend?
18:53justin_smithI was just showing the list could easily be a set
18:53justin_smithif the list is just generated once, then the set could be generated once and reused
18:53patchwork,(clojure.string/split "hello world" #"")
18:53clojurebot["" "h" "e" "l" "l" ...]
18:54patchworkSeems wasteful
18:54justin_smith,(map identity "Hello World")
18:54clojurebot(\H \e \l \l \o ...)
18:54patchworkYeah but those are chars, not strings
18:54patchwork,(map str "hello world")
18:54clojurebot("h" "e" "l" "l" "o" ...)
18:55patchworkThat may be best
18:55justin_smithas long as you know you can't do it with chars, sure
18:55patchworkThe algorithm expects strings yeah
18:57amalloy&(.equals [] ())
18:57lazybot⇒ true
18:58amalloyhm. i guess i expected that to return false, since there was some work done on making clojure collections obey the "broken" java APIs and instead use equiv or something for "useful" equality
18:59technomancyI think that was just for numerics?
18:59dabdhow can I make sure int-array will create an array of 32 bit integers?
19:00tieTYT2i've often got this problem when I develop clojure code that I assume the types that are input/output and I assumed wrong. But the errors aren't very helpful in figuring out what is really going on. How do you guys usually debug these issues? EG: an arity exception is only sometimes helpful. It doesn't tell you what you passed in, just the amount you passed in
19:00amalloydabd: call it. how could it ever do anything else?
19:00tieTYT2another eg: I have a function I think will return a vector of x, but it really returns a vector of vectors of x
19:00dabdi was searching the docs but nowhere it says it won't create a 64 bit integer
19:00amalloy&(doc int-array)
19:00lazybot⇒ "([size-or-seq] [size init-val-or-seq]); Creates an array of ints"
19:01amalloy$google java int
19:01lazybot[Primitive Data Types (The Java™ Tutorials > Learning ... - Docs Oracle] http://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html
19:01tieTYT2amalloy: why do you use & there?
19:01tieTYT2,(doc int-array)
19:01clojurebot"([size-or-seq] [size init-val-or-seq]); Creates an array of ints"
19:01tieTYT2same thing?
19:01amalloydid you notice anything different that happened in response to my message vs yours?
19:02amalloy(hint: if the answer is no, keep looking)
19:02tieTYT2yeah that little => thing
19:02amalloyanything else...?
19:02tieTYT2not that I see
19:02amalloysay, that two different nicks responded?
19:03tieTYT2oh ha, right
19:07patchworkWhat is the name of that function that chooses a random element from a list? I thought it was `choose`, but I was wrong
19:08patchworkOr I can just write it again
19:08amalloy$findfn [1 1 1 1 1] 1
19:08lazybot[clojure.core/second clojure.core/last clojure.core/peek clojure.core/first clojure.core/fnext clojure.core/rand-nth]
19:08pppaulwoah
19:09pppaulthat's like smalltalk stuff
19:09pppaul$findfn {} []
19:09lazybot[clojure.core/lazy-cat clojure.core/sequence clojure.core/vec clojure.core/concat clojure.core/seque clojure.core/drop-last clojure.core/reverse clojure.core/cycle clojure.core/rest clojure.core/lazy-seq clojure.core/flatten clojure.core/sort]
19:09justin_smithis findfn in clojure.repl?
19:09pppaul$findfn {} [1]
19:09amalloy$google clojure findfn
19:09lazybot[Raynes/findfn · GitHub] https://github.com/Raynes/findfn
19:09patchworkamalloy: Badass
19:10justin_smithahh
19:10lazybot[]
19:10pppaul$findfn {:a 1} []
19:10lazybot[clojure.core/drop-last clojure.core/rest clojure.core/flatten]
19:10pppaultoday i almost found a use for empty
19:11pppaulit was related to displaying the shape of data
19:21tieTYT2i have these java junit tests that test my clojure code (because they were written before the clojure code was used). Is there a way to run the tests in a repl?
19:21tieTYT2i guess I can do it with a doto that calls the setup
19:21hiredmantieTYT2: sure, just figure out how junit runs tests and do that from clojure
19:22hiredmanhttps://github.com/sonian/Greenmail/blob/20247759a0c6b1782e4307e4f143e700f057bd39/test/greenmail/test/zzz.clj
19:23hiredmanor something
19:24tieTYT2i see, thanks
19:41patchworkBecause I know this is what you are all looking for: https://github.com/prismofeverything/zalgo
19:43justin_smithpatchwork++
19:43justin_smith(inc patchwork)
19:43lazybot⇒ 1
19:43justin_smith;oops
19:51muhoohu, theres' no way to get array types like org.postgresql.jdbc4.Jdbc4Array into a db using clojure jdbc is there?
19:51tieTYT2why am I getting this error? https://www.refheap.com/paste/6b946c5e313795f048f8ac253
19:51tieTYT2is it because the 2nd and 3rd are both lists as input?
19:52hiredmandestructuring is not pattern matching
19:52tieTYT2i see
19:52hiredman[a] and [[a]] are both one argument functions
19:52hiredmanthe second just treats the one argument as a list and binds a name to the first value
19:52tieTYT2ok that's what I figured. What should I do that will still be concise?
19:52muhooi can get them OUT, but not in. (-> (jdbc/query db ["select * from array_test"]) first :ips .getArray set) works great in the query direction. insert, not so much.
19:58arrdemhum... so my project explicitly requires ring 1.1.8, lein deps :tree shows 1.1.8 loaded but even after restarting nrepl can't find ring.util.request
19:58arrdemideas?
19:59weavejesterarrdem: ring.util.request was only added in 1.2.0-beta1
19:59arrdemweavejester: that'd do it :/
19:59weavejesterSpeaking of which, I need to sort out RIng this weekend and release an RC
20:06arrdemweavejester: is com.cemeric/friend usable?
20:07weavejesterarrdem: I know people who've used it
20:07weavejesterAs far as I know it is
20:07arrdemweavejester: ok thanks
20:08tieTYT2i've got a long threading macro, I've got a bug in one of the steps. How can I trace that piece?
20:08tieTYT2it's currently doing: (map update-algorithm)
20:08tieTYT2I want to see the end result of that
20:09dabdcould someone help me trying to read a gzip file of ints into an int-array. So far I got this https://gist.github.com/anonymous/5551539. But java IO is not so simple and I don't get why instead of an int array it shows a ByteBufferAsIntBufferB instead of an int-array.
20:09justin_smithinsert (first (juxt identity pprint/pprint)) if you are using ->>
20:09justin_smitherr
20:09justin_smithnot quire
20:09justin_smith((juxt identiy pprint/pprint)) first
20:10justin_smiththat works with either style of threading
20:10justin_smithprints anyhere in the midle
20:10justin_smith*middle
20:10tieTYT2why is the first outside of everything?
20:10justin_smith(-> foo bar baz)
20:11justin_smith(-> foo bar ((juxt identity pprint/pprint)) first)
20:11justin_smithreplicates data flow while printing
20:11tieTYT2i see
20:11justin_smithoops, should have kept the baz at the end
20:11justin_smithbut you get the idea, I hope
20:11tieTYT2ok I think I get it, thansk
20:13callenStuff like juxt makes me so happy. FP lets you avoid so much boilerplate.
20:14justin_smith<3 juxt
20:14technomancypprint doesn't need juxt though
20:14technomancy(doto x pprint)
20:16justin_smithdoto does not work as nicely with ->> though
20:16justin_smith((juxt x y)) works with both threading styles
20:17technomancyoh yeah, true
20:23tieTYT2this is horrible, how do I make this more concise?
20:23tieTYT2https://www.refheap.com/paste/02e9f3d0ee4e0d3a474bf9607
20:24justin_smiththe nested ifs could be a cond?
20:25tieTYT2i'll try that
20:25tieTYT2this destructuring is not making things easier for me
20:26dnolentieTYT2: seems convoluted this looks like map
20:27SegFaultAXtieTYT2: (if (and c1 c2 (= (.getStartTime c1) (.getStartTime c2))) ...
20:27dnolenwhere the sequence is pairs of values that aren't neseted
20:27dnolennested
20:27SegFaultAXAlso, why is there a nullary clause at all?
20:28justin_smith[nil] as input?
20:28tieTYT2I'm getting nil as input because of the &rest
20:28justin_smiththat is how c1 could be falsey
20:28tieTYT2which I didn't expect
20:28tieTYT2this would be easier for me to think about with pattern matching
20:29dnolentieTYT2: I don't see how, you're just mapping over a sequence
20:29dnolenwrite it as a map
20:29tieTYT2but I'm reducing
20:30tieTYT2(perform-update! c1 c2) may return c1 or c2
20:30dnolenmapcat
20:30tieTYT2hrm, I'll look into that
20:31tieTYT2but the INPUT is one collection, not a collection of collections
20:31tieTYT2it's the output that's a collection of collections
20:32justin_smithtieTYT2: also (partition 2) may help get your pairs
20:32tieTYT2my newb brain looks at mapcat and thinks it's only for the latter
20:32justin_smithtieTYT2: an extra level of [] fixes that
20:32dnolen(apply concat (map (fn [[c1 c2] ...) (partition 2 xs))))
20:33dnolensans typos
20:33justin_smith,(mapcat identity [[:a] [[[:b]]] [[:c]]])
20:33clojurebot(:a [[:b]] [:c])
20:33tieTYT2ok but if the input is [1 2 3 4], won't that only map on [[1 2] [3 4]]?
20:34dnolen,(partition 2 [1 2 3 4])
20:34clojurebot((1 2) (3 4))
20:34tieTYT2I need to call the fn on 1 2, take the result of that and call the fn on it and 3
20:34dnolen,(map list (map first (partition 2 [1 2 3 4])))
20:34clojurebot((1) (3))
20:34justin_smithyour code as stands does not do that
20:34tieTYT2seems more like a reduce to me
20:34dnolen,(apply concat (map list (map first (partition 2 [1 2 3 4]))))
20:34clojurebot(1 3)
20:34tieTYT2justin_smith: oh you're right!
20:34tieTYT2i move on to the next one
20:34tieTYT2shoot
20:35justin_smiththat is why I thought partition would be apropriate - bug for bug compatibility
20:35tieTYT2haha
20:35tieTYT2see my real long term problem here is I don't know how to peer into my code to figure out that bug
20:35dnolentieTYT: ok, rewrite it as a real reduce
20:36tieTYT2I realized that after you said it, but I don't know the tools to figure it out on my own
20:36dnolener tieTYT2
20:36tieTYT2i've already got it that way
20:36tieTYT2i'll show you what i do
20:36tieTYT2i thought that the direction I was going would be cleaner
20:37tieTYT2https://www.refheap.com/paste/a701a23918dd942500eae55be
20:37justin_smithregarding "knowing how to peer into the code" - the more code you read and write the easier that is
20:38tieTYT2yeah but this doesn't seem like a challenge in java. I'm biased, but it seems like a compiler would catch a lot of my issues (not this one)
20:38callendabbling with and reading a lot of open source code has a way of inducing familiarity with alien concepts that might not otherwise happen with writing code in your comfort zone.
20:38dnolentieTYT2: it's not a challenge in Clojure either once you're thinking functionally
20:38justin_smithyeah, other people's code is key
20:38tieTYT2that algorithm above does exactly what I want. It passes all my tests
20:39tieTYT2dnolen: well I came from haskell actually
20:42tieTYT2anyway thanks for the help. I gtg now
20:59nkoza(type ...) returns the :type metadata, but there is no reader macro shorcut to set it? You can only set it using ^{:type :mytype} {...} ?
21:00ivanlinkedin spam suggests that Apple is looking for a Clojure/Java consultant
21:09dnolennkoza: putting types on maps like that isn't so useful, kind of a holdover from the days of structs. If you want typed maps might as well use records.
21:32technomancyivan: and twitter spam and email spam and probably lots of other forms of spam; geez =)
21:33ivansomeone must have secretly written a mission-critical pile of Clojure
21:36xeqioh, are they being public about it now?
21:36gdevwhat happened?
21:45nkozadnolen: but how you dispatch using multimethods if the map isn't tagged? or the common idiom is to use also defrecord's for them?
21:46bbloomnkoza: you can dispatch on a key in the map
21:47bbloomlike the clojurescript compiler uses the dispatch-fn :op and has maps like {:op :let …} and {:op :fn …}
21:47nkozaok, then using {:type xxx ...} in maps is obsolete, you usually dispatch by another key
21:48nkoza(I'm only trying to get what's the common idiom)
21:48bbloomnkoza: i think dnolen was trying to say that maps with METADATA of :type was obsolete
21:48nkozaah ok
21:48bbloomgenerally, you'd prefer to avoid naming a key :type since that implies a JVM or other host type
21:49bbloomif you're going to switch by type, you can name the key the same way you'd name an enum in C or something like that
21:49bbloomso like if you were to have a server that can respond to 5 different kinds of messages, you might enum MessageType { Connect, Chat, Disconnect} or whatever
21:50nkozayou do :message-type :connect , et al
21:50bbloomin that case, you can use a :message key, so you'd have {:message :connect …} {:message :disconnect ...}
21:50bbloomyeah
21:50bbloomsomething like that
21:50nkozathanks, I think I need to read more clj code :)
21:51bbloomif you need strict dispatch by host type (for speed, interop, custom semantics, whatever) then it is preferable to use protocols than multimethods
21:51bbloombut as a general rule, start with a multimethod & maps and move to custom types & protocols when you need them
21:52bbloom(which should be a lot less often than you'd expect it is, coming from more type-ful languages)
21:54hiredmanthe other thing is sometimes a map can have different types depending on what operations you are doing
21:55bbloomhiredman: yup, good point
21:55hiredman{:storage :s3 :send :broadcast} might be something that in one context has a "type" of SavedOnS3
21:55gfredericksUsing ::foo must be smelly if you ever use the expanded version as well, eh?
21:55bbloomgfredericks: huh?
21:55hiredmanand in another context has the "type" BroadcastableMessage
21:56bbloomhiredman: that's a pet peeve of mine
21:56gfredericksbbloom: due to the possibility of changing the namespace of the implicit one without thinking to change the explicit ones
21:56bbloomi've seen sooo many projects with app/models/user.py
21:56bbloomwhere that's 10X larger than all the other model code combined
21:56bbloomthere is no way it could possibly be a good idea to have PRECISELY ONE representation of a user
21:56bbloomer s/.py/.rb/
21:57bbloomgfredericks: oh, yeah, ::foo has burned me a few times
21:57gfredericksbut it seems like a nice sugar if you _don't_ have any explicit usages
21:57bbloomyes
21:58bbloomafter dnolen taught me that you can use aliases ::foo/bar, then i decided that i'd never use ::bar and ::full.path.to.foo/bar together, instead spelling it out for ::bar
21:58bbloomso yeah, exactly what you are saying :-)
21:58bbloomit's too bad you can't assign a local alias for your current namespace...
21:58bbloomlike (ns [full.path.to.foo :as foo] ...)
22:00hiredman,(ns foo (:refer foo :as bar))
22:00clojurebotnil
22:00hiredmanI wonder if that actually works
22:00bbloomheh
22:00bbloomit's a grand mystery to me every time i need to write a namespace....
22:00hiredmanreally?
22:01hiredmanI :require all day long
22:01hiredmansometimes :load
22:01bbloom*shrug* i eval whole files or individual forms from vim with cpr and cpp
22:01bbloomi basically cargo cult copy paste namespaces every time i make a new 1 :-P
22:02bbloomand i even understand them
22:02bbloomi just fail at the syntax every time
22:02bbloomhugod: so i think i have time to figure out code signing
22:03bbloomhugod: but i'm looking at your code & realizing that you are overriding protocol implementations… isn't that, um… bad form? if anyone else loads your library, they will break their other uses of fipp
22:41technomancy:require :as and :refer-clojure :exclude are basically all I ues
22:42technomancyoh, and :require :refer :all for tests
23:24gdev55 issues tagged "newbie" and here I am wondering what I'm going to do with the rest of my night, here we go
23:27gdevnevermind, those are all closed; only 4 open newbie issues; false alarm
23:35technomancygdev: is the link wrong?
23:36gdevtechnomancy, I think i was already in the issues section, clicked on the left nav tag, and it showed all the closed ones =/
23:47n_bI'm in the process of building a language model for Danish by parsing over wikipedia dumps, and part of that is the semi-canonical MapReduce example of getting a count of each word that appears in a corpus
23:48n_bHowever, I'm trying to avoid all the Hadoop overhead since this is really such a simple example, and not that large of a dataset, and curious what data structure you would suggest for computing it in memory
23:49n_bA trie is probably how I'd do it with a mutable data structure, but I'm not sure exactly what approach would be best in Clojure
23:51n_bOr should I just use a transient map and persist it at the very end?
23:51mthvedtn_b: the standard pattern is to (reduce processing-fn my-data-structure my-input-data)
23:51mthvedtif performance becomes an issue, you can swap in transients but the code shape for transients is the same (on purpose)