#clojure log - Oct 27 2008

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

0:51 sohail: how are you guys doing multi-file projects in clojure? there is no asdf equivalent is there?

1:11 danlarkin: you can leverage namespaces and :uses

1:12 or you can use #c

1:12 sorry

1:12 #'clojure/load-file

1:34 larrytheliquid: how do you specify public vs non-public symbols in namespaces?

2:05 bradbev: hi all. I'm a Java & Clojure newbie. I'd like to have a thread sleep & from another thread send a wake up event. What is the usual way to do this? I've looked at wait & notifyall, but can't figure out how to obtain the monitor for the thread correctly, so feel like that might not be the correct way.

2:07 danlarkin: bradbev: a common pattern is have one function adding things to a list and another polling that list, which can block on an empty list

2:08 bradbev: danlarkin: OK, so use a Java lib for the blocking list?

2:08 danlarkin: no, clojure lists,

2:09 bradbev: how do I get the thread to block in the case of the empty list?

2:09 danlarkin: TBH I haven't started much into the concurrency aspects of clojure yet, but I think you can use refs to accomplish it with a regular old list

2:10 bradbev: that does sound along the lines of what I want to do. But I can't find the magic to actually do it :)

2:10 danlarkin: last week someone was asking about the best way to keep around a set of jdbc connection objects

2:10 to do connection pooling

2:11 and his first thought was to mark the ones currently in use as "dirty" or something

2:11 and then pull a clean one from that list, mark it as dirty, do work, mark it as clean, etc

2:11 but rich suggested he just use the method I described to you

2:11 bradbev: ah

2:12 danlarkin: although he was much more eloquent and descriptive

2:12 than I was

2:12 bradbev: I guess I could try to find the logs that detailed that :)

2:12 I get the concept, just the Clojure implementation is eluding me

2:12 danlarkin: yes, I'm sorry I can't remember the exact day

2:12 I believe it was this past week sometime though

2:12 bradbev: no probs

2:12 danlarkin: searching for jdbc should turn it up

2:15 found it

2:15 http://clojure-log.n01se.net/date/2008-10-23.html

2:15 bradbev: thanks, I'm looking now

2:15 danlarkin: 11:14

2:15 bradbev: oh, awesome!

2:15 thanks much

2:18 danlarkin: sorry... perhaps you can't use a regular old list

2:19 bradbev: LinkedBlockingQueue would do it

2:21 unfortunately it's not quite the behavior I'd like. :( I really want the equivalent to WaitForSingleObject/SetEvent

2:25 danlarkin: how does the behavior differ?

2:26 bradbev: so the code I'm writing is an emulation of some C code I've seen, just to see how different it is. There is a fixed vector of refs that represent work units. Worker threads look at the vector & pick the best work unit for them to do.

2:27 When there are no work units pending in the vector, the worker threads should block until a new job is put into the vector.

2:27 even though it is not idiomatic, I explicitly want my data structures this way

2:28 danlarkin: I see

2:30 so a queue isn't what you want

2:30 bradbev: nope, fraid not :)

2:30 danlarkin: perhaps my original suggestion then? a list of "work", and any pushing/popping to that list you do inside a dosync?

2:31 I think dosync is correct... as I said I haven't learned the concurrency features much yet

2:31 bradbev: yup, that would do the same job. But for right now, I want to emulate the existing C code in terms of implementation as much as possible

2:32 danlarkin: so that would match, wouldn't it?

2:33 bradbev: nope. Having a blocking queue is a different mechanism for doing the same job. Right now I want to do the work just by having a vector, which is how the C code works

2:35 danlarkin: so is there a mechanism for making sure two workers aren't working on the same task?

2:36 bradbev: yes, in the C code a CAS (compare & exchange) operation is done in place on the vector. In Clojure, it is a Ref that I modify. I have the code doing the right thing now, except the threads busy loop when there are no jobs.

2:36 sorry, the CAS is done on a single element of the vector

