#clojure log - Aug 22 2010

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

0:01 trptcolin: ah, throwing an exception in the thread: java.lang.IllegalStateException: Can't change/establish root binding of: *ns* with set

0:14 technomancy: ihodes: do you mean to say the repl task doesn't work at all?

0:14 inside or outside a project?

0:14 git master or lein stable 1.3.0?

0:18 trptcolin: I'm thinking we could get rid of eval-without-project and just call clojure.main/repl directly

0:18 there's also the question of whether lein repl should attempt to mimic the args of clojure.main's repl

0:18 haven't thought that through very thoroughly yet

0:19 trptcolin: wouldn't calling clojure.main/repl directly circumvent the new port-listening feature?

0:20 technomancy: oh, of course

0:20 so it could just eval the server form instead of using eval-in-project

0:21 trptcolin: right, and that was my first attempt, thwarted so far by the need for doing some binding magic with *ns* so it can be changed... not sure how to get around that

0:30 technomancy: we could still accept as much as we can of the same args as clojure.main/repl and simply pass them through

0:30 ihodes: technomancy: no, REPL works. what i've done is clone the git repo, and i'd like to be able to test my changes made there. should i compile/make a jar file and then call my hacked on version of lein with the shell script, or perhaps another way? i'm trying to figure out how you'd test changes you make to lein, as I can't test the REPL from slime/swank

0:31 technomancy: since lein repl used to be just a wrapper around clojure.main/repl, it used to do this by accident, and some people asked why it stopped working

0:31 trptcolin: yeah, that seems like a good idea.

0:31 technomancy: ihodes: you can run lein straight from the checkout; there's no need to "build" it other than just getting lein's lib/ dir populated

0:33 trptcolin: technomancy: i need to bail for the night, but yeah, having it mirror/call through to clojure.main/repl seems like the way to go. seems like it takes care of the ns-binding issues internally

0:33 technomancy: well, I'm headed off; let me know how the hacking goes.

0:33 trptcolin: :)

0:33 technomancy: thanks for your help

0:34 trptcolin: thanks for yours :) it's great to hack on a project with a helpful & available leader

1:27 Bahman: Hi all!

1:47 chouser: Bahman: hi!

1:47 Bahman: Hello chouser!

2:32 wooby: http://gist.github.com/543427 - anybody know why this doesn't work the way a fool like i would suspect?

2:40 dsantiago: You're trying to invoke a symbol like it's a function.

2:40 What that does is try to look up itself in its argument.

2:41 For example, ('Class {'Class 2}) -> 2.

2:58 wooby: dsantiago: thanks, i see

2:58 more generally i'm looking for a way to generate a method call

2:59 dulanov: try to use defmacro

2:59 dsantiago: Yeah, you want a macro.

2:59 wooby: i am, but i hit a wall... it only works with literal arguments

3:00 it works also with def'd arguments because i eval what gets passed in, but that doesn't work with locals

3:02 http://gist.github.com/543427 updated with a new shenanigan

