#clojure log - Sep 29 2011

The Joy of Clojure
Main Clojure site
Google Group
List of all logged dates

0:11 ibdknox: dnolen: awesome. I should dig through that sometime soon to understand how it all works :)

0:12 out of curiosity, has anyone read Land of Lisp?

0:12 amalloy: ibdknox: yeah

0:13 ibdknox: what'd you think of it? I've been considering purchasing it

0:13 amalloy: i gave a brief review of it earlier today in #clojure, if i can find it

0:13 dnolen: ibdknox: the upside is that core.match now generates a reasonable amount of code - so even fairly complex pattern like red-black-tree balancing won't a) cause AOT errors b) will be inlined like mad by the JVM. and all the other good stuff unchanged.

0:14 some pluses for ClojureScript here as well.

0:14 amalloy: but basically: it's interesting, and i definitely picked up a few useful ideas. but a big chunk of it is focused on mutable state, and another big chunk is proselytizing about common lisp

0:14 ibdknox: dnolen: sweet, I remember you had a gist a while back showing some of the code it would spit out and it was unbelievably nested haha :)

0:15 dnolen: ibdknox: yeah so maybe 10X less code than that is now generated.

0:15 amalloy: eg, he advances an iterative series of macros that eventually allow you to create closures with a special hook for getting and setting their closed-over variables

0:15 dnolen: for that case anyhow.

0:15 amalloy: neat, and powerful, but ultimately not that useful in clojure

0:16 ibdknox: amalloy: yeah. Part of my motivation for reading it is, I like the concept of teaching lisp through a series of games. I was thinking that it might be a fun project to do something similar for Clojure :)

0:17 dnolen: that's an impressive improvement

0:17 amalloy: ibdknox: oh haha wait, i was revieing the wrong book

0:17 that was a description of Let Over Lambda; i always confused the two because of their initials

0:17 ibdknox: hahaha

0:17 I've not heard of that one

0:17 brehaut: amalloy: LOL

0:17 amalloy: Land of Lisp is fine, and short enough to get through in an hour or two so it doesn't much matter if it's good

0:18 ibdknox: haha

0:18 dnolen: ibdknox: I was dreading it … but I think I only had to change 10 lines of code or something.

0:19 ibdknox: dnolen: wow. Gotta love easy wins

0:19 amalloy: ibdknox: i don't think small implies easy :P

0:19 ibdknox: fiiine

0:20 Gotta love wins?

0:20 lol

0:20 amalloy: i am in favor of...benefits!

0:20 ibdknox: screw anyone who isn't ;)

0:21 dnolen: well props mostly to Maranget - his algorithm is simple - so changes not so painful.

0:21 it's actually the main thrust of his paper - the simplicity of the algorithm compared to others

0:22 ibdknox: mhm

0:23 tomoj: "Compiling Pattern Matching in Join-Patterns", or..?

0:23 dnolen: tomoj: Compiling Pattern Matching to Good Decision Trees

0:23 tomoj: ".. to good decision trees" perhaps?

0:23 ah

0:25 dnolen: tomoj: tho Maranget doesn't get into backtracking there - I had to pick Sam Tobin-Hochstadt's (Typed Racket, Racket match) brain to see the benefits of backtracking

0:27 and by backtracking I mean pre allocating a JVM exception to use it a GOTO

0:46 Jpeerindex: hello

0:46 looking for a 2D array solution in clojure.

0:47 For 2D arrays, they say list of lists is the way to go. or a map.. I wonder why ?

0:48 amalloy: huh? java uses an array of arrays; why is the switch to a list of lists (or vector of vectors) so surprising?

0:49 Jpeerindex: good pt.

0:49 arrays are an abstraction

0:49 BUT some data is naturally a uniform grid with fixed size

0:49 for example, a chess board. or a table

0:52 can you use array "like" syntax in clojure ?

0:53 or how would you access array operations in clojure. like if i have an Object[] and want the third element. I assume standard . syntax won't work... since java arrays have their own sytnax for access with []s

0:53 anyways, just some thoughts but have to go :(

0:53 !

0:54 amalloy: ...

1:05 ibdknox: lol he must've been trolling

1:05 I hope he was trolling..

1:08 alandipert: dnolen: how might one express a 'not' predicate in core.logic? (or is it built in?)

1:09 dnolen: alandipert: negation as failure, like prolog.

1:10 alandipert: negation is a pretty wild topic in LP, and I'm on the fence about whether such a thing should be introduced.

1:11 alandipert: the idea is that if a subgoal succeeds you cut and fail

1:12 alandipert: you do have a limited version of it in core.logic which is disequality over trees. You can express that two trees should never unify.

1:13 alandipert: dnolen: i see. i'm a prolog noob, but what i'm trying to express is something like :- foo(x,y), not bar(z,y).

1:14 are you saying that if i express the args as trees, then i can use disequality?

1:14 dnolen: alandipert: (=/= x y) means you just don't want two things to ever unify.

1:16 alandipert: other option, (defn not-baro […] (conda ((baro …) fail) (…)))

1:16 alandipert: what happens ^, is that if baro succeed all other possibilities are cut off, and we fail.

1:18 alandipert: dnolen: ahh ok i think that will do the trick for me. because i can try to unify my failure case, and fail when it does

1:18 dnolen: alandipert: out of curiosity .. what are you doing? :)

1:19 alandipert: dnolen: the greatest and best meal/menu engine ever conceived by humankind (in clojure)

1:19 dnolen: alandipert: haha! awesome.

1:21 alandipert: dnolen: as always, thanks for the awesome shit and help to go with. sleepy time, see you later!

1:22 dnolen: alandipert: np

1:25 alandipert: dnolen: oh, one more quick question. math preds on lvars, is there a pattern to follow?

1:26 dnolen: alandipert: arithmetic preds on lvars are the pits. I will probably start on integrating clpKanren into core.logic soon.

1:27 alandipert: I'm assuming you're working with finite domains, no infinite chicken salads or nuthin

1:27 alandipert: dnolen: i was hoping to support infinite nutella

1:28 dnolen: haha

1:28 alandipert: but yes, it's all finite, and the regular clj stuff is working fine for me

1:28 just curious

1:28 dnolen: alandipert: yes, what's coming will be way better than what's there now, and it won't break anything.

1:28 amalloy: alandipert: a restaurant near here puts that on your french toast. more nutella than anyone could reasonably want

1:29 alandipert: dnolen: i don't believe you, math-related thingies tend to be breaky ;-)

1:29 dnolen: you'll be able to say things like: (domfd (range 0 100) x y z) (plusfd x 2 z), etc

1:29 alandipert: amalloy: that is fantastic

1:30 amalloy: $google the griddle restaurant la

1:30 errr, except lazybot is down. pretend i intended you to google that yourself

1:30 dnolen: alandipert: I think Dan Friedman is a fairly trustworthy brain ;)

1:31 alandipert: amalloy: np, i am lazybot command feature-complete. just higher latency.

1:32 brehaut: alandipert: but do you compensate for lacking parens?

1:34 alandipert: brehaut: yes, i own sports car

1:34 brehaut: alandipert: aha :)

3:13 zhouc: hello, Lisp hackers

3:19 pcavs: hello hello

3:35 zhouc: :-)

3:35 I need coding some dirty c++ code for food

3:36 LoL

4:57 tomoj: sorenmacbeth: hey

4:59 darq: hello. I try to figure out the thread macro.. (-> 5 inc inc) this work prefecty .. but what if i have a list of function something like this (-> 5 (inc inc))... is there a way to give to the macro in this form?

4:59 cark: not with ->

5:00 that's the trouble with macros

5:00 you need a functtion so that you can apply

5:00 i think this is relevant http://blog.fogus.me/2010/09/28/thrush-in-clojure-redux/

5:01 now you can do (apply trush 5 [inc inc])

5:02 amalloy: meh. ##((apply comp [inc inc]) 5), what is the point of thrush there

5:02 lazybot: ⇒ 7

5:03 cark: well that's just like the -> macro, but you can apply it

5:03 though there was an apply-macro in old contrib

5:03 amalloy: cark: no, it's not really just like ->

5:03 cark: it's better !

5:03 amalloy: it's *different*

5:03 cark: hehe ye

5:03 amalloy: &(-> 1 (list 4))

5:03 lazybot: ⇒ (1 4)

5:04 cark: (trush 1 #(list % 4))

5:04 you get to choose where your param goes with trush

5:04 amalloy: &(-> (1 4) quote)

5:04 lazybot: ⇒ (1 4)

5:05 amalloy: the set of things you can do with -> and the set of things you can do with comp/thrush intersect; neither one subsumes the other

5:05 cark: ah that's something you cannot do with trush

5:05 yes that's the nature of macros =P

5:06 amalloy: cark: btw it's thrush with an H. trush keeps stopping me in my tracks

5:06 cark: ahh sorry, not a native speaker

5:06 seancorfield: uh-oh, looks like the "variable position thrush macro" suggestion that rolls around every three or four months :)