2:37 danlarkin: ah

2:37 Lau_of_DK: Morning gents

2:38 albino: good morning

2:38 hoeck: good morning

2:38 danlarkin: morning! 2:38 to be exact... what am I doing up!

2:40 bradbev: I'm stumped, then :-[

2:40 bradbev: danlarkin: thanks, though

2:41 danlarkin: bradbev: haha no problem, sorry I brought you full circle back to your current implementation

2:41 bradbev: no probs :)

2:41 danlarkin: and I'm off to bed, night all

2:41 bradbev: night

2:45 Pupeno: Good morning.

2:45 Hi there Lau_of_DK!

2:46 Lau_of_DK: Hey man

2:47 * Pupeno fires NetBeans... this is not going to end good.

2:47 Pupeno: Lau_of_DK: How are you doing?

2:48 Lau_of_DK: Im doing good! Last day at work through 3 years, so Im excited. Secondly, Im wrapping my mind around Qt, I REALLY want to see Clojure/Qt intertwined!

2:48 Pupeno: Lau_of_DK: leaving your job?

2:48 Lau_of_DK: Yes sir

2:48 Pupeno: Lau_of_DK: got a new one?

2:49 Lau_of_DK: Yes sir, I'll be selling Linux/OpenSource solutions to danish businesses

2:50 Pupeno: Lau_of_DK: Congratulations then!

2:50 Lau_of_DK: Hope you enjoy your new job!

2:50 Lau_of_DK: Thanks alot, I will!

2:51 bradbev: for anybody following my previous issue, the way to obtain a monitor on a Java object from Clojure is (locking ...)

2:51 it seems very silly to need to lock the object just so you can wait on it or notify other monitors to wake up

2:59 Pupeno: Lau_of_DK: I'm still thinking of writing about it, but Enclojure is a Clojure application (or library rather) that uses the Swing GUI designer.

3:00 Lau_of_DK: Writing 'it' ?

3:01 Pupeno: about it, on my blog.

3:01 Lau_of_DK: Qt ?

3:02 The reasons for Qt are much more than the just the ease of UI design. Its a powerful platform, well coding, works on Mac OSX, Windows, Linux, LiMo and WMobile. It would really bring some power to Clojure

3:02 Pupeno: No, mixing Clojure and the Swing Visual Editor.

3:03 Lau_of_DK: Ah ok - Looking forward to it

3:05 Pupeno: Lau_of_DK: well, what I as saying is that it is not terra-incognita, Enclojure is already doing it.

3:05 Anyway, I have to go to work now.

9:49 cemerick: I'm getting some very strange stack traces these days, with line numbers corresponding to whitespace, lines that are in the middle of an ns form, etc....

9:50 rhickey: cemerick: anything specific I could chase down, only on use/required files ?

9:51 cemerick: rhickey: I couldn't speculate on a domain at the moment -- lots of :use going on, and everything's mediated through gen-classed classes.

9:51 If I can narrow it down, I'll definitely post it.

10:01 tayssir: Hi! Possibly dumb question -- I want to find out the namespaces of symbols. In the "user" namespace, when I type (namespace '+), I get nil... Does that mean + doesn't belong to a namespace?

10:02 rhickey: when you say 'blah you are giving the symbol named "blah" directly, to resolve a symbol you can syntax-qoute `+

10:03 tayssir: Ah, thanks!

10:03 Gotta unlearn Common Lisp... ;)

10:06 Interesting, symbols which represent names of special forms (quote, def, etc) don't seem to be associated with namespaces.

11:16 scottj_: How do you change the current directory within the clojure repl?

11:17 jao: in slime?

11:17 scottj_: As in, the directory it looks at when you do (load-file "foo.clj")

11:17 yeah

11:17 jao: ,cd

11:21 scottj_: (swank.commands.basic/set-default-directory "/bar")

11:22 jao: scottj_, didn't ,cd work for you?

11:22 scottj_: yeah, but I want to include it in my source code

