#clojure log - Mar 27 2010

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

0:04 brian__: Hi, I have a very basic question about leiningen, if I have a random jar file, x.jar to put it in the classpath, do i just drop it into the project dir's lib directory and put [x.jar] under dependencies in the project.clj file?

0:05 slyphon: brian__: no, you need to import it into your local maven repo

0:05 lemme see if i can find the command-line

0:05 brian__: ok

0:06 somnium: brian__: if you put it in lib and use lein-swank or swank-clojure-project it gets added automatically regardless of project.clj

0:06 slyphon: crap

0:07 the only problem is if you call 'lein clean'

0:07 crap

0:07 brian__: Im not using swank

0:07 slyphon: my shell history must've gotten clobbered at some point :(

0:08 brian__: atleast not knowingly

0:15 technomancy: brian__: if it's a one-off, dropping it in lib/ is fine

0:15 brian__: but if it's a more serious project you want to get the jar into clojars or somethnig

0:18 brian__: the jar is not mine, ie not what I'm working on

0:18 technomancy: if you add it to project.clj and then run lein deps it will show you the proper invocation needed to get it into ~/.m2 if you want to go that route

0:18 but that doesn't help if you're collaborating with others

0:18 brian__: you can upload to clojars as long as you use a custom groupId

0:19 that way when the official author gets around to uploading it, your version won't conflict

0:19 brian__: man, thats heavy

0:19 * slyphon is definately not 3l337 enough to write a macro-that-creates-a-macro

0:19 brian__: its not a public project

0:20 technomancy: brian__: is it secret code?

0:20 * slyphon stays over here in the shallowish end of the pool

0:20 defn: Unknown location: error: java.lang.NoClassDefFoundError: Could not initialize class incanter.core__init (analyze.clj:1)

0:20 brian__: not the jar, but the project is not public

0:20 defn: any ideas?

0:20 technomancy: slyphon: there's a nice article on infoq about clojars that does a good job of explaining this stuff

0:21 liebke: ping

0:21 slyphon: technomancy: ?

0:21 technomancy: misfire?

0:21 technomancy: slyphon: http://www.infoq.com/news/2009/11/clojars-leiningen-clojure

0:21 liebke: technomancy: hey

0:21 technomancy: slyphon: oh, I thought you meant the shallow end of the dependencies pool, never mind

0:21 slyphon: hahahaha

0:22 technomancy: well, thanks anyway :)

0:22 * slyphon bookmarks this

0:22 technomancy: brian__: you might like to read that article anyway

0:22 liebke: I had a question about the way you use multi-module builds in incanter if you've got a moment

0:22 slyphon: technomancy: i was just deciding to not try and write-the-code-that-writes-the-code-that-does-the-thing

0:22 liebke: sure

0:23 technomancy: liebke: we use a multi-module maven build at work and it's kind of a PITA, so I've been brainstorming about how lein could make it smoother

0:23 liebke: that would be great

0:24 multi-module maven is indeed a PITA

0:24 technomancy: my idea is that the top-level project (incanter-app in your case) would declare its dependencies as normal, but then would have a "checkouts" directory that would allow you to hack multiple projects in parallel

0:24 slyphon: VISIBLE BLOCK!

0:25 technomancy: so if you wanted to hack on incanter-app and incanter-charts, you could have the changes to -charts visible in -app without performing an install in charts followed by copy-dependencies in app.

0:25 liebke: interesting, so each of incanter's modules would just be projects in the checkouts directory?

0:25 technomancy: you'd put a symlink to charts in the checkouts dir of app

0:25 liebke: ah

0:25 that sounds like it would do the trick

0:25 technomancy: and the build would be smart enough to add to the classpath src, classes, resources, etc from each project in checkouts

0:26 the bonus there is that someone interested in hacking it would not have to build the whole project

0:26 liebke: I'd be happy to test it when it's ready

0:26 technomancy: for the pieces they aren't interested in actively working on, they could get them prebuild from repo.incanter.org

0:26 *prebuilt

0:27 liebke: makes sense

0:27 technomancy: it's only in the case where someone wants to hack two modules in parallel that it even comes into play

0:27 so it's sort of an ad-hoc opt-in multimodule setup

0:27 liebke: I do that frequently, since core and charts are in different modules

0:28 technomancy: rather than a top-down predefined multimodularity

0:28 brian__: technomancy> I put the jar file under lib and ran lein deps, I didn't see anything about ~./m

0:28 technomancy: liebke: I can't tell you how many times we'll edit something in src/main/resources and then restart slime only to have the changes not show up

0:28 since we forgot to do process-resources, which copies things into target/classes

0:29 brian__: if you just put it in lib it will get added to the classpath without having to put it in project.clj or ~/.m2... for quick hacks that may be the simplest thing

0:30 brian__: ok, thanks much

0:30 technomancy: brian__: but if you end up sharing the project with others it will be frustrating because the code relies on dependencies which aren't clearly stated

0:30 so that's why it's better to get it into a maven repo in the long run

0:30 brian__: ok,understood

0:32 technomancy: liebke: I've prototyped this in the checkout-dependencies branch of leiningen, but it's just an hour or so's work and might not quite be usable yet

0:32 but if you're interested in trying it out I could see about polishing it further

0:32 liebke: technomancy: well, as soon as you think it's ready for me to test it out, let me know

0:33 technomancy: sure. glad the idea makes sense to more than just me. =)

0:34 liebke: technomancy: it makes sense to me :)

0:38 technomancy: incanter's probably the most complicated oss clojure project out there

0:38 so it's a good test case

0:38 liebke: technomancy: for better or worse :)

0:38 KirinDave: It's easily one of the most impressive, too.

0:39 liebke: KirinDave: thanks :)

0:39 KirinDave: liebke: Haha. For what it's worth

0:39 liebke: haha

0:41 technomancy: liebke: there's a little more detail on the thread here: http://groups.google.com/group/leiningen/browse_thread/thread/f67cb42c06515e53

0:41 but I'll let you know once I've got a chance to evolve it further

0:41 liebke: technomancy: thanks, I'll check out the thread

0:49 defn: liebke: have things changed in 1.2.0? Unknown location: error: java.lang.NoClassDefFoundError: Could not initialize class incanter.core__init (analyze.clj:1)

0:49 liebke: defn: I think I need more information, when did you get this error?

0:50 defn: C-c C-k in my REPL

0:50 swank-clojure-project

0:50 in my (ns ... (:use (incanter core datasets io charts stats)

0:50 liebke: defn: you started swank with the bin/swank script?

0:51 defn: no i have swank-clojure "1.1.0" as one of my :dev-dependencies

0:51 then i run M-x swank-clojure-project and navigate to the project root and get my REPL

0:51 liebke: defn: try the bin/swank script as a test to see if you can load incanter

0:52 defn: where is that script liebke ?

0:53 liebke: ah, you don't have the full project, nevermind

0:53 are you using lein?

0:53 Mec: Is there a way to walk through a recursive structure without recursion as it wont be full tail call

0:53 defn: liebke: yes

0:54 [org.incanter/incanter-full "1.2.0-SNAPSHOT"]]

0:54 liebke: try lein swank

0:54 defn: yep, just did -- still no dice

0:54 liebke: same error?

0:54 defn: oops started it from my leiningen source dir

0:54 one sec

0:55 that worked

0:55 KirinDave: Hum, my science experiment failed. :\

0:55 defn: wonder why swank-clojure is being fussy -- it worked fine with 1.0

0:55 KirinDave: I was trying to make enlive templates more efficient, but it turns out that some degenerate templates can't be compiled the way I was hoping.

0:55 liebke: defn: no idea, sorry

0:56 defn: I only use mvn clojure:swank and lein swank

0:57 defn: ah liebke -- found the issue -- when i upgrades i had an old 1.0 version of incanter on my classpath

0:57 upgraded*

0:57 liebke: ah, cool

0:57 defn: after removing the lib/ dir and lein dep'ing it is all working again

1:01 Raynes: technomancy: ping

1:13 brian__: technomancy> I tried this simple experiment, I put mongo.jar in the project lib directory, ran lein deps, then I started repl ie lein repl, then I simply did this -> (import '(com.mongodb.Mongo)) then (def m (new Mongo))

1:13 java.lang.IllegalArgumentException: Unable to resolve classname: Mongo (NO_SOURCE_FILE:7)

1:13 tomoj: brian__: you don't want to drop jars into lib/

1:13 let 'lein deps' do that for you

1:14 brian__: do I put the ppath in the project.clj file?

1:15 tomoj: ppath?

1:15 brian__: where do I put the jar?

1:15 sorry, path to jar

1:16 tomoj: http://mvnrepository.com/artifact/org.mongodb/mongo-java-driver/1.3

1:16 you don't

1:16 it looks like that's the latest version

1:16 so (unless you need to build from the bleeding edge) just tell lein about this dep

1:16 brian__: ok

1:17 i'm beginning the light

1:17 tomoj: e.g., in :dependencies, add [org.mongodb/mongo-java-driver "1.3"]

1:17 brian__: ok

1:17 tomoj: then, when you run 'lein deps', the jar will be downloaded and cached in your local maven repository

1:17 and also inserted into lib/

1:17 brian__: ic ok thanksmuch

1:17 tomoj: this way someone else can grab your project and build it without you having to send the dep jars along

1:18 and you have the option of setting up your own internal maven repository, too

1:18 brian__: ok, although its a private project

1:18 tomoj: it can still be nice

1:18 brian__: sure

1:18 tomoj: if you have multiple clojure projects that use eachother, for example

1:19 then you don't have to build one and copy the new jar to everyone else

1:19 brian__: yes,sounds great

1:19 tomoj: you can just use 'lein install' to put the project in your local repo and other projects can get it with 'lein deps'

1:20 brian__: do i need to configure a maven repo?

1:20 tomoj: unfortunately this does seem to require a jvm restart once you 'lein deps' and get the updated jar

1:20 brian__: no, leiningen automatically sets up a local one in ~/.m2

1:20 you would only need to set up a remote repo if you were distributing these deps to many people/boxes, I think

1:20 brian__: im unclear last remark about restarting jvm

1:21 tomoj: well, I meant that if you update one project, install the new version into your local maven repo, go to another project which is currently running, and 'lein deps' to get the updated jar

1:21 the jvm that is running won't see the updated, it needs to be restarted

1:22 can't update your dependencies without restarting the jvm, I mean

1:22 brian__: ok

1:22 tomoj: which makes sense in a way I think

1:23 brian__: yes, i guess so ;-)

1:23 tomoj: I mean, you've loaded one version of some java classes and you have some objects of these classes, now you update the dep and the class changes, what do you do about these old objects?

1:23 I guess ruby handles it ok

1:23 brian__: of course

1:23 tomoj: clojure handles this fine I think when you're in one project

1:23 but not across projects

1:24 brian__: hmm

1:41 tomoj> that didn't seem to work, I still get (import '(com.mongodb.Mongo))

1:41 nil

1:41 user=> (def m (new Mongo))

1:41 java.lang.IllegalArgumentException: Unable to resolve classname: Mongo