5:07 amalloy: meh, nobody really talks about thrushes anyway. they're a kind of bird

5:08 cark: seancorfield: not really we're talking about getting (some) of -> functionalities in a functional context instead of a syntactic one

5:08 kzar: Is there a way to use moustache with Noir?

5:08 seancorfield: it always looks like a good idea when it comes up on the list... but i understand the resistance to adding it (after having seen it explained several times)...

5:09 amalloy: cark: if you want variable position, you're just rewriting comp

5:09 cark: i'm not rewriting anything, i just have this in my toolbox when needed

5:09 and comp is backward looking

5:09 darq: Thx to all. This discussion really helped :)

5:10 cark: btw : i'm not fogus

5:11 amalloy: haha we know

5:12 cark: =)

5:16 seancorfield: i remember reading fogus' blog post now and wondering what scenario you needed thrush... yeah, i see the benefit of function over macro but i guess it depends on how often you have an opaque list of functions that you can't arrange to be in reverse order (where you could use comp)?

5:17 cark: the order is only about making it easy on the eye

5:18 seancorfield: so it reads outside-in rather than inside-out?

5:19 cark: so that the function are applied from left to right

5:19 functions

5:21 seancorfield: i guess i find ((apply comp [f g]) 5) more intuitive than (apply thrush 5 [g f]) - or ((comp f g) 5) more intuitive than (thrush 5 g f) ...

5:22 cark: well if you have a long list of operations to perform, one per line, it suddenly makes sense

5:22 seancorfield: ... but i do use the -> and ->> macros when i have a sequence of forms that i want applied as function calls with an argument added ...

5:22 thorwil: kzar: sure, by either bypassing noir's routing, or by forking noir to replace the routing entirely, i guess

5:25 seancorfield: ... but i use -> a lot more than ->> so i guess i haven't run into a need (in my code) for thrush as a function (fogus' post talks about -> but really thrush is closer to ->> isn't it?)

5:25 kzar: thorwil: How would I go about bypassing noir's routing?

5:25 cark: amalloy would say they're different =)

5:26 seancorfield: cark: lol... yeah...

5:28 looks like he's gone away... and so should i since it's 2:30 in the morning... i work up and had to check the log files... been doing a bunch of jvm tuning so i'm neurotic about memory usage :(

5:28 s/work/woke/

5:28 lazybot: <seancorfield> looks like he's gone away... and so should i since it's 2:30 in the morning... i woke up and had to check the log files... been doing a bunch of jvm tuning so i'm neurotic about memory usage :(

5:28 cark: good night =)

5:29 kzar: s/\)/D/

5:29 thorwil: kzar: study noir's source to learn about it's expectations regarding routing, to see where you can step in

5:30 seancorfield: cark: you're in central europe?

5:30 cark: yes, belgium

5:30 that's near france

5:31 seancorfield: i'm originally from england so my european geography is better than most americans :)

5:31 glad to see clojure in use in europe :)

5:31 cark: hehe such a tiny country, i can understand they don't know about it =)

5:31 seancorfield: makes great beer! :)

5:31 cark: ohhh but i'm not the only european clojure user

5:32 * lucian timidly raises his hand

5:32 pyr: seancorfield: it definitely is

5:32 kzar: thorwil: Fair enough, I've been reading the documentation but I can't get their defpage macros to work as they described. I'll have a look at the source

5:32 lucian: i barely use it at all

5:32 pyr: seancorfield: both in france and switzerland

5:32 clgv: germany has better beer than belgium ;)

5:32 pyr: seancorfield: at least :)

5:32 seancorfield: i see various european clojure groups announcing meetings on twitter...

5:32 cark: clgv : that's a casus belli

5:33 clgv: lol

5:33 seancorfield: heh, didn't mean to start a european beer war...

5:33 thorwil: kzar: bypassing that problem by using different routing and thus stepping wide out of the framework does not sound like a good idea ;)

5:33 cark: clgv: very different kind of beers actually, the world is big enough for both our country beers

5:34 clgv: cark: maybe, or maybe not? ;) :P

5:34 cark: !

5:34 lucian: clgv: sure it is. instead of choosing between two bottles of beer, just drink both

5:34 cark: too early for that anyways, going for a coffee instead

5:35 clgv: hehe. coffee will have to wait after lunch ;)

5:36 chrido: here another european clojure user, austria vienna :)

5:39 cark: you guys are using it professionaly ?

5:40 chrido: cark: since 3 weeks

5:41 cark: what kind of projects ?

5:42 chrido: datafeeds, statistics and so on, trying to calculate everything in realtime

5:43 cark: ahyes a good fit

5:43 chrido: but f# is also very nice

5:43 cark: i gave it a test run recently, it's not bad at all yes

5:43 i just hate the lack of parenthesis tho =P

5:43 chrido: but there isn't incanter and the whole apache ecosystem

5:43 Blafasel: chrido: Coming from F# as well.

5:44 cark: the real trouble with f#, it that whole miscrosoft echosystem

5:44 chrido: completly agree

5:45 cark: but i love their async stuff

5:45 and there really is something to say about those strongly typed languages like f# or haskell

5:45 chrido: i was looking for something what could compete with hadoop and could be used with f#/.net, but didn't found something

5:45 cark: very different from clojure of course, but good in their own way

5:46 chrido: so i gave clojure a try

5:46 lucian: not THAT different from clojure

5:46 * lucian is a python dev primarily

5:47 cark: well typing directed programming is a whole other world, and it has many advantages

5:47 tho i still prefer clojure

5:47 * lucian prefers dynamic typing (protocol-based, like clojure/python)

5:47 lucian: although the term "protocol" has been overloaded too much

5:48 "implicit interface" is probably less overloaded

5:48 cark: chrido: you'll find that there is a library for everything in the java world, and mosthave friendly licensing

5:51 chrido: cark: completely agree the java/apache ecosystem is just great. after 5 years .net it's hard to get used to that :) the only commercial library i use currently is aspose for generating word documents

5:52 cark: yep that's really fantastic

5:52 chrido: cark: on which kinds of projects are you working on?

5:53 cark: i'm in telephony stuff

5:53 chrido: in europe?

5:53 cark: interfacing with switch software, presenting the data to the admins and end-users

5:53 yes

5:54 chrido: interesting

5:54 cark: hehe nope that's boring =P

5:54 seancorfield: i thought microsoft had turned F# over to the community and were no longer maintaining it themselves? or did i just imagine that?

5:55 cark: seancorfield: oh no, it's first class language now

5:55 it's included with visual studio

5:55 chrido: seancorfield: no, they even announced f# 3.0 with some interesting type extension mechanism

5:56 seancorfield: good... not that i'm a fan of MS but i'm glad they're still fully supporting it

5:57 i haven't tried F# - i don't use any MS tech so i've not had the opportunity - but i used to do some ML back in the day

5:58 chrido: seancorfield: f# is also available for mac, they even founded some extensions for monodevelop

5:58 seancorfield: btw, on clojure in production... we took 1.3.0 to production earlier this week... we've had prerelease 1.3.0 versions in production since april!

5:59 chrido: oh, i'll have to take another look at mono... i was involved with the mac port several years ago (mostly testing and bug reporting around xsp but i think i actually did submit a patch or two)

5:59 cark: my production stuff is still on 1.2

5:59 seancorfield: cark: we decided to jump to 1.3.0 early on and avoid the 1.2 -> 1.3 migration

6:00 cark: the trouble is with libraries

6:00 seancorfield: yeah, hence my crusade with contrib :)

6:00 i just cut maven releases of data.priority-map and math.combinatorics (both 0.0.1)

6:01 cark: contrib is one thing

6:01 i'm still using an old version of compojure for clojure 1.0

6:01 seancorfield: i need to tie up a few loose ends in java.jdbc and push that to 0.1.0

6:01 cark: which i'm patching from the outside to make it work

6:01 seancorfield: yeah, there's a lot of 3rd party libraries that haven't become 1.3-compatible yet

6:02 talios: seancorfield: using the clojure-maven-plugin? any issues with 1.3?

6:02 * talios should rev his integration tests to use 1.3 final

6:03 kzar: I'm trying to accept JSON posted to me through Noir. I can't see how to set the Accept type to JSON and I can't get anything parameters coming through the params destructuring feature of defpage. I'm just returning (str params) and unless I add a route params like "/user/:id" in which case it seems to work

6:03 seancorfield: i don't touch maven myself, except for the contrib libraries and that's all set up by Clojure/core

6:03 kzar: Jeez I can't string a sentence together today, sorry about that mess

6:03 talios: ah :)

6:04 seancorfield: i assume that maven setup uses the clojure plugin but i don't know... i'm a leiningen fan :)

