#clojure log - Aug 22 2011

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

0:01 chewbranca: technomancy: checkout deps looks like it could accomplish it, but I mean more along the lines of declaring a project with a direct git source

0:02 just curious if that's ever on the radar or if maven is just the way to go and that I need to get more familiar with using it

0:03 talios: an entire project from git? that doesn't contain the project.clj?

0:03 that sounds... broken.

0:03 chewbranca: because here's what I don't understand, if I'm working on a project on several different computers, how do I declare deps for plugins that require manual installation?

0:04 technomancy: chewbranca: definitely not looking to add support for projects that aren't published as artifacts anywhere.

0:04 chewbranca: talios: no I mean being able to specify a git source for an individual project in projects.clj

0:04 technomancy: ok cool, so means I need to get familiar with maven

0:04 talios: chewbranca: if plugins require manual install, then thats a flaw in lein IMHO.

0:05 can you not say "this project has plugin deps"?

0:05 chewbranca: so now that brings back the question, how do I declare that I depend on manually installing some x projects from git

0:05 technomancy: more like a flaw in the plugin

0:05 chewbranca: here is a perfect example: https://github.com/getwoven/webmine

0:05 talios: (not having actually used lein beyond uber single things, I don't know what it is, or doesn't actually do )

0:05 technomancy: chewbranca: step 1 is to open a bug report for the project saying "you need to publish your jars"

0:05 chewbranca: sweet looking project, but there is 6 plugins that don't have public artifacts of the required versions

0:06 technomancy: already did, on step 2 right now ;-)

0:06 technomancy: ah, well that's a start =)

0:06 talios: technomancy: can lein deploy to remote maven repo, like Nexus or the like?

0:06 technomancy: chewbranca: if they show no intentions of fixing it, you can upload org.clojars.chewbranca/foo to clojars as a workaround, but it's a shame if it comes to that

0:06 talios: or does it only have the clojars/ssh way?

0:07 technomancy: talios: yeah, it can do archiva/nexus deploys

0:07 chewbranca: so how do I programmatically define the dependency and installation of a handful of projects, so that I can reproduce this again?

0:07 technomancy: yeah I really dislike uploading other peoples' projects

0:07 talios: normally I'd suggest installing nexus locally, and using that as a mirror, deploy those artifacts to nexus.

0:07 chewbranca: I mean I guess could just do a shell script, would work I guess, but that gets ugly in a hurry

0:07 technomancy: chewbranca: if they had their act together, you wouldn't have to =(

0:08 this isn't the first time I've seen shenanigans like this with getwoven

0:08 chewbranca: technomancy: I agree, but shit happens, and seeing as they deleted clj-http I don't expect them to

0:09 technomancy: geez

0:09 chewbranca: talios: nexus looks interesting, but seems more useful as a centralized server, so should I just look into doing something like setup nexus.chewbranca.com and run my own maven server?

0:09 technomancy: an internal nexus/archiva is a good solution if you need to share jars among a team, clojars might be better if it's OSS.

0:10 talios: or oss.sonatype.org - and get syncing to maven central

0:10 chewbranca: I just want to easily be able to have the same setup on my laptop or desktop or random other computer from wherever I am

0:11 technomancy: sonatype won't let you republish other folks' jars though, will they?

0:12 talios: yes and no - you can raise a JIRA ticket to get them to deploy jars.

0:13 that you don't own. but they'll do a bit of verification on the jar first.

0:13 but as simple and isolated as clojars, where you just go rampantly slapping jars online under your own groups

0:14 chewbranca: talios: yeah definitely something I'm trying to avoid, especially since its a handful of their plugins that need to be released, hopefully something will come of the ticket

0:14 talios: s/but/not/

0:14 lazybot: <talios> not as simple and isolated as clojars, where you just go rampantly slapping jars online under your own groups

0:15 talios: one of the weaknesses I still see in the clojure community is everyone is source dependant, no one wants to publish jars, or frankly - release anything.

0:15 technomancy: talios: really? getwoven seems to be the exception rather than the rule

0:16 chewbranca: talios: yeah seems like it, but on the opposite end of the spectrum people release rubygems constantly, and it gets problematic to manage deps between a large number of gems

0:16 talios: maybe I just havn't taken a closer look lately :) really need to get back into some clojure hacking

0:16 chewbranca: rubygems is NOT a good model to chase after tho :)

0:17 chewbranca: talios: oh absolutely not, was not suggesting that by anymeans

0:17 talios: rubyist just say "I depend on X, not X v2.3.1"

0:17 tho I think they -can-

0:17 technomancy: it's mostly a cultural thing

0:18 chewbranca: talios: with bundler now, you basically snapshot a set of version deps to use, much nicer than before, but upgrading gets ugly

0:21 technomancy: nice, haven't looked at the leiningen plugins page in a while, pretty good set of stuff there now!

0:23 talios: I see the new Cucumber-JVM has a clojure module for writing steps. Must play with that tonight

0:25 dnolen: k, regex pattern match whittled down to 9 meaningful lines of code, https://gist.github.com/1161596

0:25 to-source will probably become a multimethod.

0:53 ibdknox: technomancy: I was trying to see if there was something obvious I could do to get something that requires 1.3.0 in a lein plugin

0:53 technomancy: I was working on the cljs watching stuff and my first thought was to just do it as a lein plugin :)

0:54 technomancy: ibdknox: you could construct a dummy project in-memory with 1.3.0 as a dependency and use eval-in-project

0:55 ibdknox: oo

0:55 technomancy: let me know if that actually works; I really have no idea

0:55 ibdknox: haha

0:55 technomancy: but it seems theoretically possible

0:56 ibdknox: I might just leave it be for now, and instead get the script into clojurescript proper

0:57 since I have that working at this point

0:57 it'd be so much better in lein though... since it could benefit from having the classpath setup correctly

0:57 technomancy: well, lein 2.0 will be able to use clojure 1.3 if hiredman's bootclasspath patch gets applied

0:58 so there's that