11:23 jdz: scottj_: why would you want to do *that*?

11:23 scottj_: because I don't want to set the current directory everytime I load emacs, and it can be different I think based on what file you have open when slime starts

11:39 Chouser: Is there a better way to make a map whose keys are from the items from a seq and whose values are all 1?

11:40 (into {} (for [i s] {i 1}))

11:44 gnuvince_: looks fine to me

11:45 cemerick: rhickey: disregard my missive re: line number from earlier. My bad.

11:49 jdz: scottj_: i always start slime in directory where i'm gonna work...

11:54 vy: I'd expect to see a generic CONCAT method instead of STR. Is there any?

11:55 Chouser: vy: to build a seq or a string?

11:55 vy: A sequence.

11:56 Chouser: (concat [1 2 3] '(4 5 6))

11:57 vy: Why does STRINGs treated different than SEQUENCEs?

11:58 Chouser: well, they're different concrete objects. You can treat them similarly in a lot of cases: (concat [1 2 3] "456")

12:57 duck1123: does anyone have a working example of how to use the sql package to connect to a MySQL server?

13:06 drewr: duck1123: Which sql package? clojure-contrib?

13:09 duck1123: yeah

13:09 I actually just got it connecting, but now I'm getting a different error

13:10 Operation not allowed after ResultSet closed

13:10 I'm trying to select a record and return it

13:11 drewr: Let's see code.

13:12 duck1123: lisppaste8: url

13:12 lisppaste8: To use the lisppaste bot, visit http://paste.lisp.org/new/clojure and enter your paste.

13:13 duck1123 pasted "select a user and return the result" at http://paste.lisp.org/display/69305

13:16 duck1123 annotated #69305 with "grabbed wrong version" at http://paste.lisp.org/display/69305#1

13:27 duck1123: ok, it appears I can print the value from inside the macro, but I don't know how to return it.

13:39 is there a way to create a copy of a value?

13:39 Chouser: when values are immutable, that doesn't make much sense. You have a mutable value?

13:40 duck1123: no, I have a value that I can't access except for within the macro

13:40 Chouser: hm. I guess I'd need to see the code.

13:40 duck1123: it seems like I can do whatever I want with the results of with-results, except for return it or assign it to a var

13:41 http://paste.lisp.org/display/69305#1

13:44 Chouser: Ah, I think it's because statement and result-set are closed when you leave the with-results block.

13:44 You could try copying the resultset-seq into a vector: (vec user)

13:44 duck1123: that's basically what I was thinking, let me try

13:45 that works, thanks

14:06 cemerick: rhickey: ArraySeq.count is broken: (count (rest (to-array (range 10)))) => 10

14:07 The fix is simple (drop the usage of oa.length in ArraySeq.count), but I'll post a patch if you like.

14:07 I presume that's an optimization, though -- maybe there's a more fundamental bug in how the index is being mishandled?

14:08 s/the index/the oa reference

14:11 rhickey: cemerick: fixed

14:12 cemerick: rhickey: thanks

15:27 gnuvince_: Chouser: lovely code btw (seq-xor)

15:31 Chouser: oh, thanks.

15:32 It seems a bit odd, I often end up choosing "for" over "map" because then I can return a literal data structure. (for [i s] {i 1}) vs. (map #(hash-map % 1) s)

15:33 what I mean is, it seems like an odd reason.

15:34 lisppaste8: rhickey pasted "seq-xor, no counting" at http://paste.lisp.org/display/69309

15:34 rhickey: sorry, the counting bothered me

15:35 achim_p: Chouser: indeed, very nice!

15:35 that's a really cool thing about clojure - efficient high-level data structures are built right in. algorithms often look like textbook pseudocode (plus parens ;)

15:38 Chouser: a minor itch: you should really check for odd count, not for count = 1. symmetric set difference defined for more than one set really only makes sense if defined like this ...

15:38 Chouser: rhickey: your latest behaves a bit differently when there are repeats within one of the seqs.

15:39 achim_p: hm, good point. I didn't read the original poster's code carefully enough to see what he was actually doing there.

15:40 but with that behavior, counting makes even less sense.

15:42 gah, I'm losing my ability to identify the Right Way to right code in imperative languages. It all looks so bad, no matter what.

15:42 s/to right/to write/

15:43 gnuvince_: Chouser: been there :)

15:43 You should see my Python code

15:43 Super ugly

15:43 bunch of generator expressions wrapped inside a couple functions from itertools

15:44 danlarkin: *shudder*

15:46 Chouser: I wonder how long it would take for me to port our entire C++ app to Clojure and re-train the development staff.

15:48 gnuvince_: Chouser: :)