6:04 talios: I believe contrib is using my plugin still, I know stuart was looking at his own rewrite ( I kinda got overly sidetracked with $work )

6:05 I just found a heap of stackoverflow questions about it as well - I should go answer some of them :)

6:05 looks like most have decent answers already tho

6:05 seancorfield: i'm lucky that $work involves clojure and since we rely on a bunch of libraries, my $work includes helping maintain those too...

6:07 talios: nice. We have 3 folk at work who are keen on introducing clojure to the stack, but we're still holding off - too much else to get done first. need to get a proof-of-concept of clojure running in our osgi setup before we can really sneak something in

6:07 thankfully - all 3 of us comprise the back-end team :)

6:08 seancorfield: :)

6:09 i get to make that decision and, so far, it's worked out well... we're sending another team member to clojure training at the conj so that'll help too

6:09 talios: nice

6:10 seancorfield: he goes out sunday for training and i go out wednesday to join him for the conj itself... looking forward to that... just came back from strange loop and there was quite a bit of clojure content there too...

6:11 i'm just happy to see a lisp on the jvm so that i can use it at work :) i never thought i'd get to use lisp in production when i first started learning it about 30 years ago!

6:12 talios: Would loved to have gone to strangeloop.

6:12 I see some posts that some of Rich's comments kinda.... annoyed/insulted a few people. regarding tools/toolchains

6:12 seancorfield: i wanted to go last year but couldn't swing it... i won't miss it again!

6:13 chrido: will there be recordings of conj

6:13 seancorfield: heh, rich has strong opinions and likes to make people think

6:13 talios: way too expensive here. ( new zealand )

6:13 seancorfield: yes chrido everything will be up on InfoQ eventually

6:13 i think ppl were most upset by his dig at TDD / unit testing

6:14 but on the language panel, everyone said they wish they'd invented lisp :)

6:16 meh, i really must go back to bed now i've satisfied myself the latest round of jvm tuning has been reasonably successful... 3:15am... ugh! and i have to be up again in 4 hours for a conf. call with europe!

6:17 clgv: seancorfield: jvm tuning? - what did you tune?

6:42 robermann: I've just found that a "lein repl" process started from inside a lein project directory does not inherit the same classpath of a "lein repl" process started from a non-project directory. I was assuming that in the former case we would obtained the default lein classpath + project specifics libraries.

7:05 by "default lein classpath" I mean that set in the lein.bat startup file

7:20 mcstar: hi, how can i make cake use swank-clojure 1.3.3, when i invoke cake swank ?

7:26 wink: is there any hidden benefit for using a defrecord when a map satisfies all my needs? (I'm grabbing JSON, so the structure already contains everything with the correct name)

7:27 cark: a record is faster when doing (:name my-record)

7:28 wink: ok, that's a point.

7:28 cark: but there's more ceremony so is it worth it ?

7:28 then you have all the protocol stuff

7:29 a record can be part of a protocol

7:30 i personally almost always go for simple maps

7:30 wink: just by telling me that :name record works you've basically blown away my doubts, thanks (yep, just starting and poking around)

7:32 cark: also i think you cannot dissoc from a recor

7:32 d

7:32 not one of the declared fields anyways

7:32 which makes sense

7:33 wink: well, I'n having real datastructures, more like container objects for a handful of properties

7:33 so I think it really makes sense to have them defined and not just a map that matches by chance

7:34 cark: ahwell then you might want to check on reify which doesn't carry all the baggage of defrecord

7:34 clgv: I have implemented a lazy way to read a file and apply a function on each data entry. Now my heap blows and yourkit profiler says that inputstream has allocated 1,5GB of memory. can I convince inputstream to not do that? what is my error here?

7:35 I dont keep the data after I read it

7:36 cark: clgv: i woudl guess that you're holding onto the head of your lazy sequence somewhere

7:36 though it seems strange that yourkit says the inputstream is holding the data

7:36 clgv: cark: no I do not. I explicitely made sure of that ;)

7:36 its an ObjectInputStream though

7:37 cark: hum doesn't it maybe need to hold a reference to all data in order to resolve cross-references ?

7:39 clgv: cark: that might be the cause. but I dont have cross references between the objects since they were appended independently to the file

7:39 thorwil: how is name-with-attributes to be used? the name it returns appears as #<core$name clojure.core$name@5f6b0b29> in macro-expansion, but triggers "First argument to def must be a Symbol"

7:39 cark: " It automatically traverses references between objects, saving and restoring entire graphs."

7:40 clgv: cark: yes. so I have to hack it to persuade it that it does not have to.... :/

7:41 cark: in my experience binary serialization is always hairy for large datasets

7:41 clgv: it was the easiest way to get my result-data stored in compressed form

7:42 cark: still not as good as a gzip stream

7:43 then you can serialize to text with print

7:43 makes for easy debugging =P

7:43 clgv: cark: lol. I do a result -> ObjectOuputStream -> gzip -> ZippedObject -> ObjectOutputStream (append)

7:43 cark: wow

7:44 clgv: so I have a file of ZippedObjects that are entirely independent

7:44 cark: so you encapsulate your results in separate gzip "packets" ?

7:44 clgv: yes since I need the append behaviour

7:45 cark: i guess it might be usefull if you cannot wait for buffers to overflow

7:45 clgv: my last algorithm runtime was one month consuming 10months cpu time ;)

7:46 cark: so you're processing a given set of data in one go ?

7:47 clgv: now I want to process the resultdata in one run, yes

7:47 cark: i'm pretty sure you'd use less bandwidth with one single gzip stream

7:48 clgv: cark: not much. I tried

7:48 cark: though you might want to test that

7:48 clgv: and I cannot hold more than 100GB in memory at once ;)

7:48 cark: well then you can't use the objectstream =P

7:48 clgv: which would be needed for the gzipstream...

7:48 cark: i disagree there

7:49 it only holds enough to fill its buffer

7:49 clgv: gzipstream holds everything in memory and compresses it on closing

7:49 I tried that

7:49 cark: huh

7:49 clgv: it has to, for the gzip algorithm to work

7:52 hmm maybe I can clear the handle table with reflection myself

7:54 cark: indeed it's not flushable =/

7:56 clgv: cark: yeah under normal constraints thats reasonable

7:59 cark: there is a bug report about that

7:59 maybe you could try apache commons

8:00 clgv: what do you mean?

8:00 cark: org.apache.commons.compress.compressors.gzip

8:00 it has a flush method, doesn't know if it works tho =P

8:00 clgv: gzipoutpustream has one as well ;)

8:00 cark: but it doesn't work

8:01 clgv: but it doesnt do anything. the problem is not the gzipping, thats pretty fine.

8:01 the problem is the objectinputstream caching those independent objects ;)

8:02 michael_campbell: You know it's going to be a good day when you misspell your own name first thing...

8:03 cark: how about you do it this way : serialize each object to binary -> zip it -> put it in a binary packet -> stream it

8:04 the packet would have a data size as first bytes

8:04 clgv: cark: you dont understand. I already have 600GB data that I want to process now ;)

8:04 cark: oh already serialized ?

8:08 wink: hm, I seem to have run into some build problem. first it said "unknown ctor" and now after reverting and doing a clean I can't compile because of ClassNotFoundException, any ideas?

8:10 clgv: yes

8:11 wink: just found some _init.class that are still used. wtf

8:11 clgv: wink: build of what?

8:11 wink: my lein project

8:12 clgv: lein clean does not help?

8:12 wink: nope, it doesn't kill some class files.

8:12 I got an unkillabla javaw.exe

8:12 that seems to be it

8:13 system problem. doh

8:16 robermann: on Windows I find Unlocker an unvaluable tool for that problems: http://www.filehippo.com/download_unlocker/

8:17 this the source: http://www.emptyloop.com/unlocker/

8:21 wink: gah, now I checked out the last revision and I still get a classNotFoundException.

8:23 clgv: wink: and without providing details you even wont get an answer or hint here

8:24 wink: yeah sorry, I'm really trying to scrap some info at all together.

8:25 but basically it is: I did a lein clean and now I can't get it to compile again, sounds like java bein stupid

8:30 clgv: wink: or you actually renamed or deleted something previously

8:31 wink: and some class was still available under an old name somewhere and not cleaned by a previous clean? yeah

8:34 seems that was the culprit, sorry for the noise.

8:36 clgv: happens easily when moving or renaming defrecord/deftypes

8:42 hmm I have a little hobby project where I want to generate graphs dynamically via a webinterface. it needs just a combobox and maybe some editboxes to specify parameters and shall display a graph image. how and with what tools can I do that easily?

8:43 wink: my first guess would be raphaeljs + jquery

8:44 or some other canvas lib

8:44 clgv: I would want to try one of the clojure webframeworks - since it's a hobby project.

8:45 and the image to be displayed should be generated on the server as jpg or something