1:02 aaelony: I just followed the "Getting started" instructions for Noir (http://webnoir.org/#started). lein run gives me a server, but going to localhost:8080 the site does not render. The stack trace says java.lang.ClassCastException: java.lang.String cannot be cast to clojure.lang.Named

1:06 ibdknox: aaelony: you made no changes to the code?

1:06 aaelony: I didn't change anything.

1:06 I'm using Leiningen 1.6.1 on Java 1.6.0_26 Java HotSpot(TM) 64-Bit Server VM

1:07 ibdknox: what'd you name your project?

1:07 aaelony: I gave it the name "noir-ui"

1:07 maybe its the dash?

1:08 ibdknox: nope

1:08 I just did lein noir new noir-ui

1:08 lein run

1:08 and it worked

1:09 aaelony: maybe its my machine

1:09 ibdknox: ugh, I hope not :(

1:09 do lein clean, lein deps

1:09 aaelony: I just tried it again with the name "nnoir", same thing

1:09 will do

1:10 ibdknox: just to make sure, it's using noir 1.1.0 right?

1:10 aaelony: yeah, I did exactly what's on the Getting started section: lein plugin install lein-noir 1.1.0

1:10 lein noir new my-website

1:10 cd my-website

1:10 lein run

1:11 except I didn't use "my-website"

1:11 ibdknox: mhm

1:11 I'm not sure without looking at it, you could zip it and send it to me

1:11 aaelony: I'm using the name "nnoir" now, still an issue

1:12 will do. I'll use the email on the site.

1:12 ibdknox: Lately I've been struggling with a class of issues where things, once jarred, no longer behave consistently on different machines

1:12 which makes no sense to me

1:12 I've not heard of it with Noir though

1:12 just the ClojureScript jar I made

1:13 aaelony: there may be an older version of something conflicting on my host, but I don't know where it would be coming from

1:13 come to think of it, I think laprepl gave me a similar problem

1:14 ibdknox: remove ~/.m2/repository

1:14 that will force it to get new deps for everything when you call lein deps

1:14 aaelony: I think I've been down that path before, but I'll try that again

1:32 no_mind: I have a try clause inside a doseq. I want that if an exception is raised, the doseq should continue with next element in the sequence, without raising an exception. How do I do this ?

1:34 ibdknox: anyone know if ClojureScript's (meta) actually works?

1:34 it's there...

1:34 but I'm always getting null :(

3:28 michaelr525: hello!

3:28 ibdknox: hello lol

3:29 michaelr525: why lol? and when are you going to go to sleep?

3:34 amalloy_: ibdknox: meta on what kind of element?

3:34 i don't do any cljs, but looking at the source, at least meta on a list should work

3:35 ibdknox: amalloy_: it seems vars can't have it

3:35 amalloy_: which is what I was trying to do

3:35 :(

3:35 I have a cheater's solution for now though

3:35 amalloy_: ibdknox: cljs doesn't have vars anymore at runtime, i thought

3:36 ibdknox: amalloy_: yeah

3:36 amalloy_: hadn't realized that until tonight

3:36 amalloy_: what's your cheater solution, ooc?

3:37 ibdknox: the information I need is also stored in the result of an invocation of the function

3:37 amalloy: man, i knew there were too many _s in this conversation. usually it's you, so i didn't notice :P

3:37 ibdknox: haha

3:38 this is what I was doing

3:38 allowing you to attach event handlers to anything that comes out of a (defpartial some-html-here) in pinot

3:39 so you can bind events to all dom elements produced by that function

3:39 once

3:40 pyr: which book on java should a clojurian buy ?

3:41 it's hard to separate the chaff from the grain when it comes to java books

3:41 ibdknox: amalloy: metadata would've made that "nicer"

3:49 amalloy: pyr: you don't care much about java the language, just the jvm and the standard libraries. not sure what would be useful for that

3:55 pyr: amalloy_: yes, i came to clojure as my first jvm language, a bit more used to the specifics of the jvm and java now, but sometimes i think a bit more background litterature would be nice

4:27 lnostdal: is there some way of getting better stack-traces? .. i'm using swank-clojure at the moment, and i think i recall there being some additional plugins that improves debugging

4:43 raek: pyr: Java Concurrency in Practice, IMHO. On the other hand, it's not really a book on general Java programming.

4:47 pyr: raek: yes, this one i wanted to get. i guess i'll take a chance for the rest :)

4:56 michaelr525: lnostdal: swank clojure should also include swank cdt in it's latest version, but I didn't manage to get it to work so far..

4:56 lnostdal: http://georgejahad.com/clojure/swank-cdt.html

4:57 lnostdal: tell me if you have better luck

5:42 lnostdal: hm, ok. .. i think i have the latest swank-clojure .. perhaps i need to activate CDT tho

6:20 fhd1: So how do you guys host Clojure web applications?

6:21 fhd: I have a Compojure web applications running in Jetty, and I'm wondering how to best put it on a server

6:22 I've hosted Clojure web apps on Tomcat before, but making the routes work in both Tomcat and Jetty was pretty tedious, can't be the normal way.

6:35 michaelr525: error: java.lang.Exception: Cyclic load dependency: [ /http/async/client/request ]->/http/async/client/util->[ /http/async/client/request ]->/http/async/client->/fetcher/core

6:35 damn

6:35 trying to use the 'fetcher' library

6:36 that's what i get when compiling the code. just added (:require [fetcher.core :only [fetch]])

6:50 weird, the version on clojars is older than on githut but the version number is higher.. hhh

8:16 ordnungswidrig1: Why doesn't accept ring a LazySeq of Strings as body? It says it accept's ISeq

8:20 tomoj: any gloss users around these parts yet?

8:20 hardly ever see any aleph questions here..

8:20 ordnungswidrig1: sorry, I found my error. I was using ring 0.3.5. which does not recogize iseq as response body yet in ring-lint

8:49 tomoj: https://gist.github.com/4a57022921afde8a6465

8:49 there's gotta be a seqier way

8:50 chouser: tomoj: you want it in the order given by 'both'?

8:51 tomoj: yeah

8:51 hmm

8:51 I think I see the way

8:51 nope

8:52 chouser: The way you're doing it is actually very efficient, taking advantage of the fact that all three are in the same order

8:52 tomoj: yeah

8:53 hmm

8:53 well, it works..

8:54 chouser: (defn in-out-with-both [in out both] (let [in (set in)] (for [b both] [(if (in b) :in :out) b])))

8:54 tomoj: well..

8:54 not quite the same

8:55 that will probably work just fine for me

8:55 in and out are subsequences of both

8:55 so if you traverse in and out and both all in order, the worst ambiguity is who sent consecutive duplicate messages

8:55 if you turn in into a set it gets worse

8:56 but actually, in and out will almost certainly be disjoint

8:56 chouser: oh, there can be dups?

8:56 ah, you're catching :wtf as well

8:56 tomoj: there should be none of those though

8:56 it's a packet dump

8:56 and the two sides cut out in order

8:57 chouser: as I said, yours is very efficient, esp if thes seqs are long

8:57 tomoj: I'll stick with it.. seems like there should be a more elegant way to fold (?) through two seqs or whatever that's doing

8:57 chouser: There's not much in core that allows you to choose to consume (or not) a step of a seq based on the value(s) at hand

8:58 tomoj: I guess because you don't often need to?

8:58 chouser: well ... dunno. It comes up from time to time.

8:58 It might be interesting to look at some cases and see if there's some HOF that can be factored out.

9:04 You could do it with 'reductions' I think, but you'd end up with almost all that code and it would be less efficient.

9:08 dnolen: tomoj: https://gist.github.com/1a58aca035fbbc040b58, would look like this using match once we have locals matching.

9:10 tomoj: cool

9:25 michaelr525: heya!

9:31 dnolen: bam, locals matching, https://github.com/swannodette/match/commit/10b735782b65c7be392a1387253d86c4758a342e

9:34 sometimes dynamic vars really rule.

9:43 drewr: dnolen: why ^:dynamic -> ^{:dynamic true}?

9:43 (just curious)

9:44 dnolen: drewr: 1.2.0

9:44 drewr: backward compatibility? bah

9:44 pjstadig: dnolen: ITYM 1.2.1

9:45 drewr: dnolen: this is great btw

10:07 gtrak: is there an existing 'closeable' protocol I can use to extend types with or should I make my own?

10:14 bendlas: gtrak: java.io.Closeable

10:16 gtrak: hmm, but apparently you can't extend-type over an interface, must have a protocol

10:16 I think I could use reify, but it's more awkward

10:16 bendlas: you can't extend-type, but you can implement it directly

10:17 like (deftype foo [] java.io.Closeable (close [this] ..))

10:17 same with defrecord

10:18 gtrak: hmm, I think it's still simpler to make a protocol

10:19 bendlas: don't hesitate; good thing is, with-open doesn't care about the type

10:19 it just calls .close

10:19 gtrak: yea

10:46 jaley: hey guys, quick question... is there a way to "apply" a constructor call?

10:47 i.e. ;; (apply SomeType. args-seq) ?

10:48 ordnungswidrig1: jaley: doest applying "new" work?

10:48 (apply new SomeType args-seq)

10:48 (no repl at hand)

10:48 gtrak: new's not a fn, it's a special form

10:49 jaley: ordnungswidrig1: no but maybe wrapping new in a closure is the way to go

10:49 tufflax: You can at least wrap the constructor in a (fn [& x] (apply Type. x))

10:49 or something like that

10:49 gtrak: new is static, you'd have to use reflection to instantiate dynamically

10:49 tufflax: maybe memfn works

10:51 gtrak: http://download.oracle.com/javase/1.4.2/docs/api/java/lang/Class.html#newInstance()

10:51 tufflax: gtrak is there a way to give arguments when using newInstance?

10:52 joegallo: no

10:52 gtrak: don't believe so

10:52 tufflax: Hm, so what if I wanted to? :p

10:52 joegallo: for that you need to Class/getConstructor(s) with the right type arguments

10:52 gtrak: but there's a getDeclaredConstructors that you can use to find the right one?

10:52 tufflax: oh ok

10:52 joegallo: yeah, declaredconstructors, missed that word

10:53 and then you can newInstance with arguments off the provided constructor

10:53 gtrak: tufflax, a constructor with varargs takes an array

10:53 so you wouldn't want to use apply on something with unpredictable size anyway

10:54 jaley: ok i'm getting the idea the best way to do this is with a help function and arity overloading. thanks for the suggestiosn though guys!

10:54 gtrak: yes, that's probably simplest

10:55 tufflax: gtrak hmm yes

10:55 I learned that java varargs takes arrays the hard way :p

10:55 take*

10:59 gfrlog: who manages the clojars project?

11:01 tufflax: I think ato (alex osbourne) made the site at least

11:01 coopernurse: yes, github project is here: https://github.com/ato/clojars-web

11:02 tufflax: alex osborne, sorry :p

11:02 gfrlog: okay. I sent a pull request a while ago and have not gotten any comment on it, so I should send a message to his github account?

11:02 I'm locked out of clojars until the bug is fixed

11:04 tufflax: I dunno :p im not alex :p

11:05 gfrlog: okay. I was just making sure clojars didn't have any more formal of an organization/process behind it

11:06 tufflax: I don't think so

11:06 gfrlog: k, thx

11:07 oh I see github says he hasn't been around for a while. maybe that's why.

11:21 dsantiago: dnolen, I love how you file an issue, implement the feature, and then close the issue an hour later. :)

11:23 dnolen: dsantiago: well I never know how easy is something is going to be, or when I'm going to actually work on it :)

11:25 dsantiago: It's very disciplined. Nothing wrong with that.

11:29 TimMc: It also gives a richer commit log and project history. If someone later encoutners the bug, a search may turn up the (closed) issue.

11:29 Very nice for users.

11:34 ambrosebs: also good to know what's rattling around in dnolen's head at that moment :)

11:34 dnolen: heh

11:35 TimMc: Oh yeah, and it also means that you don't have to cram a whole wad of rationale into a commit message, you can just refer to an issue #.

11:35 gtrak: so I tried to extend-type over an interface that a class implements, and I get this: " java.lang.IllegalArgumentException: No matching field found: close for class org.apache.http.impl.conn.SingleClientConnManager" does extend-type not work for the subclasses of the extended class?

11:36 ambrosebs: TimMc: fossil scm got this right, tickets and wiki are versioned and part of the repo

11:36 github in a box

11:38 gtrak: err wait... that's not it, I did something else wrong

11:42 PPPaul: is using clojure with couchdb easy?

11:46 gtrak: so I created a protocol with a close method, and I extended it over the type, but when I run it, I get java.lang.IllegalArgumentException: No matching field found: close for class org.apache.http.impl.conn.SingleClientConnManager, what could be the problem?

11:47 dnolen: gtrak: paste por favor.

11:49 gtrak: http://pastie.org/2411964

11:51 dnolen: gtrak: why would that work? with-open calls a .close method, not an fn.

11:52 gtrak: hmm, well it's not obvious to me, the protocol's close method is not able to be called by .close?

11:53 is that what reify is made for?

11:53 dnolen: gtrak: fns and methods are not the same thing.

11:54 gtrak: you could try creating your own close *interface*.

11:54 (definterface Closeable (close [])

11:55 gtrak: would I have to use reify then?

11:55 dnolen: oh sorry, mispoke

11:56 the problem with reify is that you can't delegate.

11:57 gtrak: ah

11:57 dnolen: you could write you're own version of with-open that does the right thing if the object satisfies Closeable.

11:58 gtrak: hmm, I'm surprised there isn't a way to delegate though, is there one?

11:58 this would make it easier on client code

11:59 dnolen: how could that be done w/o reflection given the design of the JVM ?

11:59 one day Clojure may support invokeDynamic.

11:59 gtrak: ah, it's that kind of problem

11:59 dnolen: until then, writing your own version of with-open ain't much work.

12:00 gtrak: also one day more of Clojure will be pushed into protocols, could be addressed then.

12:01 hiredman: scopes!!!!

12:01 gtrak: hmm, I still don't quite get it, in java I would subclass both interfaces, instantiate the class of interest, and delegate accordingly

12:02 dnolen: gtrak: you can use proxy/genclass. but that doesn't sound like less work to me.

12:04 gtrak: interestingly enough google tells me clojure/clr has a gen-delegate

12:08 it looks like reify could work if I do it at the point of instantiation

12:09 you just can't do it for a class it seems, can use it for an object

12:11 err-wait, that would only return the closeable, not something that implements both

12:12 dnolen: gtrak: replacing with-open is 10 lines of code. Why pick a more complicated solution?

12:13 gtrak: for the sake of client code, documenting that they should use a specific with-open is just like telling them to look up .shutdown, doesn't really save anything

12:14 it would remove a try-finally block, I guess that's something

12:16 dnolen: gtrak: ah so this isn't some internal detail. then use proxy/gen-class

12:18 gtrak: also protocols wouldn't help you much if you're going for real interop here since that stuff is invisible to Java.

12:44 lobotomy: ö

12:44 oops sorry

13:09 PPPaul: anyone here use clojure with couchdb?

13:12 devn: PPPaul: Why do you ask?

13:12 PPPaul: Short answer, yes, and I know more than a few people who do.

13:16 chewbranca: PPPaul: I'm currently using clutch for interacting with couchdb from clojure, although I'm relatively new to clojure so I can't say much about long term experience with it

13:57 rpg: Does clojure-mode in emacs have any equivalent of hyperspec-lookup that will jump to clojure.org docs?

14:03 dnolen: rpg: no, but you can get the docstring with slime-documentation, or typing (doc symbol) in the REPL

14:04 rpg: dnolen: Got it. But I think the hyperspec-like facility would be handy, don't you?

14:12 chewbranca: dnolen: that regex pattern match turned out very slick, I'll definitely put that to use

14:14 michaelr525: dnolen: can you explain in two words why pattern matching is usefull?

14:15 rpg: In clojure-mode, is there some obvious way to get the swank server to tell you what is the namespace of a symbol in the buffer? Seems like that's necessary for the equivalent of hyperspec-lookup to work....

14:17 raek: it could evaluate (resolve <the symbol>)

14:17 chewbranca: michaelr525: how about 'pure awesome', or 'concise dispatch', or 'clear branching'?

14:18 PPPaul: can someone recommend a website for me to get started making couchapps via clojure?

14:19 chewbranca: michaelr525: I'm a big fan of erlang's use of pattern matching, where everything passed around as a tuple, so the convention is to do pattern matching on {ok, _} or {error, Error} and perform appropriate operations

14:20 PPPaul: you can't realy make 'couchapps' with clojure in the traditional sense of couchapps as a self contained application hosted from couchdb, although I'm intrigued to see what I can do with clojurescript and couchdb in that regard

14:20 dnolen: chewbranca: nice.

14:20 PPPaul: so, clojure is good for interacting with couchdb, but not so easy to make couchapps?

14:20 chewbranca: PPPaul: https://github.com/ashafa/clutch works pretty well for interacting with couchdb, then you go where ever you want with it

14:21 dnolen: chewbranca: we're working on making that API clean, no need for deftype/record. only multimethods / plain maps.

14:21 chewbranca: PPPaul: well in couchdb terms, a couchapp is a javascript application that is self hosted inside of a couchdb database, so its not really a choice of language (clojurescript blurs this distinction, but I don't think this is what you're talking about)

14:22 PPPaul: in terms of interacting with couchdb, clojure is great for doing that and lot of good stuff to work with

14:22 PPPaul: ok

14:22 chewbranca: dnolen: very nice, I'm already impressed with how clean it is

14:22 PPPaul: what exactly are you trying to accomplish?

14:22 PPPaul: making couchapps

14:23 dnolen: michaelr525: probably not in two words. do you use Clojure destructuring features much?

14:23 PPPaul: i'm good with javascript, but i rather use clojure

14:23 chewbranca: PPPaul: and what does 'couchapp' mean to you? an application with couchdb as a backend, the python couchapp tool or couchapps as nested javascript applications inside of couchdb

14:23 michaelr525: dnolen: sometimes I use them. I'm not doing clojure much in general.. just when I have some spare time you know

14:23 chewbranca: couchapps in the latter meaning are strictly javascript/html apps, no way around that

14:23 PPPaul: couchapp means that the app is in couchdb

14:24 so i can replicate the app

14:24 rpg: raek: So presumably that's what's happening in swank:find-definition in the swank server, so probably the same logic could be done for something hyperspec-like...

14:24 chewbranca: PPPaul: then it has to be in javascript, you could look into using clojurescript, but you can't use native clojure in a couchapp

14:24 dnolen: michaelr525: well if you those, pattern matching takes that to another level.

14:25 PPPaul: ok. thanks

14:25 michaelr525: dnolen: i see, i have to take the blue pill in order to understand ;)

14:25 PPPaul: clojure script works in couchdb?

14:25 chewbranca: PPPaul: no it doesn't, but clojurescript compiles to javascript

14:26 dnolen: michaelr525: it's also extensible, and you can use it on things you can use destructuring on - bytes for example. for performance sensitive stuff it introduces no overhead.

14:26 can't use destruturing on I mean.

14:26 PPPaul: hmmm... sounds like it may be a bit of a process to do a couchapp with clojurescript

14:26 michaelr525: hmm

14:26 chewbranca: PPPaul: I would just stick with javascript for couchapps, or build a more traditional app with clojure up front and couchdb as the backend

14:27 dnolen: michaelr525: destructuring won't let you pattern match bits. match will.

14:28 chewbranca: PPPaul: what I will do sometimes is a combination of that, so host your assets and javascript UI in couchdb as a couchapp, but throw a reverse proxy up front and have a route like '/api/' kick off to a clojure api server, so you could do things you can't do in a couchapp while still getting to host out of couchdb for most stuff

14:28 michaelr525: dnolen: can you give me some "real world" usage example where it can give me advantage?

14:29 dnolen: michaelr525: personally, I don't think I'll do much serious primitive array work without.

14:29 michaelr525: say you have an image data in an array and you want to increase the red component uniformly.

14:30 michaelr525: so you destructure the rgb bits?

14:30 dnolen: michaelr525: yes.

14:30 michaelr525: hmm

14:31 i see, more concise code and good performance.

14:44 yfrank: whats clojure's solution to not having tail call recursion?

14:45 coopernurse: yfrank: take a look at loop / recur

14:45 http://clojuredocs.org/clojure_core/clojure.core/loop

14:46 Chousuke: note that you can use recur without loop

14:46 functions are recur targets

14:46 also use lazy sequences

14:47 yfrank: ok, thanks :-)