3:04 dsantiago: (defmacro abc [x] (let [m (symbol (str ".get" x))] `(~m (Object.))))

3:04 clojurebot: slime-install is an automated elisp install script at http://github.com/technomancy/emacs-starter-kit/blob/2b7678e9a331d243bf32cd8b591f826739dad2d9/starter-kit-lisp.el#-72

3:05 dsantiago: Then you can do (abc Class)

3:06 Chousuke: wooby: macros can't work with nonliteral arguments. You can't store the method name in a runtime variable.

3:08 * wooby gets to work on first class macro support

3:09 wooby: thanks Chousuke

3:09 and dsantiago

3:10 Chousuke: you can generate reflective code from a macro though if you need to be able to figure out the method at runtime

3:10 wooby: i think that's what i should do

3:11 hm

3:11 well i know what the method should be, i just need a good way of generating it and calling it

3:13 anyways, bedtime for me, thanks for the help folks

3:31 LauJensen: Good morning all

4:42 defn: morning

5:03 LauJensen: I dont think I quite understand this Last Var Win approach to clashes. I have a situation now where I initialize a namespace and several warnings are given that libs are overlapping. Then if I have changed one of my (:use imports) I re-eval the (ns) declaration, which now instead of warning me, throws an exception which is only resolvable by restarting the repl

5:15 noidi: I'm getting an exception when realizing a lazy seq. The problem is the stack trace only shows the fn that realizes the seq, and the fn is a common helper so I have no idea where the seq might have been created.

5:16 any idea how to find out where the buggy seq was created (other than going through the source checking all calls to the realizing fn)?

5:19 hoeck: noidi: in slime, one can throw or expand the nested exceptions and so maybe find the fn that caused the real trouble

5:20 noidi: other IDEs should provide that too

5:21 noidi: I'm getting the error during compilation, and mvn clojure:swank compiles before launching swank so I can't get to slime

5:21 on the bright side that narrows down the calls to the fn quite a bit

5:21 LauJensen: paste the code + backtrace?

5:22 noidi: it would be nice if Clojure printed something like "Caused by realizing a lazy seq at somefile.clj:123" after the stack trace

5:22 LauJensen: yea that would be fantastic

5:22 Its actually a little odd that Rich has given more priority to backtraces yet

5:22 s/has/hasnt/

5:22 sexpbot: Its actually a little odd that Rich hasnt given more priority to backtraces yet

5:22 noidi: that should be quite doable with metadata

5:23 LauJensen, I can't, this is for work, but thanks

5:23 LauJensen: k

5:24 noidi: this is bordering on ironic, the seq is realized in a precondition that I wrote just to avoid digging through pages of stack traces :)

5:24 LauJensen: hehe

5:24 the only sure winner is printlines

5:25 hoeck: isn't that just as easy as (doseq [x (take-while identity (iterate #(.getCause %) <the-exception>)))] (.printStackTrace))

5:25 LauJensen: Did you see marcyks (?) 'trace all functions in an ns' trick on StackOverflow?

5:25 noidi: no

5:26 hiredman: ,(use 'clojure.stacktrace)

5:26 clojurebot: nil

5:26 hiredman: ,(doc root-cause)

5:26 clojurebot: "([tr]); Returns the last 'cause' Throwable in a chain of Throwables."

5:27 noidi: hiredman, thanks, I'll check that out

5:27 hiredman: ~google clj.stacktrace

5:27 clojurebot: First, out of 208 results is:

5:27 mmcgrana&#39;s clj-stacktrace at master - GitHub

5:27 http://github.com/mmcgrana/clj-stacktrace

5:27 noidi: I get two "Caused by" stack traces alread, doesn't that suggest that Clojure's doing that already?

5:28 LauJensen: http://stackoverflow.com/questions/3346382/clojure-adding-a-debug-trace-to-every-function-in-a-namespace

5:29 noidi: LauJensen, thanks

5:29 LauJensen: np

7:44 jcromartie: I don't think there's a link to http://clojure.org/datatypes on the left-hand side of clojure.org

7:46 Raynes: All hail multimethods.

7:47 jcromartie: are multimethods still relevant in light of deftype and defrecord?

7:48 or protocols, I suppose

7:53 LauJensen: Yea

7:53 They give you more freedom in terms of dispatching

7:56 raek: protocols are grouped and have better performance (since they integrate with the host's dispatch system), but are not as general as multimethods

8:08 I still think multimethods are a good alternative to long conds (typically value-based)

8:08 jcromartie: nownow, here's a question

8:08 the docs say "By default, pr and prn print in a way that objects can be read by the reader"

8:08 but that's definitely not true for defrecord

8:09 so what are the persistence implications for defrecord, if they can't be pr'ed

8:10 raek: there is a ticket for it: https://www.assembla.com/spaces/clojure/tickets/374-print-read-syntax-for-defrecords

8:13 jcromartie: cool

8:38 noidi: is it ok to use promises as a synchronization mechanism between threads?

8:39 I call a function in thread A that starts thread B, and I want the function to wait until B has performed it's initialization before returning from the fn.

8:40 raek: noidi: do you know about futures?

8:40 noidi: would it be bad style to create a promise b-ready and at the end of the function that starts b do a @b-ready

8:40 raek, yes

8:41 raek: (my opinion is that) it would only be bad style if it could have been done with futures

8:42 LauJensen: noidi: I think all the use cases of promises are still unchartered, but your suggestion doesn't sound offensive to me, because its a phase in the thread you're waiting for and not the entire thread

8:42 noidi: yup, in my case B is a long-running thread

8:43 and I want to make sure that when I start it in A by calling (start-b), B is really ready when the function exits

8:43 LauJensen: So you'd either end up using a promise or a global/shared switch of some kind. I would try with the promise first

8:43 noidi: ok, thanks

8:44 the reason I asked if it's bad style was that I don't really care about the value of the promise, just that it's delivered

8:44 but I'll go with the promise then

8:44 LauJensen: Well. Back in the day, thats how agents were abused, simply as a way of threading operations, which eventually made the case for futures :)

8:58 no_mind: what is drupal 7 semantics web ?

9:08 LauJensen: Its a new thing for Drupal which would enable the system to understand contexts which humans intuitively pick up (http://www.cmswire.com/cms/web-cms/call-for-feedback-on-drupal-7-semantic-web-impementation-006392.php)

9:09 Anything else you need me to google for you? :)

9:55 AWizzArd: Clojure and JNI? I have a C program which I would like to use in Clojure. This is the spell checker program “Hunspell” (used in OpenOffice, Firefox, Chrome, etc). There already IS a JNI lib for that and I use it for over a year already. But its Hunspell version is old, and also does not run on Windows64.

9:56 So I am thinking about writing some bindings to call into Hunspell. Should this better be done in pure Java?

9:57 Or are there benefits of doing JNI in Clojure?

9:57 LauJensen: AWizzArd: Didn't chouser work on clojure-jni interface? And also there was a debate on the ML regarding the naming of what used to be clj-native I think - I cant tell you if they would be preferable to Java in your situation, but I imagine they would

9:57 AWizzArd: LauJensen: I discovered that chouser did some JNA work.

9:58 LauJensen: Im not sure if chouser ever worked on anything which he actually completed, but there should be some code floating around :)

9:58 AWizzArd: I will ask him later about JNI.

9:59 LauJensen: AWizzArd: btw, doesnt look like Das Keyboard is purchable in Denmark, so its a good thing Im going to Germany before long

10:00 AWizzArd: LauJensen: yes, if you visit Germany by car, coming from Denmark/North you could make a stop in Kiel and buy one directly.

10:01 LauJensen: Kiel is very close to me, Frankfurt isnt :( I think I'll fly

10:02 AWizzArd: LauJensen: then you could ask kotarak to order one for you (from Kiel), and meet him in Frankfurt.

10:02 LauJensen: Yea that would work

10:33 raek: LauJensen: have you tried Das Keyboard yourself? If so, how was it?

10:35 * Raynes just uses an old MS ergonomic.

10:38 LauJensen: raek: No - We had a lengthy (and good) debate about keyboards last night, as Im looking to buy a new one

10:38 AWizzArd got me hooked on Das Keyboard, technomancy suggested Kinesis Advantage or ibms M.

10:43 Chousuke: Model M keyboards work great for self-defense too.

10:43 LauJensen: Chousuke: So would Das Keyboard

10:43 qbg: My Unicomp works fine

10:43 LauJensen: (its heavily inspired by Model M)

10:44 Chousuke: LauJensen: Is it equally indestructible? :P

10:44 LauJensen: Time will tell

10:44 check out their website, they promote it as a better M

11:01 AWizzArd: Well, I had a Das Keyboard and Model M, and definitly find the Das better.

11:03 LauJensen: AWizzArd: How long have u had it?

11:04 AWizzArd: I got my first Das around 2006

11:04 LauJensen: How long do they last?

11:04 AWizzArd: Didn’t find out yet :)

11:05 LauJensen: Good!

11:06 AWizzArd: The scooped keys are very nice. I can blindly put my fingers on the keys and feel how they have to be positioned to type blindly.

11:06 LauJensen: scooped?

11:08 AWizzArd: http://www.tekgear.com/PDF/scooped-key.jpg

11:08 On qwertz this is F and J, and those keys typically have a marker.

11:13 LauJensen: k, Dinovo has something like that, only its just a slim line

11:14 btw, DiNovo is worn down in max 2 years, then the keys start sounding very aged

11:14 clojurebot: maxine is http://research.sun.com/projects/maxine/

11:28 LauJensen: technomancy, Chousuke, or anybody else knowledgable with Emacs. I have M-. bound to slime-edit-definition in Clojure-mode, yet it never gives me anything other than an exception. What do you guys use to speed-jump to the definition of an fn ?

11:36 pdelgallego: is it possible to create custom task to run them with Leiningen? I mean the same way that you can create and execute rake task.

11:42 LauJensen: pdelgallego: Im not entirely sure, but I think that issue might have been one of the factors which made way for 'cake'

11:43 pdelgallego: LauJensen, you are right, I just found cake. and it looks like a rake replacement.

11:44 cake documentation explains how to create custom tasks.

11:45 it is nice that it support persistent jvm

11:46 LauJensen: Im still waiting for 1 - 2 hour of sparetime to play with it, but yea it looks very promising

12:08 hv: assume I don't care about leiningen plugins defined inside a project. Are there other reasons why I shouldn't keep an instance of clojure running and just send -e "(leiningen.core/-main args)" for each project?

12:16 gfrlog: would it be accurate to say that vars allow using dynamic scoping?

12:23 Chousuke: I suppose.

12:23 thread-isolated though.

12:24 ie. dynamic rebinding of a var does not affect its value in other threads.

12:27 gfrlog: but it does in other functions

12:36 raek: the variables are always lexically scoped, but the value can be dynamically bound

12:37 gfrlog: aah

12:40 raek: (def x 1) (defn f [] x) (let [x 2] (f))

12:40 gfrlog: that returns 2 I take it?

12:41 raek: this would return 2 if clojure would have dynamically scoped vars

12:41 exactly

12:41 (def x 1) (defn f [] x) (binding [x 2] (f))

12:41 ahem... I meant "no"

12:41 this however returns 2

12:42 the symbol x in f is resolved to user/x (the global variable)

12:42 gfrlog: oh wait

12:42 hmm

12:42 okay

12:42 raek: the let introduces a local value in in the lexical scope of the let

12:42 gfrlog: so let always creates a new var

12:43 raek: which does not include the inside of f

12:43 gfrlog: that then is the crucial difference between binding and let?

12:43 other than the order thing

12:43 raek: actually, not a var, but a local name for a value

12:44 binding rebinds the global variable to another value temporarily and thread-locally

12:44 it's like it saved the old value, sets the var to the new value and after everything in the binding form has been executed, restores the old value of the var

12:46 scoping answers the question "which var/parameter/let'ed-value?" and binding "what value?"

12:46 gfrlog: hmmm

12:46 okay

12:46 I believe good sense has been made here

12:46 thank you.

12:47 raek: also, note that the var has to exist before you can rebind it with binding

12:47 a (def x) is sufficient

12:47 gfrlog: gotcha

12:51 Bahman: Hi all!

13:04 hv: how can I add a symbol to 'clojure.core? (intern 'clojure.core '*foo* nil) and then *foo* gives me Unable to resolve symbol *foo* in this context

13:09 raek: what are you trying to do? :) (if you have to, I guess you could alway do a (in-ns 'clojure.core) and then def enything you like)

13:09 *anything

13:11 hv: raek: thanks, I think that would be the same as (intern 'clojure.core '*foo* ...). Maybe I am missing something else.

13:11 raek: user=> (intern 'clojure.core 'foo)

13:11 #'clojure.core/foo

13:11 worked for me

13:12 ah, now I see

13:12 you have to (use 'clojure.core) agter that

13:12 otherwise, the new var will not be referred

13:12 hv: well, maybe it is actually added to clojure.core. it is just that the namespace "user" does not get it.

13:13 raek: hv, yes... intern and def should be the same in that case

13:13 exactly

13:13 does clojure.core/*foo* work?

13:13 hv: yes

13:13 dnolen: hv: (refer 'clojure.core) if you want to get it into the user namespace

13:14 though I don't see why you'd want to put something clojure.core

13:14 raek: but now, why would you want to do all this? :)

13:14 hv: dnolen: because it is still missing from there :p

13:14 raek: then :use that var from another namespace until it appears in core

13:15 hv: raek: I am lazy

13:16 bartj: Hi, am trying to build a new interface for IRC logs

13:16 dnolen: hv: heh, what you're doing sounds like about the same amount of work.

13:16 raek: ...or define it in the namespace that needs it

13:16 what dnolen said...

13:17 bartj: users will tag relevant conversations with keywords (eg: clojure 1.2/ concurrency/etc) - so that users can follow relevant topics easily

13:17 do you think this would be useful ?

13:17 I find that a lot of information / my learning of Clojure was done on the IRC

13:18 what do you guys think of this ?

13:18 rhudson: Who does the tagging? When?

13:19 bartj: wiki-style -> users do the tagging

13:19 LauJensen: bartj: I think its an interesting idea to have a logreader which categories conversations based on tags, like if I said 'tag: New IRC reader' then that would become a category. If people would get behind it and support it, it could make for some sweet documentation

13:20 bartj: I have learnt so much hanging around here...

13:20 rhudson: me too

13:20 bartj: but scavenging through a lot of old logs is kinda tough

13:21 and maybe have threaded conversations too....

13:23 LauJensen, thanks!

13:27 may I ask how I can obtain the IRC logs ?

13:27 I contacted the freenode guys...and they said they didn't log anything server side

13:27 mrBliss: bartj: http://clojure-log.n01se.net/

13:28 bartj: mrBliss, yes but, how is it logged - by a client ?

13:28 mrBliss: bartj: you could write a bot

13:29 LauJensen: bartj: You could write a (pirc)bot, but why not just scrape clojure-log.n01se?

13:31 bartj: am reading the first clojure log here - http://clojure-log.n01se.net/date/2008-02-01.html

13:31 Raynes: Or, you could use Irclj. :>

13:32 bartj: and the first question in there by chouser seems so surreal to me

13:32 Raynes: LauJensen: I'll let you off with a warning this time, but the next time I see you peddling Pircbots rather than Ircljbots, I'll be forced to write you a citation.

13:32 LauJensen: Sorry, ircljbots is your wrapper on pircbot I suppose+

13:33 bartj: LauJensen, yes scraping is an option

13:34 Raynes: LauJensen: Nosir.

13:34 LauJensen: Irclj is what I wrote to avoid having to use Pircbot in sexpbot. raek also uses it.

13:34 :D

13:34 LauJensen: oh ok - whats wrong with Pircbot?

13:34 * Raynes is actually doing an overhaul on it today.

13:34 Raynes: Nothing really. I just wanted something written in Clojure. Preferably by me.

13:35 LauJensen: Raynes: Im curious, what do you do besides hacking on interesting projects?

13:35 bobo_: scary, i was reading the source of irclj, tabbed to irc and here you are talking about it

13:35 Raynes: Watch television and eat sunflower seeds.

13:35 LauJensen: bobo_: We are very well prepared

13:35 hv: is there a "with-ns"?

13:35 LauJensen: Raynes: oh

13:36 bartj: Raynes, what's the diff b/w irclj and sexpbot ?

13:36 and which would you recommend that I use.

13:36 Raynes: bartj: sexpbot is a bot that uses Irclj.

13:37 Irclj is the library that forms the basis of sexpbot.

13:38 So, if you want to write your own bot, you'd want to use Irclj.

13:39 raek: Ping me when you push. I'm going to have to take off for a couple of hours soon, so I'm going to try to get a little work done first.

13:39 bartj: Raynes, I wouldn't want to write my own bot

13:39 Raynes, just log the conversations here

13:40 Raynes: sexpbot doesn't actually have decent logging yet. However, it probably wouldn't be hard to write a quick logbot with Irclj.

13:41 bartj: Raynes, couldn't you point me to some background info/material I would need to write one ?

13:42 Raynes, *please

13:43 Raynes: Irclj's README and API docs are pretty much *it* as far as documentation goes. I also have a small example bot in the examples/ directory of the repository. I'll put a brief tutorial near the top of my TODO list.

13:44 raek: Raynes: pong!

13:44 Raynes: Weeee, codes.

13:44 Oh noes, merge conflicts.

13:44 Not quite. Local changes.

13:44 raek: could be the tabs->spaces...

13:45 anyway, here's my bot using irclj: http://raek.se/trattern.clj

13:45 the irc stuff is at the bottom

13:46 I'm only using the :on-message callback, but so far that's the only thing I have needed

13:46 Raynes: raek: Naw, it was just a little change I made after I pushed earlier.

13:47 raek: right. don't forget to set emacs to use spaces... ;)

13:47 Raynes: I already did.

13:47 I believe I had that set a while back.

13:47 I must have accidentally only set it for that session.

13:48 bartj: Raynes, raek thanks!

13:48 raek: I should create a ticket to get that cond-re macro into clojure.contrib.cond

14:03 hehe "Cake or death!"

14:29 rhickey: 'equiv' branch now merged into master, primitive args returns et al

14:33 LauJensen: Sweet!

14:34 Whats the artifact for that, still 1.2-master-snapshot?

14:45 rhickey: got artifact?

14:54 rhickey: LauJensen: no artifact

14:55 AWizzArd: rhickey: do you already have an idea what "the" main change will be in 1.3?

14:56 Pods? More Clojure in Clojure? Unboxed numbers?

14:56 LauJensen: AWizzArd: primitie args returns et al = unboxed numbers

14:57 AWizzArd: yes, I thought this could come for 1.3 as rhickey already made very substantial progress with this.

14:58 LauJensen: If its already in master I assumed it was surefire for 1.3

14:59 AWizzArd: Btw, Googles boss (Schmidt) just published some info: every 2 days now we create as much information as we did from the dawn of civilization up until 2003 - about five exabytes of data.

14:59 LauJensen: ouch

15:01 AWizzArd: He also said that he thinks that mankind is not ready for the technological revolution that is about to come soon. I guess he talks about the Singularity.

15:02 LauJensen: Really...

15:02 AWizzArd: Could also be a reference to Das Keyboard II, you never know :)

15:06 Scriptor: AWizzArd: does that include information that is copied from another source, or is it all new info?

15:07 fro0g: AWizzArd: yes, give us entropy information about the data

15:09 LauJensen: Weird: http://beust.com/weblog/2010/08/19/clojure-concurrency-and-silver-bullets/

15:32 amalloy: suppose i've defined a record as (defrecord Storage [a b]). is there a way i can construct it without having to pass its fields in order? eg (Storage. :b 1 :a 2)?

15:33 raek: amalloy: you have to make a functiion for that

15:34 records are rarely exposed to the user (at least in clojure.core)

15:34 a contructor function is very common to have

15:35 AWizzArd: amalloy: if you created a (def empty-Storage (Storage. nil nil)) then you could use into

15:35 amalloy: oh, i see. so it's stylistic/idiomatic to internally create a record, but only publicly expose a (make-myrecord) function?

15:36 AWizzArd: amalloy: in practise a factory fn is often useful

15:36 Not always you will want to really store 1:1 data in your records, but instead have some initialization.

15:37 Records may contain internal fields that the user is not supposed to touch, something like that.

15:37 * rbolkey thinks "nice, I was just about to ask this same question."

15:38 amalloy: AWizzArd: it seems like if i want information hiding i ought to use a type instead, oughtn't i? as i understand it records are usually used just as a convenient storage space

15:40 tomoj: (defrecord Foo [a]) (Foo. 1 nil {:a 2}) ; weird

15:42 AWizzArd: tomoj: yes, there are still some things that can be optimized.

15:43 for example (eval (Foo. 1)) ==> {:a 1}

15:43 Records evaluate to maps, not to themselves.

15:44 akhudek: ,(case (class 1)

15:44 java.lang.Integer :x

15:44 :y)

15:44 clojurebot: EOF while reading

15:44 akhudek: ,(case (class 1) java.lang.Integer :x :y)

15:44 clojurebot: :y

15:44 akhudek: I would have expected :x there :/

15:46 nirly: I'm trying to run an example from "programming clojure" which requires that ant.jar and ant-launcher.jar be in the class-path. I'm using clojure box and added "(setq swank-clojure-classpath (list "c:/clojure")" to my .emacs file as was suggested somewhere. The books says to run this command "(def mkdir-task (org.apache.tools.ant.taskdefs.Mkdir.))" in the REPL in order to check that the files are available. I get " [Thrown class java.l

15:46 ang.ClassNotFoundException]" when running it.

15:50 tomoj: -> (case Integer Integer 1 2)

15:50 sexpbot: java.lang.ClassCastException: clojure.lang.PersistentVector cannot be cast to clojure.lang.MapEntry

15:50 tomoj: wat

15:50 ,(case Integer Integer 1 2)

15:50 clojurebot: 2

15:55 kmc: what's a good document for getting up to speed on the Clojure-specific aspects of Clojure quickly?

15:56 say i'm already familiar with Scheme, Haskell, FP concepts in general, etc.

15:57 dnolen: kmc: Joy of Clojure ? also I think the website is pretty good.

15:57 xternal: also, it's not really a contrast document, but I think labrepl is pretty good for diving in.

15:57 kmc: what part of the website?

15:57 xternal: http://github.com/relevance/labrepl

15:58 dnolen: kmc: pretty much the entire left column

15:58 kmc: ok

15:58 thanks

15:58 :)

16:01 akhudek: huh, that case thing is odd

16:01 works everywhere else

16:01 with =

16:02 or defmulti type dispatch

16:02 dnolen: nirly: ant might not be on that path. I'm not familiar with Clojure Box, but lein can save you a lot of trouble when it comes managing your classpath

16:02 amalloy: well case is at compile time, so that's surprising in that it's a bug, but not earth-shattering

16:04 akhudek: so that *is* a bug then? not intended behaviour somehow?

16:05 tomoj: ,(case 'Integer Integer 1 2)

16:05 clojurebot: 1

16:05 amalloy: *shrug* i'm not a language designer or anything. but it seems to be surprising behavior, so if it's "intended" there's a bug in the documentation

16:06 tomoj: "The test-constants are not evaluated"

16:06 doc seems fine to me

16:07 amalloy: "They...need not be quoted"

16:07 nirly: dnolen: I tried adding the actual directory that contains the jar to the classpath as well (not sure if that's what's needed), I still get the same error.

16:07 tomoj: the quoted 'Integer there is not a test constant

16:07 akhudek: ah, I see, hm

16:07 amalloy: oh right

16:08 tomoj: it's the same as (case 'x x 1 2)

16:08 nirly: dnolen: do I need to add the jar itself to the classpath?

16:08 amalloy: nirly: that's usually the case with jars

16:08 nirly: ok i'll try

16:09 akhudek: ,(case (str (class 1)) "class java.lang.Integer" :x :y)

16:09 clojurebot: :x

16:10 tomoj: .getName to get rid of the "class "

16:10 akhudek: maybe I should just use a multimethod instead, although it's ironic because this is for a dispatch function

16:10 essentially I'm trying to group certain class pairs into catagories

16:10 and dispatch on the catagory

16:15 kmc: beginner question: i'm told clojure.contrib.complex_numbers provides complex numbers. how would i import this library in order to use it?

16:15 akhudek: (ns user (:use clojure.contrib.complex-numbers))

16:15 amalloy: from the repl, or in a package you're editing?

16:16 kmc: i'd like to edit a file, then load a repl in its namespace and poke it

16:16 akhudek: the above will import all the symbols into the "user" namespace

16:17 amalloy: (ns my-pkg (:use clojure.contrib.complex-numbers))

16:17 then from the repl (in-ns 'my-pkg)

16:18 raek: kmc: you also probably need some kind of project management system (for example Leiningen) to start a repl or swank server with the correct CLASSPATH (so that clojure can find the files for my-pkg)

16:20 amalloy: kmc: raek is right. even if you're only editing a single file and not collaborating, leiningen is very handy to have around

16:21 raek: there are some good mini-tutorials here: http://www.assembla.com/wiki/show/clojure/Getting_Started

16:21 just pick an IDE + a build tool

16:25 bobo_: dont even need an IDE, lein repl is enough if you just want a repl

16:26 tomoj: don't even need lein

16:27 bobo_: true, but then it gets annoying if you want to add deps

16:27 tomoj: indeed

16:27 bobo_: and lein is probably easier to start then just a clojure repl

16:27 rhudson: cljr is a nice middle ground

16:28 amalloy: bobo_: meh. of course i use lein, but with the clj script from clojure.contrib it's not hard to start a repl

16:30 what's the recommended way to name packages/namespaces? the java-verbose org.mydomain.myuser.myproject.core, or the conflict-prone myproject.core, or some nice compromise?

16:32 raek: I once had an idea of starting a project name register service

16:33 called something like "cljlibs"

16:33 so that one could register the project "foo"

16:33 and then use cljlibs.foo as the namespace

16:34 my compromise so far has been to use my relatively short domain: se.raek.foo

16:34 but not everyone have their own domain...

16:34 amalloy: yeah, and my domain is a bit long: org.malloys.akm (i could probly leave off akm, as nobody else in the family will use clojure ever)

16:36 raek: let me know if you ever start cljlibs, so i can snap up project names like "poker" to sell when clojure goes mainstream

16:36 raek: :)

16:37 I don't know how to handle those cases

16:37 maybe an URL to existent project page should be required

16:38 some middle ground between how things are done in clojars and maven's central repo

16:46 amalloy: i don't quite get when to use protocols. i just want to define a pluggable "strategy" function that takes certain parameters and can be passed to other functions. on the one hand, i would like to have the code reflect the expected parameters, but on the other it seems silly to declare a protocol and create new classes to do nothing but hold a single method

16:56 LauJensen: amalloy: Have you see the video Stuart Halloway did on Protocols?

16:56 amalloy: no, i haven't! where is it?

16:57 LauJensen: sec

16:57 http://vimeo.com/11236603

17:14 ssideris: hello

17:14 I have trouble running "lein swank" on windows

17:14 has anyone encountered such problems?

17:15 raek: what happens?

17:21 LauJensen: ssideris: To answer your question: Yea I think quite a few people have had that

17:27 ssideris: raek: it says: That's not a task. Use "lein help" to list all tasks.

17:27 LauJensen: any way to fix it?

17:29 raek: did you run "lein deps"?

17:29 technomancy: pdelgallego: it's very easy to create new lein tasks; see the file plugins.md that comes with leiningen

17:29 ssideris: raek: yes

17:30 raek: and add swank-clojure to project.clj?

17:30 if so, then I don't know

17:30 ssideris: yes, I did all that :-)

17:31 pdelgallego: technomancy, ok, Im going take a look. thx

17:31 technomancy: pdelgallego: basically: create a functino called leiningen.mytask/mytask

17:32 pdelgallego: if it has an argument called "project", it will be passed the current project; otherwise it will be runnable outside projects. the rest of the args are just the command-line args that are passed in.

17:33 pdelgallego: there's no difference between your custom tasks inside src/leiningen/mytask.clj and the built-in tasks, so you can look at the build-in ones as an example, or the plugins on http://wiki.github.com/technomancy/leiningen/plugins

17:33 * technomancy goes outside and builds a fence

17:34 technomancy: (not a metaphor)

17:34 pdelgallego: technomancy, I see.

17:36 ssideris: is there any other way to run swank apart from "lein swank"?

17:40 amalloy: for what it's worth, on my linux box, lein swank resolves into the following command line. you may be able to get it working by replacing the pathnames as appropriate

17:40 java-Xbootclasspath/a:/home/akm/.m2/repository/org/clojure/clojure/1.2.0/clojure-1.2.0.jar-client-cp/home/akm/.m2/repository/leiningen/leiningen/1.3.0/leiningen-1.3.0-standalone.jar::lib/dev/swank-clojure-1.2.0.jar::src/:-Dleiningen.version=1.3.0clojure.main-e(use 'leiningen.core)(-main)/dev/nullswank

17:41 hrm, the spaces all seem to have been stripped

17:42 raek: ssideris: lein repl, (use '[swank.swank :only [start-repl]]) (start-repl 4005 "localhost")

17:43 sunkencityryleh: Is there some variant of foldk

17:43 whoops.

17:44 is there some variant of inject/foldl or what it can be called that can operate on several lists at once?

17:46 right now I zip them together first with (mapcat #(list [%1 %2] ... and then use apply when i iterate on the list

17:46 amalloy: not built-in, i think, but should be easy to write. what usage did you have in mind?

17:47 sunkencityryleh: this is the scenario

17:47 raek: ,(map vector [1 2 3 4] [5 6 7 8]) ; map can take arguments from multiple sequences

17:47 clojurebot: ([1 5] [2 6] [3 7] [4 8])

17:47 sunkencityryleh: (map last (drop-while #(apply = %) (mapcat #(list [%1 %2]) "FOOFOO" "FOOBAR")))

17:48 I want to strip off the things that are similar in the beginning

17:49 an irritating side effect of using mapcat is that the lists need to be the same length

17:49 hiredman: huh?

17:49 do you mean the same depth?

17:50 sunkencityryleh: mapcat stops at the shortest list

17:50 or string in this case

17:50 hiredman: ah

17:50 right, just like map

17:50 I was assuming you meant the sublists

17:50 raek: what do you want to return? a sequence of pairs? two sequences?

17:50 sunkencityryleh: a string ideally

17:51 the last string in the argument to mapcat

17:51 but without the part that similar to the first :)

17:53 map vector is a lot cleaner than my list %... thnx

17:55 raek: I suspect you have to roll you own looping in this case

17:55 shouldn't be too hard with loop and recur

17:56 you kind of wanna do a [(rest a) (rest b)]

17:56 derka: Hello Guys

17:56 hiredman: or just use reduce

17:56 derka: Is anybody using clojure on macosx

17:56 snowleopard

17:57 rhudson: derka: yes

17:57 derka: cool rhudson

17:58 how did you setup clojure, i am trying to learn clojure, reading programming clojure book from stuart halloway, but cant find a way to properly install stuff. i havent touched java since the 90s so the setup is complicated for me :)

17:58 and i am lazy

17:58 :)

17:59 sunkencityryleh: raek: thanks

17:59 rhudson: I've had Java on my Mac forever so I don't remember if that's part of the standard install or not. It certainly updated Java when I upgraded to Snow

17:59 Do you have Java on your machine?

17:59 derka: yes java is installed by default, java 1.6

18:00 rhudson: OK. Probably the easiest way to get started is to use cljr.

18:00 derka: in /System/Library/Frameworks/JavaVM.framework/Versions/1.6/Home/bin/java

18:00 rhudson: You download a script that downloads everything else you need.

18:00 AWizzArd: derka: first you should decide with which environment you would like to work. A very simple start would be to download clojure.jar from http://build.clojure.org/ and put it somewhere on your disk, open a shell and cd into the right directory and then do: java -cp clojure.jar clojure.main

18:00 derka: cljr? is that: http://github.com/carlism/Clojure-MacOSX/

18:00 rhudson: No, let me find the ref

18:01 derka: ok thanks rhudson

18:01 AWizzArd: But you can also work with Emacs, Vim, NetBeans or Eclipse.

18:01 derka: thanks awizzard, i have used clojure.jar already, but in the programming clojure book there are lot of examples to test, and i need to seutp the environmment

18:01 awizzard i am using textmate

18:01 rhudson: http://github.com/liebke/cljr

18:01 derka: thx rhudson

18:01 rhudson: There's a Clojure bundle fore TextMate apparently

18:02 http://www.assembla.com/wiki/show/clojure/Getting_Started_with_Textmate

18:04 derka: thx a lot rhudson

18:04 and awizzard

18:08 rhudson: AWizzArd, the reason I recommend cljr in cases like this, is that it's about the easiest way I know of to get a repl with clojure-contrib and jline on the classpath.

18:09 AWizzArd: yes sure, the example I gave is the most basic way to start with Clojure, it is only sufficient for small tests

18:09 rhudson: Right. I'd be dead without jline

18:13 amalloy: wait, i was expecting records to behave like maps: (defrecord Foo [a]) ((Foo. 17) :a)

18:16 rhudson: amalloy, as you found out they're not

18:16 The (:a foo) form is very efficient

18:16 amalloy: oh, and (foo :a) isn't? i see

18:17 i was thinking it'd make it awkward to get at items of a nested record hierarchy, but (.. foo bar baz) is more readable than the map equivalent

18:18 raek: shouldn't get-in work for records too?

18:18 amalloy: probably. i just don't know get-in exists :)

18:19 raek: get-in, assoc-in and update-in is a neat family of functions :)

18:19 amalloy: i knew about assoc and update, but managed to not find get

18:19 * Raynes can't remember the last time he had to use get.

18:20 raek: I often use get when both the key and and the map are variables

18:20 amalloy: ddsolve.core> (get-in posn :state :trumps)

18:20 ; Evaluation aborted.

18:20 ddsolve.core> (.. posn state trumps)

18:20 :nt

18:21 raek: ,(get-in {:a {:b {:c 1}}} [a b c])

18:21 clojurebot: java.lang.Exception: Unable to resolve symbol: a in this context

18:21 rhudson: you can also do (-> posn :state :trumps)

18:21 raek: ,(get-in {:a {:b {:c 1}}} [:a :b :c])

18:21 clojurebot: 1

18:21 amalloy: oh sorry, it works - forgot you need a seq of keys, not variadic args

18:21 raek: yeah, get-in and -> have some overlap

18:24 danlarkin: hiredman: pingaling

18:26 hiredman: danlarkin: pongalong

18:38 rgl: which book do you guys advice me to buy? I was thinking Programming Clojure but I'm affraid it might be outdated that news ones like Practical Clojure?

18:38 amalloy: i've enjoyed (ha ha) The Joy of Clojure

18:39 ssideris: is "the joy" out yet?

18:39 arkh: amalloy: a good link re: clojure books is here - http://stackoverflow.com/questions/2578837/comparing-clojure-books

18:39 rgl: that one is not in print yet

18:39 amalloy: no, i don't think it's out, but the MEAP has almost every chapter

18:39 arkh: ssideris: JoC is not out in print yet but you can get the full unedited version through the MEAP program

18:40 amalloy: and it discusses 1.2 features, which must be a plus if you don't want to be "outdated"

18:45 raek: if you are a beginner, I would recommend Programming Clojure

18:45 I don't think that is outdated

18:45 *it's

18:46 rhudson: The only parts that's outdated is the "getting started" stuff -- other than that it's a great into

18:46 => intro

18:46 raek: imho, the new stuff in 1.2 does not replace older stuff

18:46 arkh: I still find Programming Clojure really useful and it's only occasional that I need to remind myself what's in the changelogs for 1.1 and 1.2

18:47 raek: there are more features to fill the gaps that existed in 1.1

18:47 at least when considering protocols

18:49 arkh: yeah, e.g. Prog Clojure doesn't go into deftype and defrecord very deep and says nothing about reify (along with protocols) All that intro information can be found at http://clojure.org/datatypes easily enough.

18:50 rgl: thx guys :-)

18:50 arkh: that is to say, introductory information can be found on those topics there - not saying those are all introductory features ;)

18:50 Raynes: arkh: Programming Clojure doesn't go into deftype and defrecord *at all*.

18:50 It was Clojure 1.0.

18:50 rgl: I'll get practical clojure for starting with clojure. Later I'll get the joy one :-)

18:50 Raynes: raek: It's very outdated.

18:51 arkh: Raynes: defrecord is on page 5. It's not much though, more of a "this exists"

18:51 Raynes: arkh: Really?

18:51 I never saw it.

18:51 rgl: what you guys think about enclojure.org?

18:52 rhudson: arkh: that's not the 1.2 defrecord per se -- it's handwaving about how you can add things like that with macros

18:52 arkh: rhudson: true

18:54 rhudson: lol, yeah, that's well put

18:54 rhudson: But we know it's handwaving that's fully backed up!

18:55 arkh: Raynes: you're pretty much right

18:55 * Raynes wasn't sure.

18:55 Raynes: I haven't read that part of the book in a long time.

18:55 Or any of the book for that matter. I usually refer to Joy now.

18:55 rhudson: Still, I think you need to know most of 1.0 Clojure before protocols and datatypes makes sense

18:56 amalloy: agreed. i used JoC as my intro book and pretty much glazed over that chapter

18:56 rhudson: :)

18:56 I think JoC is a great second book

18:57 amalloy: "this sounds pretty cool, i wonder what it all means"

18:57 arkh: I really look forward to the print version. It's easier on the eyes to read a book that way (no e-reader in my inventory)

18:57 amalloy: it's coming soonish, isn't it?

18:57 rhudson: Sept I think

19:01 amalloy: does anyone know how a map is stored internally? i don't plan to rely on any implementation details, i just wonder how well clojure can avoid new'ing objects for operations like assoc

19:04 arkh: , (class {})

19:04 clojurebot: clojure.lang.PersistentArrayMap

19:04 arkh: amalloy: check out the source for ^^^

19:04 amalloy: thanks

19:05 arkh: amalloy: there's a bunch of videos Rich has done, too, like http://blip.tv/file/812787

19:06 (sort of OT to your question, but they're good to see)

19:07 tomoj: amalloy: clojure can't avoid new'ing objects for assoc

19:07 maybe I don't understand what you mean..

19:08 amalloy: tomoj: certainly it has to new *some* objects, eg the new map and the new key

19:09 but does it manage to reuse references to the old key/value pairs or does it have to make new Entry's as well, was what i was thinking about

19:10 tomoj: amalloy: http://blog.higher-order.net/2009/09/08/understanding-clojures-persistenthashmap-deftwice/ and http://blog.higher-order.net/2010/08/16/assoc-and-clojures-persistenthashmap-part-ii/ might be helpful

19:10 amalloy: tomoj: thanks!

19:12 tomoj: looks like it only has to create new nodes in the trie for the path from the root to the new entry

19:13 PersistentHashMap will probably be more interesting than PersistentArrayMap

19:14 and it might be easier to start with vectors http://blog.higher-order.net/2009/02/01/understanding-clojures-persistentvector-implementation/

19:14 amalloy: yeah, i'm reading vectors

19:20 arkh: Raynes: none of my business, but will you be going to college earlier than the usual 4-years-high-school-then-college? Have you picked a college?

19:21 Raynes: I'm in 11th grade.

19:21 Whether or not I'll go to college is up in the air. At least immediately.

19:21 It'll probably be a while, if I do.

19:21 arkh: that's totally cool - I went right away and it probably wasn't the right time

19:22 tomoj: Raynes: wow, nice head start

19:22 Raynes: tomoj: ?

19:22 arkh: I hope you're not too frustrated by the way classes are structured, i.e. I hope you find a program that accommodate where you are with your learning

19:23 s/accommodate/accommodates

19:24 maybe Relevance will hire you out of "high school" ;)

19:24 Raynes: :p

19:24 I'm doubtful.

19:24 ;)

19:47 amalloy: suppose i have (defrecord Foo [a b]) (let [f (Foo. 1 2), accessor :a]). is there a more-clever way to get a result of 1 than (get f accessor)?

19:49 AWizzArd: amalloy: did you try (accessor f)

19:50 amalloy: *blink* well, apparently not, lol

19:51 thanks

20:24 bortreb: would a function still be pure if it opened up a swing gui window but then closed it before it itself terminated?

20:28 polypus: bortreb: not if the gui can affect your application state in any way. the function might always return the same value, but calling it pure would be a bit of a stretch

20:40 bortreb: but let's say it's just an empty window, and then it gets destroyed and garbage collected

20:41 tomoj: no.

20:41 if you take the call to this function and replace it with its return value, the program will behave differently

20:42 bortreb: that's a very good point, but it depends on what you mean by bahave differently doesn't it?

20:43 because, it seems like it's exactly the same as creating a mutable java object, getting something from it, and destroying it -- that is still pure isn't it?

20:43 Raynes: bortreb: Not open a GUI qualifies as behaving differently.

20:43 Greating GUI window is a big fat side effect.

20:43 Creating a*

20:43 bortreb: but if you could see the memory changing (like the led's on a connection machine) it would bahave differently

20:44 so does it really depend on the observer and what he considers "different" ?

20:44 amalloy: but then no function could be pure, because they all change memory

20:44 bortreb: what if it's on a headless machine and you don't ever see the screen, is it pure then?

20:44 tomoj: just curious, why do you care?

20:45 dreish: Anyone recognize this error from "lein native-deps"? Exception in thread "main" java.lang.IllegalAccessError: default-repos does not exist (native_deps.clj:1)

20:45 bortreb: I wanted to know a more rigorous definition of "pure" -- it seems like the "pure" we throw around everyday is actually relative!

20:46 tomoj: if you want to get rigorous I think you'll have to talk about imaginary computers

20:47 but, of course it's relative. if you consider the noise your computer makes an output of your program...

20:48 bortreb: I wrote a function using the ImageJ to transform images. that library is so tied to gui that it opens up a blank window for ~1 ms. But if I had to classify it as pure or not, I'd say it's pure...

20:48 Raynes: I'd disagree, but that's just me.

20:49 bortreb: but then you turn your monitor off or disable x, and it's suddenly pure?

20:49 it seems you have to wither accept that or say that literally no function is pure which seems like a paradox

20:50 tomoj: if you disable x, won't the function throw an error?

20:52 bortreb: You could always intercept the call and just not display the window, but I think just turning your monitor off or running it on a headless machine is a better example

20:53 maybe the concept is "pure at this level of detail" ?

20:53 tomoj: if a program prints to a file and no one ever looks at it, did it do any I/O?

20:55 (I mean, it doesn't matter to me whether the monitor is on :))

20:55 bortreb: depends whether your monitor's on

20:56 tomoj: if my monitor is off, my program doesn't do file I/O? O_o

20:56 bortreb: if the hard disk played a song whenever a file was written to it, they maybe yes, but only if you care about sound?

20:57 if you don't care about sound, then it's pure w.r.t anything non-sound related?

20:57 chouser: the real question is -- why do you care?

20:57 Raynes: <bortreb> I wanted to know a more rigorous definition of "pure" -- it seems like the "pure" we throw around everyday is actually relative!

20:57 chouser: if you memoize the function, will your program still work correctly?

20:58 if you call the function in a transaction, and the transaction retries, will you program still work correctly?

20:58 those are more interesting questions than the definition of "pure"

20:58 bortreb: that's the thing ---- it _would_

20:58 .... unless you care about the screen

20:58 chouser: then it's "pure enough" *shrug*

20:59 hm...

20:59 bortreb: I think there's different levels of pure

20:59 and the definition we use is: it doesn't change any state we can _see_

20:59 clojurebot: you're doing it wrong!

21:00 bortreb: lol clojurebot

21:01 tomoj: does referential transparency require that you can replace a single call with many calls?

21:01 Raynes: Regardless of whether I can see it or not, if my function does something other than compute a value and return that value, I'm going to say it isn't pure.

21:03 tomoj: I mean, e.g. if your function which opens a window is called a million times in parallel and opens a million windows...

21:03 bortreb: but to "compute a value" it still has to do physical things in the reality in which it is embedded --- what's the difference between moving a robotic arm on your hard drive platter to go to the memory location of a function definition and having your "hard drive" be a tape archive that requires a 2-ton robot to do the same?

21:05 actually, that's exactly what it does and it makes me very sad, but in terms of taking in a bitmap and giving me a log-polar transform of that bitmap, it works correctly and is referentially transparent

21:07 Raynes: bortreb: There is a crucial difference between you and I: I don't care. ._.

21:09 bortreb: Raynes: fair enough! but it's interesting to think about sometimes nevertheless

21:11 dreish: Looks like lein 1.3.0 breaks native-deps 1.0.1. :(

21:12 Anyone know how to reach dnolen?

21:30 defn: hmmm, is it possible to define 5 defs with different values attached to them all at once?

21:30 (def foo "bar"), (def baz "bees"), ...

21:31 i think i want defmulti

21:32 tomoj: really?

21:32 defn: tomoj: what would you do

21:33 tomoj: (def foo "bar") (def baz "bees") ... or write a macro

21:33 I don't see how defmulti will help you

21:34 defn: :foo, :baz

21:34 polypus: technomancy: you around? if i follow the instructions for lein-clojars and put :repositories [["clojars" "http://..."]] in project.clj, lein spews this out: Exception in thread "main" java.lang.IllegalArgumentException: Vector arg to map conj must be a pair (NO_SOURCE_FILE:0)

21:34 defn: dispatch on those and return their values

21:34 tomoj: but then you still have to defmethod for each, no?

21:35 defn: oh...right :)

21:35 tomoj: and if you're doing that, you might as well just (def blah {:foo "bar"..}) and (:foo blah)

21:35 defn: *nod*

21:35 polypus: ok i see the leiningen sample project has a map there instead. the instructions at lein-clojars are wrong

21:36 tomoj: but maybe something like (defmacro defbymap [m] (list* 'do (for [[k v] m] `(def ~k ~v)))) ?