8:46 wink: oh ok, sounded more like a quick live manipulation thingy

8:47 clgv: no. I have some data behind it that is update on a regular basis

8:49 and the backend generating the data is already implemented in clojure, so it would be great to implement the frontend in clojure as well

8:50 cark: seems my reflection hack works

8:53 cark: haha nice

8:59 mcoffbyone: clgv: maybe it is worth to have a look at https://github.com/pallix/lacij and vijual

9:00 clgv: mcoffbyone: oh nice.

9:01 mcoffbyone: clgv: also if you can afford to place the nodes by hand you could try using d3.js and the clojurescript wrapper

9:02 clgv: but the world of displaying graphs is hard, even for a small number of nodes

9:02 clgv: hmm and webnoir might work for the interface I guess - dont know how much for interaction it offers

9:43 duck1123`: Does anyone know why, if I have Clojure 1.3 in lib/dev/ I get a NoSuchMethodError. If I delete that jar, then it works

9:53 cemerick: duck1123`: you probably have some dependency that contains class files AOT-compiled against clojure 1.2.

9:55 duck1123`: yeah. I think it may be the ordered-set lib that's doing it

10:00 clgv: duck1123`: did you try a lein clean?

10:04 duck1123`: lein clean fails. I can't do anything until I remove that jar

10:11 Blafasel: lein deps wants to download org.clojure:clojure:jar:1.+ (literally, it seems?) and fails as soon as I add vimclojure/server 2.3.0-Snapshot to the dev-dependencies.

10:12 Is that a bug in that package? My ignorance/own fault?

10:21 mindbender1:

10:22 joegallo: Blafasel: ITYM 2.3.0-SNAPSHOT

10:23 is that a typo here in irc, or do you have it wrong in project.clj? (maybe it's not case sensitive though, but i'd be surprised)

10:24 Blafasel: joegallo: That was a typo here - I didn't c/p

10:24 joegallo: i just created a new project locally, and it works for me with:

10:24 Blafasel: Trying to fix the last minor hiccups with my environment here. I want better integration between lein and vimclojure..

10:24 joegallo: [vimclojure/server "2.3.0-SNAPSHOT"]

10:25 Blafasel: joegallo: :dependencies or :dev-dependencies?

10:25 joegallo: The 1+, it seems, translated into 1.2.1

10:25 just dependencies

10:25 Blafasel: For me it was dev-*. Let me try changing that.

10:25 joegallo: huh, neato

10:25 it blows up on me, too, as a dev dependency

10:26 Blafasel: Ah.

10:26 And that's not expected, right? I mean - it's not a totally stupid idea on my side to try to add it like that?

10:26 joegallo: add clojure (whichever version) as a dev dependency, though, and then it works fine.

10:26 as to whether that is representative of a bug, or some known and expected behavior, i have no idea

10:26 robermann: FYI: recently I was trying to install Emacs on Windows; here I "documented" my steps - maybe this could be useful for someone else - purist Emacs people forgive me :) - https://sourceforge.net/apps/wordpress/codesounding/

10:28 Blafasel: joegallo: Added org.clojure/clojure "1.3.0" as a dev-dependency, same trouble with vimclojure/server. What did you put in?

10:29 joegallo: 1.2.1

10:29 but 1.3.0 works for me, too

10:30 Blafasel: *sigh* Yeah, _this time_ it was a typo. Sorry and thanks for the help.

10:31 joegallo: heh, no worries

10:31 Blafasel: Now.. let's see where I can get/build a recent lein-vimclojure

10:45 dpritchett: I'm jealous of GitHub's Hubot. It's a node-built CampFire bot that does all kinds of hooks like building and deploying stuff, googling things for people, etc.

10:45 If you were building somethign similar for your company but didn't want to introduce a Campfire dependency (monthly fees!) where would you start?

10:46 I could do a jabber bot but that's 1:1 communication and I much prefer public micromessaging type stuff. The only OSS twitter clone i've tried is status.net and it requires a bit more LAMP than I'd like to deal with today.

10:47 clgv: how do I flush printlns?

10:47 raek: clgv: 'flush'

10:47 clgv: ,(doc flush)

10:47 clojurebot: "([]); Flushes the output stream that is the current value of *out*"

10:48 clgv: doh! :P

10:48 thx raek

11:02 kzar: dpritchett: Could you use one of the IRC bots?

11:03 dpritchett: kzar: I guess I could use an IRC bot but I'd really like something that's got a web frontend with permalinks. Something like Twitter.

11:04 Plus our non-tech users aren't on IRC anyway.

11:04 Maybe I should just build a little in-house twitter clone myself.

11:04 kzar: dpritchett: Hmm well it could be a starting point I guess, anyhoo I don't know to be honest. We tried campfire and ended up using jaconda.im where I work

11:09 dpritchett: If you make a great Clojure powered alternative let me know, I'll give it a try

11:11 robermann: vista

11:11 ops

11:34 simonj: dpritchett: What about http://yammer.com? It's a private company but the service is free. Not sure what the API is like though...

11:53 dpritchett: simonj: I'm just sticking with xmpp right now, i'll teach it to use the public network later. http://i.imgur.com/TnnwW.png

11:53 err i probably meant to send that to kzar sorry.

11:59 technomancy: dpritchett: we have a clojurebot instance running against subrosa that works great

11:59 you can set up persistent chat history, so it's not like other IRC servers where stuff just disappears

12:00 dpritchett: persistent chat (see http://clojure-log.n01se.net/) is almost good enough, i think I might still want per-message permalinks though

12:00 there's plenty of low hanging fruit before i get to that point anyway

12:00 thanks

12:10 glob157: tryin to set up a clojure dojo east coast

12:23 jweiss: how do i go from [{:a :b} {:c :d} {:e :f}] -> {:a :b :n {:c :d :n {:e

12:23 :f}}} ? (list of maps to nested maps)? thought there may be a simpler way than loop, accumulator and ever-deeper assoc-in

12:25 raek: ,(reduce #(assoc %2 :n %1) (reverse [{:a :b} {:c :d} {:e :f}]))

12:25 clojurebot: {:n {:n {:e :f}, :c :d}, :a :b}

12:26 raek: it's easier to build inside out

12:40 jweiss: raek: excellent, thanks!

13:05 bsod1: what's the purporse of int-array? is it faster for int arrays?

13:06 dnolen: bsod1: mostly a convenience

13:08 bsod1: dnolen: I'll use a data structure, I'll only hold integers, and I need fast lookups, should I use this one or set?

13:08 arohner: bsod1: you should probably be using set or vector, unless you know the unboxing is a bottleneck

13:10 bsod1: arohner: no I didn't know, can you give some resources about unboxing thing for further information?

13:11 arohner: bsod1: http://my.safaribooksonline.com/book/programming/clojure/9781935182641/performance/288#X2ludGVybmFsX0ZsYXNoUmVhZGVyP3htbGlkPTk3ODE5MzUxODI2NDEvMjkx

13:12 bsod1: definitely start with set or vector. Switch to java arrays only after you've demonstrated it's necessary

13:14 kzar: Any ideas why some symbols are getting messed up in my templates? I'm using Noir but my templates are being defined with Enlive's deftemplate. For example &nbsp; in the template is replaced with �.

13:38 srid: `M-x clojure-jack-in` is broken since yesterday. nothing happens beyond the "Starting swank server..."

13:39 slime-connect is also broken :(

13:41 i'm going to reboot to see if that fixes the problem

13:41 open-network-stream: make client process failed: Connection refused, :name, SLIME Lisp, :buffer, nil, :host,, :service, 4005, :nowait, nil

13:50 technomancy: check the *swank* buffer?

14:01 srid: `cake swank` threw an exception: NoSuchMethodError: clojure.lang.RestFn.<init>(I)V (macroexpand.clj:1) - from cake.log https://gist.github.com/1251430

14:01 technomancy: there is no *swank* buffer.

14:02 technomancy: though clojure-jack-in creates one with "Process swank exited abnormally with code 1. That's not a task. Use "lein help" to list all tasks."

14:04 technomancy: ok, well the first thing you need to do is install swank

14:04 or better yet, start with the readme

14:06 srid: i had removed lein m2 cache yesterday to fix some problem. so that removed swank itself.

14:16 aaelony: I've been cheating a bit by copying a needed jar file that I have in a local directory into my lib directory. I am looking at https://github.com/technomancy/leiningen/blob/1.x/sample.project.clj for the lein option to simply point lein to where this needed jar sits. Can anyone recall the correct project.clj option to copy a local jar to the lib directory without clobbering it?

14:16 srid: technomancy: didn't help unfortunately, I still get "NoSuchMethodError: clojure.lang.RestFn.<init>(I)V (macroexpand.clj:1" https://gist.github.com/1251478 (from swank buffer)

14:17 i've been getting since yesterday even for 'lein run' and sometimes as a single-line warning in 'lein repl'

14:18 technomancy: srid: that's a 1.2/1.3 mismatch; nothing to do with swank

14:18 duck1123`: Is there anything like clj-record yet that uses Protocols, or is that still the best thing w.r.t. ORM's in Clojure