14:49 dnolen: yfrank: less frequently used, but useful, trampoline

15:03 grumpytoad: can graphics programming be stateless in FP clojure(script) ?

15:03 finding it hard to get the right event model for this

15:03 ibdknox: grumpytoad: I don't think clojure suggests that everything should be stateless

15:03 just that its use is explicit

15:04 and judicious

15:04 grumpytoad: i would like to get a stateless js graphics demo..

15:04 just for kicks

15:04 ibdknox: what do you mean by graphics?

15:04 grumpytoad: i'm tending towards hmm.. possible but not practical

15:05 well a game.. like that pacman demo, only without state

15:06 arohner: grumpytoad: every useful program has state. the issue is where it's kept, and how it's managed

15:06 tufflax: grumpytoad so I assume you have not seen this http://prog21.dadgum.com/23.html

15:06 ibdknox: a game will always have state, it just may not be stored globally

15:06 arohner: maybe you mean no *global* state?

15:06 grumpytoad: tufflax: thx for the link..

15:06 ibdknox: I never finished it, but I was curious what games would look like in Clojure as well

15:07 so I did pong

15:07 https://github.com/ibdknox/clojure-pong/blob/master/src/clojure_pong/core.clj

15:07 grumpytoad: i mean, if one has a bunch of event handlers ... they could trigger due to different reasons