1:42 chouser: (import 'com.mongodb.Mongo)

1:43 brian__: chouser , thank you

1:43 KirinDave: Something I've been meaning to ask

1:43 a module like compojure

1:44 how do I write a require that renames it?

1:44 With like enlive it'd be (require '(org.cgrand [enlive-html :as html]))

1:44 tomoj: compojure has a single-segment namespace?

1:44 :/

1:45 KirinDave: For the main require, doesn't it?

1:45 tomoj: yep, you're right

1:45 I don't use that

1:45 try (require '[compojure :as foo])

1:45 or (:require [compojure :as foo]) in ns

1:46 defn: (require [compojure :as foo])

1:46 yeah

1:46 tomoj: personally I just :require or :use whatever I need from the actual namespaces, not the compojure namespace

1:46 that way I know where it is

1:46 which version of compojure are you using? just curious

1:47 KirinDave: Man that's weird

1:47 Why does that work with [] but not with '() ?

1:47 defn: tomoj: lol probably one of the 100 that exist on clojars

1:47 KirinDave: user=> (require ['compojure :as 'foo])

1:47 nil

1:47 user=> (require '(compojure :as 'foo))

1:47 java.lang.RuntimeException: java.lang.IllegalArgumentException: Don't know how to create ISeq from: clojure.lang.Keyword (NO_SOURCE_FILE:0)

1:47 defn: clojars is a mess man -- we need to standardize as a community on naming schemes for namespaces

1:47 or at least have best practices

1:48 KirinDave: Even if you remove the 'foo with foo (just a transcription error)

1:48 tomoj: what's the problem with clojars?

1:48 KirinDave: It still screws up

1:48 defn: tomoj: i just think the repo is messy

1:48 KirinDave: Aren't all seqs interchangeable?

1:48 tomoj: (require '[clojure :as foo]) and (require '(clojure :as foo)) are different?

1:48 defn: tomoj: lots of versions of compojure etc. are up there that need to be pruned

1:48 tomoj: er, s/clojure/compojure/

1:48 defn: tomoj: one works in the ns macro

1:49 tomoj: defn: yeah, but aren't they all named by the uploader's name?

1:49 in the ns macro, it's :require with no quoting

1:49 defn: tomoj: not all, see enlive

1:49 or incanter, etc. etc.

1:49 tomoj: oh duh, :require, my bad

1:49 tomoj: defn: ah, dynsel uploaded to enlive

1:49 incanter is old and out of date, too, then?

1:50 KirinDave: defn: I just pasted showing one works and one doesn't tho?

1:50 defn: tomoj: i just find it awfully confusing, the multiple versions of a jar. it's not an official release repo, it's like a weird mix of hacks and then some possibly official releases

1:50 tomoj: I guess what we need is a better way for people to assert ownership of a project