14:18 srid: technomancy: hmm, my project uses 1.2 (it used 1.3 until yesterday afternoon)

14:18 ibdknox: duck1123`: that uses protocols?

14:18 srid: lein clean

14:18 srid: the traceback contains swank.clj

14:19 duck1123`: Well, that returns the records as defrecords, and allows them to be extended

14:20 A while back, I had a patched copy that added metadata to the returned records, but it's very out of date

14:20 pmooser: In clojure 1.3, RT.classForName() catches a ClassNotFoundException and wraps it in a runtime exception before re-throwing. Anyone know what the rationale for this is ?

14:20 srid: ibdknox: did `lein clean`. but it didn't fix the exception.

14:20 duck1123`: Rich hares checked exceptions

14:20 ibdknox: duck1123`: hm, what in your case requires a protocol over generic functions over a map?

14:20 duck1123`: *hates

14:21 Well, I would like to be able to detect the type of record I'm dealing with and dispatch on that type

14:21 llasram: A checked exception killed Rich Hickey's mother. True story.

14:22 Does anyone (technomancy?) know of an off-the-shelf way to make flymake do something sane with leiningen projects?

14:23 s,flymake,Emacs flymake, (if there was any confusion)

14:23 ibdknox: duck1123`: I've been getting fed up with clj-record, and I've written ORMs before. There's a good chance I'll be writing one soon

14:24 duck1123`: but for now, jdbc, clojureql and clj-record are the only things I know of

14:24 duck1123`: Yeah, I've kinda felt the same way. I had to write this elaborate system to reload the connection info, because my username and password aren't available at compile time

14:26 pmooser: I know from reading the list that there was an effort to remove checked exceptions, but wrapping them all in Runtime ones seems like it obscures things a bit.

14:27 TimMc: Anybody know of a document rationalizing that change (and also addressing the downsides?)

14:27 duck1123`: At one point does that wrapping occur? In my experience, catching specific exceptions always seems to do what I want it to.

14:29 gtrak`: you can still catch specific exceptions

14:34 pmooser: gtrak, you can't, as far as I know.

14:34 If you have a runtime exception which is wrapping a ClassNotFoundException, a catch for ClassNotFoundException will not catch it

14:38 TimMc: Exception-destructuring catches would be great in Java.

14:38 dechaining, really

14:38 technomancy: destructuring is cooler

14:38 duck1123`: does slingshot do that?

14:39 I haven't gotten around to trying that one yet

14:40 technomancy: duck1123`: it does

14:43 semperos: parsing a bunch of XML, consistently structured, for simplicity let's say <parent> item with <title> and <content> children

14:43 I want to lazily parse the XML, and as I go create a datastructure for each <parent> (writing that into MongoDB along the way)

14:44 (using 1.2.1)

14:44 I've gotten as far as (1) contrib.lazy-xml for lazy parsing and (2) contrib.zip-filter.xml for creating a zipper from the parsed XML

14:44 srid: crazy. (use 'clojureql.core) makes `table` available in current namespace. but (require '[clojureql.core :as cql]) does not make cql/table available. looking at core.clj doesn't give any hint as to why.

14:44 semperos: what's a/the best way of going about the processing I'm attempting in Clojure?

14:45 srid: technomancy: FTR, i was using homebrew's lein; removing that and installing lein manually fixed the issues for me.

14:48 tsdh: Why doesn't if-let allow accessing the test result in the else case? I mean, in Clojure we have 2 different false values, so one might be able to distinguish them...

14:48 bsod1: I have 2 functions which are making same things, how can I measure their performance in clojure?

14:49 tsdh: bsod1: (time (dotimes 999999999 (my-fn)))

14:50 bsod1: If they produce lazy seqs, then put a doall arround your function call.

14:50 zippy314: Hey folks. What's the right way to use try/catch in clojurescript? I'm getting things I don't understand about "instanceof" when I say (catch Exception e ...)

14:50 bsod1: tsdh: thanks

14:50 tsdh: bsod1: yw

14:53 bhenry: in lein, does :jvm-opts in the project.clj file apply to everything done within a clojure.main repl too? i.e. java -cp my-uber-standalone.jar clojure.main

14:54 zippy314: The actual error message I get is: TypeError: Result of expression 't' [true] is not a valid argument for 'instanceof'.

14:56 dnolen: zippy314: under which evaluation environment? browser? Rhino?

14:56 zippy314: dnolen: browser

14:58 I'd just like to be able to capture all errors. If I try: (catch Exception e (js/alert "here"))

14:58 I get: Uncaught TypeError: Expecting a function in instanceof check, but got Error: NOT_FOUND_ERR: DOM Exception 8

14:58 in the browser

14:59 that's in chrome.

14:59 In Safari I get: TypeError: Result of expression 't' [undefined] is not a valid argument for 'instanceof'.

15:00 dnolen: zippy314: you don't write Exception, you throw js/Error and catch js/Error

15:00 devth_: how would one go about embedding rhino to interpret js inside of a clojure app? is it even possible?

15:01 dnolen: devth_: seems very possible

15:02 devth_: dnolen: i read that ClojureScript does it but don't know how

15:02 dnolen: devth_: Clojure can call into Java so for many things, integrating Java stuff is straightforward.

15:03 devth_: dnolen: ah, right. i will look into that route. thanks.

15:04 mattmitchell: I've used a function before that allowed me to temporarily go into a namespace, run code in that namespace and then jump back out. What function is that?

15:04 arohner: mattmitchell: with-ns

15:05 in contrib.with-ns

15:05 mattmitchell: ahh that's it. thanks, arohner!

15:05 amalloy: probably not a function

15:06 mattmitchell: true

15:08 tsdh: What's the special var that holds the last value in the repl?

15:08 cemerick: *1

15:08 tsdh: cemerick: Ah, thanks.

15:11 zippy314: dnolen: thanks! That solves the newbie problem! However, js/Error isn't what closure dom stuff is throwing because js/Error isn't catching that. And idea what it is throwing?

15:12 naeu: I'd like to modify a dynamic var within a fn which may or not be called within an explicit binding - what's the standard way of doing this?

15:12 I can't seem to call set! without being in a call to binding

15:13 yet I'd like to fall back on the default value of the dynamic var if an explicit binding isn't specified