15:08 but the main render cycle still needs to know the outcome of some of these handlers

15:08 ibdknox: grumpytoad: eventing requires global state

15:08 instead you would have to think of it as during my loop, is a key pressed?

15:09 grumpytoad: ibdknox: not sure - i thought flapjax and stax-haxe prevented this

15:09 ibdknox: if an event happens, you need it to change something

15:10 grumpytoad: yes, you could do that, but might miss the key press, though i admit i haven't tried

15:12 ok that link on retrogames is the Right Way tm

15:17 dnolen: grumpytoad: I think Clojure is less about stateless then it is about managing state. Rich Hickey famous ants.clj demo had plenty of state in it. But it was managed.

15:20 grumpytoad: well... there he uses transactions among actors - this isn't really workable in the js event world

15:20 which, if you have a larger copus of code, becomes quite a nightmare

15:24 dnolen: grumpytoad: oops, I missed the bit earlier that you wanted to do this in JS.

16:14 jweiss_: I'm testing 2 maps for equality, and it seems to be inexplicably failing - i tried printing out the 2 maps with println and they inexplicably print differently: {:name "login", :steps (fn [] (Thread/sleep 2000) (println "logged in"))} and the other is {:name login, :steps (fn [] (Thread/sleep 2000) (println logged in))} -- the 2nd one doesn't have any quotes, which is wrong, and i suspect that's what's causing the inequality, but I

16:14 don't know how this munging happened.

16:15 hiredman: use pr

16:23 tufflax: ,(prn (fn [x] x))

16:23 clojurebot: #<sandbox$eval6122$fn__6123 sandbox$eval6122$fn__6123@d3258f>

16:24 jweiss_: i tried pr, it doesn't print to stdout on every thread