15:48 I was thinking the same thing with regards to a PHP daemon that was written a couple years ago.

15:49 achim_p: how expensive are conj/disj on the hashed structures?

15:49 gnuvince_: The daemon highlights a nice PHP flaw: resource ids are not reused. So after a few weeks, it reached 2^32-1 and the program crashes.

15:49 Chouser: gnuvince_: yikes.

15:49 gnuvince_: Yeah

15:49 Chouser: achim_p: constant time! everything's constant time.

15:50 well, O(log-base-32) which comes close.

15:50 gnuvince_: and since this is a network application, I figured that Clojure would probably be good for it.

15:50 achim_p: Chouser: yeah, in knew lookup was, but wasn't sure about "writes". thanks!

15:50 "i knew"

15:51 Chouser: achim_p: Hm, well I think it's the same. Certainly slower, but the same big-O category.

15:52 conj/disj have to copy one path through the tree rather than just navigate one path.

15:59 achim_p: yes, of course, that makes sense.

16:02 scottj_: Any compojure users here? Are you using session and cookies for users?

16:16 gnuvince_: So I've been golfing the seq-xor thing down to 86 characters :)

16:16 damn you codegolf.com!

16:18 Chouser: you're removing all the spaces you can?

16:18 gnuvince_: pretty much :)

16:18 Haven't found a more concise way than you presented.

16:26 jao: hmm. so there's no 'retry' in the STM transaction API, is there?

16:28 Chouser: jao: as in to manually force a retry? I don't think so.

16:28 jao: Chouser, so, if i need some condition to be met, how can i wait on it? (say, a container non-empty, or something)

16:30 Chouser: if you want blocking behavior, try using some java.util.concurrent construct.

16:31 jao: but then i'm outside the nice STM world, no?

16:32 Chouser: yes, you're right. Is that a problem? I guess I'd need to know more about your specific context.

16:33 jao: well, no specific context, really. just that other STM systems i've seem provide this manual retry, and a typical use case is the one i mentioned.

16:33 s/seem/seen

16:33 Chouser: there are examples of using java concurrent classes in boot.clj. I think for the most part they and clojure's STM are covering different bases.

16:35 if you want to manage the mutation of data objects, use STM (refs, agents, etc.). If you want to manage thread blocking, work queues, etc., Java provides nice APIs already.

16:35 jao: i'd rather do all my programming on the clojure side. but oh well.

16:35 Chouser: you can certainly block on something and then enter a dosync.

16:36 jao: blocking implies some kind of lock and, therefore, the kind of pitfalls STM circumvents

16:37 Chouser: Java provides a lot of features in a lot of categories that Clojure doesn't try to mask or replace: Strings, most of regex, a lot of Math, a lot thread control, etc.

16:38 jao: well, I'm not deeply experienced in Clojure's STM. There may be a case to be made for manual retries. You should post an use case or something to the google group.

16:39 jao: ok

16:40 Chousuke: jao: I don't think all locking is bad. what STM is for keeping your data consistent without complex locking, but if you have to block and wait for an event, using a lock for that seems natural to me.

16:40 +is

16:45 jao: well, if i can obtain the same behaviour without locking, i'm happier

17:16 Grahack: Hi folks, somebody running clojure on gij ?

