#clojure logs

2008-12-31

00:00falconaithanks for you help Chouser
00:10falconaii sometimes see defn written as defn- , what's the difference?
00:11hiredmandefn- is like java's protected
00:12falconaithx
00:14clojurebotsvn rev 1188; added speculative load when no .clj or .class resource found, for Dalvik VM
00:14clojurebotsvn rev 1189; unified clojure.main, patch from Stephen C. Gilardi
00:14clojurebotsvn rev 1190; Make sure all integer ops return smallest representation, patch from Christophe Grand fixed inc/dec long for max/min values
00:14clojurebotsvn rev 1191; made Repl and Script public again
00:14clojurebotsvn rev 1192; made method matching handle differ only in return type, resolving to more-derived return type when bridge methods are involved tweaked RT.load for Android tweaked DynamicClassLoader parenting for Android Android now works if you comment out bean in core_proxy.clj (java.beans is not supported on Android)
01:15timothypratley(def a (atom 1))
01:15timothypratley(swap! a + @a)
01:16timothypratleywhen will @a be evaluated... ie: is it possible that it gets updated before the function + is called?
01:19timothypratley"Changes to atoms are always free of race conditions." <--- I read this as meaning no to my question
01:20timothypratleybut want to understand why... ie: swap! is not a normal function
01:23timothypratleyWell understand is probabbly a bit much, I'd be happy with confirming this is true :)
01:28ericlavigneI imagine that swap! is a macro that locks 'a while performing the operation (+ @a)
01:28ericlavigneLooks like a no-op though, as you are adding up one number.
01:29ericlavigneOh, never mind, I see that swap! uses the first argument for two things.
01:29ericlavigneSo a gets doubled each time.
01:29timothypratleythat is right. What I want to know is:
01:30timothypratley(swap! a * 2) is obviously free of race condition
01:31timothypratleywhile (swap! a + @a) on the surface looks like @a could be evaluated to be 1, but meanwhile another thread changes a to be 2,
01:31timothypratleyso when swap! applies + to a it does 2 + 1
01:31timothypratleyie: a race condition
01:31ericlavigneIn that case swap! will fail (not change anything) and try again.
01:32timothypratleyreally? I don't think swap! can fail...??? its not transactional
01:32ericlavigneThe description of swap! says that the function must be free of side-effects because it may be called more than once. That is a good indication of how it deals with race conditions.
01:32gnuvince"Internally, swap! reads the current value, applies the function to it, and attempts to compare-and-set it in. Since another thread may have changed the value in the intervening time, it may have to retry, and does so in a spin loop."
01:33timothypratleyah!
01:33timothypratleygreat, that explains it perfectly thanks.
01:40timothypratleySo on the group discussion, Mark E suggested (defn atom-set [a val] (swap! a (constantly val)))
01:41timothypratleyNow that would create a race because val is evaluated by the atom-set function?
01:50Chouser'swap!' would read 'a', pass it to '(constantly val)' (which ignores it), and then attempts to set 'a' to the value of 'val'
01:51Chouserif no other thread changed 'a', it succeeds and is done.
01:51Chouserif 'a' changed between the time that 'swap!' read 'a' and when it attempted to set 'a', it will go round and try again.
01:52ChouserI don't think that qualifies as a race condition.
01:53timothypratleybut a was read before swap! was ever in scope: [a val] binds it
01:54Chouserno, 'a' is the atom object. you read it's current value by using @ or deref
01:54timothypratley(atom-set a (+ @a @a))
01:54timothypratley<--- maybe that explains what I'm trying to describe better
01:55timothypratleysurely here (+ @a @a) gets evaluated and bound to val
01:56Chouseryes, I see what you're saying. Using @a in an atom-set of 'a' successfully defeats the purpose of atom and introduces a race condition.
01:56ChouserCongrats. :-)
01:57timothypratleyhahahaha well thanks... but I still want to confirm how this is avoided by (swap! + @a)
01:57timothypratleyie: if swap! is a macro
01:57timothypratleythen @a wont be evaluated
01:57timothypratleybut if it is a function, it would be
01:57Chouserswap! is a function not a macro
01:57timothypratleyis there a way I can easily tell what swap! is?
01:58timothypratleyif it is really a function, then arguments should be evaluated before the function is even invoked (I think - is this really true)
01:58Chouserseveral ways. (doc swap!) doesn't report "Macro" (compare to (doc defn))
01:58timothypratleyah! :)
01:59Chouser(:macro ^#'swap!) returns nil
01:59timothypratleywhat about your source slurper?
02:00timothypratleyhmmm I'll try that
02:00Chousertyping "swap!" (without quotes) at the repl returns a function instead of throwing an exception
02:00Chouseryep, (source swap!) reveals its defined using 'defn' not 'defmacro'
02:01Chouserand yes, all arguments to a function are evaluated before the function is invoked.
02:02ChouserI think that deref'ing the atom within the args to 'swap!' will generally lead to a race condition. Is this what you were originally contending?
02:02timothypratleyprecisely
02:03Chouseryeah, I think you're correct. It is unnecessary and should be avoided.
02:04ChouserUnnecessary because the correct value of the atom to use is passed in to the function you provide to 'swap!'
02:05ChouserThis should be pretty easy to test if I can think of the function.
02:08replacaQ for you guys: I'm about to extend java.io.Writer so I can build a wrapper that will keep track of what's being printed by print, prn, etc. Can I do this via proxy? I know that I can extend the class, but I need a way of getting at the data I stashed (the current column #).
02:08replacaI'd rather not do gen-class if I don't have to.
02:08Chouserreplaca: yes, it's common to have proxy close over state.
02:09replacaBut I've not done proxy before and I don't see how I can stash/recover a ref
02:09replacabut can I add a method to retreive it? Or what's the mechanism?
02:09replacabasically, I want to add a "getCurrentColumn()" method
02:09replacabut perhaps I want to think about it differently
02:10Chouserno, you can't add a method using 'proxy', but you can either make the ref itself or another fn that closes over it visible to the outside.
02:11Chouserreplaca: I had to do something quite similar for the 'source' macro. Do you use that?
02:11replacahmmm, that makes sense. I'm not sure how I'll do that in the context of my program (which is throwing Writers around)
02:12replacano, is it in contrib?
02:12Chouseryes, clojure.contrib.repl-utils
02:12replacaahh, I'll take a look.
02:13ChouserI extended PushbackReader, but also for tracking line numbers.
02:13Chouserah, yes, you may need to start throwing around objects that contain writers.
02:14replacayeah, that's a bunch of conditionals I'd rather not deal with, since I end up pasing them to "print" et al at the bottom
02:14replacamight be easier just to go the gen-class route
02:14Chouser{:writer #<Writer> :col-num (ref 42)}
02:15Chouserbleh, I'd avoid gen-class it at all possible for new application structure.
02:15replacaactually, that might work now that I think of it
02:15Chousers/it/if/
02:15replaca(I've already got gen-class for typed exceptions)
02:16Chouseryeah, I'd recommend avoiding those too. :-)
02:16replacaYeah, I think my problem is I'm prone to do the Java thing for things that feel like Java
02:16Chouserbut I'm less confident about avoiding typed exceptions. Perhaps there are contexts in which they are the best available answer.
02:17replacaand both exceptions and writers feel like I'm "entering java space"
02:17replacaone of the interesting things about clj
02:18replacaI keep changing my mind about the exceptions
02:18Chouserreaders and writers are definitely mutable, which makes dealing with them feel a little less clojurey, but you can still keep those parts remarkably well-contained.
02:18replacaone thing I wonder about is the degree to which we'll end up making things that are consumed by other jvm languages
02:19replacain which case things like typed exceptions fit
02:19replaca(the big thing is that I like to be able to specify exactly which exceptions I want to catch)
02:19ChouserI've started using the pattern (take-while pos? (repeatedly #(.read rdr)))
02:20replacais take-while lazy?
02:20Chouseryep
02:20replacammm, nice
02:21Chouserreplaca: you know CL, right?
02:21replacaoh yeah :)
02:21Chouserso have you considered handling "exceptional cases" using a dynamically bound function instead of a java Exceptoin?
02:21ChouserI don't know CL but I'm under the impression that's a common idiom.
02:22replacaright now I'm doing the column-aware directives in CL format, so I want to wrap the stream I'm handed with one that watches what's written and keeps track of newlines.
02:22replacaYeah, but clojure really does it the java way, with (try ... catch...)
02:22Chouser(binding [*my-specific-error-fn* (fn [details] ...)] (foo ...))
02:23replacaalthough in my case, I could do it as you suggest
02:23replacabut I do need the non-local exit
02:24replacacause I'm 82 layers deep and I realize that I've got a bad parameter
02:24Chouserhm, yeah.
02:24replacabut then I want to add info to that higher up the stack
02:24replacaso I can tell the user where he screwed up :-)
02:25replacabut I might be able to turn that inside out a little bit and then throw a more generic exception
02:25Chouserwell, you could 'set!' all the info you need into a dynamic var, throw a general Exception, and when you 'catch' be able to get everything you need.
02:26replacaI like your first sol'n better! :-)
02:26Chouserheh
02:26replacait keep everything together
02:26replaca*keeps
02:26replacain fact I like it a lot
02:26Chouserbut as you say, you may need to 'throw' to bail out of nested iteration etc.
02:27replacayeah, but you do it like this:
02:27replaca(binding [*my-specific-error-fn* (fn [details] ...)] (throw (Exception. (str ...error message container both external state and details arg...)))
02:28replaca*my parens didn't balance :-)
02:29replacathen I can just call *my-speci...* froom the error point
02:29replacanice
02:29Chouseroh, the 'throw' is inside the (fn [details] ...) ? makes sense.
02:30replacayeah, so the error site doesn't worry about it
02:30Chouserthe error site still has to pass in appropriate 'details', but doesn't need to know that you're using Java exceptions or how that info is stored, etc.
02:31replacabasically at the error site I have a specific error ("Directive ~Q unrecognized") and a location of that, but not he global state about the format and such. I want to show where in the format string the bad directive was
02:32replacaright now I have an "InternalFormatException" that has a message (inherited) and :state field that has the position in the format string
02:35ChouserUsing this mechanism, is there an equivalent to re-throwing the same exception?
02:36ChouserWhen the *my-spec* fn is called, it still sees itself as the value of *my-spec*, so is there any way to call the outer binding (if any)?
02:36replacawell, I rethrow another exception (a FormatException) which has the complete error message
02:36replacaoh, in the new way
02:37replacaI'm not sure I completely understand the Q
02:37Chouseroh, I guess you could capture the outer value lexically and get to it that way.
02:37replacayeah, that's exactly what I was thinking
02:37replacathat would be the point, kind of
02:38replacaso you end up using dynamic binding instead of throw-catch
02:39replacawhich is kind of a cool translation
02:39Chouserbut still using throw-catch for flow control.
02:39replacayeah, but flow control all the way out of my universe
02:39replacarather than inside my universe
02:40replacaso from my point of view, I'm just using throw
02:40replacawhich is also nice because of clojure's war with checked exceptions
02:41replacawhich makes you have to unwrap things in unpredictable ways
02:41Chouseroh, you don't need to use throw to escape from your own section of call stack?
02:42replacaI do, but I won't need to catch it again, because I can do all the error processing in the bound function and throw once and for all
02:42replacathen the caller can catch if he wants or just get an error
02:42replacabut he probably just wants an error
02:43Chouserah...
02:43replacathe intermediate catch was only to give him a better error
02:43replacaby giving hi a message with precise context
02:43replaca*hi -> him
02:44Chouserso you were specifically using catch and re-throw to add details.
02:44replacayeah
02:45replacalike this:
02:45replaca com.infolace.format.FormatException: Directive "<" is undefined
02:45replaca~15<~S~;~^~S~;~^~S~>
02:45replaca ^
02:46replacajust to get that little ^ in the right place :-)
02:46Chouserheh, yeah.
02:46Chouserbut a very helpful little ^ it is.
02:46replacabut it's the principle of the thing
02:46replacayeah, esp. given the fear of "format" :-)
02:47replacaas was discussed earlier
02:47Chouserok, so this is an even better case for the use of a dynamically-bound function than I was thinking.
02:47replacayeah, could be
02:51replacawow, thanks for the brainstorm. I think I can get all my AOT requirements out of the way now
02:52replacasweet
02:52Chouseryeah, it's a worthy goal. :-)
02:52replacaI'm writing up the column-writer now and I think I've got it
02:52Chouserexcellent!
02:52replacaI thought it was worth trying for :-)
02:53ChouserI've going to learn how to use your format, aren't I.
02:55replaca:-)
02:55replacait's a lisp thang :)
02:55Chouserfunny, it doesn't *look* like lisp.
02:55replacabut folks have really been arguing about it for 20 years, so it's up to me to keep it going
02:56replacayeah, that's cause you look at the format string, but when you look at the *arguments* it is
02:56replacabecause it let's you give lisp arguments without a lot of control flow around them
02:57replacathat's what I've always liked about it
02:57replacabut I get why people don't like it so much, too
02:57ChouserI'm a sucker for that kind of argument.
02:58replacabut I also have always disliked printf and it's only gotten worse in Java, C# etc.
02:59replacaonce you've learned to love ~[ and ~{ you're doomed :-)
02:59replacaI even added Roman numerals today
02:59Chouserare the ~ just to escape control chars and allow literal text inthe format string?
02:59replacanow that's a feature added by someone who stayed up way too late some night back in 1984 :-)
02:59replacayeah, like % in printf
03:00replacaso %s from printf is ~a in format
03:00ChouserIf so, could we flip that around and escape plain text instead?
03:00replacayeah, internally that's kind of what I do
03:00ChouserThen your example above would look like 15<S;^S;^S> or something
03:00replacait's actually a list of lambdas
03:01replacanow I'm confused
03:01Chouserin the (very few) format strings I've seen there appears to be very little plain text.
03:01replacayeah, that's cause lispers are mostly printing structures
03:01Chousernaw, don't be confused. I don't know what I'm talking about.
03:01replacaand don't care too much about the text
03:01replaca:)
03:02replacathe cool one is something like ~{~s: ~8.2d~}
03:03replaca*the cool one is something like ~{~s: ~8.2d~%~}
03:04replacawhich will print something like this (("corn" 82.5) ("wheat" 13.3)...)
03:04replacaas:
03:04replacaCorn: 82.50
03:04replacaWheat: 13.30
03:04replacaand you can line them up and stuff
03:06Chouserhm, a bit like destructuring.
03:11replacayeah, or regexes as someone said earlier
03:12replacain fact "destructuring regexes" would be cool
03:12replacawhere you got rid of the intermediate group crap and just went straight into sexprs
03:14ChouserI think that's what perl6 does -- regexs are callable and can compose other regexs linearly, or can use matched text in-place, etc.
03:15Chouserbacktracking must make that all rather interesting to think about
03:15replacayeah, it's too late for me to think about that now! :)
03:15replacatalk to you later - thanks for your help
03:16Chouser:-) yep!
03:54lisppaste8Chouser pasted "musings on exception handling" at http://paste.lisp.org/display/72867
04:03lisppaste8Chouser annotated #72867 with "benefits" at http://paste.lisp.org/display/72867#1
05:30knaprI compile successfulyl but when I try to run it fails. should a hmm.class fiel be able to run when you do java hmm ?
05:48lisppaste8knapr pasted "compile, run error" at http://paste.lisp.org/display/72868
05:48knapr^^ how should I run that program?
05:48knaprand when making jars how do I do that? it is just zipped class-files right? but that doesnt seem to do the trick
06:34hoeckknapr: there is the jar command which creates java archives
06:35hoeckknapr: to be able to run it with java -jar myprog.jar you need to put a manifest file into the jar
06:36hoeckknapr: you may also look into clojure.jar (opens with winrar) to see how it should look like
06:38knaprcant i just run the class file?
06:38hoeckof course yes
06:40knaprhow?
06:40knapri get exception thread main or something
06:40knaprshould the clojure function be called -main or main?
06:40hoeckmhh, -main needs an argument for commandline args
06:47hoeckand then run with java -cp your-path-to-classes;path-to-clojure.jar progs.comex.compileexample
06:49hoeckso yes, the function should be called -main
07:44Lau_of_DKGood afternoon everyone
09:10duck1123Can anyone tell me why (partition-by odd? [1 2 3]) blows the stack?
09:22AWizzArdduck1123: which svn?
09:23duck1123one sec
09:23AWizzArdis this in core?
09:23duck11231185
09:23duck1123partition-by is in seq-utils
09:24duck1123clojurebot: latest?
09:24clojurebotlatest is 1192
09:25duck1123contrib is rev 313
09:26durkaclojurebot: latest contrib is 313
09:26clojurebotOk.
09:26durkaclojurebot: latest contrib?
09:26clojurebotlatest contrib is 313
09:27duck1123clojurebot: latest contrib is 334
09:27clojurebotAlles klar
09:28duck1123I'm not running the latest
09:29AWizzArdlatest is also broken
09:30duck1123it works fine with a list, but not a vector
09:31duck1123it wasn't what I was looking for anyway. I wanted a seq broken into those that match, and those that don't. This wasn't it
09:33AWizzArdyou will have to write your own filter for that, if you want to do it efficiently
09:34AWizzArdotherwise you could simply say [(filter odd? numbers) (remove odd? numbers)]
09:34duck1123This is a one-off transformation script, so efficiency isn't a concern. I just thought there was a fn that did exactly that.
09:59craigmarshall9Can someone give me a hint towards implementing my own sort function please?
10:00RSchulzDo you need to implement sort, or do you just need to sort things?
10:00craigmarshall9I am trying to implement sort as a learning exercise, but am stuck at the first hurdle!
10:00RSchulzHave you implemented sorting algorithms before?
10:00craigmarshall9I just don't seem able to think in an FP way yet...
10:01craigmarshall9I could do it in python or similar, yes.
10:01RSchulzI'm still a complete rookie at FP.
10:02RSchulzWhich sort algorithm are you implementing?
10:02duck1123FP is a little different, because you're not going to be going around and mutating your variables
10:02lenstmerge sort seems a good match for FP
10:02duck1123have you implemented sort recursively in another language before?
10:02craigmarshall9I don't have a particular algorithm in mind (I wouldn't know the names or details of any, anyway), just anything that actually does a sort would be good enough at the moment.
10:03craigmarshall9No - the recursive nature is half the problem, and the "no variables" is the other half :-)
10:03craigmarshall9Actually, now I think about it, I have played with both quicksort and bubble sort in python.
10:03duck1123We had to do a recursive sort in my C++ class a couple weeks ago. My clojure experience really helped there.
10:04geofftYou can write a quicksort with FP if you have the function that duck1123 wanted earlier
10:04geofftsplit into sublists less the pivot and greater than the pivot, and then recurse.
10:04craigmarshall9Yes - that approach sounds familiar.
10:05craigmarshall9I think maybe I should be attempting easier things with clojure at this point though.
10:06duck1123it's interesting that functional and imperative programming have different ideas about what is easy
10:07waltersshouldn't be surprising, different languages are good at different things
10:07craigmarshall9I'm only just at the stage of "Add a supplied 'param' to the start, middle and end of a list/vector" as far as FP goes...
10:09craigmarshall9Okay - I'm going now, off to see if I can make quicksort work.
10:09craigmarshall9(thanks)
10:09duck1123does anyone remember the key command to change namespaces in slime off hand?
10:10drewrduck1123: I just type it at the REPL...
10:10drewr(in-ns '...)
10:10drewrThat and M-p are pretty sufficient.
10:11duck1123right, there is a command that'll prompt you inthe minibuffer with completion
10:11hoeckC-c M-p ?
10:11duck1123I found it while reading the slime manual, but can't remember it
10:12duck1123hoeck: that's it, thanks
10:12drewrCool, didn't know about that one.
10:13duck1123I was looking for a whay to implement that, when I discovered it had already been done. :)
10:13duck1123I just wish it used ido-completing-read
10:16craigmarshall9Well - with the power of google, I found this: http://swisspig.net/r/post/blog-200603301157
10:16craigmarshall9(LISP quicksort)
10:42duck1123There needs to be an (i-need 'symbol) function. Searches all namespaces for a function with that name. Uses that function if only one result, otherwise returns list of matching namespaces. for REPL use only.
10:43duck1123(i-need 'spit)
10:43AWizzArdduck1123: that function is available in Firefox, when you visit google.de :-)
12:13CardinalFangHi all. I'm eager to write some apps for Android, but I don't want to use Java. My worry is that importing Clojure will make my apps uncomfortably big, for a phone's memory. Before I dig in a lot, I want to know: If my code is simple, can I decouple the "eval" part of Lisp/Clojure, so I don't need a Lisp interpreter in the JVM? Maybe I can get the compilation part of Clojure to get from Lisp to a ".class" or ".jar" file, without the space used by an
12:13CardinalFang interpreter later.
12:14waltersCardinalFang: there's no interpreter
12:14CardinalFangWould you prefer the word "compiler"?
12:15waltersi doubt the compiler is very large, though i could be wrong
12:15CardinalFangIt doesn't have to be "very large" to be too large.
12:16rhickeyCardinalFang: there are lots of opportunities to trim things down, but no work done yet. I think a first target would be to get rid of metadata in the compiled code. Stripping out the compiler is a bigger task, as there is some utility code in there that is used even when not compiling. Dropping ASM would be a huge cut
12:25CardinalFangrhickey, ah, thanks.
12:25danm_good morning
12:27CardinalFang(Whew! I feared my question would reveal my shallow understanding of the internals of Lisps and seem incredibly silly.)
12:29craigmarshall9Does anyone know what this error means: Don't know how to create ISeq from: Integer
12:30walterscraigmarshall9: someone called e.g. (seq 42) ?
12:31hoeckcraigmarshall9: like in (map + 1)
12:38craigmarshall9I think it means I don't know how to treat a single integer as a sequence, but I don't think my code is trying to do that.
12:41craigmarshall9good evening :-)
12:48replacaQ: do proxies handle overloading? I'm trying to proxy java.io.Writer by overriding only the write method that is defined as abstract and I'm getting a "wrong number of args" exception on the write. This makes me think it's using my write func for a different overload.
12:48lisppaste8replaca pasted "Using a proxy to wrap java.io.Writer" at http://paste.lisp.org/display/72877
12:49replacabut I could be doing something stupid, too. :-)
12:49vogelrncraigmarshall9: Did you fix your problem? It might be that you forgot your argument list
12:51lisppaste8replaca annotated #72877 with "How I'm calling it" at http://paste.lisp.org/display/72877#1
12:51lisppaste8craigmarshall9 pasted "Boken quicksort" at http://paste.lisp.org/display/72878
12:53craigmarshall9Yes - that's what it looks like - I'm trying to debug a quicksort function, and I've spotted "(first coll)", but I thought coll was a single element collection at that point...
12:55Chouserreplaca: proxy method implementations can provide multiple arity bodies, just like regular functions.
12:56replacahmm, ok. Time to debug, I guess. Thanks!
12:57craigmarshall9I've got something broken somewhere!
13:10triddel1Can a def be made lazy? I have some clojure code that works just the way I want... I've even compiled it into a class and used from Java (which will be the main use.) Now I'm just trying to add a constructor for one string variable I need as parameterized state. Since this string is not available unless an object is created, other defs are try to execute (load configuration files) with no value and failing on compile.
13:10vogelrn1craigmarshall9: You need to have (list (first coll)) instead of (first coll) in the if statement
13:10vogelrn1otherwise it tries to concat an int
13:16vogelrn1craigmarshall9: you also need to handle the 0 count case separately from the 1 count case then
13:17replacaso proxy does support overloads, but it appears to have a small bug. If you don't override all the overloads of a method from an abstract class, it won't go to the superclass for the ones you didn't implement.
13:18lisppaste8replaca annotated #72877 with "Corrected implementation" at http://paste.lisp.org/display/72877#2
13:19replacaI would tell you I shouldn't need the second version of (write ...) in the proxy pasted here
13:43Chousertriddel1: your problem is at compile time?
13:44Chouserreplaca: are you sure you can still get to the 3-arg overload of write?
13:44triddel1Chouser: yes... probably my misuse of something.... I have a def like this: (def app-cfg (load-yaml-config (str solo-path file-sep "application.yaml")))
13:45Chouserreplaca: I think to provide both you might need the format (write ([cbuf off len] ...) ([s] ...))
13:45triddel1that tries to load a file... the path string is something I'm trying to now do as a constructor value
13:46Chousertriddel1: I think you may be able to test *compile-files* to get what you want.
13:46triddel1so clojure still executes this on compile I guess
13:46Chouser(def app-cfg (when-not *compile-files* (load-yaml-config ...)))
13:47craigmarshall9What does it mean when a function starts : (defn foo [[pivot & vals ]] - specifically the double square brackets?
13:47craigmarshall9Is that documented anywhere?
13:48Chousercraigmarshall9: that's destructuring. same format as 'let': http://clojure.org/special_forms#let
13:48triddel1Chouser: or maybe there is also a better way... what's easiest way to basically get a parameterized field value through a constructor? when I say :state state, this is not know to clojure functions right?
13:48craigmarshall9thanks
13:50triddel1Chouser: but I'll look at using *compile-files*
13:57replacaChoser: Hmmm, I don't know. Let me try. But my bigger point is that I shouldn't need the 1 argument version (since it's supplied by the superclass)
13:59replaca*Chouser: that is :-)
14:01chrisnhas anyone here used miglayout?
14:02AWizzArdOMG, Rich is Santa! http://www.dancingsantacard.com/?santa=6977602 :-)
14:04vogelrn1that's slightly frightening :P
14:06rhickeyho ho ho!
14:51craigmarshall9Is there a vuilt-in function that will tell me whether an item is in a collection? Like the python's "in"?
14:51craigmarshall9*built-in
14:51craigmarshall9I want to do (in? "w" '("x" "y" "z")) and get false, for example.
14:53hiredmanyou could use some
14:53hiredman(doc some)
14:53clojurebotReturns the first logical true value of (pred x) for any x in coll, else nil.; arglists ([pred coll])
14:53craigmarshall9Okay - thanks.
14:54pjb3craigmarshall9: clojure contrib has an includes?
14:54craigmarshall9okay - thanks for that too
14:54vogelrn1craigmarshall9: as I learned recently, specifically like (some #{item} coll)
14:55craigmarshall9excellent, I'd already made the in? function, but thought I'd better use a standard one if one exists.
14:55craigmarshall9And several do, apparently!
15:02RSchulzQ: Is destructing binding implemented in Clojure or Java?
15:02RSchulz"destructuring"
15:03rhickeyRSchulz: Clojure
15:03RSchulzExcellent, thanks.
15:03RSchulzDid you invent the algorithm yourself?
15:04rhickeynothing to invent really - I did first impl, Chouser has helped along the way, see destructure in core.clj
15:05craigmarshall9@ line 2260 approximately
15:06RSchulzOK. But it's similar to tree regular expressions, isn't it? Similar to RELAXNG schema validation? I could never find any good references.
15:07rhickeyhttp://groups.google.com/group/clojure/browse_frm/thread/38d2477f7d7133a/391f86cea65444eb
15:07craigmarshall9Q: How would one go about counting unique items in a list? Is it possible with reduce? I would normally start a new list and only copy the item across if it weren't already there, but isn't this impossible in clojure?
15:09craigmarshall9Another idea I've had is automatically map them to the keys of a hash-table, then return them, but ... Again this seems difficult.
15:09rhickeycraigmarshall9: (count (distinct your-list))
15:09craigmarshall9Ha! Thanks.
15:09RSchulzrhickey: Thanks for the reference.
15:10rhickeyRSchulz: I'm afraid it's rather mechanical, it's not unification or anything
15:10RSchulzYes, since it's one-sided, it wouldn't have to have the properties of unification. Still pretty interesting.
15:54duck1123okay, if I have a file containing a form, what's the best way to read that into a var? I can't figure out how to get a PushbackReader from a filename.
15:55Chouser(read (java.io.PushbackReader. (java.io.FileReader. "/tmp/foo.clj")))
15:57duck1123thanks
17:52replacacondp is awesome! It's a great addition to core.
18:04AWizzArdHNY!
18:07replacaAWizzard: right back at ya!
18:09RSchulzI'm clinging to 2008 for another 8 hours, 51 minutes and 15 seconds
18:11ChousukeI'm in 2009 already
18:12Chousukeso far so good.
18:18replacaI'm whipping around the Sun in the same orbit as RSchulz apparently
18:18hoeckhappy new clojure year 2009!
18:18replacaIn SanFran, we still have a while to go
18:19replacaDare we hope that 2009 is clojure's breakout year? Wouldn't that be fun!
18:20dreishI thought I read once about a way to get an unquoteable quote _without_ namespace resolution. I.e., '(foo ~(+ 1 2) bar) evaluating to (foo 3 bar) instead of (user/foo 3 user/bar). Anyone know of that?
18:22RSchulzreplaca: Not that orbit where you can make 364 gifts given at the rate of one every other day last only one year.
18:22RSchulz(I'm in Googleville, by the way.)
18:23duck1123<-- Michigan
18:23replacaha-ha! Nice place to be. I'm in SoMa/North Beach, depending on the tim eof day
18:24replaca*tim eof -> time of
18:27dreishI don't see anything in LispReader. My vote would be for #`
18:30replacadreish: I did that before, but I think it meant skipping backquote and doing some consing
18:30dreishreplaca: You know about the ~'sym trick, right?
18:31replacaWhich one is that? Maybe it's how I did it...
18:31dreishI have to admit this isn't an actual need. I was just playing around with quoting.
18:31dreishLeap second in 30 minutes, folks.
18:31replacaHold on tight!
18:31dreishreplaca: Inside a syntax-quote, ~'x will become x, rather than user/x. Go ahead and try it at a repl.
18:32dreishIn case you _really_ want variable capture, that's the way to do it.
18:32replacaThat's right, now I remember!
18:33dreish,(meta '#^Object x)
18:33clojurebot{:tag Object}
18:33dreish,(meta #^Object 'x)
18:34dreish(clojurebot doesn't want to say it, but the answer is nil)
18:34gnuvinceHave we got an interpreter?
18:34gnuvince,(+ 3 4)
18:34clojurebot7
18:34gnuvinceooh!
18:34gnuvinceWho did that?
18:34dreishclojurebot: author
18:34clojurebotexcusez-moi
18:35dreishHmm. Can't remember who wrote clojurebot.
18:35dreishIt's had that for at least a week or two.
18:35gnuvinceI think it's a Java bot
18:35cmvkkjust tell the bot to do something really lengthy and time consuming and then wait and see who comes in here and yells at you.
18:35gnuvinceDid they get around the obvious problems of side-effecting code?
18:36replacaI think chouser and hiredman were working on it
18:36replacaThey discussed the sandbox a lot
18:36dreish,(apply + (range 0 10000000))
18:36clojurebot49999995000000
18:36gnuvince,(println "hello")
18:36clojurebothello
18:36gnuvince,(throw (Exception. "sorry"))
18:36clojurebotjava.lang.Exception: sorry (NO_SOURCE_FILE:0)
18:37gnuvinceneat
18:37dreish,(time (apply + (range 0 10000000)))
18:37clojurebot"Elapsed time: 2811.943 msecs"
18:37clojurebot49999995000000
18:45RSchulzclojurebot is the brainchild of hiredmind.
18:45RSchulzclojurebot: hiredmind?
18:45clojurebotIt's greek to me.
18:45RSchulzclojurebot: hiredmind ?
18:45clojurebotTitim gan �ir� ort.
18:45RSchulzclojurebot: who is hiredmind?
18:45clojurebotPardon?
18:45RSchulzHe used to know his creator...
18:45Chouserclojurebot: hiredman?
18:45clojurebothiredman is an evil genius.
18:45RSchulzMaybe his KB wasn't fully restored after the crash.
18:45RSchulzThere we go.
18:46RSchulzOh. That's it, _hiredman_ not, hiredmind.
18:46RSchulzI like hiredmind...
18:47hiredmanclojurebot: who is your creator?
18:47clojurebotNo entiendo
18:47RSchulzWere your ears ringing?
18:47hiredmanChousuke has done a lot of great work in his clojurebot tree on github, I just haven't had time to do anything with it
18:48durkai think clojurebot needs an answering machine service
18:48RSchulzNot to mention and Elisa module.
18:49RSchulzclojurebot: I'm feeling down.
18:49clojurebotI don't understand.
18:49durkathat would fulfill the lisp/ai stereotype
18:49RSchulzclojurebot: Well, this time of year...
18:49clojurebotTitim gan �ir� ort.
18:49RSchulzYou know, Weisenbaum wrote Elisa to prove to people that AI was a sham. Instead, people confided in it!
18:50replacaActually, he proved that psychotherapy was a sham :-)
18:50RSchulzWell, _Rogerian_ psychotherapy, anyway...
18:53retepBTW: Happy new year. At least in germany.
19:24durkawhat's the idiomatic way to concatenate a bunch of strings?
19:24durkai.e. (concat root-path "/" class-name ".class")
19:25gnuvince,(str "foo" "bar" "baz")
19:25clojurebotfoobarbaz
19:26durkaaha
19:26durkawas about to use format, but i don't need any formatting so it would be overkill
19:36durkai'm writing a thing to automatically find missing imports