1:50 KirinDave: (require '(compojure :as foo))

1:50 defn: tomoj: yeah exactly

1:50 KirinDave: Fails

1:50 tomoj: what should it be modeled after

1:50 defn: clojars should distinguish between the official release and other people's releases

1:50 tomoj: github? rubyforge?

1:50 KirinDave: (require '[compojure :as foo]) works.

1:50 tomoj: there is a practice in place

1:50 defn: tomoj: clojars can do this just fine -- it just needs some TLC

1:50 tomoj: but people don't listen all the time I guess

1:51 KirinDave: defn: It's unfortunate that services like github can't provide little baby maven repos.

1:51 defn: KirinDave: yeah :\

1:51 KirinDave: Well it's possible with github-sites.

1:51 defn: although I suppose it could

1:51 yeah

1:51 KirinDave: Maybe lein git mavenize

1:51 tomoj: very interesting

1:51 that would create a gh-pages branch and set it up so that you can deploy maven artifacts into it?

1:52 KirinDave: sure

1:52 defn: KirinDave: the :as doesn't work in () I don't think

1:52 KirinDave: defn: Why?

1:52 tomoj: and does this work with multiple projects?

1:52 I'd like to know why as well

1:52 defn: KirinDave: i...don't know -- maybe i dont know what im talking about? ;)

1:52 KirinDave: tomoj: Well every project gets its own url, so you'd have to add-repo.

1:52 defn: I mean I believe you.

1:52 I just think it's weird.

1:52 tomoj: I guess it thinks () means a prefix list?

1:52 KirinDave: Why does require and use care what kind of seq it is passed?

1:52 defn: KirinDave: Yeah, I'm just speaking anecdotally -- i use [] when I use :as :only :exclude etc

1:52 just because () always failed for me

1:53 tomoj: investigating..

1:54 KirinDave: I dunno, it seems kind of evil to use what underlying seqtype you're using as an implicit meta-language in function calls

1:54 In macros like (ns ... ) it is fine. I even think it's laudable.

1:54 tomoj: yes, I see this behavior too

1:54 defn: when im doing lein compile can i tell leiningen to use -Xms512m etc.

1:54 tomoj: KirinDave: ehh

1:54 KirinDave: consider destructuring

1:55 KirinDave: tomoj: I get that, but read the docstring.

1:55 Does it mention an explicit type?

1:55 tomoj: yes

1:55 * defn cannot wait to optimize his silly log parsing project

1:55 tomoj: "A libspec is a lib name or a vector containing a lib name..."

1:55 just like you can't do (let (foo 3))

1:55 KirinDave: That seems weird to me tho.

1:55 Like, maybe

1:56 Can you destructure seqs?

1:56 Without caring about the underlying representation?

1:56 tomoj: ,(let [[a b & rest] (iterate inc 0)] [a b (take 3 rest)])

1:56 clojurebot: [0 1 (2 3 4)]

1:57 tomoj: ,(let [(a b & rest) (iterate inc 0)] [a b (take 3 rest)])

1:57 clojurebot: java.lang.Exception: Unsupported binding form: (a b & rest)

1:57 tomoj: also, fogus had some good examples the other day

1:57 KirinDave: Okay so why is destructuring an issue?

1:58 tomoj: ,(let [{a 1, b 2} [1 2 3 4]] [a b])

1:58 clojurebot: [2 3]

1:59 tomoj: ,(let [{a 1, b 2} #{1 2 3 4}] [a b])

1:59 clojurebot: [1 2]

1:59 tomoj: ,(let [{a 1, b 2} '(1 2 3 4)] [a b])

1:59 clojurebot: [nil nil]

1:59 tomoj: thing is, vectors aren't seq

1:59 vectors aren't seqs

1:59 ,(let [{a 1, b 2} (take 4 (iterate inc 1))] [a b])

1:59 clojurebot: [nil nil]

2:00 tomoj: er, what?

2:00 I get different results on the last two line

2:00 I get [2 nil], not [nil nil]

2:13 LauJensen: Morning

2:19 defn: hi LauJensen

2:19 * defn waves

2:19 defn: tomoj: let me try

2:21 yes I get [2 nil] also

2:21 very interesting

2:22 ,(take 4 (iterate inc 1))

2:22 clojurebot: (1 2 3 4)

2:22 defn: ,version

2:22 clojurebot: java.lang.Exception: Unable to resolve symbol: version in this context

2:22 defn: tomoj: which version of clojure are you on? 1.2.0-master-SNAP?

2:23 tomoj: defn: yep

2:23 ,*clojure-version*

2:23 clojurebot: {:interim true, :major 1, :minor 1, :incremental 0, :qualifier "master"}

2:23 defn: ding ding ding

2:23 tomoj: wonder what changed

2:23 defn: map destructuring

2:23 tomoj: so, that very recent commit?

2:23 I didn't know I had it yet

2:23 defn: i think like 2 days ago

2:24 so maybe im not referring to the right thing

2:24 let me find the code sec

2:24 tomoj: I saw the commit but didn't understand the implications of the code

2:24 defn: yeah im still not so hot on map destructuring

2:24 i dont "get" destructuring fully to begin with

2:25 and maps make them quite a bit more difficult to reason about IMO

2:25 for me, anyway -- not in general

2:25 tomoj: I think map destructuring has been around for a while

2:25 but something changed recently with destructuring

2:26 defn: yeah i know where the link is i swear! :)

2:27 slyphon: so how long you figure before someone writes a < macro that lets you embed XML in your code?

2:27 defn: I don't know about < -- what is <

2:27 ,-

2:27 clojurebot: #<core$___4541 clojure.core$___4541@174409e>

2:27 defn: ,<-

2:27 clojurebot: java.lang.Exception: Unable to resolve symbol: <- in this context

2:27 slyphon: hmm

2:27 defn: slyphon: ohhhh nvm i see what you mean, sorry

2:27 slyphon: no, i mean <this-is-a-tag/>

2:27 yah :)

2:28 defn: i intentionally block XML from my mind from time to time

2:28 * slyphon is *so* not volunteering for that

2:28 slyphon: defn: yeah, totally

2:28 defn: lol amen

2:28 Apage43: can you implement syntactic sugar as macros?

2:28 slyphon: Apage43: uh, yeah?

2:28 Apage43: that's kind of what macros do

2:28 Apage43: well

2:28 to a point

2:28 slyphon: indeed

2:28 i dunno if that would actually work

2:29 Apage43: i wasn't sure you could actually usurp the paren

2:29 from a macro

2:29 slyphon: oh, you can bind < to something

2:29 Apage43: within a macro

2:29 but you couldn't make < itself a macro

2:29 so you could be all (xml <blah/>)

2:29 slyphon: defmacro is a method

2:30 er, function

2:30 so, if you *really* wanted to, i bet you could

2:31 Apage43: I also don't know if you can get around the whole thing being tokenized at once

2:31 defn: ^good point

2:31 i dont think it's possible without being able to add your own reader macro

2:31 slyphon: Mec : most simply a macro is just a function that doesnt evaluate its args

2:31 defn: yeah, that's true

2:32 defn: i read a post about doing such a thing

2:32 slyphon: also, there's no space between '<' and the word

2:32 defn: but it was discouraged throughout the article

2:32 Apage43: slyphon: yeah

2:32 that's why i brought up the tokenization

2:32 you couldn't pull the < off the front

2:32 defn: (xml < blah />) wouldn't be so bad

2:32 slyphon: yuck

2:32 defn: haha

2:32 Apage43: defn: eh.. then it gets yuckier than quoting it

2:32 defn: 'nod

2:32 ,'nod

2:32 clojurebot: nod

2:36 tomoj: the question is, why use < and > at all?

2:36 we already have sexps

2:36 and more than most

2:37 defn: hmmmm I keep getting this j.l.String cannot be cast to j.l.Number -- does (defn -main [& args] (let [n (nth args 2)] n))

2:37 for some reason turn its args into string values?

2:37 tomoj: that's what args are

2:38 Apage43: i'm personally fine with the way compojure does html

2:38 defn: ?

2:38 * robink needs to learn lein to get clojure-contrib compiled.

2:38 robink: I'm not touching Maven

2:38 defn: robink: cemerick had a good post on why maven is a good thing

2:38 tomoj: you don't need lein to compile clojure-contrib, do you?

2:38 defn: maven + the polyglot plugin makes it not suck

2:38 robink: defn: OK

2:39 defn: Ah, OK

2:39 defn: However!

2:39 robink: tomoj: No, I don't

2:39 defn: I am of the opinion that clojure needs something like rubygems for jruby

2:39 robink: I would agree

2:39 Something that integrated well with Portage would be awesome

2:39 defn: rubygems for jruby enhances the relationship

2:39 (with ant in jruby's case)

2:39 noidi: http://clojars.org/

2:40 defn: noidi: ?

2:40 robink: Gentoo has a rubygem eclass that makes ebuild files for gems just a few lines long.

2:40 defn: noidi: what rubygems does is different from what lein + clojars do right now

2:40 Apage43: gems are global

2:40 lein makes project-local copies of deps

2:40 noidi: and that's the problem with gems :P

2:40 tomoj: I'm not sure that makes sense in the jvm

2:40 noidi: I think local installations per project are the way to go

2:40 tomoj: yeah

2:41 headius: gems are only as global as you let them be

2:41 with jruby, they're local to the jruby dir

2:41 defn: ^^

2:41 noidi: global gems are fine as long as you only have one project depending on them

2:41 defn: headius: i would like the option to make some jars global and some local

2:41 noidi: as soon as you have two projects that depend on different versions, you have to move to per-project dependencies

2:41 headius: mvn installs are global

2:41 tomoj: I have many projects depending on many different versions of different stuff

2:41 headius: or at least as global as rubygems

2:42 Apage43: can you not require a specific gem version?

2:42 headius: of course

2:42 defn: you absolutely can require a specific gem version

2:42 Apage43: oh

2:43 tomoj: so lein would have to figure out what version of each dep you want and compose a classpath pointing to the jars in the global cache?

2:43 headius: you can even use bundler to roll specific versions into your app dir directly, and not depend on the "global" installs at all

2:43 Apage43: but can you have multiple versions installed

2:43 headius: Apage43: certainly

2:43 I think I have 4 versions of rails installed here

2:43 Apage43: hmm

2:43 noidi: ok, maybe I confused ruby and python module systems here

2:44 headius: tomoj: this isn't any different than multiple versions of jar files

2:44 defn: i think there are a lot of misconceptions about mvn, ant, rubygems, etc. etc. etc. -- I really don't care *at all* which tools we end up standardizing on. what i'm concerned with: does it work? is it easy for me to start a new project and do some very basic things? can i do tons more stuff if I want to? is there a tool to facilitate the interaction?

2:44 headius: that's a problem for every packaging system

2:45 defn: mvn does deps well -- im not against mvn, but i think it's too much extra garbage to learn about when you first start learning clojure -- it's the icing on the cake

2:45 talios: 'lo all

2:45 defn: that's why something like lein or another tool should be around to make those first steps easy for new users to clojure

2:45 Apage43: yes

2:45 tomoj: headius: right

2:45 noidi: I looked into maven yesterday, after reading cemerik's blog post, and was very positively surprised

2:45 Apage43: i am pretty happy with lein so far

2:46 tomoj: headius: and maven solves it by copying into the project dir

2:46 defn: noidi: same

2:46 tomoj: what's the other solution?

2:46 noidi: the design was much cleaner than I expected for all the flak it gets

2:46 talios: noidi / defn - glad to hear you liked the maven support

2:46 headius: there is no good solution for multiple libs depending on different versions of things

2:46 Raynes: Leiningen has been all I've needed insofar.

2:46 I don't think I want to switch to maven if I don't need what it offers.

2:46 noidi: talios, thanks, it works great :)

2:46 tomoj: aren't you already using maven, really?

2:46 Apage43: if there's one thing i've seen clojure excel it it's wrapping things that are horriby complex to use in java and making them surprisingly friendly

2:46 defn: people who use lisp *hate* XML because it's like lisp, but is terribly ugly

2:47 Apage43: *excel at

2:47 robink: Link to blog post?

2:47 noidi: robink, http://muckandbrass.com/web/display/~cemerick/2010/03/25/Why+using+Maven+for+Clojure+builds+is+a+no-brainer

2:47 talios: defn: if you hate the XML - you could always checkout the polyglot maven project - our clojure DSL reads similar to lein

2:47 defn: talios: oh im aware of it

2:48 talios: defn: the problem with the polyglot maven stuff tho is having to support -all- of maven, which tends to make it a bit messy when getting more complex things added

2:49 Apage43: feh

2:49 defn: talios: here's my feeling on polyglot: awesome.

2:49 Apage43: i hated building vimclojure git

2:49 defn: however, as a new user it's just one more thing i need to setup and understand

2:49 Apage43: had to download freaking -gradle-

2:49 which is 26 -megs-

2:49 defn: we need a community tool that just does that kind of garbage for a new user

2:49 talios: headius: OSGi or Jigsaw -might- help on that, but it also brings in its own problems

2:49 Raynes: Yeah, screw gradle.

2:49 :|

2:49 defn: i also dont want to create my own xml file and learn the syntax and write every new project's xml file by hand

2:49 i want that to just be generated for me

2:50 im fine with XML as long as for 90% of the things I do, I don't need to edit it

2:50 talios: defn: you could use maven archetype's for that. I think stuart (or someone) made on for the clojure plugin, which handles all the basic foo

2:50 defn: talios: so many choices, so little consensus

2:51 headius: hah, gradle

2:51 defn: it's a bit frustrating, which is why im sticking with leiningen until someone gives me a better solution

2:51 headius: I'll keep my mouth shut on that one

2:51 talios: defn: it's a build system - EVERYONE has different requirements. That's what makes it hard.

2:51 defn: it's focused on our community, and i like that

2:51 noidi: well, that's software development :)

2:51 Apage43: hah, groovy

2:51 noidi: first you pick a language, then a build system, then a vcs

2:51 oh and the editor's quite important too...

2:51 headius: why is gradle 26MB?

2:51 defn: noidi: your forgot testing frameworks!

2:51 noidi: if you keep second-guessing yourself you never get anything done (that's me!)

2:51 defn: one for BDD and one for TDD!

2:52 headius: jruby's complete jar with ruby and rake and rubygems and rspec is like 9MB

2:52 defn: headius: wow

2:52 Raynes: I think Leiningen will improve quite a bit in the future.

2:52 Apage43: headius: uses groovy.

2:52 talios: defn: one thing I love about maven's ecosystem is the release plugin etc. does lein support anything like that?

2:52 headius: Apage43: oh right :)

2:52 * talios really needs to look into lein sometime

2:52 defn: talios: yes and no -- leiningen is so new -- the answer to your question is yes, you can build plugins for lein

2:52 however, that process is largely undocumented, and it is still a new tool

2:52 it will come with time i imagine

2:53 talios: defn: *nod* which is why I still prefer the maven side, I just added a compiler plugin, and the rest comes for free.

2:53 maven isn't the be all and end all tho.

2:53 Raynes: Wasn't technomancy talking about a maven adapter or something?

2:53 noidi: the great thing about maven is that people have been banging their heads against it for years and figured out and documented how to do all kinds of things

2:54 Apage43: and lein gives you the maven package system, without anyone having to actually -learn maven-

2:54 defn: leverage maven's long support and big user base, plugin functionality, but do it in a community-based tool that makes doing stuff *we* need to do easier

2:54 tomoj: yeah, great

2:54 defn: that's my feeling

2:55 Apage43: lein keeps you in clojure

2:55 talios: Apage43: does lein keep its deps in ~/.m2/repository ?

2:55 noidi: talios, yes

2:55 defn: talios: yes

2:55 Raynes: Indeed.

2:55 tomoj: defn: so, pmaven-clojure?

2:55 defn: tomoj: wuzzat?

2:55 talios: I was thinking a "clojure installer" that installed lein, the maven clojure plugin and a bunch of plugins/deps into .m2/repository would be great, get that initial 'download hell' out of the way

2:55 tomoj: polyglot stuff for clojure

2:55 talios: tomoj: yep?

2:56 Raynes: defn: It's totally the greatest thing evar, haven't you heard?

2:56 tomoj: http://polyglot.sonatype.org/clojure.html

2:56 talios: I meant, does this satisfy defn's dream

2:56 Apage43: fun thing is

2:56 defn: Raynes: not sure if you're joking :)

2:56 Apage43: the pmaven and lein syntax for a project def

2:56 Raynes: defn: I'm being sarcastic.

2:56 defn: tomoj: not totally -- it's close

2:56 Apage43: arealmost exactly the same

2:56 talios: tomoj: oh right. close I guess

2:57 * talios really needs to find some time to do some work on pmaven-clojure. Plugin configurations are technically "broken" as such.

2:57 noidi: talios, in my experience the biggest benefit of lein is the ease of setup, so with such an installer I don't know what the benefit of lein over "plain maven" would be

2:58 Apage43: that's pretty much it

2:58 noidi: other than "mvn clojure:swank" is more characters than "lein swank" :)

2:58 defn: lol

2:58 talios: noidi: alias!

2:58 Apage43: lein is a "make maven quick and easy and throw in a couple clojure specific commands while we're at it"

2:58 Raynes: I like Leiningen because technomancy made it. <3

2:58 defn: id like to see a tool which hooks into clojars.org or some other community site that does pmaven-clojure stuff for you

2:59 talios: Apage43: pmaven-clojure is pretty much the same there.

2:59 Apage43: talios: yep

2:59 Like i said

2:59 you could use the exact same project def file if you didn't specify dev/test dependencies

2:59 because in the two examples, that's the only thing that differs

2:59 talios: defn: the ultimate goal for polyglot maven from memory is, that it'd automatically pull in the polyglot "plugin" from maven central, from a standard maven install

3:00 defn: talios: that would be nice

3:00 i want a tool that ties into our community more

3:00 leiningen was on the right track in that respect

3:00 talking to clojars.org for example

3:00 Raynes: My heavens, are we already signing Leiningen's death certificate? :p

3:01 talios: get clojars.org syn'd to central - then maven would be automatic

3:01 sync'd even

3:01 defn: not the same thing

3:01 noidi: defn, Clojure-specific convention (default configuration) over pom.xml configuration :)

3:02 talios: defn: why not? works fine for every other repo out there.

3:02 at least, those that are sync'd

3:02 defn: talios: can i search for repositories using mvn

3:02 talios: im sort of departing from build tools and getting into community integration here

3:02 talios: defn: repositories or artifacts?

3:03 defn: both

3:03 artifacts mostly

3:03 talios: You can use http://mvnrepository.com for artifact searching.

3:03 defn: oh god please dont make me go there

3:03 talios: I also know that IntelliJ, Eclipse, and I think Netbeans download the indexes from central for local searching

3:03 defn: i want a rubyforge for clojure -- and we'll need a tool to talk to it, that's my opinion

3:04 talios: if we're going tool route, said tool could just download the maven indexes from central, and search them ( theirs client api's for doing that already )

3:05 that's something that came out of the nexus repository manager

3:05 defn: talios: yes that'd be fine with me

3:05 talios: if it could also publish to our site with some metadata in a local file tacked onto the submission, that'd be nice also

3:05 talios: mmm, I wonder if there's already a command line client for that, or a maven plugin

3:06 actually - does clojars run any form of repository manager at all? or is just a raw repo?

3:06 defn: raw i believe

3:06 it's a mess

3:07 talios: defn: have you seen nexus? http://oss.sonatype.org is sonatypes Open Source repo ( where I publish the clojure plugin )

3:07 defn: im complaining and not doing anything about it -- but ive got a notebook dedicated to it

3:07 Apage43: who runs clojars anyway

3:07 defn: ato i think

3:07 talios: sonatype looks like something id be cool with

3:08 but again id really like to stamp the hell out of a similar style site with the *clojure* logo

3:08 it's partly just a cultural identity thing for me

3:08 talios: defn: sonatype's the company behind it ( main company behind maven as well )

3:08 defn: we need tools we own

3:08 talios: nexus is all themeable

3:09 defn: talios: sure

3:09 talios: im just thinkin out loud here

3:09 talios: *nod*

3:10 I believe nexus has a nice REST API as well, so even if the UI was kept 'away from the public' a custom site could easily integrate

3:10 defn: i dont know the answer -- i just sort of envision a rubyforge-esque site that is the community's disclojure + planet.clojure.in + release notes for clojure + the one true place for official projects to live

3:10 talios: time to a .clojure TLD? :)