17:19 java -cp clojure.jar clojure.lang.Repl works but gij -cp clojure.jar clojure.lang.Repl fails with a java.lang.NoClassDefFoundError: clojure.lang.Symbol

17:32 rapido: i wonder: is clojure an 'lispy' array language in disguise?

17:32 Chouser: what's an array language?

17:32 Hun: APL?

17:32 rapido: J?

17:32 k?

17:32 Hun: yes - are we playing jeopardy?

17:33 rapido: the sequence protocol is the crux

17:33 however, clojure's sequence is an immutable array

17:34 don't know if APL arrays are immutable

17:34 but i believe they are

17:35 Chouser: clojure sequences can be views of arrays, hash-maps, sets, lines of a file, just about anything.

17:36 rapido: Chouser: not anything, if not immutable

17:36 preferably

17:37 Chouser: clojure seqs can be views of anything, though they can only mutate in part you haven't gotten to yet.

17:37 rapido: Chouser: what about views of views of ....: a big stack of views?

17:38 Chouser: you can nest data structures, but if you ask for a seq of a seq, you just get the same object again.

17:39 rapido: what happens if you lazily concatenate sequences (n times)?

17:39 you build a stack of n 'views'

17:40 Chouser: hm, sure.

17:41 rapido: eventually that will show in the big O

17:43 anyway, i think that clojure has a relationship with array languages

17:44 idiomatic clojure code (using seq protocols) tends to lean towards an array language solution

17:47 gnuvince: rapido: I find that this kind of programming yields the nicest code, whether it be Clojure or Python or Smalltalk or Haskell.

17:48 It's so natural: take this list of things, do this to them, then take out the items that don't match this criteria, combine the remaining elements in this way and here's the result

17:48 Hun: map/reduce :)

17:49 rapido: gnuvince: if the problem fits the array approach, yes.

17:50 but surely there problems that aren't feasible to solve, array wise?

17:50 gnuvince: Surely.

17:50 rapido: polymorphism

17:50 ?

17:50 gnuvince: How do you mean?

17:51 Chouser: clojure has multimethods and a flexible taxonomy system.

17:51 rapido: Chouser: i know clojure has multimethods, that's my point

17:51 apl hasn't

17:51 gnuvince: APL is also a lot older :)

17:52 Clojure builds upon a lot more litterature and experience.

17:52 Chouser: so maybe Clojure isn't an array language? I'm not sure what you're driving at.

17:52 rapido: may be multimethods and the seq protocol could be a killer combination :)

17:52 Chouser: ah. :-)

17:52 plus STM

17:53 plus easy Java interop

17:53 rapido: immutability rather

17:54 STM is a efficient compromise between mutability and immutability

17:54 Chouser: but yeah, i like the java interop - i'm a practical guy

17:55 Chouser: STM is a nod to practicality too, I think, vs. a more "pure" immutable system.

17:58 rapido: impertinent remark: i think the current clojure implementation (in java code) is bit messy.

17:59 is bit <- is a bit

17:59 Chouser: rapido: :-) I've heard others express that.

17:59 rapido: but i see why

17:59 Chouser: messy in real structure, or messy textually?

17:59 rapido: getting to lisp as quickly as possible

18:00 bootstrapping ..... macros, ah yeah!

18:00 structurally it is ok. but i don't like code that is commented out

18:00 lisppaste8: rhickey annotated #69309 with "seq-xor fixed for seqs w/dupes" at http://paste.lisp.org/display/69309#1

18:01 rapido: so textually, yes

18:01 Chouser: rapido: yeah, that fits with other comments I've heard. Good thing that doesn't really matter. :-)

18:01 rhickey: heh. nice.

18:03 rapido: rhickey: nicely compressed by the master :)

18:03 wwmorgan: rhickey: are the global vars like *print-meta* officially supported? I wonder because I can't find any documentation for them.

18:04 rhickey: thanks Chouser for pointing out the dupe problem, once I started thinking sets I forgot it was spec'ed for seqs