15:13 zippy314: naeu: can you use refs and call (dosync (alter the-ref...

15:13 That's what I do.

15:14 naeu: zippy314: but that ref will be shared by all threads and I want this to be thread-local

15:14 nerooth: I have a function which adds something to a database with a generated id. After it has been added I'd like to use that generated id for something else. In python I would return the id with the function and use that. What's the idiomatic way to do it in clojure?

15:14 amalloy: naeu: you can't set! without a binding, yes

15:14 zippy314: naeu: I see. Is there a way to check if a binding has been made?

15:16 naeu: amalloy: ok, thanks

15:16 dnolen: zippy314: maybe a goog.Error?

15:16 naeu: amalloy: so what's the point of a dynamic var having a default value?

15:16 if the only way you can modify it within a thread if you re-bind it to a different value usign binding

15:17 amalloy: naeu: you can use a ThreadLocal object perhaps?

15:17 https://github.com/flatland/useful/blob/develop/src/useful/utils.clj#L151-174

15:17 like a thread-local atom, for example

15:18 i don't understand the question

15:19 naeu: sorry, I clearly don't fully understand what I'm doign and therefore am unable to clearly communicate my question

15:19 zippy314: dnolen: Ah, I see, to catch anything I can just: (catch js/Object... That works.

15:19 amalloy: dynamic vars have default values because usually you don't want/need to rebind them anyway?

15:20 naeu: amalloy: ah ok, so dynamic vars are only really meant to be 'modified' by calls to binding?

15:21 amalloy: mostly. they're set!-able so that you can use them to communicate up the stack as well as down, but mostly it's just for bindings

15:21 naeu: but you're only able to call set! if you konw it's already been explicitly rebound by a call to binding

15:22 amalloy: otherwise the scope of your set! is global and unknowable

15:22 if there's a binding in place, you know that someone is going to set it back to what it was before you started messing with it

15:22 thereby avoiding full-out global mutable state

15:24 naeu: amalloy: ah, that makes a lot of sense

15:24 amalloy: &(do (binding [*clojure-version* *clojure-version*] (set! *clojure-version* 20) (println *clojure-version*)) (println *clojure-version*))

15:24 lazybot: java.lang.SecurityException: You tripped the alarm! set! is bad!

15:24 tsdh: amalloy: While we are at dynamic vars: What's the purpose of `with-bindings' and `with-local-vars'?

15:25 amalloy: lazybot: y u no run my code?

15:28 tsdh: amalloy: I mean, `with-local-vars' creates dynamic vars that you can access only in its lexical scope. So why dynamic vars here?

15:31 amalloy: And `with-bindings' seems to be equal to `bindings' except that it wants a map of Vars to vals instead a vector of var symbols to vals...

15:38 amalloy: tsdh: you don't always have symbols

15:41 and i don't understand the use of with-local-vars either, but my understanding is that rich needed it for some kind of deep magic

15:42 drewr: one of them was supposed to be cross-thread was it not?

15:42 like, say, for tests

15:44 tsdh: drewr: Oh, indeed. with-local-vars says it creates per-thread bindings...

15:46 michaelr525: heey

16:02 * srid posted his first clojure question in stackoverflow - http://stackoverflow.com/questions/7602753 - question about restarting HTTP server from REPL

16:05 Blafasel: Is the vimclojure guy present here, sometimes?

16:07 gfredericks: I'm trying to expose some methods to JRuby.

16:07 dnolen: srid: http://stackoverflow.com/questions/2706044/how-do-i-stop-jetty-server-in-clojure

16:07 gfredericks: our first pass at this is rather hairy, with our (:gen-class :methods [...]) full of class names and method signatures and things

16:08 and some (def -foo_bar foo-bar)'s at the bottom of the NS

16:08 which of course have to be kept in sync

16:08 srid: dnolen: that question doesn't address the "edit" part in the workfklow though. AFAIK, for that I need to (.stop server) C-c C-k and then (.start server)?

16:08 can the above 3-steps be automated?

16:08 gfredericks: are there built in tactics we're overlooking? should I just whip up some macros?

16:09 dnolen: srid: I don't follow - do you understand defonce?

16:12 gfredericks: $findfn (fn [a b] 4) 2

16:12 srid: just read about defonce. I replaced def with defonce, and did C-c C-k ... then magically my server is reloaded (eg: I changed hiccup <title> that is reflected in the browser without myself having to .stop and .start the server)

16:12 dnolen: so I wonder if defonce is doing more than what it is supposed to do (as per doc)

16:14 hmm, perhaps the ring handler (defined with `def`) get overwritten during C-c C-k and so the old sever (defined with defonce) uses that automatically.

16:14 dnolen: srid: it doensn't do anything more. yup.

16:15 srid: i still don't understand how this "magic" works in repl. the first time I compile the module, my repl gets myproject.web namespace

16:15 the second time, this namespace gets overwritten by totally new code, no?

16:15 except for defonce'ed exprs?

16:16 jkkramer: srid: yes

16:17 srid: this means you can redefine things on the fly for a running server

16:18 srid: the only explanation that makes sense to me is that defonce will tear down the (already assigned) expr's closure environment and bind it to the newly compiled code. and so, the new ring handler comes to effect automatically

16:23 jkkramer: srid: is the code on SO the same as the code you're working with now?

16:24 srid: jkkramer: yup (private company project). and I solved it by using dnolen's defonce suggestion. it just works.

16:47 zerokarmaleft: https://gist.github.com/1251899 <= hmm, why doesn't SLIME display the println?

16:48 technomancy: zerokarmaleft: the root value of *out* is the swank process's stdout

16:48 unless you upgrade to swank-clojure 1.3.3-SNAPSHOT

16:48 guess I should man up and cut a release

16:48 srid: ,(inc technomancy)

16:48 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: technomancy in this context, compiling:(NO_SOURCE_PATH:0)>

16:48 srid: hmm

16:49 pjstadig: clojurebot: but he's right here

16:49 clojurebot: Huh?

16:49 srid: ,inc technomancy

16:49 clojurebot: #<core$inc clojure.core$inc@189ff97>

16:49 pjstadig: $inc technomancy

16:49 technomancy: srid: it's lazybot that handles karma

16:49 who appears to be absent

16:49 amalloy: technomancy: linode is having troubles today

16:50 technomancy: I blame node.js

16:50 can't spell linode without node!

16:50 srid: can't lazybot be run on heroku? (without workers)

16:50 amalloy: srid: yeah, if we wanted to pay for heroku and figure out how to do it. i'd rather just use the vps we're already paying for, which gives us an actual shell, thanks

16:51 * srid is going to refactor his ugly first-pass code to load data from sqlite https://gist.github.com/1251915

16:51 gtrak`: ,(inc 'technomancy)

16:51 clojurebot: #<ClassCastException java.lang.ClassCastException: clojure.lang.Symbol cannot be cast to java.lang.Number>

16:51 gtrak`: ,(inc "technomancy")

16:51 clojurebot: #<ClassCastException java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Number>

16:51 srid: ,(def karma-yogis {})

16:51 clojurebot: #<Exception java.lang.Exception: SANBOX DENIED>

16:52 technomancy: I'm flattered you guys, but clojurebot is not your man.

16:52 gfredericks: (inc technomancy)

16:52 lazybot: ⟹ 15

16:52 amalloy: $login

16:52 lazybot: You've been logged in.

16:53 amalloy: $say #clojure I'm here to save the day!

16:53 lazybot: I'm here to save the day!

16:53 srid: how to get the top list?

16:53 amalloy: anyway. back to your regularly-scheduled programming

16:54 srid: $say #emacs you are all lazy!

16:54 lazybot: srid: It is not the case that you don't not unhave insufficient privileges to do this.

16:54 gfredericks: those last four words had way too few negatives

16:54 lazybot: who gots the mostest karma?

16:55 (apply max #clojure)

17:00 zerokarmaleft: technomancy: ah ok, not a huge deal

17:07 dbushenko: hi all!

17:07 how to join two vectors?

17:07 Raynes: &(concat [1 2 3 4])

17:07 lazybot: ⇒ (1 2 3 4)

17:07 Raynes: &(concat [1 2 3 4] [5 6])

17:07 lazybot: ⇒ (1 2 3 4 5 6)

17:07 dbushenko: thanks!

17:07 amalloy: Raynes: :(

17:08 Raynes: And if you want them to stay vectors: ##(into [1 2 3 4] [5 6])

17:08 lazybot: ⇒ [1 2 3 4 5 6]

17:08 amalloy: yay!

17:08 Raynes: amalloy: I was getting there. ;)

17:08 * amalloy always does it in one go with ##((juxt concat into) [1 2 3 4] [5 6]), and damn anyone who doesn't follow

17:08 lazybot: ⇒ [(1 2 3 4 5 6) [1 2 3 4 5 6]]

17:09 Raynes: o/

17:09 gfredericks: amalloy: and if you want just one of those, you'll comp with first or last, right?

17:09 kjeldahl: So what's the idiomatic way to check if a function returned anything at all, "empty?"?

17:09 amalloy: i don't always use higher-order functions...but when i do, i prefer juxt

17:10 gfredericks: kjeldahl: depends on what your definition of "not returning anything" is

17:11 kjeldahl: probably one of nil? or empty? will be what you want

17:11 kjeldahl: Let's say from a when-let in a function that did not succeed...

17:11 Raynes: $google vimclojure git mirror

17:11 lazybot: [clones/vimclojure - GitHub] https://github.com/clones/vimclojure

17:11 gfredericks: ,(prn (when-let [x false] :poo))

17:11 clojurebot: nil

17:11 Raynes: Doh, It's old.

17:11 gfredericks: kjeldahl: that's nil, so you can check the return value with nil?

17:11 dbushenko: where is duck-streams now?

17:12 I mean it was in contrib

17:12 TimMc: clojurebot: what happened to contrib?

17:12 Raynes: Where all bad libraries go to die.

17:12 clojurebot: Excuse me?

17:12 gfredericks: kjeldahl: but the question sounds fishy to me, as I don't think most people would want to check such a thing

17:12 kjeldahl: ,(nil? false)

17:12 clojurebot: false

17:12 TimMc: clojurebot: where did contrib go?

17:12 clojurebot: well... it's a long story: http://dev.clojure.org/display/design/Where+Did+Clojure.Contrib+Go

17:12 TimMc: dbushenko: ^

17:12 Raynes: dbushenko: clojure.java.io is essentially the evolution of it.

17:12 dbushenko: Raynes, thanks!

17:12 Raynes: dbushenko: But yes, do read the above link.

17:14 dbushenko: can't find anything about clojure.java.io in the above link...

17:14 Raynes: Yeah, I just noticed that.

17:14 http://clojure.github.com/clojure/#clojure.java.io

17:15 dbushenko: Raynes, is this the core functionality?

17:15 Raynes: Yes.

17:15 dbushenko: thank!

17:15 Raynes: Welcome!

17:16 dbushenko: though I miss the duckstreams, I can find a solution with clojure.java.io...

17:18 * technomancy misses to-byte-array and delete-file-recursively

17:19 * gfredericks wonders what delete-byte-recursively would do

17:23 gtrak`: gfredericks, deletes the byte at the value of the byte

17:24 gfredericks: gtrak`: best virus ever?

17:24 gtrak`: yes

17:24 gfredericks: at least on an 8-bit machine

17:25 so does nobody have any opinions/advice about populating a :gen-class with a bunch of methods?

17:25 gtrak`: do it in style, or don't do it at all

17:26 code like nobody's watching, etc..

17:27 macroexpand like you've never been hurt,

17:34 gfredericks: (defn macrocontract [form] ...)

17:35 figures out why your code isn't dry, writes a macro to make it better, and applies the macro

17:35 jorgeb: Afternoon. I am trying to find a Clojure library for logging to Scribe (https://github.com/facebook/scribe), but haven't had much luck. Let me know if anyone here can point me in the right direction. Thanks.

17:38 brehaut: jorgeb: have you looked for a Java library?

17:38 jorgeb: brehaut: yeah, but keep hoping for a Clojure one

17:38 or at least a wrapper

17:39 brehaut: using java in clojure is first class

17:39 jorgeb: yeah, I know, but I am lazy

17:39 brehaut: and idiomatic

17:39 bsod1: what is (subs) equivalent for vector and lists?

17:40 brehaut: bsod1: subvec for vectors

17:40 dbushenko: how to cast a vector of chars to a string?

17:41 brehaut: ,(apply str [\a \b \c])

17:41 clojurebot: "abc"

17:41 dbushenko: thanks!

17:41 brehaut: bsod1: for lists i suspect you would use drop and take?

17:42 gfredericks: subs?? how have I used clojure for two years and not heard of this?

17:42 brehaut: gfredericks: that was my reaction too

17:42 gfredericks: sometimes I wonder if clojure.core is infinite

17:43 bsod1: brehaut: yes, thank you. I think lists are implemented like linked lists, right? operations like get is O(n) instead of O(1)

17:43 brehaut: gfredericks: .substring is so easy though, theres little motivation to go looking

17:43 bsod1: correct

17:45 bsod1: i say correct, but ive never looked at the imp so i could be extremely wrong

17:46 dbushenko: how to define a function name prior its implementation? I want a function name in the beginning of file, and then, 10 lower -- define the function

17:46 I need that for recursive definition

17:47 gfredericks: declare

17:47 dbushenko: thanks

17:47 gfredericks: shouldn't need it for a vanilla recursive function though...

17:48 TimMc: Mutual recursion?

17:48 gfredericks: yeah maybe

17:48 dbushenko: yep

17:48 gfredericks: dbushenko: be careful about the stack depth. If you need tail-optimization, use trampoline

17:49 dbushenko: thanks, I have to check it out

17:51 bsod1: brehaut: http://stackoverflow.com/questions/1147975/in-clojure-when-should-i-use-a-vector-over-a-list-and-the-other-way-around about the question I asked about lists

17:51 gfredericks: so what's up with the :tag metadata and clojure 1.3?

17:52 I should try it in 1.2 before I ask...

17:53 brehaut: bsod1: theres nothing that definitively stats that lists are cons pair/singly linked lists in their implementation

17:54 gfredericks: okay, so old behavior for ^:foo is {:tag :foo}, and new behavior is {:foo true}, right?

17:59 amalloy: brehaut: in whose implementation?

17:59 brehaut: amalloy: in clojure lists. (in the thread that bsod1 linked)

18:00 im fairly sure they _are_ but it doesnt have to be the case

18:00 amalloy: basicly im backpedaling from an absolute claim i made via assumption

18:00 amalloy: seeing as there is basically no javadoc or comments of any kind in PersistentList.java i guess that's true

18:02 but certainly the actual impl is a singly-linked chain of Lists

18:02 brehaut: that was my assumption

18:04 amalloy: hah. reading through the impl caused me to discover something amusing

18:04 &(with-meta inc {:name 1}) ;; works

18:04 lazybot: ⇒ #<core$inc clojure.core$inc@d1e727>

18:04 amalloy: &(with-meta inc {:name 1}) ;; no good

18:04 lazybot: ⇒ #<core$inc clojure.core$inc@168c70e>

18:04 amalloy: er

18:04 &(with-meta list {:name 1}) ;; no good

18:04 lazybot: java.lang.UnsupportedOperationException

18:05 brehaut: lists dont support metadata?

18:05 or you cant name them 1 ?

18:05 amalloy: brehaut: the function clojure.core/list doesn't support metadata on itself

18:05 brehaut: oh right

18:06 i think i can conclusively say that i have read more of clojure's source than any other language ive used

18:06 (despite having hardly scratched the surface of clojure's source)

18:06 gtrak`: clojure's source makes me happy

18:06 amalloy: brehaut: brings up the question of what it would mean to read english's source

18:07 brehaut: amalloy: i dont use english, i misuse it

18:07 anyhow, i imagine it looks similar to the perl internals

18:08 or perhaps bash, if bash was english and C was german

19:25 success. necessary-evil now runs on 1.3

19:26 * gfredericks has a memory leak

20:33 devn: gtrak`: :)

20:33 gtrak`: It's like reading a good book.

20:34 The beginning is a little slow, confusing -- but once the main characters are introduced things get rolling along nicely.

21:13 mindbender1: how do one choose between let and binding?

21:15 brehaut: mindbender1: bindings is for rebinding dynamic vars, let is for defining local variables

21:15 mindbender1: 99.9% of the time you'll probably want a let

21:17 mindbender1: brehaut:in which cases then do binding suffice as it seems to be confusing to me when to use which

21:17 brehaut: mindbender1: what language have you come from?

21:18 mindbender1: Java but not much an expert

21:18 brehaut: do you know what a local variable is in java?

21:18 mindbender1: yes vars within a function

21:18 brehaut: ok

21:18 thats what let does

21:19 mindbender1: ok

21:19 brehaut: in contrast, the def family of forms creates Vars

21:19 (big v)

21:20 mindbender1: and so you rebind them within a function with binding?

21:20 brehaut: mindbender1: yes, but they have different scope rules

21:20 mindbender1: yes I understand their diffs

21:21 binding's scope is broader than let?

21:21 brehaut: let is for lexical scoped variables and bindings are dynamic scoped variables

21:21 its not exactly a case of broader

21:22 mindbender1: lok

21:22 brehaut: say for have a Var deffed called *foo* and then you define a function (defn do-baz [x] (frobitz *foo* x))

21:23 mindbender1: cos I read that binding's continues outside their forms

21:23 brehaut: you can later wrap a binding around a call to do-baz (which is btw a terrible name for a function) like (binding [*foo* 2] (baz 3))

21:23 mindbender1: ok

21:24 brehaut: mindbender1: but you very rarely use a binding

21:24 mindbender1: so nothing to worry about?

21:24 brehaut: if in doubt, use a let

21:24 mindbender1: ok thanks a lot

21:25 brehaut: mindbender1: http://en.wikipedia.org/wiki/Dynamic_scope has sections on Lexical Scoping and Dynamic Scoping

21:26 mindbender1: ok.. checking it out.. thanks

22:00 amalloy: mindbender1: neither one is "broader": consider (defn foo [x] (fn [y] (+ x y))), where x can "live on" forever, bound in the functions returned by foo

22:02 compared to (defn bar [x] (binding [*data* x] (some-other-fn))) - now *data* doesn't "live on" in that sense (if some-other-fn returns a function, then it won't know about the temporary binding), but it does reach "farther" by being visible from within some-other-fn even though they're not lexically related

22:03 SegFaulty: Hi, as a person new to clojure would I be better off using 1.2.1 so that I can use the monolithic version of clojure-contrib or should I start with 1.3?

22:06 mindbender1: amalloy: does your (foo x) imply an implicit let

22:06 as you did not use a let in foo

22:07 brehaut: mindbender1: function arguments are lexically scoped variables in the samew as let defined locals are

22:08 SegFaulty: depends what you are writing, and what you are going to depend on

22:08 SegFaulty: a lot of the monolithic contrib is dead code these days, so you dont really want to waste time learning it

22:13 jkkramer: there's been talk of creating a monolithic 1.3 "contrib", but it hasn't materialized yet

22:13 SegFaulty: ok, thanks!

22:14 brehaut: jkkramer: do you have a link for that?

22:14 jkkramer: btw, clojuresphere is cool

22:14 SeqFaulty what are you planning on starting with?

22:15 SegFaulty: brehaut: not really sure, I'm just really curious about functional programming

22:18 hamzaa: can anyone explain me this behavior? http://stackoverflow.com/questions/7605241/clojure-priority-map

22:20 jkkramer: brehaut: i'm going off a vague recollection of messages on clojure-dev to the effect of someone (stuart sierra?) saying they might create a bundled version of all the new contrib libs, for convenience, but it hasn't been a priority

22:20 brehaut: jkkramer: ok thanks. i'll go have a dig

22:21 zerokarmaleft: SegFaulty: i'd recommend 1.3 if you're just testing the waters

22:22 when you get to the point where you need to pull in deps outside of core, you can just cross that bridge when you get there

22:22 SegFaulty: zerokarmaleft: I figured that's where I should start but I wasn't sure if I'd be missing anything important without contrib

22:23 brehaut: SegFaulty: you arent without contrib entirely

22:23 ~contrib

22:23 clojurebot: contrib is http://github.com/richhickey/clojure-contrib/tree/master

22:23 mindbender1: brehaut: I want to extend a java apllication with clojure. Do you think that's a good idea?

22:24 brehaut: rats

22:24 mindbender1: i have zero idea

22:24 jcromartie: mindbender1: what do you mean by extend?

22:24 mindbender1: I think it would be perfect for some cases

22:24 brehaut: clojurebot: tell me about contrib

22:24 clojurebot: well... it's a long story: http://dev.clojure.org/display/design/Where+Did+Clojure.Contrib+Go

22:24 mindbender1: as in customize the application

22:24 jcromartie: mindbender1: someone else's application?

22:25 mindbender1: the customization will be in a seperate jar

22:25 jcromartie: mindbender1: or adding things like config/plugins?

22:25 mindbender1: yes an open source app

22:25 jcromartie: mindbender1: sounds like http://www.gnu.org/s/guile/

22:25 but for Java

22:25 I'd encourage that

22:26 jkkramer: brehaut: https://groups.google.com/d/msg/clojure-dev/k6Oc9gxJxI8/C-M4nzUN-XgJ

22:26 brehaut: jkkramer: thanks!

22:26 SegFaulty: that second link clojurebot spat out ("well… its a long story") is relevant

22:27 whoa when did completely different groups happen?

22:28 SegFaulty: brehaut: ok, thanks

22:29 jkkramer: brehaut: clojure-dev's been around a long time

22:29 brehaut: jkkramer: sorry, i mean the google groups interface

22:30 jkkramer: oh, yeah. i'm not sure i like the new one. the interface is cleaner, but it's slow

22:30 of course, the old one was slow & buggy, too

22:33 jayunit100: hi guys. anyone use nailgun ? I just got vim / clojure working . but get a weird error about nailgun.

22:35 brehaut: jkkramer: heaps of the new google stuff has been a total PITA with apps for your domain accounts.

22:39 symbole: Can anyone recommend a commonly used clojure-hadoop fork? Seems like Stuart Sierra's version is not being maintained.

22:42 amalloy: jkkramer: arohner, i think, did it

22:43 the "1.3 contrib", that is

22:45 jkkramer: amalloy: o, i didn't know someone actually put that together yet. using the new contrib libs?

22:47 jayunit100: does "load-file" run the commands in a file ?

22:48 i have a simple user=> )print "aaa")

22:48 im sorry, i mean a simple load-file with a print statement, but nothing happens.

22:50 amalloy: jkkramer: i dunno. i don't recall who it is, but someone has published a version of old-contrib with the 1.3-incompatible bits pulled out

22:50 i think he posted it on the mailing list a week or so ago

22:51 jkkramer: amalloy: ah ok. i meant a bundled-up version of all the new contrib libs -- core.incubator, data.zip, etc

22:51 amalloy: no, definitely not, and i do't think anyone *should* do that

22:51 (whether anyone should do the other thing is also questionable)

22:52 jkkramer: i think it would be handy for experimental or short-lived projects

22:53 i'd like to have a generic, batteries-included project i can "lein swank" anytime to play with

22:56 and be able to keep it up-to-date without changing 20 dependencies

22:56 jayunit100: (load-file "a.clj") runs a file.... load-file "a.clj" doesnt :) i keep forgetting about the parenthesis

22:57 brehaut: jayunit100: already lisping at an advanced level ;)

22:57 amalloy: hah

22:58 jkkramer: jayunit100: after using clojure for a while, i regularly write (foo bar...) in non-lisp languages, and leave out commas/semicolons

22:59 brehaut: jkkramer: i find i do that a lot more in python than other languages

23:00 jayunit100: yeah im kikin butt ovr hereee ((((( )

23:00 ))))))

23:00 jkkramer: I never realized how useless most commas are until Clojure

23:00 zerokarmaleft: jkkramer: i've started doing that too ><

23:00 brehaut: jkkramer: i never realised how useless most parens are until Haskell ;)

23:01 jayunit100: what happens if you dont have parens around something ?

23:01 jkkramer: true... i sometimes envy a well-placed $ or .

23:01 brehaut: type system magic

23:01 likewise

23:02 jayunit100: & load-file "a"

23:02 lazybot: ⇒ #< clojure.lang.RT$3@12db656>

23:02 brehaut: or more precisely i miss >> and |> from F#

23:02 jayunit100: what does that mean ? Is that an object or something ?

23:02 amalloy: jayunit100: that's the function "load-file" being displayed, not called

23:03 &inc

23:03 lazybot: ⇒ #<core$inc clojure.core$inc@1019bf1>

23:03 amalloy: &(let [x inc] (x 1))

23:03 lazybot: ⇒ 2

23:03 jayunit100: oh ok. so what is the # sign ?

23:03 brehaut: jayunit100: classname on the left of @ and memory address on the right

23:03 amalloy: #<...> means "whoa some kind of crazy object, i'll try to print it, but no guarantees"

23:03 jayunit100: &(inc 1)

23:03 lazybot: ⇒ 2

23:03 jayunit100: oh ok...

23:03 really?

23:04 amalloy: brehaut: s/memory address/toString

23:04 &(.toString inc)

23:04 lazybot: ⇒ "clojure.core$inc@1019bf1"

23:04 amalloy: &inc

23:04 lazybot: ⇒ #<core$inc clojure.core$inc@1019bf1>

23:04 brehaut: amalloy: its not just the memory addr that is the tostring

23:04 jayunit100: i guess under the hood , that means everything in clojure is ultimately an object. and there are some artifacts of that in the repl that are meaningless :( thats kinda scary.

23:04 brehaut: (java.util.Date.)

23:04 ,(java.util.Date.)

23:05 clojurebot: #<Date Thu Sep 29 20:04:35 PDT 2011>

23:05 amalloy: brehaut: huh? it prints the toString on the right; you only see memory addresses because the default impl of toString involves the memory address

23:06 brehaut: amalloy: i think we are talking past each other again

23:06 mindbender1: please I need more light on when to use which of clojures collections object like vectors, maps, sets, and seq

23:06 brehaut: amalloy: the default object tostring is "class@memaddr" right?

23:06 amalloy: more or less

23:07 it's actually "class@identityHashCode", and the identityHashCode is a truncated memory address

23:07 mindbender1: please I hope I'm not asking for too much

23:07 amalloy: &(.toString (Date. 1 1 1))

23:07 lazybot: java.lang.IllegalArgumentException: Unable to resolve classname: Date

23:08 amalloy: &(.toString (java.util.Date. 1 1 1))

23:08 lazybot: ⇒ "Fri Feb 01 00:00:00 PST 1901"

23:08 amalloy: &(System/identityHashCode (java.util.Date. 1 1 1))

23:08 lazybot: ⇒ 12900739

23:11 brehaut: mindbender1: maps are for when you have some associative relationship between the data

23:11 mindbender1: vectors are for contiguous groups of things, with O(1ish)lookup by index

23:11 vectors also double as tuples

23:12 mindbender1: sets are mathematical sets

23:12 a collection of things where each item in the set occurs exactly once

23:13 and you have a range of set wise operations like union, interesection etc

23:13 mindbender1: seqs are an abstraction, rather than a collection

23:13 for when you want to process things sequentally

23:15 mindbender1: brehaut:thanks a lot

23:15 much clearer to me now

23:17 hamzaa: can anyone explain me this behavior? http://stackoverflow.com/questions/7605241/clojure-priority-map

23:29 jkkramer: ,(sorted-map-by (fn [[a] [b]] (< a b)) [1 2] :foo [1 3] :bar)

23:29 clojurebot: {[1 2] :bar}

23:29 jkkramer: hamzaa: ^ priority-map-by is based on sorted-map-by, which says that items which compare the same are the same

23:45 cark: does anyone know of a way to prevent warnings from *warn-on-reflection* for a small part of a file ?

23:47 by that i mean not on top level

23:47 like from inside a proxy declaration

23:48 brehaut: cark: im guessing where, but (binding [*warn-on-reflection* false] (code you dont want to warn))

23:48 s/where/here/

23:48 lazybot: <brehaut> cark: im guessing here, but (binding [*warn-on-reflection* false] (code you dont want to warn))

23:48 cark: brehaut: ahwell that doesn't work, because (not= compile-time run-time)

23:49 i'm guessing *warn-on-reflection* isn't even bound at run time

23:50 butbut maybe with some macro trickery ...

Logging service provided by n01se.net