3:10 +get

3:10 defn: haha

3:11 talios: http://www.clojure

3:11 Apage43: www.clj ;]

3:11 defn: i just think it would be nice, you know?

3:11 talios: Apage43: real geeks drop the www. now don't they?

3:11 Apage43: now that'd get confusing

3:11 talios: right

3:11 talios: defn: yep.

3:11 Apage43: talios: http://clj./

3:11 defn: we have lots of sources of information for clojure floating around right now -- half of the official stuff i read about clojure comes from an unofficial site where tweets are the source of news

3:11 Apage43: well

3:12 defn: im not averse to that per se, i just think we need to cement some things into a community site, one of which should be project hosting, a place for "official" stuff to live

3:12 Apage43: there's certain folks that will tell you that dns is hierarchichal and you should identify the subservice being pointed in the name [www for http]

3:13 talios: Maybe a first step would be still have all these things separate, but bring them all under the *.clojure.org domain - centralize the DNS

3:13 defn: that could go a long way i think, yes

3:13 talios: getting build.clojure.org was a big win IMHO.

3:14 defn: idk, we're just going through growing pains i think as a community

3:14 Apage43: make stuff way easier to find and help prevent duplication of effort

3:14 defn: clojure is a young lang, our tools are evolving, hell, the core of the lang evolves every couple months

3:14 Apage43: s/^/it would

3:14 defn: Apage43: yeah good plan

3:15 * talios is still dreaming of the day the compiler can generate JDK annotations. I fear I might have to dive into the compiler myself and research bytecode

3:17 talios: Are any of you guys using clojure-CLR at all? Is that actually getting any traction?

3:18 defn: talios: one other thing im sort of on the fence about with regard to mvn, and i know this isnt a good reason BUT i suppose im a little emotional about it

3:18 i want clojure to be its own language, and i dont want to sacrifice and go with what have been historically java tools because, well, we aren't java

3:19 when ruby got on the jvm they didnt switch to maven

3:20 granted they're using ant + rubygems -- but to me that's how it ought to be i guess, we have our tool which does our stuff, and we integrate with maven second

3:20 noidi: well, if Clojure didn't embrace the JVM, it would have as much traction as Ruby in 1997

3:20 defn: :)

3:20 the JVM != Java -- I know that's almost a cliche at this point, but well, it's true

3:21 talios: I've seen a few JRuby project use maven, simply because they integrate into a larger build system

3:21 defn: oh sure talios -- im just trying to suggest that jruby projects use rubygems AND maven -- i feel like we need a similar combination

3:21 talios: *nod*

3:21 defn: one of those tools facilitates the interaction

3:22 talios: defn: that fact that IDEs now support maven out of the box is a compelling reason as well.

3:22 defn: it's a fuzzy line because clojure projects are still .jar files -- it's not like it was with ruby where you have gems and jars

3:22 talios: I think we're arguing for arguing sake now :)

3:22 defn: maybe we dont need a tool

3:23 talios: defn: mmm not always .jar files tho - clojure libraries yes... what about .war files tho?

3:23 defn: ill be sold when someone gives me 3-4 lines of stuff to put in my command line from not having clojure at all, to starting up a repl and (use)'ing a library

3:25 talios: mmm, if clojure "knew" about ~/.m2/repository - and you (require 'org.clojars.compojure/1.3.2) (use 'what.ever.ns) that might get us there

3:26 Apage43: eeeehhh.

3:26 talios: then you'd be: apt-get install clojure, $ clj-repl

3:26 defn: how do you make a new project?

3:26 (in this scenario)

3:26 Apage43: hesitant to make maven a dependency of the -language-

3:27 talios: Apage43: not of the language, but of -a- distribution, that might bootstrap a dependency manager ns

3:27 defn: i want to install clojure, scaffold a project directory, get a dependency from a remote repo by searching from my command line, and then open a repl and include it

3:27 talios: defn: oh - you asked for getting a REPL and (use'ing something, NOT setting up a project! :)

3:27 defn: so i suppose that's like 6-7 "lines"

3:27 Apage43: talios: maybe not hook (require then ?

3:27 talios: Apage43: yeh, not (require but something similar ( i was trying to think of a term to use 0

3:29 defn: maybe if lein had a project init command, similar to "git init", "lein init" creates a project.clj in the current dir..

3:29 defn: "apt-get install clojure leiningen && lein init repl"

3:29 Apage43: talios: you mean like lein new?

3:30 talios: Apage43: well there you go :)

3:30 Apage43: :)

3:30 talios: I remember reading something about someone suggesting having something like ~/.clojure/lib for default jars on the classpath, like ant and groovy have, that would also help here

3:31 Apage43: and now you mention that, I think I need to add a clojure:new to the maven plugin :)

3:31 Not sure if maven needs a pom.xml to bootstrap itself tho, I can only try !

3:32 * talios should really write up release note for the 1.3.2 release last week

3:33 noidi: talios, can new archetypes be defined outside the archetype plugin?

3:33 maybe "mvn archetype:clojure" could create a new clojure project

3:34 talios: noidi: yep - an archetype is a type of artifact, if its in your repo then it'll appear in the archetype:generate menu, other wise you have to mention the archetype type on the command line

3:34 noidi: it'd not been updated lately, but http://github.com/nullstyle/clojure-quickstart is one such arcehtype

3:35 defn: talios: what do i need to do to get up and running with pmaven

3:36 talios: defn: looks like the download page is broken currently - so easiest way is to clone http://github.com/sonatype/polyglot-maven and build that, unzip the dist into a directory and just run maven out of there

3:38 defn: once you have it installed, its just like maven: mvn install will find a pom.clj, pom.groovy etc. in the current dir and just work

3:39 defn: inside the bin directory theres also a "translate" command, which you go "./bin/translate pom.xml pom.clj" to convert an existing maven project over

3:39 cd

3:39 bah, wrong window :)

3:39 first time I've done that in years.

3:41 defn: talios: hehe -- okay i must say though that a broken install page does not help the polyglot mvn + clojure cause :)

3:41 noidi: polyglot maven needs a clear "getting started" page

3:42 defn: it should be easy enough to explain in like 3 lines of text max

3:42 talios: this is the first time in about 2-3 months I've even looked at it. I'll ping the sonatype guys about getting the download page sorted

3:42 defn: i want it to be a brief aside in a blog post, not the whole post

3:42 Apage43: talios: it's not bad until you "ls" a channel to see who's in it

3:43 talios: Apage43: I blame that its the first time in ages I'm using a console based IRC client.

3:43 Dayam where's my mastery of the english languge today?

3:43 Apage43: i am used to doing silly stuff in a terminal, since at home I use bash and from 8 to 5 at work I use ksh88

3:44 key combos are all different

3:44 talios: I recently switch to zsh, love it apart from the completion. Much prefer bash's completion

3:44 defn: im having a brain fart

3:44 "44" -> 44

3:44 * talios updates his polyglot maven checkout and builds, my god I'm downloading the whole internet again!

3:45 * talios should really a) get some dinner b) edit this stinkin podcast. I think a) shall get priority.

4:00 defn: talios: thanks for the constructive chat about this stuff

4:00 talios: defn: if you're building pmaven - ignore the last test failing on pmaven-commands, and grab the dist from pmaven-cli/target

4:00 defn: talios: i know im probably in the touchy feely, willfully focused on aesthetics, etc.

4:00 camp

4:01 talios: we need that touchy feely focus tho, in part

4:01 to keep the balance

4:01 defn: but those things matter enough to make good tools suck if they're not paid attention to

4:01 talios: *nod*

4:01 defn: it's kind of a weird place to be that guy, though

4:02 talios: esp. for a LISPer :)

4:02 defn: lots of very serious objective opinions on this matter, and i come in and say "yeah but it's not easy enough to use" and they say "well of course it is, you just build this thing from source, and then you learn the structure of the pom.xml, and then you... oh and dont forget to..."

4:02 talios: (wheres (the (aesthetic)))

4:03 defn: "and THEN, you just type this command, and boom! you're halfway there!"

4:04 talios: defn: you know, you sound like a VB developer :-)

4:04 "point, click. make money"

4:04 * talios grins

4:05 * talios actually thought about a clojure-virtual-box image the other day. Set up with everything, Eclipse, Netbeans, IntelliJ Community, Emacs etc.

4:06 talios: start labrepl on bootup, auto launch a browser etc.

4:07 could also be a livecd maybe

4:08 tomoj: you could distribute that as a vagrant box

4:08 er

4:08 not really

4:09 talios: vagrant box? I'm not familiar with that term?

4:09 tomoj: http://vagrantup.com/

4:09 that's all headless stuff though

4:10 for headful there's not a whole lot of reason to use it unless you provision with chef

4:10 talios: oo it uses chef! nice.

4:10 tomoj: but you could use vagrant to provision with chef, then use the regular VirtualBox gui to launch the machine headfully

4:10 (that's what I'm trying to figure out now for a windows coworker)

4:11 talios: true. just use vagrant to do the build.

4:11 tomoj: ah yeah, and then distribute the big exported VMs?

4:11 talios: yep

4:11 tomoj: or if someone wants to wait around to build it themself they can

4:11 talios: they probably wouldn't be that big either

4:12 tomoj: I wonder if vagrant can kickoff a headful gui

4:12 talios: it'd just be a different set of chef recipes wouldn't it? to install gnome or something

4:12 tomoj: guess you can just 'vagrant up', 'vagrant halt', VirtualBox

4:12 yeah, that's exactly what I was going to work on

4:12 but not sure what my coworker uses

4:13 the problem is that typically with vagrant you just get ssh access and that's it

4:13 talios: mmm, you wouldn't even need the 'vagrant up' I guess, I assume 'vagrant init' makes the image, and 'up' just starts it

4:13 tomoj: well 'up' does the provisioning

4:14 cus the provisioning happens after the machine starts

4:14 talios: surely that'd be on "first run"? i.e. when the end user starts it in VirtualBox GUI

4:14 tomoj: VirtualBox GUI won't do the provisioning

4:14 talios: mmm, I thought it'd run chef on boot? I guess not

4:15 tomoj: what you can do is build your chef recipes, run them with 'vagrant up' (first run) and 'vagrant reload' (later runs)

4:15 talios: ah right

4:15 tomoj: and then expor that

4:15 s/expor/export/

4:15 then they can import the fully-provisioned vm