21:39 defn: you're awesome tomoj

21:41 tomoj: i still do not understand macros

21:41 teach me your magic

21:45 (doc list*)

21:45 clojurebot: "([args] [a args] [a b args] [a b c args] [a b c d & more]); Creates a new list containing the items prepended to the rest, the last of which will be treated as a sequence."

21:53 tomoj: or (defmacro defbymap [m] (list* 'do (map #(list* 'def %) m))) :D

21:54 it's just `(do ~@(for [[k v] ...

21:59 are there any examples of &env usage out there?

22:00 qbg: I think it is used in the serializable function library

22:02 tomoj: ah, yeah, thanks

22:02 so you do have to dig down through some undocumented java methods to use it.. strange

22:02 ihodes: http://github.com/technomancy/serializable-fn

22:03 yeah it's a bit sketch

22:03 tomoj: maybe the java part of clojure uses it?

22:03 ihodes: i *think* it's used in conjunction with macros, specifically...? (tell me i'm wrong?)

22:04 tomoj: yeah, it's for macros, but nothing in the clojure part of clojure seems to actually use it

22:04 ihodes: yeah i think it's what is passed to macros at macro-expansion time

22:05 since it's only, along with &form, in macro definitions

22:06 polypus: defn: could also go macroless (defn keydef [& kvs] (doseq [[k v] (partition 2 kvs)] (intern *ns* (symbol (name k)) val)))