16:24 tufflax: try prn

16:24 jweiss_: k

16:24 tufflax: or flush

16:25 amalloy: there

16:25 's no way prn will work if println doesn't

16:25 ibdknox: ,(doc bound-fn)

16:25 clojurebot: "([& fntail]); Returns a function defined by the given fntail, which will install the same bindings in effect as in the thread at the time bound-fn was called. This may be used to define a helper function which runs on a different thread, but needs the same bindings in place."

16:25 devn: grumpytoad: There are web workers. I know it's not an equivalent, but it's something worth considering.

16:25 amalloy: jweiss_: ##(= (fn [] 1) (fn [] 1))

16:25 lazybot: ⇒ false

16:26 tufflax: I'm confused by jweiss original question, what are you trying to do? printing functions doesn't "work" right?

16:26 amalloy: no function is ever equal to any function unless they are pointer-identical, so your maps won't compare equal if they're not the same

16:26 hiredman: but look at the maps he showed us

16:26 jweiss_: amalloy: yeah i am aware that compiling two different functions will not be equal even if they look the same. i just have one compiled function

16:26 hiredman: neither one has a fn in it

16:27 they have forms that would compile to fns

16:27 tufflax: oh

16:27 amalloy: hiredman: well, i think he's given us too little information about where that text came from for us to decide what the problem is

16:28 but you're right, of course, if those are actually lists

16:28 jweiss_: no, it's really a compiled function, sorry i forgot i am using technomancy's serializable-fn so that i see the source when i print them out.

16:30 i'm just printing things out to help figure out why map equality returns false when i expect true

16:30 hiredman: have you actually looked at the two maps?

16:30 jweiss_: it's definitely the same compiled function: test.tree$fn__6505 is the class in both cases

16:31 and the only other key in the map is a string

16:31 amalloy: jweiss_: that is insufficient info

16:31 closures have the same class but aren't the same function

16:31 jweiss_: amalloy: ok, but it's not a closure

16:32 i really don't think it's the fn value that's causing inequality here

16:32 ibdknox: jweiss_: just put some code in a gist :)