4:15 I wonder how well x-forwarding onto a VM works

4:15 * talios tries vagrant out on osx. I wonder if it'll work :)

4:16 defn: is it possible to get "bed sores" from sitting down too long?

4:16 tomoj: yeah, osx is probably the most support

4:16 let me know if you do work on dev recipes, I was planning to start a repository of them

4:16 talios: shit - 9pm, no wonder i'm hungry! dinner time, then podcast editing for a bit, and some vagrant reading.

4:16 tomoj: I don't care about the javaland ides though :)

4:17 guess I should if I want my coworkers to use clojure

4:17 talios: true, but if we're building a box for all - would be good to cater for all sorts

4:17 tomoj: exactly

4:17 talios: must read up on chef more too. ops guy at work was looking at that as well.

4:17 tomoj: what I actually planned was to build a cookbook repo for my personal dev environment

4:17 then later parametrize it for others

4:18 I sort of secretly nominated myself to be ops guy when I discovered chef :)

4:18 talios: heh

4:19 doh - need to upgrade my virtual box :)

4:19 tomoj: yeh :(

4:19 the version in the ubuntu repos is too old

4:20 * talios grabs dinner whilst it downloads - cheers for the vagrant link. that will help for MANY a thing!

4:22 talios: vagrant requires rails?

4:22 interesting

4:24 tomoj: uhh, I didn't know that

4:25 talios: maybe i'm just misreading the tutorial

4:25 tomoj: the vagrant gem does not require the rails gem

4:25 talios: http://vagrantup.com/docs/getting-started/setup.html <-talks about "rails project setup"

4:26 tomoj: talios: let's move to #vagrant

4:36 defn: hmmmm

4:36 so if im running java -jar myjar.jar arg0 arg1 arg2

4:36 does it automatically make my args strings?

4:39 nevermind i found the damn problem :)

4:39 talios: yep

4:39 defn: talios: oh, really?

4:39 talios: public static void main(String[] args) { .... }

4:39 its a string array for the args

4:39 defn: oh, well crap

4:40 so to get an integer for an arg i have to go through all of that trouble to coerce it to an int?

4:40 talios: Integer.valueOf(arg0)

4:42 defn: talios: thanks buddy

4:42 i was beginning to think i was crazy

4:42 talios: you're using java - you just might be :)

4:42 I know I am.

4:43 defn: yeah i was just going to say...probably a safe bet im nuts if im talking to you! :)

4:43 talios: oi

4:43 :)

5:21 defn: 90s to parse 300M of logfiles for IPs -- any ideas?

5:22 _mst: tried using awk/sort/uniq? :)

5:22 defn: no awk -- i felt dirty and this potentially has to run on windows

5:22 _mst: (depressing the number of times a combination of shell programs has come up faster than some special-purpose thing I wrote myself ;) )

5:23 ah, right :)

5:23 defn: yeah ive used grep and felt bad about myself :)

5:23 maybe this is a silly thing to be doing in the first place...

5:24 i could probably make this run unoptimized in perl faster than itll run fully optimized in clojure

5:24 however once you get like 16 cores into the mix, mine could potentially kick the crap out of it

5:24 but...we dont have 16 cores yet :)

5:24 _mst: after fighting along with _ato on widefinder I can sympathise :) Is your code online anywhere?

5:25 defn: no i can put it up though, just have to sanitize it for some company specific details

5:25 1s

5:38 * talios sniggers at the ls

5:40 defn: that was a one second :)

5:40 1l

5:40 * talios should use a bigger font ;)

5:40 defn: cd ~

5:40 now you got me! :)

5:50 _mst: yeah ive been looking at widefinder, specifically _ato's code and I don't feel very comfortable with it just yet

5:51 _mst: chunking would obviously do me a lot of good, and im not using any reference types

5:51 i thought id be able to do better than 90s without any optimization for 300MB of logs though

5:51 * talios fires up cubase and starts editing a podcast - I really wish we could talk without ums and arrs by default :)

5:51 defn: anyway, here is the stuff..

5:52 _mst: http://gist.github.com/345880

5:53 _mst: it's pretty much guaranteed to be a complete mess, my function names are terrible, some of it just plain nasty :\

5:53 _mst: not to worry :)

5:56 defn: _mst: the other thing is that i think i am taking some totally unecessary steps with the data early on -- the story of the structure is like this:

6:04 _mst: bah sorry, busy with some work stuff for a minute

6:05 and then i broke my repl due to no *print-length*

6:06 :)

6:11 _mst: defn: it's just one thing, but I wonder how you'd go using transients for your counting bit: http://gist.github.com/345896

6:11 on my machine, at least, that fn spends a lot of time garbage collecting

6:11 and using transients seems to cut that down significantly

6:12 talios: 'lo cemerick

6:13 _mst: defn: and you could do the same thing to the add-country-codes fn, since it's doing the same sort of thing

6:23 defn: _mst: awesome advice

6:24 thank you!

6:24 _mst: how do you profile?

6:24 _mst: I vary a bit... sometimes I just run the JVM with "-agentlib:hprof=cpu=samples,depth=6,force=n,thread=y,verbose=n"

6:24 sometimes I use the profiler in jvisualvm

6:25 defn: this is fantastic info

6:25 * talios uses yourkit for profiling

6:25 _mst: sometimes I just take a wild stab in the dark :)

6:25 defn: talios: link?

6:25 talios: http://www.yourkit.com

6:25 commercial - ex guys from jetbrains I believe

6:25 defn: runs on linux?

6:25 talios: yep

6:25 its java ;)

6:25 defn: cool

6:25 it's not always a foregone conclusion :)

6:26 talios: the profiler in jvisualvm ( which is the netbeans profiler ) is good, but could be better

6:26 I love how yourkit till trace down to SQL statements etc. profiling to that level is darn handy

6:26 _mst: ah, I've used jswat too... but I think that's the netbeans one too

6:27 talios: _mst: isn't jswat just a debugger? didn't think it had a profiler

6:27 _mst: oh! hm, you might be right

6:28 yeah, ignore me :)

6:28 talios: http://ejp.sourceforge.net looks quite cool tho. open source

6:28 oo thats old tho :(

6:31 http://jrat.sourceforge.net is one that I've heard mentioned favorably a lot

6:31 I don't think it gives runtime results tho

6:32 _mst: probably not the time to mention that I also like System/currentTimeMillis and println :)

6:32 talios: heh

6:36 Ug. 3 hours or so into editing this podcast and I'm only at 28mins of recorded audio :( Might give up for the night and read, or code.

6:47 tomoj: talios: clojure podcast?

6:48 talios: tomoj: http://www.illegalargument.com - java/jvm podcast mostly - but we do talk clojure a bit. greg's an old common lisp lover but does mobile stuff now (co host), and richards a freak groovy/grails lover

6:49 tomoj: one could say its a maven hate podcast as well, as pretty much each week we discuss the "maven pain of the week" :)

6:51 oh and tony's a scala lover

6:51 so we talk languages and rant :)

6:54 bsteuber: talios: which podcast are you referring to?

6:54 talios: bsteuber: http://www.illegalargument.com as I just linked tomoj

6:55 we record far more regularly than we post episodes tho - they take a surprisingly long time to edit up :( and finding time is hard.

6:55 bsteuber: thx - sorry, just entered the chat

6:55 talios: ah so you did :)

6:58 tomoj: talios: jvm in mobile?

6:58 like J2ME? or android?

6:58 talios: tomoj: greg does j2me and android, and symbian

6:58 tomoj: I need to learn android :)

6:59 talios: I got as far as a Hello World app :)

6:59 too many projects, not enough time

6:59 tomoj: yeah :(

7:09 defn: _mst: still there?

7:10 _mst: I get an error with your code

7:10 clojure.lang.PersistentArrayMap$TransientArrayMap cannot be cast to clojure.lang.Associative

7:12 oops, forgot the ! on assoc!

7:18 licoresse: Anyone doing Swing development with MigLayout here?

7:26 defn: do i need a special merge-with to wrap a (reduce (fn [a {:foo [bar baz]}] (merge-with + a {bar baz})) {} ...)

7:27 do i need a special merge-with to wrap a (persistent! (reduce (fn [a {:foo [bar baz]}] (merge-with + a {bar baz})) (transient {}) ...)

7:34 esj: licoresse: No, but I think I just changed to it :)

7:35 bsteuber: licoresse: I'm at least considering it - because using netbeans just for form designing seems a bit weird

7:36 licoresse: Just curious how the reception was

7:36 I understand that it is built on jgoodies

7:50 talios: I've heard a lot of good things about MigLayout

7:50 wasn't stuart sierra clojure/swing posts using it?

7:50 LauJensen: talios: Here's another approach http://www.bestinclass.dk/index.php/2009/10/functional-social-webscraping/

7:51 talios: ahh - looks like it was standard swing ( http://stuartsierra.com/2010/01/02/first-steps-with-clojure-swing )

7:52 LauJensen: (though I see that blogpost is semi broken, the link to the source at the bottom should be what u need)

7:52 talios: oh yes - macswing! very nice

8:35 licoresse: macswing?

8:35 _invis: hi all

8:37 Guys could I make colors parentheses like this http://i41.tinypic.com/f2rons.png ???

8:37 This is picture from Vim

8:37 And I am work with emacs

8:37 somnium: _invis: like this? http://tinypic.com/view.php?pic=2urqmgl&s=6

8:39 _invis: indeed

8:39 but when you write a function paretheses are white :) why ?

8:41 bsteuber: I don't nee rainbow parens - just using paredit is best for me :)

8:41 licoresse: yeah, paredit rocks, no need for color

8:41 somnium: _invis: I think you want HighlightPaerentheses mode and you can customize the colors with m-x customize group

8:42 * somnium feels paredit and rainbow-parens are orthogonal

8:42 _invis: thanks Will try to google HighlightPaerenthese for emacs :)

8:42 Chousuke: somnium: they are, of course.

8:42 somnium: but since learning paredit I've never felt the need to have rainbow parens

8:43 bsteuber: needing paren colors means that you actually SEE parens in the first place :)

8:43 * lithpr likes his parens the way way he likes his eggs and ham, a dim soothing dark-sea-green

8:43 Chousuke: bsteuber: well, sometimes you do need to look at them

8:43 licoresse: working with paredit makes the parans go away

8:44 Chousuke: bsteuber: but I agree, they kind of disappear

8:44 they are there, and you see them, but your conscious mind ignores them

8:44 somnium: licoresse: working with haskell makes them go away :P

8:44 lithpr: lol

8:44 licoresse: :)

8:45 well, I mean this, and I hardly use any syntax coloring either, only the function names are colored

8:45 (and the comments)

8:46 Chousuke: I like syntax colouring still

8:46 licoresse: (and the strings) :/

8:46 but thats it

8:46 Chousuke: it's useful to differentiate between strings, numbers, symbols and operators visually.

8:47 somnium: I think I often use keywords just for the syntax highlighting

8:47 bsteuber: sure, sometimes you do need them :)

8:48 Chousuke: It's weird though

8:49 you can keep telling people that the parens disappear with experience, and they won't believe you until they experience it themselves

8:49 and at that point they're already convinced :/

8:50 bsteuber: :)