18:04 wwmorgan: *print-meta* is, and yes, not yet doc'ed

18:06 wwmorgan: would it be helpful if I documented them?

18:07 rhickey: wwmorgan: patch welcome if you've got a CA (don't have the list at hand)

18:07 Lau_of_DK: rhickey, Qt is really making some good stuff atm, and with QtJambi it runs on the JVM also - Are you considering taking some steps to make it easier to integrate QtJambi and Clojure?

18:07 wwmorgan: I'll send one in

18:08 rhickey: Lau_of_DK: not in particular - it's just another Java lib

18:09 Lau_of_DK: rhickey, but Qt is a cross-platform lib that runs on Mac, Windows, Linux, Windows Mobile, LiMo, which makes UI design so easy, including Webkit and Multimedia libs... It would really bring some power to Clojure imo

18:10 rhickey: Lau_of_DK: I have nothing against QT, but there are lots of Java libs for lots of purposes - what's Clojure's role in supporting them other than the host interop? If the community wants to build enhanced bridge libs that's fine by me, but not a language issue

18:11 Lau_of_DK: Ok youre right, I understand the seperation.

18:15 rapido: rhickey: i'm attracted to clojure's seq protocol.

18:15 clojure may be not about lisp.

18:15 rhickey: rapido: as far as Clojure's Java code - well, I'm not apologetic. That's what Java code in which there was a lot of experimentation looks like after a couple of years. It's easy now to imagine it cleaned up, and I may do that if I get time. What matters for me is the structure, esp. the class hierarchy, which is fine IMO

18:15 rapido: or maybe Lisp is about sequences in some sense

18:16 rapido: it's about the right abstractions: concurrency is becoming more and more important

18:17 rhickey: Also there's a way to look at Lisp as programming directly with recursive data structures, in which case Clojure is even more a Lisp, given its recursive vectors sets and maps

18:17 Chousuke: maybe lisp should've been seqp, but that doesn't really sound cool.

18:17 rapido: lol!

18:20 jao: rhickey, what's the rationale for not having 'retry' (and perhaps 'orelse') in Clojure's STM? what substitutes it?

18:21 rhickey: jao: I don't want to mix flow control and transactions

18:22 I don't want transactions to block, would prefer people use queues etc

18:23 jao: rhickey, i see. but say a transaction can only succeed (logically) if some collection has data... it'd be nice to be able to express that inside the STM; otherwise one has to use blocking primitives, i.e., dreadful locks... or am i missing something?

18:25 (rhickey, ah sorry, didn't see your mentioning queues etc)

18:25 rhickey: there are models for STM that are oriented towards implementing the facilities of j.u.concurrent with STM - I don't believe in that - use j.u.concurrent - the queues etc require no locking

18:25 jao: i see. thanks.

18:25 rhickey: once you know you have work to do, do it in a transaction

18:25 jao: aha

18:26 rapido: rhickey: your java code resembles my style: it works just to achieve a higher goal.

18:26 but you are very gutsy to put it out like that! :)

18:27 rhickey: i see that your code is about making your concepts work

18:27 rhickey: what I put out was something that substantially works - I've seen plenty of prettier code that didn't

18:28 I admit it's not ready for people to jump into the compiler code, but the interfaces are nice

18:28 just need some JavaDoc

18:28 rapido: rhickey: the most beautiful java code, imho, is the lucene implementation

18:29 rhickey: but it's a matter of first things first - first thing is the Clojure side

18:29 rapido: rhickey: i understand that - i see that the java codes jumps to clojure with maximum stride

18:31 enough about java - more about clojure!

18:32 kotarak: Is there some interest to make the Repl a "real" class? So it would be easy to provide customised Repls, eg. running via a socket connection. I made a simple patch, but I most likely don't grok the details.