16:33 amalloy: &(map pr ["string" 'string])

16:33 lazybot: ⇒ ("string"stringnil nil)

16:33 amalloy: (inc ibdknox)

16:33 lazybot: ⟹ 1

16:33 ibdknox: aw my karma is all gone

16:34 TimMc: lazybot is lazy

16:34 ibdknox: either that or you've all secretly been dec'ing me behind my back

16:34 jweiss_: it's 350 lines, i wish i knew how to boil it down

16:34 * ibdknox looks at amalloy

16:34 ibdknox: hehe

16:34 tufflax: give yourself some then ibdknox :)

16:35 ibdknox: haha, I shant cheat

16:35 (this time)

16:36 jweiss_: can i print out the hashcode or something to make sure it's the same?

16:37 ibdknox: jweiss_: what is the scenario that causes you to try and prove that two functions are equal?

16:37 it's hard for me to contrive a situation where that would be the right solution

16:39 jweiss_: ibdknox: what i have is an atom, a map where the keys are maps. i assoc a map/value into the main map, and then later on another thread try to get the value using what *should* be an identical map as a key.

16:40 ibdknox: jweiss_: sounds reasonable so far

16:40 jweiss_: the only difference between the key i assoc and the one i later use to get the value is, at most, an assoc/dissoc that leaves the same k/vs

16:40 and yet i get nil

16:41 if i manually try to retrieve the value, though, i get it

16:41 ibdknox: ,(= {:x 1} (dissoc {:x 1 :y 1} :y))

16:41 clojurebot: true

16:41 ibdknox: ,(= {:x 1} (dissoc {:x 2 :y 1} :y))

16:41 clojurebot: false

16:42 ibdknox: ,(= {:x 1} (assoc (dissoc {:x 1} :x) :x 1))

16:42 clojurebot: true

16:42 ibdknox: are you sure the value is the same after the assoc's happen?

16:42 jweiss_: ibdknox: no, I'm trying to *make* sure, but I don't know how

16:43 ibdknox: ah, this is where your println's don't work?

16:43 jweiss_: ibdknox: yeah, one prints without quotes, the other has quotes.

16:43 amalloy: &(map pr ["string" 'string])

16:43 lazybot: ⇒ ("string"stringnil nil)

16:44 amalloy: (repeated for posterity who didn't read it last time)

16:44 jweiss_: amalloy: maybe i'm missing the point of the above

16:44 ibdknox: if it prints with quoest

16:44 quotes*

16:44 it's a string

16:44 amalloy: jweiss_: a symbol prints like a string but without quotes

16:44 jweiss_: amalloy: ok, what about println?

16:45 amalloy: &(map print "test" "\"test\"")

16:45 lazybot: ⇒ (t "e tnil s enil t snil nil)

16:45 amalloy: &(map print ["test" "\"test\""])

16:45 lazybot: ⇒ (test"test"nil nil)

16:46 jweiss_: &(map print [(str {:hi "there"}) {:hi "there"}])

16:46 lazybot: ⇒ ({:hi "there"}{:hi there}nil nil)

16:46 jweiss_: i used str in both instances though

17:19 srid: string construction is not all that pretty in clojure; how can https://gist.github.com/1163620 be made better?

17:21 hiredman: I have a solution to that

17:21 you it in a function

17:21 put it in a function

17:21 call as needed

17:22 pjstadig: you can also use format

17:22 michaelr525: hey

17:24 I'm trying to implement a retrying connection, using loop try-catch recur, problem it says I can't recur from catch/finally. Seems like a common case that probably many have already solved, anyone knows a good pattern of how to do it?

17:24 pjstadig: robert bruce

17:25 https://github.com/joegallo/robert-bruce

17:26 dnolen: srid: I thought that first. But I love string construction in Clojure now. none that multiline bull you have to deal w/ in other langs.

17:27 michaelr525: oh, I found this solution

17:27 http://stackoverflow.com/questions/1879885/clojure-how-to-to-recur-upon-exception

17:29 pjstadig: michaelr525: robert bruce is more mature and general than try-times

17:30 michaelr525: oh, it was for me, let me check it :)

17:30 thanks

17:31 ooh nice

17:32 i can see what you did there ;)

17:50 pjstadig: michaelr525: sorry should have been more specific about addressing you

17:52 amalloy: jweiss_: anyway, don't use print or println for anything involved. use pr/pr-str to make sure it prints as the right type

18:08 michaelr525: how do you restart swank/slime when using clojure-jack-in?

18:11 joegallo: that's kind of tricky atm

18:12 it might be as simple as just rerunning clojure-jack-in

18:12 but if that gives you an error

18:12 then you might want to kill every buffer with slime or swank in the name

18:12 and then try again

18:12 and if that doesn't work, then you should kill and restart emacs

18:12 amalloy: joegallo: from what i hear you just need to kill the *swank* buffer if the first thing fails

18:12 joegallo: i hope that's the case :)

18:14 michaelr525: hey joe! thanks for bruce! hehe

18:15 joegallo: oh, you're welcome. it was a funny little thing to write. :)

18:15 please let me know if you feel like there's anything that is missing or could be improved.

18:19 trmsw: how do I get the name of a var?

18:23 tufflax: What do you mean trmsw

18:28 joegallo: yes, a little more explanation would be helpful

18:28 what are you trying to do?

18:28 trmsw: sorry. Say I have an interned var #'foo

18:28 joegallo: it seems like instead of typing (get-the-name-of-some-var the-var) i could just type "the-var". :)

18:28 trmsw: I want the corresponding namespace-qualified symbol

18:29 tufflax: hm, im not sure but maybe `foo?

18:30 ,`foo

18:30 clojurebot: sandbox/foo

18:30 hiredman: vars round trip through the reader/prn fine

18:31 trmsw: ok so now: (def x #'foo)

18:31 joegallo: tufflax: this seems more entrerprise to me:

18:31 (symbol (str (.ns #'foo)) (str (.sym #'foo)))

18:31 jk, of course

18:31 tufflax: hehe

18:32 trmsw: yes that was what I needed, thanks

18:32 hiredman: trmsw: no, stop

18:32 tufflax: :)

18:32 hiredman: why are you putting a var in another var?

18:32 danlarkin: var turtles obv

18:32 trmsw: :)

18:32 tufflax: haha

18:33 trmsw: because I have menu items in an Eclipse plugin that I want to alter dynamically

18:33 hiredman: No

18:34 use an atom or a ref, or really anything else

18:35 trmsw: so using (#'foo) to run the action is a bad idea

18:35 hiredman: that is not what you said you were doing

18:36 that is fine, but (def x #'foo) is not

18:37 trmsw: say I have (defcmd foo ... ). It should create a function called foo (to help with interactive debugging) and maybe also add a menu item which depends on a proxy, to call (#'foo)

18:37 tufflax: is there ever any difference between (foo) and (#'foo)?

18:37 hiredman: none of that has anything to do with (def x #'foo)

18:37 tufflax: yes

18:38 tufflax: ok, what? :P

18:38 trmsw: to create the proxy, I'll have an argument x whose value is #'foo

18:38 hiredman: trmsw: and?

18:38 none of that has anything to do with def

18:39 (although, I am beginning to think you really don't know what you are doing, so most likely trying to create locals using def)

18:40 def is not scheme's define, it does not create local names, it greates global vars

18:40 creates

18:40 trmsw: def was a red herring

18:40 it was just to try and get past the "if you want the name of #'foo why not just write 'foo"

18:41 hiredman: or just use #'foo

18:42 tufflax: hiredman what's the difference between calling (foo) and (#'foo)? If I just defn foo then they do the same thing; call the fn

18:44 oh, now i remember one difference

18:44 #'foo is always a var in the namespace

18:44 while foo migth be something local

18:44 right?

18:44 clojurebot: Equal Rights for Functional Objects is Baker's paper on equality and why it's impossible to define sensible equality in the presence of mutable data structures: http://home.pipeline.com/hbaker1/ObjectIdentity.html

18:45 hiredman: tufflax: the difference generally only manifests when foo is used in a top level form, like (def foo [] 1) (def bar ((fn [x] #(x)) foo)) or def bar ((fn [x] #(x)) #'foo))

18:45 amalloy: hiredman: or when foo is a macro

18:45 hiredman: I suppose

18:47 tufflax: so run those defs at a repl, but make a bar1 and a bar2 (one with foo and one with #'foo) then re-def foo to something else and see what happens

18:47 that should be (defn foo [] 1)

18:47 tufflax: ok, let's see...

18:49 amalloy: hiredman: clojurebot's link there is dead

18:50 hiredman: bleh

18:50 currentB: I'm trying to use clojurescript to set the text for 5 seperate boxes (divs), each with an id of box1, box2, etc, with a 1 second delay between setting the text for each one

18:50 https://gist.github.com/1163853

18:50 anyone know what's wrong with that?

18:50 tufflax: ok, hiredman thanks... what was that about #' and macros? :p

18:51 oh, i see, (#'m) does not work when m's a macro

18:52 for some reason i don't understand :P

18:52 amalloy: &(#'and true false)

18:52 lazybot: ⇒ true

18:52 amalloy: ^ best joke ever

18:52 hiredman: tufflax: that actually has nothing to do with the difference between #'foo and foo

18:53 tufflax: sorry, what?

18:53 hiredman: type m in the repl, then type #'m

18:53 (assuming m is the name you gave your macro)

18:53 amalloy: currentB: well, you use delay instead of x in your multiplication? can't really tell if that's on purpse

18:55 tufflax: ok... but I didn't gain any understanding :p

18:55 hiredman: m threw an exception and #'m didn't

18:55 tufflax: yes

18:55 hiredman: "can't take the value of a macro" or similar

18:55 tufflax: yes

18:56 hiredman: that and the demo with the foo and bar defs should show you the difference

18:56 if not, spend some time thinking about it and fiddle with it some more

18:56 tufflax: ok i will ;)

18:56 thanks

19:08 eskatrem: hello, can I know on what version 4clojure.com is running?

19:10 currentB: ok I actually got something working, but it seems kind of ugly, is this acceptable? https://gist.github.com/1163881

19:11 or does anyone know any alternative way to accomplish this

19:14 ibdknox: currentB: one thing that makes it at least a little easier to read

19:14 is to change it from .getElement to goog.dom/getElement

19:15 and goog.dom/setTextContent

19:16 ideally you'd probably alias that ns as well

19:16 to dom or something

19:16 currentB: k thanks. using the incrementor is a necessary evil though?

19:17 ibdknox: if you want it to only execute 6 times, I'm not sure how else you could do it

19:17 but I'm not an expert on the goog.* APIs yet

19:17 currentB: cool thanks a ton!

19:21 michaelr525: joegallo: hey joe, are you still here?

19:23 joegallo: maybe I should go to sleep and think about whether I what I did was the right thing to do but: I used try-try-again in two functions where one cals the other and it seems that the inner one affects the sleep time of the outer

19:24 joegallo: huh... that would be super bad

19:25 michaelr525: what I did?

19:25 joegallo: no, if they affected each other that way

19:25 michaelr525: ah

19:26 joegallo: how sure are you that that's what you're seeing?

19:26 michaelr525: not 100%, I have to go to sleep. I will check it again tomorrow and tell yout

19:26 not 100%, I have to go to sleep. I will check it again tomorrow and tell yout

19:27 joegallo: okay.

19:34 amalloy: eskatrem: www.4clojure.com/about/version

19:34 eskatrem: OK, it's running on version 1.0

19:35 amalloy: of what?

19:35 eskatrem: for one problem my code produces the correct result on my machine (clojure 1.2) but fails the unit tests on the website version

19:36 amalloy: https://github.com/dbyrne/4clojure/blob/develop/project.clj

19:36 clearly clojure 1.2.1

19:39 eskatrem: right...

19:47 amalloy: eskatrem: are you using (case)? for reasons that are complicated, that throws exceptions on 4clojure

19:48 eskatrem: amalloy: not at all

19:48 https://gist.github.com/1163944

19:49 that's my code for problem "reverse interleave"

19:50 for some reason with my clojure box running on clojure 1.2.0 it produces the result I expect but it fails on the website

19:52 amalloy: eskatrem: when i try it in my repl, you return the wrong ordering for the first input

19:53 dnolen: hmm

19:53 anybody using aliased keywords?

19:54 ,(require '[clojure.string :as string])

19:54 clojurebot: nil

19:54 amalloy: dnolen: i can barely remember the syntax

19:54 dnolen: ,(= :string/foo :clojure.string/foo)

19:54 clojurebot: false

19:54 dnolen: is that right?

19:54 amalloy: ,::string/test

19:54 clojurebot: :clojure.string/test

19:54 dnolen: ah

19:54 thank you

19:55 amalloy: dnolen: what for, out of curiosity?

19:55 dnolen: amalloy: match stuff, I'm learning towards multimethods, plain-maps, and namespace keyword as extension points.

19:55 keeps things dynamic, and avoid the hassles of deftype for users.

19:56 learning -> leaning.

19:56 eskatrem: amalloy: did I do something bad? 4clojure.com is down again

19:57 amalloy: what the hell. jetty is supposed to be more resilient than this

19:59 eskatrem: i don't know how it could be your fault. the last error message in the logs was an hour ago

19:59 and it was clearly working until recently

19:59 eskatrem: amalloy: if it was my fault, the website would really suck to let a noob like me hack it

20:00 amalloy: i don't even know how to debug that. "Jetty terminates java process without printing any error messages or leaving a segfault or anything"

20:07 choffstein: Hey all! I just found cemerick's awesome post about continuous integration with hudson and I was wondering if anyone knew if there had been any progress of integrating jenkins / hudson with leiningen

20:08 eskatrem: anyway, is there a reason why my code behaves differently whether the input is a list or a vector?

20:09 hiredman: eskatrem: I suggest you look through your code, find the function you call where it behaves differently, and read the doc string

20:09 tufflax: Hm, hiredman I thought a bit about that macro business, and I don't understand how I'm supposed to know why or how (#'m and-two args) works... :P And I don't see how that foo and bar example is supposed to help

20:10 eskatrem: hiredman: will do!

20:10 hiredman: tufflax: as I said, the args thing has nothing to do with it, and you should ignore it, just type m and #'m at the repl, don't even try to call them as functions

20:10 choffstein: there is a shell task that works fine for lein builds

20:11 choffstein: hiredman: Really? Any idea where I can find it?

20:11 hiredman: choffstein: create a new build, select the one that has "shell" in the name

20:12 may actually be called Build a free-style software project

20:13 choffstein: I'll check that out. Thanks!

20:15 tufflax: hiredman hm, but I said "(#'m) does not work when m's a macro" and you said "that actually has nothing to do with the difference between #'foo and foo". But the reason it did not work seems to be that the (#'m) call, for some reason, expects 2 mysterious arguments. I don't know what you want me to see by typing m and #'m :p

20:15 dnolen: hierarchies when there are no types involved is a beautiful, beautiful thing.

20:19 hiredman: tufflax: we were talking about the difference between foo and #'foo, which has nothing to do with the implicit argumets macros take

20:28 tufflax: hiredman: At first I was talking about the difference between (foo) and (#'foo) when foo is a function. Then I amalloy said that there is a difference between the two when foo is a macro, and I wondered what it was. And it seems to me that the difference is those implicit arguments, or something. But now you say I shouldn't care about them. But that was part of my question from the beginning.

20:30 hiredman: the difference between (foo) and #'foo is the difference between foo and #'foo

20:31 the macro stuff you trying to sidetrack onto is unrelated

20:31 you are

20:32 tufflax: did you mean "the difference between (foo) and (#'foo)" just now?

20:32 hiredman: yes

20:33 tufflax: I know that foo evaluates to the value of foo, and #'foo is the var, but how the evaluator handles foo and #'foo when they are being called is something different, no?

20:34 hiredman: your confusion of the macro differences with the differences between foo and #'foo is largely a result of not understanding what happens in the two cases of 1) (m) and 2) (#'m) when m is a macro, understanding the difference between foo and #'foo will leave you about one hop away from understanding #2

20:34 amalloy: tufflax: try looking up how clojure.lang.Var implements IFn.invoke

20:38 hiredman: tufflax: so given that #'foo is a var, how come when you call it runs a fn?

20:38 tufflax: invoke calls deref

20:38 ...first

20:39 hiredman: ,and

20:39 clojurebot: #<CompilerException java.lang.RuntimeException: Can't take value of a macro: #'clojure.core/and, compiling:(NO_SOURCE_PATH:0)>

20:39 hiredman: ,(deref #'and)

20:39 clojurebot: #<core$and clojure.core$and@a6eee5>

20:40 hiredman: ,(type (deref #'and))

20:40 clojurebot: clojure.core$and

20:40 hiredman: ,(instance? clojure.lang.IFn (deref #'and))

20:40 clojurebot: true

20:40 tufflax: ,(ifn? and)

20:40 clojurebot: #<CompilerException java.lang.RuntimeException: Can't take value of a macro: #'clojure.core/and, compiling:(NO_SOURCE_PATH:0)>

20:41 tufflax: oh, right

20:41 hiredman: ,(->> #'and deref class .getMethods (map bean) (filter #(= "invoke" (:name %))))

20:41 clojurebot: ({:genericReturnType java.lang.Object, :declaringClass clojure.core$and, :typeParameters #<TypeVariable[] [Ljava.lang.reflect.TypeVariable;@c99f45>, :class java.lang.reflect.Method, :synthetic false, ...} {:genericReturnType java.lang.Object, :declaringClass clojure.core$and, :typeParameters #<TypeVariable[] [Ljava.lang.reflect.TypeVariable;@f78e4b>, :class java.lang.reflect.Method, :synthetic fal...

20:44 hiredman: ,(->> #'and deref class .getDeclaredMethods (map bean) (filter #(= "invoke" (:name %))) (map #(select-keys % [:name :parameterTypes])) (map #(update-in % [:parameterTypes] count))))

20:44 clojurebot: ({:parameterTypes 3, :name "invoke"} {:parameterTypes 2, :name "invoke"})

20:45 hiredman: ,(->> #'and deref class .getDeclaredMethods (map bean) (filter #(or (= (:name %) "doInvoke") (= "invoke" (:name %)))) (map #(select-keys % [:name :parameterTypes])) (map #(update-in % [:parameterTypes] count))))

20:45 clojurebot: ({:parameterTypes 4, :name "doInvoke"} {:parameterTypes 3, :name "invoke"} {:parameterTypes 2, :name "invoke"})

20:56 srid: could anyone point me to open-source clojure web apps with much eye candy? (I want something to 'demo' as a clojure web app for an internal project)

20:56 (ideally, it would be something like one of those node knockout entries)

20:59 ibdknox: the eye candy would have nothing to do with Clojure though..

20:59 lol

20:59 srid: true, eye candy is merely a tool of persuasion :-)

21:01 amalloy: what about the recent pacman port to cljs?

21:01 ibdknox: webnoir is opensource

21:02 currentB: what's the normal way to call swap! with a function such as drop that takes the collection as the second arg?

21:02 or what's the workaround for it, rather

21:03 amalloy: just give it a different function

21:03 #(drop 3 %)

21:03 currentB: actually yeah nvm stupid question

21:03 thanks

21:03 amalloy: (partial drop 3)

21:03 srid: amalloy: that's static js (compiled from clojurescript), and doesn't demonstrate clojure running on JVM as such.

21:03 amalloy: srid: fun fact: you didn't ask for it to demonstrate clojure on the jvm

21:04 srid: ibdknox: actually i am using the noir default template at the moment, but looking for a demo app with real functionality.

21:08 ibdknox: srid: typewire.io is all clojure

21:08 but not oss

21:11 actually

21:11 srid: why not do clojure atlas?

21:11 srid: http://www.clojureatlas.com/

21:11 srid: by 'do' you mean reimplement clojureatlas? (i assume it is not osss)

21:12 ibdknox: I meant show it

21:12 4clojure, clojuredocs

21:12 srid: hmm. here's the context -- i want something that I can 'push' the cloud ... in order to demonstrate my clojure plugin for http://activestate.com/stackato

21:13 *to the cloud

21:14 tufflax: hiredman ok, so, (deref #'and) is a function that takes 2, 3 or 4 args. And that is somehow different from just typing and (this is where most of my current confusion stems from). I know that macros have like :macro true in their meta, and that they are a (kind of) function(?) but I don't know the any details of how that works.

21:14 srid: 4clojure seems interesting, i'll try to get it working first

21:17 tufflax: Maybe that is enough about that for one day. Thank you, hiredman. Maybe some day I'll dig deeper :)

22:06 mudge: hey, there are several clojure pattern matching libraries, anybody know if any of them are planned to be added to clojure.contrib ?

22:53 dnolen: mudge: I proposed mine, but haven't heard anything.

23:15 srid: interesting, so defining a map like {:foo 2 :bar 3} doesn't allow me to use the keys as string when needed (eg: when constructing query urls). (str :foo) => ":foo" ... not "foo" as I'd expect when adding it to the final UR.

23:15 * srid switches to {"foo" 2 "bar" 3} which is not as pretty

23:17 jeremyheiler: ,(name :foo)

23:17 clojurebot: "foo"

23:19 jeremyheiler: srid: just use the name function

23:27 icey: are there any screencasts of people doing heavy refactoring of clojure code?

23:28 or any refactoring at all :) (all the screencasts i've seen feature people who Get It Right the First Time)

23:29 srid: that would be useful to me as well; for non-screencasts, see http://codereview.stackexchange.com/questions/tagged/clojure

23:30 icey: srid: i hadn't seen this stackexchange before; thanks!

23:31 srid: ah. also checkout - http://stackoverflow.com/questions/tagged/clojure?sort=votes

23:31 codereview seems to be a new site. i hope it becomes awesome.

23:32 jli: video seems like a weird format for that

23:33 icey: srid: the biggest thing for me is *how* people go about refactoring their code... right now I feel really clumsy when hacking away at stuff I wrote weeks ago, and it would be interesting to see how people go about doing surgery on their software

23:34 dnolen: icey: I'm curious as to cases where you find your Clojure code needs "heavy refactoring".

23:34 ibdknox: icey: amalloy has a nice post about refactoring clojure

23:34 dnolen: I've been in cases where I've needed to do a fair amount of refactoring

23:35 dnolen: ibdknox: what I mean is, what led up to that point?

23:35 icey: dnolen: it's just a case of learning the language. as I learn to be more functional with my approach I realize that I've done things in a suboptimal way

23:35 ibdknox: dnolen: mostly just trying to get something done, and perhaps picking the wrong way to represent something initially

23:36 dnolen: granted, it's nothing compared to what I've done in other languages

23:36 * srid can relate to icey

23:37 icey: ibdknox: by any chance do you have a link or some keywords i could google to find amalloy's post? is it on hubpages?

23:37 ibdknox: http://amalloy.hubpages.com/hub/The-evolution-of-an-idea

23:37 icey: ibdknox: awesome, thanks

23:37 ibdknox: icey: btw, in answer to your question the other day

23:38 icey: it's something that would be neat to do, but the problem is that doing long polling forces a server choice

23:38 icey: you'll need to be on top of netty to support any real number of users

23:39 icey: ibdknox: ahh, so a framework is the wrong level for that. thanks for thinking about it anyways :)

23:40 ibdknox: icey: I'm not saying "no", just something that would have to be done deliberately and probably a bit down the road... though a proof of concept should be fairly trivial :D

23:40 icey: clojure is the only jvm language that's been bearable for me; i'm still getting used to having all these options (i'm coming from c# and python mostly)

23:41 jli: I think when you're learning, refactoring is kind of silly. just rewrite it.

23:41 maybe that's wrong

23:41 icey: jli: well, i'm always concerned about how well i'll be able to maintain a new piece of technology

23:42 jli: so i refactor where i can, and rewrite when i must

23:42 ibdknox: icey: I used to the Microsoft PM for C# :)

23:42 be*

23:43 technomancy: icey: you can go through the git history of the peepcode screencast project; all the mistakes are in there =)

23:43 not covered in the video of course

23:43 jli: ibdknox: oh hey, I saw your cljs-watch project on github. I was actually kind of disappointed because I just got done doing my own :P

23:43 without any fancy colorss

23:43 ibdknox: haha dude

23:43 colors ftw

23:43 ;)

23:44 jli: it does show a diff though!

23:44 ibdknox: a diff?

23:44 icey: ibdknox: hah! that's awesome. it's always nice to have other C# guys around

23:44 jli: and it uses inotify, though that's linux only

23:44 icey: technomancy: that's a great idea, thanks - I have the video too, so it might be good to compare and watch it again

23:45 ibdknox: icey: it's my second favorite language these days :)

23:45 jli: so it shows a diff of the generated JS?

23:45 jli: ibdknox: no, of the source

23:46 ibdknox: ah

23:47 icey: ibdknox: yeah, i still do .net consulting, but there is so much great stuff on the JVM that I couldn't ignore it anymore.

23:47 jli: meanwhile, I tried using inotify-java, but couldn't find jars or figure out how to build it. is there something about having to hook into C that makes it hard to package a jar?

23:48 technomancy: jli: yes, there are no widespread conventions on how to package native code alongside JVM bytecode

23:48 from what I can tell Leiningen is the first tool that even attempts it

23:49 jli: technomancy: oh, what native code in is leiningen?

23:49 technomancy: thanks for lein btw :)

23:49 technomancy: there's no native code in leiningen, but it has tools for helping you use libraries that include native components

23:49 ibdknox_: gah, my internet died

23:50 jli: did you send a link

23:50 jli: ibdknox_: for what?

23:50 ibdknox_: jli: is your watcher on github? :)

23:50 jli: ibdknox_: oh, I didn't bother after I saw yours :P

23:50 ibdknox_: aw

23:51 jli: ibdknox_: do you develop on linux?

23:51 ibdknox_: jli: mac mostly

23:51 jli: ah okay

23:51 ibdknox_: jli: I try to build things agnostic to platform as much as I can

23:53 icey: if anyone is bored: this all works fine, but am i doing anything stupid? https://gist.github.com/1164308

23:53 jli: ibdknox_: I was thinking about submitting a patch optionally using inotify

23:53 icey: i don't like the way i'm setting visits, but don't know a better way to do it

23:53 ibdknox: jli: do it

23:53 though

23:53 I'll probably clean cljs-watch up some and do it as a patch to clojurescript itself

23:54 technomancy: icey: include an :only clause with your :use calls

23:54 icey: does clojure have something like python's dir() available?

23:55 ibdknox: icey: I'm pretty sure you shouldn't need to include the status and headers parts of the map

23:56 technomancy: this might be better for visits: (-> r :cookies (get "value") :value Integer/parseInt inc str)

23:56 except you should be using a default value instead of try/catch

23:56 icey: ibdknox: ha, thanks - you're right

23:56 ibdknox: yeah, I'd just use an if to set visits

23:56 don't do try/catch

23:57 jli: icey: you could use if-let for the referer

23:58 ibdknox: icey: completely unrelated to clojure, but you shouldn't really use html labels in that context :)

23:58 jli: (if-let [referer (get ...)] [:div ..])

23:58 ibdknox: destructuring would help there too

23:59 jli: oh, and I know next to nothing about web development, but I would probably make the thing that returns html a function

Logging service provided by n01se.net