8:50 somnium: Im still not sure if they go away or if people in the jungle just dont notice the shrubbery

8:51 licoresse: they don't really go away, you just learn to like them

8:51 in my code each paran has a name

8:52 joe, gill, john and lisa etc

8:52 somnium: wow, with such a relationship using paredit must feel like coaching kickball

8:53 licoresse: hehe

8:54 _invis: http://nschum.de/src/emacs/highlight-parentheses/

8:54 Chousuke: somnium: I think the parens are still there, but a good tool relieves you from the need to pay attention to them :)

8:55 licoresse: _invis: are you sure you want to give them so much attention?

8:55 _invis: why not

8:55 licoresse: _invis: it's true what Chousuke says

8:55 Chousuke: Most of the information of lisp code is in the indentation and code layout.

8:55 and of course the symbols

8:56 licoresse: invis_: use M-C-q to reformat

9:22 defn: _mst: thank you again for that tip on persistent!/assoc!/transient -- that sped things up quite a bit, from 60s to 21s

9:23 Anyone here use yourkit? If so, how does one test with emacs? Is that possible?

9:25 bsteuber: anyone used maven to deploy signed jnlp packages so far?

10:02 defn: anyone have any profiling setup tips for yourkit and clojure? preferably id like to steer clear of IDE integration and just use emacs

10:04 or any profiling tools for that matter

10:12 maybe a silly question, but how do i add a JVM flag -- Are those just arguments to `java`?>

10:17 noss: yes

10:24 defn: wow. YourKit is awesome.

10:25 Mec: How do I display a JFrame so that it doesnt shut down my repl when I close the window?

10:31 mattrepl: Mec: http://java.sun.com/javase/6/docs/api/javax/swing/JFrame.html#setDefaultCloseOperation(int)


10:43 raek: Mac: you could use EXIT_ON_CLOSE to shut down the whole application

10:43 http://java.sun.com/javase/6/docs/api/javax/swing/JFrame.html#EXIT_ON_CLOSE

10:44 defn: well -- using a profiling tool SEEMED like a good idea, heh

10:44 i have absolutely no idea what is going on

10:44 Mec: I'm looking for one that wont kill my repl

10:49 raek: Mec: sorry, missed the "don't" in the question...

10:50 what happens if you simply don't set any close operation?

10:50 Mec: HIDE_ON_CLOSE is default

10:51 raek: that will not shut down your repl, anyway

10:53 btw, does anyone know how to get that green/red bar in clojure-test-mode?

10:59 bsteuber: raek: only did it with clojure.test so far - which went fine

11:00 so I guess the bars only come for (is ...) forms

11:00 Mec: Is there a way to destructure the first key/val pair in a map

11:01 defn: Mec, could you give an example of the input and your desired output

11:01 raek: green red bar? got a link?

11:01 bsteuber: ,(let [[[k v]] (seq {:a 42 :b 23})] [k v])

11:01 clojurebot: [:a 42]

11:02 Mec: That, but without having to use seq

11:02 defn: bsteuber: there should be a way to destructure maps now IIRC

11:03 bsteuber: defn: oh, I thought yesterday we concluded that this just doesn't work yet

11:03 but I'm always happy about new information :)

11:03 defn: bsteuber: i think we did too, but then someone showed me an example last night with something that looks like it works

11:04 bsteuber: ic

11:04 could you recall that example?

11:04 defn: let me hunt through logs, one sec

11:06 bsteuber: ,(let [[[k v]] {:a 42 :b 23}] [k v])

11:06 clojurebot: java.lang.UnsupportedOperationException: nth not supported on this type: PersistentArrayMap

11:06 Mec: too obvious ;p

11:07 bsteuber: :)