22:06

22:06 val should be v

22:07 defn: polypus: cool

22:13 hamza: is there a particular reason for leiningen plugins not including lib folder in classpath?

22:14 polypus: hamza: do you mean the classpath of the lein process itself or the project classpath?

22:15 hamza: project classpath

22:15 I can't access any dependencies from my leiningen plugin because lib/ is not on the classpath

22:15 polypus: in that case i think you'd have to include the lein plugin as a regular dependency of your project and not a dev-dependency

22:16 or maybe i'm misunderstanding

22:18 hamza: I have a plugin that I am writing which needs to access a jar now the jar is in lib/ but when lein runs lib folder is not on the classpath so plugin crashes with class not found.

22:18 I am not using someone elses plugin

22:18 defn: i need some good excuses to make up some macros now...

22:20 polypus: hamza: are you running lein from within your plugin's directory to test it?

22:21 hamza: no i am running it from the project directory

22:22 tomoj: you're running lein in project/ and you want plugin/lib/ on the classpath?

22:22 or project/lib/^

22:22 ?

22:23 hamza: running from project/ and I want project/lib/ on the classpath

22:23 tomoj: well, that's odd

22:23 polypus: ok so you have two projects, one for the plugin, and one that you are using to test the plugin right? if in the test project you have your plugin as a :dev-dependency then lein should pull in whatever jars are required by your plugin

22:23 tomoj: oh, maybe I see

22:25 hamza: polypus: I have only one project.

22:41 polypus: hamza: try the two project method i mentioned above and see how you go, works for me

22:44 i'm pretty sure it is has to do with all of your plugin's dependencies being pulled into /lib/dev when you use the two project method

22:46 tomoj: does that mean that swank-clojure has to dev-depend on itself if you want to `lein swank` with it?

22:46 defn: is there a quick way to get a-z as a list of strings, like ("a" "b" "c"...)

22:47 hiredman: ,(map char (range 97 140))

22:47 defn: like a range, but for letters?

22:47 oh right...thanks

23:02 slyrus: ,(map (comp str char) (range 97 100))

23:02 clojurebot: ("a" "b" "c")

23:02 slyrus: if you want strings

23:03 defn: slyrus: cool, thanks

23:03 * defn writes down (comp str char)

23:03 defn: that's handy

23:04 comp is great -- why do i never use this?

23:58 amalloy: i find myself using update-in in a way that seems silly - what's the right way to do this? (update-in m [keyword-var] inc)

23:59 i could (assoc m keyword-var (inc keyword-var m)) but that looks worse

Logging service provided by n01se.net