18:34 Chousuke: on line 436 in boot.clj there's a comment that states that "at this point all the support for syntax quote exists". I find it pretty confusing that it just magically starts working and there's only a comment to note that. I guess it's because syntax-quote is defined somewhere else, but in terms of the macros and functions defined in boot.clj?

18:35 rhickey: Chousuke: yes, syntax-quote is a reader facility, defined in Java, but it emits Clojure that requires some of Clojure to exist to run

18:35 Chousuke: okay

18:36 lisppaste8: kotarak pasted "modified Repl" at http://paste.lisp.org/display/69317

19:02 kotarak: How can I make an empty array? (to-array [])?

19:06 danlarkin: kotarak: looks like that's one way

19:07 kotarak: Obviously I needed (make-array String 0).

19:08 lisppaste8: kotarak pasted "simple-minded socket repl using previous patch" at http://paste.lisp.org/display/69318

21:14 gnuvince: How would you transpose a sequence in Clojure?

21:14 Chouser: (doc transpose)

21:15 just kidding. What do you mean by transpose?

21:16 gnuvince: (transpose [[1 2] [3 4]]) => [[1 3] [2 4]]

21:16 as long as you got the individual subvectors, you can do (map vector xs ys zs)

21:17 But that's not terrible when you got 20 rows

21:17 Chouser: and you could use apply on that. But I think there's a func...

21:18 hm, maybe not. I was thinking interleave, but that's not right.

21:37 Jedi_Stannis: is there a function to find if something is in a collection? ie: (in? 2 '(1 2 3)) -> true, (in? 4 '(1 2 3)) -> false?

21:39 Chouser: Jedi_Stannis: "contains?" works on the keys of a collection and is very fast.

21:40 Jedi_Stannis: what is I want it on the values like in my example?

21:40 Chouser: (contains? #{1 2 3} 2)

21:41 If you want it on the values, the only possible way to find it is to walk through the whole collection looking for it.

21:41 Jedi_Stannis: I wrote a function to do that, just seemed like something that would be built in... sometimes I miss things in the api

21:41 Chouser: that's slow, but you can do it like this: (some #{2} '(1 2 3))

21:42 it's not among the standard functions because it's discouraged. If you're going to be looking for things by value, why not use a set (hash-set or sorted-set)?

21:42 then you can use "contains?" like above, or even more simply just: (#{1 2 3} 2)

21:42 Jedi_Stannis: hmm, ok, I hadn't thought about that

21:42 ill look into it for what im working on, thanks

21:43 Chouser: np

21:43 Jedi_Stannis: ill be back if I have more problems

21:43 Chouser: ok

21:53 overthink: I have a question if someone has a minute... How would you best write a function that picks k random numbers from [1..n] with no repeats (think picking lotto numbers)?

22:04 rhickey: overthink: you could use a set and disj anything you pick as you go

22:08 overthink: hm, that's an idea I hadn't considered

22:09 I was trying to build a set up by looping, picking random numbers, and counting the keys

22:10 (I'm new to clojure, and functional programming in general)

23:29 bradbev: I'm finding Clojure's debugging via Slime a bit poor. I'd like to use JSWAT, but I'm on OS X 10.4 (Tiger) & can't get a recent version of Jswat to work. And I can't install JDK 6.0. Anybody else have this problem?

23:38 pjb3: Is it possible in clojure to have keyword arguments with default values?

23:38 I think it is, or at least something close to it, anyone have a link to an example of that?

23:40 Chouser: you can destructure the args into a map

23:41 pjb3: Chouser: Is there documentation on how that works somewhere?

23:42 Chouser: http://clojure.org/special_forms#toc4

23:47 lisppaste8: Chouser pasted "keyword args with defaults" at http://paste.lisp.org/display/69329

23:52 pjb3: Chouser: thx, I'm trying to figure out how it works, what is the :keys part?

23:52 oh, nevermind, I see that in the docs now

23:53 so :keys [a b c] is the same as a :a b :b c :c

23:54 thats : c without the space, stupid emoticons

23:54 Chouser: yes

Logging service provided by n01se.net