11:08 defn: ,(let [{a 1, b 2} '(1 2 3 4)] [a b])

11:08 clojurebot: [nil nil]

11:08 defn: try that in your 1.2.0-master-SNAPSHOT repl

11:08 it yields a different result

11:08 ,(let [{a 1, b 2} (take 4 (iterate inc 1))] [a b])

11:08 clojurebot: [nil nil]

11:08 defn: that one also

11:09 bsteuber: but that's the different thing: map destructuring on seqs

11:09 defn: yeah, sorry -- that's where the topic came up so I thought it might be relevant

11:09 the fact it didnt work in 1.1 but now works in 1.2 was interesting

11:10 i think in just the last couple of days rich committed something

11:10 bsteuber: i see

11:10 raek: defn: http://vimeo.com/9350864

11:23 defn: bsteuber: http://github.com/richhickey/clojure/commit/29389970bcd41998359681d9a4a20ee391a1e07c

11:24 #map #destructure #source #core http://github.com/richhickey/clojure/commit/29389970bcd41998359681d9a4a20ee391a1e07c

11:24 (sorry, im parsing clojure irc and want to start tagging things I care about :)

11:28 Chousuke: defn: The way I understand it, that commits allows you to do keyword arguments like (foo 1 2 :op -) as (fn foo [a b & {op :op}] ..)

11:29 defn: Chousuke: brief digression, something not easy to google... could you please explain what - is?

11:29 Chousuke: the - function

11:29 defn: what is that?

11:29 ,(doc -)

11:29 clojurebot: "([x] [x y] [x y & more]); If no ys are supplied, returns the negation of x, else subtracts the ys from x and returns the result."

11:29 Chousuke: just the - function

11:29 not special syntax or anything, just the argument

11:29 defn: ,(- true)

11:29 clojurebot: java.lang.ClassCastException: java.lang.Boolean cannot be cast to java.lang.Number

11:30 defn: ,(- 1)

11:30 clojurebot: -1

11:30 defn: ahhh

11:30 Chousuke: the foo function in this case would take two positional arguments and one keyword argument (:op, bound to op in the function)

11:30 defn: ,(- -1 -1 1)

11:30 clojurebot: -1

11:32 Chousuke: you can do things like (fn f [& {:keys [init op] :or {:init 0 :op +}}] and call (f :init 1 :op conj)

11:32 defn: that's going to take me a minute to parse, let me see here

11:32 Chousuke: basically just ordinary map destructuring, but instead of having to pass an actual map, the map is constructed from the rest args by applying hash-map on them

11:33 compare with:

11:33 ,(let [{:keys [a b]} {:a 1 :b 2}] [b a])

11:33 clojurebot: [2 1]

11:34 defn: wow i am having trouble with this, heh

11:34 Mec: SUCCESS!

11:34 Chousuke: but now I need to go off for a moment

11:34 defn: Chousuke: thank you for those examples, ill study them and hopefully in the next 20min have a eureka moment :)

11:35 Chousuke: defn: map destructuring looks a bit weird a first, but it's not that difficult once you find out the right way to think about them :D

11:35 defn: Chousuke: *nod* -- ill get there -- baby steps!

11:36 Chousuke: the new syntax just allows a special kind of destructuring of rest args that are key-value pairs

11:37 essentially giving you keyword arguments

11:40 bsteuber: defn: My memory is like Chousuke's

11:40 Mec: Is there anything to use if I want to map over a seq but I dont care about the return

11:40 bsteuber: ,(doc doseq)

11:40 clojurebot: "([seq-exprs & body]); Repeatedly executes body (presumably for side-effects) with bindings and filtering as provided by \"for\". Does not retain the head of the sequence. Returns nil."

11:41 Mec: oo thanks

11:41 bsteuber: Mec: well, dosew is not exactly like map

11:41 Mec: So that works just like for?

11:41 bsteuber: *doseq

11:41 yeah

11:41 like for

11:43 Mec: does doseq have implicit do?

11:45 defn: Mec: yes

11:45 ,source doseq

11:45 clojurebot: java.lang.Exception: Can't take value of a macro: #'clojure.contrib.repl-utils/source

11:45 defn: clojurebot: source doseq

11:46 line 2141

11:51 God I want to go to the pragmatic studio course with Rich and Stuart

11:52 I cannot afford 1500$, but I'm thinking about pawning some things and going without basic necessities for a couple of weeks to make it happen...

11:58 raek: hrm, in what situations does one need doall instead of dorun?

11:58 i.e., in what situations does one need the whole seq to reside in memory at one time?

11:59 technomancy: raek: when you care about return value

11:59 vs just side-effects

12:01 raek: ah, yes... doall returns the whole seq

12:01 juanno: Hi, I had some problems with managing state in a larger gui application and was thinking of a macrobased class system which is inspired by OOP but meant and focussed on GUI and on separating functional logic from imperative state mutation. At the moment it is not very practical but I'm working on it but before I do that I wanted to ask you if there already is a better solution for managing state in a larger ui application except for strong

12:01 disciplin just using datastructures?

12:02 Mec: map->jtree (no selection listener yet) http://gist.github.com/345693

12:03 juanno: I planned on defining actions instead of methods where you can specify a logic and a ui-actor. The first one mutates a logical state map, whereas the second one get the logical state map and an ui state map.

12:04 chouser: juanno: have you looked at dgraph? I don't know if it's a solution for you but it's in the same problem space.

12:05 http://github.com/gcv/dgraph

12:11 juanno: I'm not sure if I really understand it. It seems to address the problem if an input action is dependand of the state of another GUI object. But what if the input action is dependand on a previous input action, is that what the stores values are good for?

12:17 patrkris: has anyone here experienced that Vim hangs when trying to invoke run-jetty from ring.adapter.jetty in the VimClojure REPL?

12:23 ok, wasn't only the REPL in VimClojure apparently - also a REPL started with `lein repl`

12:25 technomancy: patrkris: try (.start (Thread. run-jetty))

12:25 as long as you don't need to stop it later

12:26 patrkris: technomancy: i'll give it at try - but what if I need to stop it later? Any suggestions?

12:27 technomancy: not sure how jetty does that

12:29 patrkris: technomancy: in any case, you suggestion worked - thanks

12:36 juanno: chouser: I'm trying to understand the concept of dgraph. Maybe you can have a look at an example of my attempt(even if it is not practical) and tell me if it's really the same problem? http://juanno.pastebin.com/7cu1470D

12:36 well, I don't know if my example is understandable.

12:41 chouser: juanno: in your example, the widgets themselves store the cononical value for their state, right?

12:44 while dgraph wants to be in charge of computing the canonical state and triggering the copying of that state into the UI

12:46 So ... My guess is that your lib and dgraph are mostly orthogonal. One could have a ui-class request that looks up a node in the dgraph, and a dgraph computed noe that triggers a ui-class action

12:46 I think. :-)

12:48 juanno: chouser: the "logic" is a function which takes an implicit state argument map and returns this map. In this map there's the list(as a string) of prime numbers, so the object stores the computed list before it's getting printed. state is also an implicit argument for the actors. So the "action" specifies a logic and an actor or just an actor which get executed, the logic stores the funtionally computed value in the state map and the actor uses

12:48 it in an imperative way.

12:49 (I know that actor is not a good name for it)

12:55 phren0logy: quick question: how come in the repl I can do (.toUpperCase "hello"), but I can't do (map .toUpperCase my-list-of-words)? I get an error that .toUpperCase can't be found in this context.

12:57 The-Kenny: phren0logy: java-function aren't first-class clojure functions

12:57 try (map #(.toUpperCase %) your-list)

12:58 # is the reader macro for a anonymous function, % stands for the first argument

12:58 (# is one way to do this, the more explicit fn is also available)

13:01 phren0logy: OK thanks

13:05 juanno: another question: where do I get news about useful librarys like dgraph? is there any blog you can recommend or something like that? Should I follow the newsgroup for that or what should I do?

13:09 brian__: test

13:11 hi, anybody know mongo here? I'm calling it in clojure, when I try to load a document com.mongodb.MongoException$Network: can't say something ?

13:11 i don't know if its clojure or mongo, or something else

13:12 The-Kenny: brian__: Sounds like a network problem... but I'm not very experiences with mongo

13:13 Bozhidar: juanno: try http://disclojure.org/

13:13 Nathell: hello all

13:14 does anybody have a clue why the following might happen?

13:14 foo> (class kernel-link)

13:14 com.wolfram.jlink.WrappedKernelLink

13:14 foo> (instance? com.wolfram.jlink.WrappedKernelLink kernel-link)

13:14 false

13:14 foo> (= (class kernel-link) com.wolfram.jlink.WrappedKernelLink)

13:14 false

13:20 Mec: I think im finally done with map->jtree now that it has listener support. Anyone mind looking it over and seeing if it can be idiomized? It's rather imperative but I dont think that can be helped. http://gist.github.com/345693

13:36 Chousuke: Mec: Looks okay to me. The with-* naming convention is used for macros that create a context. I think you should just name it add-listener or something. Also, if you only have one branch in your if (the (if sub-nodes...) code), you should use when instead.

13:36 amatos: Is there any function in the standard library that creates map from 2 sequences, one sequence with the keys, another with the values? It is pretty straightforward to implement, but I was wondering if there is already something like that, since it seems pretty useful. I couldn't find anything like that in the API docs....

13:37 Chousuke: zipmap

13:37 Mec: chouser: ok, thanks

13:37 amatos: Chousuke, thanks, exactly what I was looking for! Wonder why I didn't see it before. Thanks

14:48 konr: I've got a nested structure that's sorta like a tree, something like {1 {:foo [1 2 3 4 5] :bar [6 7 8 9]} 2 {:bak [1 3 5] :fak [2 4 6]}}. Is there a function that updates elements with a function based on the depth of the element? Something like (my-func 3 inc struct) -> {1 :foo [2 3 4 5 6] ...

14:56 raek: konr: maybe you could solve it with assoc-in

14:57 ,(update-in {:foo {:bar {:baz [1 2 3 4]}}} #(map inc %))

14:57 clojurebot: java.lang.IllegalArgumentException: Wrong number of args passed to: core$update-in

14:57 raek: ,(update-in {:foo {:bar {:baz [1 2 3 4]}}} [:foo :bar :baz] #(map inc %))

14:57 clojurebot: {:foo {:bar {:baz (2 3 4 5)}}}

14:57 raek: ...or update-in

14:58 the assoc/(dissoc)/update/get-in family makes "editing" deep into structures simple

14:59 konr: hmmm, update-in requires the exact sequence of keys to the desired element :(

14:59 raek: ,(assoc-in {:foo [1 2 3]} [:foo 2] 4)

14:59 clojurebot: {:foo [1 2 4]}

14:59 raek: (also works with indicies)

15:00 maybe zippers could be useful

15:00 http://richhickey.github.com/clojure/clojure.zip-api.html

15:00 konr: Interesting! I'll check them out. Thanks!

15:00 raek: hmm, not much examples there...

15:00 http://clojure.org/other_libraries

15:01 there are some good examples

15:03 maybe c.c.walk can be user too http://richhickey.github.com/clojure/clojure.walk-api.html

15:04 *used

15:09 alexyk: hey guys -- I need to map a bunch of strings to ints. E.g. states like "NH" and cities like "Piscataway". Each class of strings maps onto its own integer sequence. Clearly there would be a "static" counter and an "add" method in an object; in clojure, how would one store the counter separately for each class but encapsulated somehow?

15:10 I need a "create-sequence" function which would return a map-string function and create the implicit counter for each class

15:12 i.e., how do we do closures in clojure?)

15:14 leifw: I have a function that parses an xml file, and returns a data structure of my own devising, part of which is generated by calling another function on some xml element. This second function is costly, and there are many calls to it for the whole file, so I would like to, instead of calling it to create the structure, instead place in that location a lazy call to it, in the haskell sense, so that it will be replaced with that function

15:14 call's value when it is evaluated

15:14 is there an easy way to do this aside from leaving a closure in the data structure and replacing it later?

15:14 I would also like to have some parallelism in these thunks if possible

15:23 The-Kenny: leifw: Maybe just put it in a future?

15:23 That would compute the value in another thread, and if you try to access it, it blocks until the function is finished. If it's finished, it just returns

15:26 raek: alexyk: (defn make-counter (let [counter (atom 0)] (fn [] (swap! counter inc) counter)))

15:27 (defn make-counter [] (let [counter (atom 0)] (fn [] (swap! counter inc) (deref counter))))

15:27 forgot arg list and to deref the atom...

15:28 (def c (make-counter))

15:28 (c) => 1, (c) => 2, ...

15:29 Chousuke: (swap! counter inc) is actually enough

15:29 swap! returns the value swapped in

15:36 alexyk: right

15:38 leifw: "a" future?

15:38 nice

15:38 thanks

15:40 Quiark: anyone got ccw for eclipse running?

15:41 alexyk: however, in my atom there will be a map string=>int. Isn't it expensive to update the whole thing with swap!?

15:44 well, I guess, just like any map

15:44 updating

15:46 Chousuke: alexyk: whole thing? what does that mean?

15:46 it's no more expensive than ordinary use of clojure maps :)

15:47 alexyk: Chousuke: my closure encompasses a map, you give it a string, it returns an int. It may need to add teh string to the map. The map may grow huge. A swap would replace one huge map with another.

15:47 right

15:47 so kinda hope it'll be smart

15:47 Quiark: but you replace just the pointers

15:47 alexyk: as usual :)

15:47 Chousuke: alexyk: those maps will share structure

15:47 alexyk: the update operation is O(log32 n)

15:48 alexyk: ie. very fast :P

15:48 alexyk: right, so you're saying it's no more expensive than a regular (let [m (assoc m k v)]...)

15:48 the swap I mean

15:48 Chousuke: right.

15:48 unless there is contention on the atom, in which case it might have to retry a couple times

15:49 but that's not usually a big deal :)

15:49 alexyk: right

15:51 leifw: hmm, looks like the future is spawning a new thread to do the computation immediately

15:51 this doesn't solve my problem, which was heap space explosion

15:51 is there something like futures that are truly lazy?

15:52 Chousuke: delay

15:52 though thay need to be explicitly dereferenced

15:52 leifw: ok

15:52 thanks

15:52 Chousuke: and remember, that delays might hold references to data and cause a heap explosion by preventing GC

15:52 alexyk: leifw: I didn't fully read your problem, but in lisps code is data -- you can store the functions and then somehow execute them when fetched as needed, I'd wildly speculate :)

15:53 leifw: alexyk: yeah, I was just hoping for an existing solution rather than trying to swap out closures for data in a thread-safe manner

15:53 Chousuke: ok, I'll keep that in mind

15:54 chouser: interesting that we don't have an 'invoke' fn.

15:54 alexyk: yeah, where's perl's eval?

15:55 raek: hrm, can someone point me to where I can read about the useage of ;, ;; and ;;;

15:55 Chousuke: (doc eval) :P

15:55 clojurebot: DENIED

15:55 Chousuke: oh damn

15:55 lithpr: yeah, clojure needs more perl mixed in

15:55 Chousuke: raek: ; end-of-line comments, ;; for commenting in the middle of code, and ;;; for top-level comments (function docs etc)

15:56 alexyk: ,(doc inc)

15:56 clojurebot: "([x]); Returns a number one greater than num."

15:56 alexyk: (doc eval)

15:56 clojurebot: DENIED

15:56 Chousuke: it doesn't like the symbol eval :P

15:56 alexyk: ,(doc eval)

15:56 clojurebot: DENIED

15:56 alexyk: hmm

15:57 ,(doc hiredman(

15:57 clojurebot: EOF while reading

15:57 Chousuke: ,(find-doc "eval")

15:57 clojurebot: ------------------------- dk.bestinclass.clojureql.util/quasiquote ([form]) Macro Quote the supplied form as quote does, but evaluate unquoted parts. Example: (let [x 5] (quasiquote (+ ~x 6))) => (+ 5 6) ------------------------- dk.bestinclass.clojureql.util/self-eval? ([obj]) Check whether the given form is self-evaluating. ------------------------- clojure.contrib.fcase/fcase ([compare-fn case-value & test-expr-clauses]

15:57 alexyk: ,(doc hiredman)

15:57 clojurebot: I don't understand.

15:57 leifw: mmm, delay/force worked beautifully

15:57 thanks

15:57 Chousuke: oh, clojureql is available...

15:57 hmmmm

16:28 raek: is there a simple way of doing "update" (as in update-in, but with only one key)?

16:28 except for (assoc m :foo (f (:foo m)))

16:41 _mst: defn: good news about the speedup. Nodded off, sorry :)

16:58 alexyk: say I have a struct which is a strict subset of another struct. Is there a simple way to pick the one from another?

17:05 raek: ,(let [struct-foo {:a 1, :b 2, :x 3, :y 4} struct-bar {:x 5, :y 6}] (select-keys struct-foo (keys struct-bar)))

17:05 clojurebot: {:y 4, :x 3}

17:06 underdev: ,(def #^{:doc "val of x"} x 15)

17:06 clojurebot: DENIED

17:06 raek: select-keys returns a subset of the entries of a map

17:06 underdev: maybe it's my mouthwash?

17:07 ,(def x 6)

17:07 clojurebot: DENIED

17:07 underdev: huh.

17:07 raek: alexyk: does (select-keys struct-foo (keys struct-bar)) solve your problem?

17:07 The-Kenny: def'ing is not possible in clojurebot

17:08 underdev: oic

17:09 did clojure lose the ability to attach metadata to symbols in 1.2?

17:10 no, it must not have

17:10 alexyk: raek: indeed it does! struct-foo is a wider value, instead of struct-bar I say (struct bar) for it doesn't exist yet

17:10 underdev: hnmnnnnn

17:11 polypus: (defmacro defmodule [name params & body]

17:11 `(defn ~name ~params

17:11 (let ~(vec (apply concat (for [p params] [p 8])))

17:11 ~@body)))

17:11 alexyk: did anybody build clojure-contrib-1.2-master-SNAPSHOT from git checkout with maven? My complained that clojure-1.2-...same is not installed, although I did install it right before with maven.

17:11 polypus: (defmodule foo [a b] (* a b))

17:11 (foo 2 3)

17:11 always evaluates to 6

17:11 i'd like it to evaluate to 64

17:13 raek: underdev: do you quote the symbol?

17:13 polypus: the macro expansion looks like: (clojure.core/defn foo [a b] (clojure.core/let [a 8 b 8] (* a b)))

17:14 underdev: oic (meta #'x)

17:14 raek: ty

17:15 raek: also: #^{:foo "bar} 'baz attaches metadata to the (quote bar) form

17:15 *(quote baz)

17:15 IIRC

17:16 underdev: that gives you the metadata of the var named x

17:17 (meta (var x))

17:17 ,(meta inc)

17:17 clojurebot: nil

17:18 raek: ,(meta #'inc)

17:18 clojurebot: {:ns #<Namespace clojure.core>, :name inc, :file "clojure/core.clj", :line 640, :arglists ([x]), :inline #<core$inc__4504 clojure.core$inc__4504@e522a0>, :doc "Returns a number one greater than num."}

17:18 raek: ,(meta (with-meta 'inc) {:foo "bar"})

17:18 clojurebot: java.lang.IllegalArgumentException: Wrong number of args passed to: core$with-meta

17:18 raek: ,(meta (with-meta 'inc {:foo "bar"}))

17:18 clojurebot: {:foo "bar"}

17:18 underdev: raek: i'm not correcting you, i am trying to understand, is the metadata on the var x, or the symbol x?

17:18 raek: both, can have metadata

17:18 underdev: oic

17:19 raek: the metadata on the var is probably the most interesting

17:19 the #^{...} reader syntax attaches metadata to the form after it

17:19 i.e. the symbol

17:19 that metadata is seen by the compiler

17:19 underdev: rt, that's what i'm trying to attach the metadata to (in this expeririment

17:20 raek: but the symbol is resolved into a value, and the metadata for the symbols is not copied to the value

17:20 you can attach metadata in eval-time with "with-meta"

17:21 underdev: okay, i'll look that up

17:21 raek: (with-meta 'foo {...metadata...}) attaches metadata to a symbol

17:21 chouser: at runtime. :-)

17:22 underdev: i like kitties. kitties purr.

17:22 <sigh>, okay, i don't even understand it enough to mess around with it

17:23 raek: (with-meta [:kitty-1 :kitty-2 :kitty-3] {:trivia "liked by underdev"})

17:23 underdev: thanx rael

17:23 raek

17:25 raek: so (possibly repeating myself), metadata can be attached to data structures (maps, vectors, etc), symbols (hints to the compiler), and vars (docstring etc)

17:25 (actually, anything that implements IMeta)

17:26 chouser: anything that implementes IMeta can report metadata, but may not have a way to change it.

17:27 reference types support changing their metadata using 'alter-meta!'

17:28 value types that implement IObj support persitent "updates" of their metadata via 'with-meta' and 'vary-meta'

17:30 alexyk: raek: after select-keys, can the map be blessed somehow at once to become a struct?

17:31 underdev: thanks guys, i've copied all that down as i go back to read more about the topic

17:32 alexyk: raek: so where is your bahnhof? :)

17:32 polypus: macro Q: http://paste.lisp.org/display/96969

17:33 raek: alexyk: 1) you can always do a (into (empty struct-object) (select-keys struct-object ...keys...))

17:33 polypus: forget it. figured it out

17:33 raek: alexyk: 2) Linköping :)

17:35 alexyk: I checked in the source for select-keys. it always returns a hash-map

17:36 maybe "(loop [ret {} keys (seq keyseq)]" shoulde be changed to "(loop [ret (empty map) keys (seq keyseq)]"

17:36 alexyk: raek: interesting!

17:37 raek: love town names with umlauts in them :)

18:46 raek: how does error-kit/raise work inside a transaction?

18:47 if I have a handler outside the transaction, will it revert correctly?

18:50 hrm, looking in the source

18:51 seems that raise will throw a java exception in order to "jump back" to the handler

18:51 thus, the transaction should be droped

18:57 chouser: raek: sounds right

19:03 raek: chouser: great job with error-kit, btw!

19:05 chouser: ah, thanks. Are you doing any clever error-handling, or just basic throw-catch kinda stuff?

19:06 raek: just basic throw-catch

19:07 chouser: ok. hardly anybody ever uses more than that. Did you look at clojure.contrib.condition?

19:07 raek: hrm, no. haven't looked at that

19:08 reading the mail thread now

19:12 interesting...

19:12 chouser: would you recommend using that instead?

19:13 it seems to have everything I need in my case

19:15 btw, are there any more try-catch libs I should know about, more than error-kit, condition and except?

19:16 defn: chouser: ive had this answered by a couple people but i just wanted to be sure im not missing something: is it possible to do destructuring on a map?

19:16 (without seq'ing on it)

19:17 i think i misunderstood a recent commit

19:18 _ato: ,(let [{f :foo, b :bar} {:foo 1, :bar 2}] f)

19:18 clojurebot: 1

19:18 dnolen: defn: it's been possible to destructure a map for a long time now. the commit is really about making it easy to define functions which take optional parameters

19:19 optional keyword parameters rather

19:19 _ato: ,(let [{:keys [foo bar]} {:foo 1, :bar 2}] foo)

19:19 clojurebot: 1

19:19 _ato: ^ very handy shorthand form

19:19 (well shorted when you have more keys anyway ;-)

19:20 raek: ,(let [[& {foo :a, bar 1}] {:a 2}] [foo bar])

19:20 clojurebot: [nil nil]

19:20 raek: ,(let [[& {foo :a, bar 1}] [:a 2] [foo bar])

19:20 clojurebot: Unmatched delimiter: )

19:20 raek: ,(let [[& {foo :a, bar 1}] [:a 2]] [foo bar])

19:20 clojurebot: [nil nil]

19:20 defn: cool thanks

19:22 raek: the thing that is (possibly) about to change is the behaviour of & {...} when passed a vector

19:22 instead of doing destructuring on the indices of the vector, apply hash-map on it and do destructuring on that

19:23 have I understood this right??

19:38 how should test namespaces be organized when using clojure-test-mode for emacs and a leiningen project directory layout?

19:40 for example, if I have foo.bar.x in src/foo/bar/x.cl, where should the test cases for that namespace go?

19:41 _ato: test/foo/bar/test/x.clj if I remember correctly

19:42 so test version of the namespace is foo.bar.test.x

19:43 raek: ah, an extra "test" segment to make sure namespaces of tests and implementations have different names?

19:43 _ato: thanks!

20:51 leifw: ok, I am really getting sick of this error: I'm trying to use slime with swank-clojure. I've installed clojure-1.2.0 from git, along with clojure-contrib, and both these jars are in ~/.clojure. I've also installed swank-clojure (and slime and slime-repl) from the ELPA. When I run M-x slime, it says it cannot find swank/swank__init.class or swank/swank.clj on the classpath

20:52 I was assuming that the elpa install would set these correctly, but that seems not to be the case. I also saw something that made it seem as though CLASSPATH was not dynamically editable, which I suppose means that maybe I have to start emacs with CLASSPATH set to include the path where it was installed?

20:53 is there a way I can just compile the jar and drop it in .swank-clojure?

20:56 raek: I think that ELPA is supposed to be able to do this correctly

20:58 however, I have no idea how the internal machinery in all this actually works...

20:59 leifw: what does your .emacs look like?

21:02 I have the path to swank set in mine

21:03 leifw: here is mine: http://gist.github.com/346470

21:04 "~/Projekt" is where I keep my clones of people's git repositories...

21:05 leifw: ok cool, thanks

21:27 alexyk: how do you add/remove an element to a set #{} ?

21:29 _ato: ,(conj #{} :a)

21:29 clojurebot: #{:a}

21:29 _ato: ,(disj #{:a} :a)

21:29 clojurebot: #{}

21:29 _ato: alexyk: ^

21:30 alexyk: cool. I grepped Stu's book to naught. What's a general way to doscover methods which work on a datastructure?

21:30 could reflection or grepping of docs tell me that?

21:31 talios: hrm

21:32 * talios must set up auto-ident on this client. No wonder I couldn't talk.

21:34 _ato: alexyk: not generally -- due to the dynamic typing there's no way to know programmatically what will work on a particular data type. However, for stuff in clojure.core, if you haven't seen it before, this is very handy: http://clojure.org/cheatsheet

21:34 alexyk: ah ok, thx

21:36 keeping state: so far, I found closures, with constructors returning maps with fn's. Then calls look like ((closure :fn-key) fn-params). Are there any better-looking ways? Or would just have to define a macro?

21:37 dnolen: alexky: creating closures to maintain state is generally not encouraged. putting fn's in maps is also not encouraged. why not just use the reference types?

21:40 alexyk: dnolen: how do you use a ref type to have a map of string to ints, which has a method for a string to return an int, possibly adding it to the map with the next integer from 0?

21:40 phren0logy: b vvvvvvv

21:40 leifw: raek: which swank-clojure did you clone?

21:40 phren0logy: oops, cat on the keyboard. sorry.

21:41 leifw: mine doesn't have src/main/clojure, only src/swank

21:42 Drakeson: with (deftype foo [a] :as this Runnable (run [] (???) "foo")), how can I set (:a this) to a value (mutate the instance)?

21:43 _ato: alexyk: so you have a map of strings to ints and when you access an entry that is missing you want to autoincrement a new int value and add it to the map?

21:43 alexyk: dnolen: do you mean ref as reference type?

21:43 _ato: yep

21:44 _ato: hmm... I guess one way would be to have the map in an atom (or ref if you need transactions), attach metadata to the map of the last int value

21:46 talios: mmm, could you use an agent which stores the map with a count metadata, send it a function to increment/store?

21:46 * talios needs to learn more on agent foo

21:48 talios: from what I know of agents, one thing that's always irked me is that it seems you can send -any- function to an agent, which could be nasty. Would be nice to have some form of pre-condition on the agent which lists acceptable functions (almost like a protocol/interface for the agent)

21:48 alexyk: _ato: that's what I did, http://paste.pocoo.org/show/194683/, but dnolen sternly admonishes me :)

21:49 show me how to do it without a closure and mapped fn's

21:51 ...or forever keep your peace :)

21:51 dnolen: alexky: checking it out

21:51 alexyk: kk

21:53 usage: (def m (make-mapper)) ((m :map) "a") ((m :map "b") ((m :map) "a") ((m :get-map))

21:56 _ato: this is the way the occurred to me: http://gist.github.com/346494

21:57 I don't know whether that's any better/worse

21:58 actually, if it's just based on the count

21:58 you could just use (count) instead of metadata

22:01 alexyk: interesting

22:01 dnolen: alexky: this is really short

22:01 http://gist.github.com/346500

22:01 I think it does what you want

22:03 _mst: do the numbers have to be sequentially assigned? Or just unique?

22:03 (.hashCode "mystring") for the smartass response :)

22:08 ... I'll get my coat

22:10 _ato: let me be the first to say, hash collisions!

22:10 JonSmith: do a sorted map

22:10 or wait

22:10 maybe not

22:10 depends on the use case

22:11 what is being done with it?

22:21 _mst: OK OK, maybe not .hashCode then :) But some other fangled hash function involving multiplication by primes and stuff like that :)

22:30 alexyk: _mst: sequentially

22:31 _mst: aw :)

22:34 alexyk: dnolen: short indeed... but closure encapsulates m and I can do whatever to it. Why is it discouraged?

22:34 basically it's a hand-made OO.

22:35 the only thing missing is Perl's ugly syntax! $ref->{oo}

23:42 DeusExPikachu: is there any form of global configuration for leiningen?

Logging service provided by n01se.net