#clojure logs

2009-10-29

00:04qedwhats the quickest way to make (a .. z)
00:04qed(\a \b \c \d \e \f \g \h..\z)
00:05hiredman,(int \a)
00:05clojurebot97
00:05hiredman,(map char (range 97 (+ 97 25)))
00:05clojurebot(\a \b \c \d \e \f \g \h \i \j \k \l \m \n \o \p \q \r \s \t \u \v \w \x \y)
00:05hiredman,(map char (range 97 (+ 97 26)))
00:05clojurebot(\a \b \c \d \e \f \g \h \i \j \k \l \m \n \o \p \q \r \s \t \u \v \w \x \y \z)
00:06hiredman,(->> [\a \z] (map int) (apply range) (map char))
00:06clojurebot(\a \b \c \d \e \f \g \h \i \j \k \l \m \n \o \p \q \r \s \t \u \v \w \x \y)
00:06qedhiredman: thanks
00:06qedhiredman: is that the thrush combinator?
00:06qedive never seen it with the >>
00:07hiredmansort of
00:07mwoelker,(map char (range (int \a) (int \z)))
00:07clojurebot(\a \b \c \d \e \f \g \h \i \j \k \l \m \n \o \p \q \r \s \t \u \v \w \x \y)
00:07qedhiredman: what's ->> called
00:07mwoelkerdarn
00:07hiredmanit could also be the thrush, just slightly different
00:08hiredman->> puts stuff in the last arg position, -> in the first
00:08tomojwooby: suppose a chain ends in 1
00:08tomojthen it enters an infinite loop of 1's
00:08hiredman(function _ arg arg etc) vs (function arg arg etc _)
00:08tomojsearching through it for 89 will never terminate
00:08adityo~ good morning
00:08clojurebotPardon?
00:08adityo~good morning
00:08clojurebotHuh?
00:09hiredman:D
00:09adityo:)
00:09hiredman,((comp (partial map char) (partial apply range) (partial map int) list) \a \z)
00:09clojurebot(\a \b \c \d \e \f \g \h \i \j \k \l \m \n \o \p \q \r \s \t \u \v \w \x \y)
00:09tomoj"ends in 1" is misleading
00:10tomojbecause "ends in 1" really means "has an infinite number of ones as a tail"
00:10woobytomoj: thanks, i figured it out earlier
00:10tomojah
00:10woobytomoj: that's exactly what was happening
00:10Dawgmatixany clojure reading material recommendations ? pointers to both code and tuts appreciated
00:11woobytomoj: i fixed and it's running, est. 20 hours to answer :)
00:11tomojI always forget, will counting a lazy seq allow it to be garbage collected as it counts?
00:11tomojhaha
00:11tomojyeah I expect you have to come up with some clever solution
00:11hiredmanDawgmatix: you seen the rhickey videos?
00:11Dawgmatixhired yes I saw those
00:12woobytomoj: i wrote a has-89 function that recurs and checks for 1
00:13tomojI just wrote something which returns either 1 or 89
00:13tomojalso seems very slow
00:13woobyoh wow, it got it
00:13woobyrenice for the win
00:13hiredmanhttp://delicious.com/clojurebot is all the urls pasted to the channel, so you might dig through those
00:14tomojwooby: are you doing (count (filter ..)) ?
00:14woobytomoj: http://gist.github.com/221142
00:14tomojok, so I guess count will allow a lazy seq to be garbage collected
00:14woobyit appears so
00:15Dawgmatixthankoo hired
00:15Dawgmatixwill look through those
00:15woobytomoj: although an earlier version ran out of memory
00:15tomojI wonder how fast your digits-of is compared to mine
00:15woobytomoj: what does yours look like?
00:16hiredmanDawgmatix: all of the urls rhickey pasted are tagged with rhickey or rhickey_
00:17tomojwooby: https://gist.github.com/1b2c0b1a7fb5807caa3d
00:17tomojmy digits is 4 times slower than your digits-of
00:17tomojI guess because of all the function calls?
00:17Dawgmatixokay hired
00:18tomojwell, and arithmetic in general
00:19tomojfor some reason I thought math would be faster than dealing with strings
00:20woobyyou would think
00:20woobyprobably the fastest would be bit shifting
00:20piccolinoHow would one write "(require 'clojure.contrib.str-utils2 :as s])" in the form of :require for use in ns? I am getting compile errors no matter how I try to do it.
00:20tomojbut how would you use bit shifting for base 10?
00:21hiredmanwell, uh, you have a dangling ] there
00:21tomoj(:require [clojure.contrib.str-utils2 :as s])
00:21piccolinoOops, that [ is there in my code.
00:22piccolinoHm. Then it gives me a compile error : No such var: s/map-str.
00:23hiredman,(require '[clojure.contrib.str-utils2 :as s])
00:23clojurebotnil
00:23hiredman,s/map-str
00:23clojurebot#<str_utils2$map_str__7819 clojure.contrib.str_utils2$map_str__7819@90d0ea>
00:24hiredmanclojurebot: works on my machine
00:24clojurebothttp://haacked.com/images/haacked_com/WindowsLiveWriter/IConfigMapPathIsInaccessibleDueToItsProt_1446B/works-on-my-machine-starburst.png
00:24woobytomoj: something along the lines of digit = (number % (int)pow(10,++place))
00:25piccolinoHm, OK.
00:25woobytomoj: in a do/while, checking for digit == number where number is the input
00:27tomojoh, wow. when I say 4x slower, that was a math error
00:27tomojit's more like 40x slower
00:28tomojbut using (int (quot n 10)) instead of (int (/ n 10)) gives a 10x speedup, so now it is 4x slower
00:32tomojseems like (zero? n) is also significantly faster than (== n 0)
00:33hiredmanmakes sense
00:42woobytomoj: it's weird, you'd really think it would be faster
00:42woobytomoj: maybe it just boils down to function size :)
00:43hiredmanless code to execute is less code
00:43HecktorIs there a builtin function that returns the first not nil item in a sequence?
00:43tomojI guess read-string is very fast on single digits
00:44tomojand no math involved
00:44tomojyou get all the modulos by powers of ten automatically because it's a string
00:44hiredman,((comp first (partial drop-while nil?)) [nil nil 1 2 3 4])
00:44clojurebot1
00:45tomojhmm
00:45tomojis there any real difference between (first (remove nil? ..)) and (first (drop-while nil? ..))
00:45hiredmanhuh
00:45wooby,(first (drop-while #(nil? %) [nil nil 1]))
00:45clojurebot1
00:45tomojsince you're only asking for the first I guess they do the same
00:46hiredmanwooby: nil? is a function, you don't need to rewrap it like that
00:46piccolinohiredman: Ah, the problem is that map-str was not in str-utils2 1.0-compatible.
00:46hiredmantomoj: right
00:46woobyhiredman: oh right, thanks
00:46wooby,(first (drop-while nil? [nil nil 1]))
00:46clojurebot1
00:46Hecktorcool
00:46somnium,(some #(or % %) [nil nil nil 1])
00:46clojurebot1
00:47hiredman:(
00:47qedhiredman: sorry i lost my buffer
00:47qedwhat is ->>?
00:47hiredman,(some identity [nil nil 1])
00:47clojurebot1
00:47woobyfancy
00:47somniumI always forget about identity
00:47tomoj,(some identity [nil false nil 1])
00:47clojurebot1
00:47hiredmanqed: ->> is like -> but it puts the arg in the last spot instead of the first
00:48hiredman(f _ arg2 arg3) vs (f arg1 arg2 _)
00:48somnium,(str (count "identity") (count #(or % %)))
00:48clojurebotjava.lang.UnsupportedOperationException: count not supported on this type: sandbox$eval__4819$fn__4821
00:48qedhiredman: i think i maybe misunderstood how the thrush combinator works
00:48hiredmanerm
00:48qedit reverses computability right?
00:48wooby,(some identity [nil false 1])
00:48clojurebot1
00:48hiredmanit's like Tax = xa
00:49qedI don't know that
00:49qedwhat is T
00:50hiredmanthe thrush
00:50hiredmanso (-> a b) = (b a)
00:50woobyseems like it's function un-nesting kinda
00:50qedhiredman: right, reverses computability
00:51hiredman(->> a b) = (b a)
00:51hiredmanbut (-> a (b c)) = (b a c) and (->> a (b c)) = (b c a)
00:51woobyso (->> a b c) = (c (b a)) ?
00:52hiredmanwithout args -> and ->> are identical
00:52qedi gotcha
00:52qedthats a neat little structure
00:52hiredmanit is
00:52qedi like it
00:52qedtbh i feel like im sort of cheating by using it
00:53tomojdid I read that rhickey doesn't like autocurrying?
00:53hiredmanyou just get this sort of flow data through your functions
00:53tomojwell I don't expect you to know whether I read that or not, but I mean, is that true?
00:53hiredmantomoj: dunno
00:54hiredmanI would love to have autocurrying, that is the main reason I want metadata on functions
00:55hiredmanto keep track of arity information
00:55tomojhmm
00:55tomojwhat about functions with overloaded arity
00:55hiredmanit's tricky
00:56qedwho asked about autocurrying?
00:56tomoj<-
00:56qedtomoj: http://groups.google.com/group/clojure/msg/d20660b459abffeb
00:56tomojwhy thank you
00:56qed:)
00:59tomojI just noticed the example in clojure.http.resourcefully uses https
00:59tomojso I guess clojure.http.client can do https? someone was asking about that the other day
01:18chouser~seen maacl
01:18clojurebotmaacl was last seen quiting IRC, 788 minutes ago
01:21hiredman,(int (/ 788 60 60))
01:21clojurebot0
01:21hiredman,(int (/ 788 60))
01:21clojurebot13
01:21hiredman,(int (/ 788 60 24))
01:21clojurebot0
01:21hiredman,(double (/ 788 60 24))
01:21clojurebot0.5472222222222222
01:21chouserhiredman: ah, thanks.
01:21chouser:-)
01:43wavis_,clojure.contrib.seq-utils
01:43clojurebotjava.lang.ClassNotFoundException: clojure.contrib.seq-utils
01:43hiredman,(require '[clojure.contrib.seq-utils :as seq-utils])
01:43clojurebotnil
01:44felzixis there any way to get more information out of a NullPointerException?
01:44felzixline number would be awesome
01:45hiredmandepends on what is generating it
01:45felzixis there a way to determine that?
01:45tomojI hate when I don't get line numbers
01:45hiredmanwell, if there is a way to get a line number you will get one
01:45hiredmanso if you aren't getting one, well, :(
01:46tomojclojure backtraces are largely still mysterious to me
01:46felzixI mean, I know the general location of the problem
01:46hiredmantomoj: have you seen clojure.stacktrace?
01:46tomojhiredman: no. I will investigate
01:46tomojI've just been peering at what slime gives me
01:47hiredmanit may be similar to what you get from slime
01:47tomojbunch of extra crap you don't care about?
01:47hiredmanI don't use slime
01:47tomojI mean, usually what I would expect to be at the top of the backtrace is buried deep down somewhere
01:47tomojunder a bunch of internal crap
01:49hiredmanhttp://gist.github.com/221188
01:49wavis_,seq-utils
01:49clojurebotjava.lang.Exception: Unable to resolve symbol: seq-utils in this context
01:50hiredmanwavis_: seq-utils is just an alias for the clojure.contrib.seq-utils namespace now
01:50tomojyeah, like that crap
01:51hiredmanuh, that is nice cleaned up stack trace
01:51tomojwell, when I do something like that in a file, the line number I do it on is not on the top of the trace
01:51tomoj(and sometimes isn't there at all)
01:52hiredmanI almost always get a line number from a loaded file
01:52tomojfor example your second attempt doesn't have a NO_SOURCE_FILE:XX
01:52hiredmanbut if I am just dumping stuff into the repl
01:52Raynes-My heavens, how did I ever life without Paredit.
01:52tomojRaynes-: :D
01:53hiredmansecond attempt?
01:53tomojwhen you just do (e) or whatever it was
01:53hiredman(e) is a sort of prettyprinter for *e
01:53hiredmancomes with clojure.stacktrace
01:53tomojooh, I get it
01:53RaynesI've never used Paredit before. Just straight Emacs. My life has been empty up until this point.
01:53tomojI thought that was causing another error
01:55tomojhttps://gist.github.com/9f0155f80915338175ad
01:56tomojmaybe swank is screwing it up
01:57tomojit doesn't show the file in which the exception occurs at all
01:58hiredmanwell, makes me feel good about not using emacs
01:58hiredmanwhat is the file name?
02:00tomoj.../clojure/contrib/json/read.clj
02:00tomojI changed something around in there to intentionally cause an error
02:00tomojmaybe next time I have a real error with a bad stacktrace I will try it in a pure repl and see if swank is the problem
02:00tomojif so that really needs to be fixed
02:01hiredmanmaybe talk to technomancy
02:01tomojit seems like the top section of the stacktrace might be missing or something
02:02tomojso far I have yet to have a nasty debugging session in clojure anyway :)
02:05mikehincheytomoj: hit 1 to see the cause
02:05tomojmikehinchey: wat
02:05mikehincheytomoj: on the slime stacktrace screen
02:05tomojyeah I understood
02:05tomojthat was my "wat" of disbelief
02:05tomojthank you!
02:06tomojI don't think I ever even read the second restart
02:06hiredmanI almost always end up with (prn x) and (doto x prn) sprinkled around
02:06tomojI hate when I start doing that
02:06mikehincheyI liked it better when the cause was shown on the same screen instead of a "restart"
02:07tomojI'm just happy I can see the cause now at all
02:07tomojnow I just have to figure out how to get slime debuggers for compile errors
03:07wavis_does anyone know if there is a library out there for composing math expressions and treating them as numbers?
03:09wavis_for example
03:09wavis_,(/ (+ 1 (Math/sqrt 5)) 2)
03:09clojurebot1.618033988749895
03:11wavis_would instead give just a composed expression
03:11arsatikiThere's clojuratica for interfacing with mathematica
03:12wavis_hmm... does mathematica run headless on linux?
03:12woobysilly question, how can i test if a number is whole?
03:13arsatikiwavis: I have not used clojuratica myself, but I assume it just uses the mathematica kernel, not the GUI
03:14wavis_i will look into that then. thanks!
03:15wavis_i could always do something like (list / (list + 1 (list #(Math/sqrt %) 5)) 2)
03:16wavis_... or not
03:16felzixwooby: You mean test if a float or double is a whole number?
03:17wavis_,(= 0 (rem 4.5 1))
03:17clojurebotfalse
03:17wavis_,(= 0 (rem 4.0 1))
03:17clojurebottrue
03:17felzixyou could do (= (int 1.1) 1)
03:17felzix,(= (int 1.1) 1)
03:17clojurebottrue
03:17felzixhmm
03:18felzixnvm..
03:18felzixah, duh. (= (int 1.1) 1.1)
03:22Licenser,(= (int 1.1) 1.1)
03:22clojurebotfalse
03:22felzixbut ,(= (int 1.0) 1.0)
03:22felzix,(= (int 1.0) 1.0),
03:22clojurebottrue
03:23Licenserthat makes sense
03:23Licenserthey have the same value
03:23felzix,(int 1.0)
03:23clojurebot1
03:23felzixit just means floats can be usefully compared against integers
03:23Licenserside quetion, is there a ofline documentation for clojure?
03:24Licenserand that is good
03:24felzixBest I know of is downloading the api html file.
03:24Licensernarf
03:25felzixwooby: does that answer your question?
03:25arsatikiL: you can always use the doc in REPL :)
03:25Licenserarsatiki: I know, but it's not as nice as a document you can work with
03:27woobyfelzix: sure does, thank you
03:27woobyi don't think i've ever had as much fun programming as i do with clojure
03:27woobywhat's with this language!
03:28Licenserwooby: did you try ruby?
03:28Licenserbut I agree clojure is fun, yet it gets very frustrating when you start to get java exeptions :/
03:28arsatikitrue
03:28woobyLicenser: yeah :\
03:29woobythe java interop is awesome but dealing with java stuff comes with its own shenanigans
03:29Licenserwhich is currently the one but issue I have with clojure, that and a sometimes less then helpful documentation
03:29Licenserbut it's still a really incredible language
03:30Licenserand considering it is only 2 years old, it is just amazing
03:30woobyit really is
03:30woobyruby, that's the dynamically typed scala variant isn't it? ;)
03:31Licenserteehee I think ruby is older then scala and is't a functional language either
03:32woobyi'm kiddn', yeah its much older... but it does have nice functional bits
03:32woobystuff just all uses smalltalk names
03:32LicenserI know you can do functional programming in ruby me thinks, and it is a joy to program too most of the time
03:33LicenserOne thing that gets me sad so is that you have a hard time as soon as you want to do anything in paralell
03:33LicenserWhich is the reason why I'm here :P so good that ruby has a horrible concurrency support, I'd have missed a lot
03:37woobyis there something like split-between, like for splitting the seq [1 2 3 3 2 1] between 3 and 3 given a comparator like (fn [a b] (== a b))?
03:37woobyor just (== %1 %2) i suppose
03:38Licenserdon't forget the # but I#ve no clue
03:39hiredman,(doc split-with)
03:39clojurebot"([pred coll]); Returns a vector of [(take-while pred coll) (drop-while pred coll)]"
03:39woobyhiredman: it seems like your pred is only fed 1 element at a time though
03:40hiredmancorrect
03:40Licenserwhat would you expect to happen when you encouther [1 2 3 4 3 2 1]?
03:40wavis_you could (partition 2 1 %) your list and get the index with which to split the original
03:42woobyLicenser: it would return the whole seq
03:43Licenserhmm partitioning won't work sice it might partition with 2 3 and then 3 2
03:43Licenserwooby: you have a tricky question
03:44hiredmanit's not tricky, but the clojure sequence library is designed for laziness, so nothing scans more than one element at a time, so if you want that you have to roll your own
03:44LicenserI say reduce is the way
03:44Licenserthere you can know the last element
03:44Licenserbut it'd be ugly slow I think
03:45woobyyeah
03:45Licenserhmm actually not soo much
03:45hiredmanwhy would you need to know the last element?
03:45Licenseras you store the lists in reverse order
03:45woobyi'm going with take-while since i'm only concerned about the first chunk
03:45wavis_,(let [l [1 2 3 3 2 1] p (partition 2 1 l)] (split-at (count (first (split-with #(= %1 %2) p))) l))
03:45clojurebotjava.lang.RuntimeException: java.lang.IllegalArgumentException: Wrong number of args passed to: sandbox$eval--4944$fn
03:45hiredmanoh
03:45hiredmanlast as in previous
03:45Licenserwavis_: take 1 2 3 4 4 3 2 1 as list it breaks it already
03:45Licenserhiredman: yap
03:47Licenserthe make a new list thing is the tricky part but that code would work I think
03:48woobyah, yeah a fold left
03:48LicenserI think I slowly get the hang of lisp
03:52hiredman,((juxt :a :b :c) {:a 1 :b 2 :c 3})
03:52clojurebot[1 2 3]
03:53Licenser,(doc juxt)
03:53clojurebot"([f] [f g] [f g h] [f g h & fs]); Alpha - name subject to change. Takes a set of functions and returns a fn that is the juxtaposition of those fns. The returned fn takes a variable number of args, and returns a vector containing the result of applying each fn to the args (left-to-right). ((juxt a b c) x) => [(a x) (b x) (c x)]"
03:53Licenserwhat the hel is a juxta position?
03:55hiredmanit means, uh, sort of side by side
03:56hiredman~google define juxtaposition
03:56clojurebotFirst, out of 60900 results is:
03:56clojurebotjuxtaposition - definition of juxtaposition by the Free Online ...
03:56clojurebothttp://www.thefreedictionary.com/juxtaposition
03:56hiredmanyeah
03:58wavis_,(let [l [1 2 3 3 2 1] p (partition 2 1 l)]
03:58wavis_ (split-at (inc (count (first (split-with #(not (= (first %) (first (rest %)))) p)))) l))
03:58clojurebotEOF while reading
03:59wavis_,(let [l [1 2 3 3 2 1] p (partition 2 1 l)] (split-at (inc (count (first (split-with #(not (= (first %) (first (rest %)))) p)))) l))
03:59clojurebot[(1 2 3) (3 2 1)]
03:59Licenser,(let [l [1 2 3 4 4 3 2 1] p (partition 2 1 l)] (split-at (inc (count (first (split-with #(not (= (first %) (first (rest %)))) p)))) l))
03:59clojurebot[(1 2 3 4) (4 3 2 1)]
03:59Licensernice
04:00wavis_needs more testing, like with zero length seqs etc...
04:00wavis_g'night all
04:03Licenserokay very strange question, how can I join the clojure google group w/o a google account?
04:22Licenserbye people
04:22Licensersee you when I'm back home :D
04:23Fossihi
04:32hiredman,(-> (->> [1 2 3 3 2 1] (partition 2) (split-with (comp not (partial apply =))) (map (partial apply concat)) ((juxt identity identity)) ((flip update-in) (juxt first (comp (partial take 1) second)) [0])) (update-in [0] (partial apply concat)) (update-in [1] (comp rest first rest)))
04:32clojurebot[(1 2 3) (3 2 1)]
04:32hiredmanhmm
04:33hiredman,(-> [1 2 3 3 2 1] (->> (partition 2) (split-with (comp not (partial apply =))) (map (partial apply concat)) ((juxt identity identity)) ((flip update-in) (juxt first (comp (partial take 1) second)) [0])) (update-in [0] (partial apply concat)) (update-in [1] (comp rest first rest)))
04:33clojurebot[(1 2 3) (3 2 1)]
04:33hiredmanflip is not in core though :(
04:35hiredmanoh
04:53tomojclojure.contrib.http.agent gives me an InputStream for the response body
04:53tomojI wrap this in an InputStreamReader and then a PushbackReader
04:53tomojreading from the PushbackReader gives -1 (eof) immediately
04:53tomojwhile if I don't wrap and just read from the InputStream, I get the expected bytes from the response body
04:53tomojideas?
04:55tomojoh, actually, that's not what's happening
04:55tomojit's just that calling stream inside the handler gives a different input stream, and that input stream eofs immediately for some reason
04:55tomojhmm
05:22ordnungswidrig*knock* *knock*
06:04Licenserwow they've free wifi at the airport wooh!
06:06woobywooties
06:07woobyhttp://gist.github.com/221336 fruits of the evenings efforts
06:11adityowooby: cool
06:11arsatikiwooby: since keywords act as functions, you can just say (map :leg triangles)
06:15ysmolskyhow to get access to meta reader data from runtime?
06:16woobyarsatiki: oh awesome thanks
06:16ysmolskyi want to pass function a to a function b and from inside of the function b to read actual reader meta data of function a
06:21Licenserclojure is really really dense, I'm impressed I've started to write a map application as web page and it has < 200 lines
06:22Licenserhmm since there are two ways to access map keys (:key map) and (map :key) which is the preffered one?
06:23ysmolskywhich is read better in the context i guess
06:25Licenserhmm so no guideline
06:28ysmolsky(defn a [x] x)
06:28ysmolsky(defn b [fun] (extract real name of "fun", arguments "fun" has, return it))
06:28ysmolsky(b a) -> {:name "a", :args [x]}
06:28ysmolskyhow do i make function b? :)
06:31Chousukeyou can get the args via reflection, but you can't get the name in all cases
06:32Chousuke(b (fn [] foo)) <- what is the name? :)
06:32ysmolskyi need only for non anonymous cases. just cannot figure out how to make without macros.
06:32arsatikiysmolsky: if you have access to the var, then you can find the information inside the metadata
06:33ysmolskyi know, but how to access it?
06:33ysmolsky(defn expand-method [m]
06:33ysmolsky (let [mmeta ^#'m]
06:33ysmolsky mmeta))
06:33ysmolskygives me exception: Unable to resolve var: m in this context
06:33Chousukethat won't work :)
06:34Chousukevar takes a symbol as a parameter. it's not evaluated
06:34ysmolskyah.. well, which direction to look for?
06:34ChousukeI must first question the purpose of this endeavour ;)
06:35Chousukeyou really shouldn't depend on the names of things :/
06:35ysmolskyok. answer will be long. i want to make life easy for one who will use my rpc server, so one can pass just functions to the server fun like this:
06:35ysmolsky(create-jsonrpc {:host "localhost"
06:35ysmolsky :port "3000"
06:35ysmolsky :methods [foo bar baz]})
06:36Chousukeand they need to know those "foo" "bar" "baz" strings?
06:36ysmolskyafter that i need to create map like name of function to real functions symbols
06:36ysmolskythose foo bar are funtcions
06:36Chousukesymbols? why symbols?
06:36Chousukewhy not just the functions? :P
06:37ysmolskyoh not symbols, but functions
06:37ysmolskyjust to be able to call them by the "string"
06:37Chousukeright. so pass in a map of name -> fn instead
06:38ysmolskyi know, but i like challenges :)
06:38Chousukethere's no way for you to win this challenge
06:38arsatikior you could pass the vars :methods [#'foo #'bar ...]
06:38arsatikibut that is sucky.
06:38Chousukeand would fail with anonymous functions.
06:39Chousukejust let the user pass in a map
06:39arsatikiyeah
06:39Chousukethat way, it'll be more flexible.
06:39ysmolskyi see. just wanted to get know how far reflection of clojure goes :)
06:39Chousukefunctions don't know their names because in most cases they don't have one.
06:39ysmolskyok
06:39Chousukeor might have multiple. or one name might map to multiple functions.
06:40Chousuke(because of closures)
06:40Licenserysmolsky: do you have a page about your RPC server?
06:40LicenserI'd be interested in such a thing
06:40ysmolskyanyway, i still to get to know the count of arguments of the function. is there a way?
06:40Chousukeyou can use reflection for that.
06:40Chousukeit's tricky though.
06:40ysmolskyLicenser: not yet, but i will drop url here when its in github
06:41ChousukeI think chouser had some code for it somewhere.
06:41Licenserthanks
06:41Chousukeclojurebot: pastes
06:41clojurebotNo entiendo
06:41Chousukehm
06:42arbschta function doesn't necessarily have one count of arguments
06:42Chousukeyeah.
06:42ysmolskyi know that i could just try to apply whatever user send to function and see if it thrown exception, but, it would be great to know it in advance.. or maybe not
06:43ysmolskyok, i will try exception way for the beginning
06:44Chousukeusing reflection involves taking advantage of implementation details, too, so I guess the exception method is safer.
06:44Licenserwhat is your JSON RPC based on? Restful HTTP?
06:46ysmolskywell, i want to make 1st version more general, but i'm planning to add restful too ..
06:47ysmolskydo you have any example of well designed restful lib for java/python?
06:48LicenserNope sadly not but I was thinking about something like that, a easy way to export resources / functions on a REST interface
06:49shmichaelHello everyone. I am trying to test if symbols in my code are macros. I tried writing a macro? function.
06:49shmichael(defn macro? [exp] (-> exp var meta :macro))
06:50shmichaelThis yields #<CompilerException java.lang.Exception: Unable to resolve var: exp in this context (NO_SOURCE_FILE:265)>
06:51ysmolskyhehe, same problem
06:51shmichaelIf I explicitly use a specific symbol, the expression is valid
06:51shmichael,(-> let var meta :macro)
06:51clojurebottrue
06:51Licenserysmolsky: but this is clojure you don't need to bother about java or pyhtin
06:53ysmolskyLicenser: just.. I have never used restful libs, so gotta to see how thats done in popular libs, not only python or java, maybe ruby, whatever actually
06:53Chousukeshmichael: the var special form doesn't evaluate its argument, which is your problem
06:53Chousukeshmichael: you're always asking for the var named "exp"
06:53shmichaelChousuke: Is this a flaw in var or am I doing something wrong?
06:53Chousukeshmichael: it's not a flaw in var
06:53Chousukeshmichael: you need to make your macro? a macro :)
06:54ChousukeOR you can have it take a symbol as an argument
06:54Licenserysmolsky: my idea was basing it on compojure you can create a REST-Full HTTP frontend with that
06:55Chousukelike: (defn names-a-macro? [sym] (-> (resolve sym) meta :macro))
06:55Chousuke,(:macro ^(resolve '->))
06:55clojurebottrue
06:55Chousuke,(:macro ^(resolve 'foo))
06:55clojurebotnil
06:55Licenserback when I tried I had barely any idea of clojure or compojure so it went horrible wrong, I quite to work with clojure for 2 weeks :P
06:55ordnungswidrigLicenser: uh, I hear REST on top of compojure. Did I miss anything? Is there still a library?
06:55Licenserhm?
06:55ordnungswidrigs/still.*y/a library yet/
06:56shmichaelChousuke: thanks, I will try it out
06:56LicenserCompojure is needed to take care of the HTTP part, (you can use anything else too I guess) but the REST protocoll is up to the user to implement
06:57Licenseryou can just use the default compojure routes to make a restufll interface
06:57ordnungswidrigLicenser: do you know erlang's webmachine?
06:57Licenserordnungswidrig: nope, never worked with erlang
06:57ysmolskyLicenser: I see your point. when I will have some general json rpc server I can add more specified solutions..
06:57Licenserysmolsky: mongodb and with that somniums mongodb driver for clojure might be interesting
06:57ordnungswidrigLicenser: making a correct restful interface is hard. implementing correct HTTP is hard. compojure / ring are very basic.
06:58ordnungswidrigLicenser: Take a look at webmachine, at least at the monster flow diagram.
06:58ordnungswidrigLicenser: this was very enlighting to me.
06:58ordnungswidrigLicenser: http://bitbucket.org/justin/webmachine/wiki/WebmachineMechanics
06:58ordnungswidrigLicenser: http://bitbucket.org/justin/webmachine/wiki/BigHTTPGraph
06:59LicenserI know that it's hard but it wraps the webserver icely for clojure quite nicely
06:59Licenser:P
06:59ordnungswidrigLicenser: yes, but the decision on E-Tag, how to negotiate content-types and so on is what compojure doesn't for you.
07:00LicenserI've no idea what E-Tag is :P
07:00Licenserand yes that's true
07:01Licenserordnungswidrig: good greif that is a graph
07:01ordnungswidrigLicenser: You see, speaking good HTTP is very hard. I'm doing web based development for 10+ years now. I remember a time where the only interaction was something like a "query" field in HTML and CGI for the NCSA server. Yet, since webmachine I know I spoke only a whimsy dialect of pidgin HTTP.
07:02shmichaelOK, for the record here is my macro? implementation:
07:02shmichael(defmacro macro? [exp] (if (symbol? exp) `(:macro ^(resolve '~exp)) false))
07:03Licenserordnungswidrig: I know HTTP is horrible complex
07:03ordnungswidrigLicenser: for a project I'm currently sketching a REST library on top of compojure. For every resource you define some multimethods which represent the decision nodes in webmachines graph.
07:04Licenseroi cool will it be OpenSource?
07:05ordnungswidrigLicenser: so, for a simple resource which is available with GET in a singe content type, you'll be able to do sth. like
07:06ordnungswidrig(defmethod clojure-rest/content-types-provided ::article
07:06ordnungswidrig [_ _ _]
07:06ordnungswidrig { "text/html" (fn [_ request context]
07:06ordnungswidrig (let [id (urldecode ((request :route-params ) :id))]
07:06ordnungswidrig (str "Hello, article no." id ". The message is: " ( context :message ) )))})
07:06ordnungswidrig
07:06woobyordnungswidrig: are you doing it state machine style?
07:06Licenserlooks nice
07:07ordnungswidrigwooby: I try to avoid state ;-) The "context" will be passed along when working on a request
07:08Licenserhmm isn't one of the 'issues' with http that it is stateless?
07:08avital-,(symbol? let)
07:08clojurebotjava.lang.Exception: Can't take value of a macro: #'clojure.core/let
07:08ordnungswidrigLicenser: Btw. I'll be happy when I pushed the whole shebang to github and I merge the first improvement from a person completely foreign to me. Yes, it will be opensource. At least I hope it will be good enough.
07:08ordnungswidrigLicenser: yes, http is stateless
07:09ordnungswidrigLicenser: what do you mean by issue? Positive or negative?
07:09LicenserThat depends on what you do :P
07:09Licensersomtimes it is negative, sometimes positiv
07:09ordnungswidrigLicenser: you started the issue on stateless, so you decide :-)
07:09woobyLicenser: a state machine is an abstraction of a system that transitions between various 'states'
07:10Licenserand glad to hear that, I'll look into it once it is gitted
07:10Licenserordnungswidrig: what I mean is, it isn't either negative nor positve in general, at least not in my eyes :P that sometimes is a issue, then it's negative
07:10ordnungswidrigwooby: If you want, it is a statemachine. But a DAG of states. And the state is held by the "instruction pointer" :-)
07:10Licenserand sometimes it does not matter then it's positive
07:10woobylol
07:11woobyordnungswidrig: thanks, i like the idea now ;)
07:11ordnungswidrigwooby: a state machine in the sense of "very-big-bunch-of-ifs-and-conds"
07:12ordnungswidrigto unknot the pile-of-ifs I'm looking still for a good abstraction. Something like an Either Monad.
07:13Licenserordnungswidrig: you're from germany?
07:14woobymaybe a like a formal grammar, which your request handler evaluates input against?
07:14avital-,(resolve 'map)
07:14clojurebot#'clojure.core/map
07:15ordnungswidrigLicenser: Neu-Ulm, Germany
07:15avital-((fn [map] (resolve 'map)) 2)
07:15LicenserWe should start to make a german Clojure community, you're the 3rd german I find here
07:15hoeck1Licenser: +1
07:15Licenserthen hoeck1 is the 4th I find :P
07:16avital-,((fn [map] (resolve 'map)) 2)
07:16clojurebot#'clojure.core/map
07:16woobyi too am from germany
07:17hoeck1Licenser: sth like a clojure-de channel would be nice, but I suspect it would get much traffic
07:17woobyborn in munster, moved to US when 2, more fluent in clojure than german :\
07:18LicenserPoor you wooby ;) you missed out on some darn good ruladen
07:18ordnungswidrigwooby: have a look at webmachines http diagramm. currently the imlementation is like (if-not (valid-method? resource request context) [501 "not implemented"] (if-not (content-type-accepted? resource request context) [415 "Unsupported media type"] (generate-body resource request context)))
07:19ordnungswidrigbtw +1 for a german clojure user group geclug
07:19Licenserhoeck1: noone stops us to make a clojure-de channel but all the smart guys hang out here so I'm not sure if it would make much sense
07:19hoeck1Licenser: exactly
07:19Licenseror we teach them german
07:20ordnungswidrigLicenser: that'll be harder than lerning some clojure
07:20Licensertrue
07:20Licenserwe could make a clojure to german translator in clojure
07:20ordnungswidriganybody know how to set the line width in ERC?
07:26hoeck1ordnungswidrig: maybe: m-x customize-variable [ret] erc-fill-column
07:28ordnungswidrighoeck1: let's set 123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.
07:28ordnungswidrig
07:28ordnungswidrighurray
07:28ordnungswidrigis there a state-monad available in clojure?
07:29woobyyou could do that fairly simply, no?
07:30ordnungswidrigwooby: i'm lazy :)
07:30Chousukeordnungswidrig: clojure.contrib.monads
07:31ysmolskytests facility was moved to clojure.core?
07:32woobyawesome, state-m-until
07:34Chousukeysmolsky: yes.
07:34Chousukeit's now clojure.test
07:40gerry_(deftype person [name age])
07:41gerry_(person "gerry" 18)
07:41gerry_java.lang.StackOverflowError
07:41gerry_??
07:42gerry_hello to all
07:44Chousukeis that the new deftype?
07:45Chousukeheh.
07:45gerry_yes
07:46gerry_i dont know what's wrong
07:47ordnungswidrigok, paredit together with viper is somewhat confusing
07:48gerry_(doc deftype)
07:48gerry_-------------------------
07:48gerry_clojure.core/deftype
07:48gerry_([name [& fields] & [[& interfaces] & methods]])
07:48gerry_Macro Dynamically generates compiled bytecode for an anonymous class with the given fields, and, optionally, interfaces and methods. The Name will be used to create a dynamic type tag keyword of the form :current.ns/Name. This tag will be returned from (type an-instance).
07:48clojurebot"clojure.contrib.types/deftype;[[type-tag constructor-name docstring? attr-map?] [type-tag constructor-name docstring? attr-map? constructor] [type-tag constructor-name docstring? attr-map? constructor deconstructor]]; Define a data type by a type tag (a namespace-qualified keyword) and a symbol naming the constructor function. Optionally, a constructor and a deconstructor function can be given as well, the defaults being
07:48gerry_A factory function of current.ns/Name will be defined, overloaded on 2 arities, the first taking the designated fields in the same order specified, and the second taking the fields followed by a metadata map (nil for none) and an extension field map (nil for none).
07:48gerry_See defclass for a description of methods and generated interfaces. Note that overriding equals and hashCode is not supported at this time for deftype - you must use the generated versions.
07:50gerry_clojurebot? ;(
07:51gerry_any ideas?
07:52ordnungswidrigis there a if-not-let
07:56gerry_no
07:56gerry_if-let not work?
07:57ordnungswidriggerry_: yes, but there is a if-not as well. but I look for something else:
07:58raekwhat is the preferred way to convert a string to an int?
07:58adityoInteger/parseInt
07:58raek(Integer/decode s) ?
07:58raekkthx
07:58wooby,(read-string "5352")
07:58clojurebot5352
07:59raekah, that's neat
07:59raek,(read-string "900000000000000000000000000000000000000")
07:59clojurebot900000000000000000000000000000000000000
08:00hoeck1gerry_: the type creation works, but the printing fails
08:00raek,(Integer/parseInt "900000000000000000000000000000000000000")
08:00clojurebotjava.lang.NumberFormatException: For input string: "900000000000000000000000000000000000000"
08:00adityocool
08:00gerry_hoeck1: type not support print yet?
08:02ordnungswidriggerry_: if have a test function that returns [true, value] or [false, value] and I'd like to handle it nicely. (foo test if-form else-form) where if-form and else-form are beeing passed the value.
08:02hoeck1gerry_: it should be printed somehow, so I think its a bug
08:02ysmolsky,(BigInteger. "990")
08:02clojurebot990
08:02ysmolsky(BigInteger. "abc" 16)
08:03ysmolsky,(BigInteger. "abc" 16)
08:03clojurebot2748
08:03ysmolsky ,(BigInteger. "ff123")
08:03ysmolsky,(BigInteger. "ff123")
08:03clojurebotjava.lang.NumberFormatException: For input string: "ff123"
08:03ysmolskyBigInteger is faster than read-string
08:04gerry_Person
08:04gerry_#<user$Person__22 user$Person__22@1a897a9>
08:04gerry_type can be printed, but not for objects
08:05gerry_(Person 1 1) => got stackoverflowerror
08:07gerry_hoeck1: right, object exists,i can test it
08:07gerry_(def me (Person "gerry" 18))
08:08gerry_(:age me) -> 18
08:09hoeck1you also could do a (defmethod print-method :user/person [the-person writer] (print-method (str the-person) writer))
08:10raekhmmm, I can't get my clojure script working
08:10raekit just quits without printing anything
08:10gerry_hmm, permethod for perobject
08:11adityo,(time (Float/parseFloat "123.75243"))
08:11clojurebot123.75243
08:12clojurebot"Elapsed time: 0.222 msecs"
08:12raekwhat are the differences between an ordinary clojure program and a clojure script?
08:12adityo,(time (read-string "123.75243"))
08:12clojurebot123.75243
08:12clojurebot"Elapsed time: 0.19 msecs"
08:13ambientraek there are differences?
08:13ysmolskyadityo: dont' benchmark on single call
08:14raeklike (ns your-ns (:gen-class)) and (defn -main [& args] ...)
08:14adityoysmolsky: true!
08:14raekbut I don't know if I have to use those
08:14tomojif you want an executable jar, you do
08:15raekoh, wait
08:15raekjava -cp clojure.jar clojure.lang.Script script.clj
08:15raeknot
08:15raekjava -cp clojure.jar clojure.lang.Script < script.clj
08:15tomojclojure.main
08:17raekok, got it working now
08:17hoeck1gerry_: it seems that the problem is, that there is no print-method defined for the generated type
08:17raekthank you all
08:18gerry_hoeck1: yes
08:18hoeck1gerry_: and the :default print-method tries to remove the :type tag from the object
08:18gerry_oh?
08:19hoeck1gerry_: for which type would then return a java object, so it could be printed at least as a plain java object
08:19jagguliadityo, G0SUB: hi
08:20gerry_(deftype [#^int age])
08:20hoeck1gerry_: but the generated type has no :type attribute and so the :default print-method is invoked again trying to remove the type-tag ... stackoverflow
08:20G0SUBjagguli
08:20gerry_java.lang.IllegalArgumentException: Wrong number of args passed to: core$deftype (NO_SOURCE_FILE:0)
08:20gerry_oops
08:21gerry_(deftype a [#^int age])
08:21gerry_java.lang.UnsupportedOperationException: Can't type hint a primitive local (NO_SOURCE_FILE:22)
08:21gerry_primitive int cant be type hint
08:22gerry_hoeck1: ic
08:22gerry_does deftype support primitive fields?
08:28adityojagguli: hey
08:29gerry_defclass Person [name age])
08:29gerry_nil
08:29gerry_user=> (new Person "gerry" 18)
08:29gerry_java.lang.IllegalArgumentException: Unable to resolve classname: Person (NO_SOURCE_FILE:24)
08:31chousergerry_: I think for deftype you just call Person as a function to create new ones
08:32gerry_chouser: yes, but for defclass i have to use new
08:34gerry_need i compile it at first or something?
08:34hoeck1gerry_: for defclass, yes
08:35gerry_hoeck1: so i need put it into one clj file, and compiling it before using it?
08:35hoeck1gerry_: right, just like gen-class
08:39gerry_from datatypes wiki, deftype could support primitive type and imporove perf , is that right?
08:42chousergerry_: I think that's right.
08:42gerry_but deftype not support primitive type hints
08:44chouserI see that. I think it's probably just a bug.
08:46gerry_chouser: deftype and defclass still underway, so it's not a bug :)
08:47gerry_maybe not finished yet
08:48chouserwell, sure. but I mean I think the support is there and there was probably a small oversight that is breaking it
08:49gerry_include type object printing
08:58fabehi
08:59fabeim currently learning clojure and found the http://clojure.org/Atoms example confusing
08:59ysmolskyhow to thrown exception of custom class from clojure?
09:00chouserysmolsky: avoid it if possible, otherwise you have to create your custom class using gen-class and compile ahead-of-time.
09:00fabeit suggestes the memoizer momoized the call before (def fib (memoize fib))
09:01chouserysmolsky: there are also a couple compromise solutions in contrib: condition, error-kit, except
09:02chouserfabe: that example tries out 'fib' once before it's memoized so you can see how long it would normally take.
09:02chouseroh, you mean that the first call after 'memoize' is already faster? Did you try it yourself?
09:04ysmolskyok. what is the best way to wrap situation like this? i thought about returning keywords like this to replace situation when keyword cannot be found:
09:04ysmolsky(defn fun-dispatch [table]
09:04ysmolsky (fn [method args]
09:04ysmolsky (if-let [f (table method)]
09:04ysmolsky (apply f args)
09:04ysmolsky :notfound)))
09:05fabei know what it does im juste saying its easy to missunderstand it
09:08chouserysmolsky: returning 'nil' is pretty common. The 'get' function allows you to pass in a "not-found" value to return instead if you want to detect the difference between nil and not-found.
09:09rhickeygerry_: fixed
09:09gerry_cool
09:12gerry_rhickey: type object printing seems not fixed?
09:13gerry_i still got stackoverflowerror
09:14chouserhe fixed the primitive support
09:14gerry_yes, i just tried it
09:19ysmolskyhow do you think reading Seibel's PCL worth anything applied to clojure? does it have some pattern or idioms useful for clojure programmer?
09:20gerry_ysmolsky: that's for cl, i don't think that's much helpful, but just my personal thought
09:22gerry_and if you compare cl and common lisp syntax, you will hate verbose of common lisp :)
09:22fauxysmolsky: http://blog.thinkrelevance.com/2008/09/16/pcl-clojure
09:26gerry_s/clojure/cl
09:26gerry_s/cl/clojure oops
09:26gerry_:)
09:36gerry_(-> me :meta :type) => nil
09:36gerry_(:type me) => nil
09:36chousergerry_: (type me) ?
09:37gerry_:usr/Person
09:44AWizzArdI try to start slime with the NEW branch of Clojure. I get: java.lang.NoSuchMethodError: clojure.lang.RestFn.<init>(I)V (pprint.clj:1)
09:44AWizzArdWhat does this mean?
09:44chouserAWizzArd: it means you need to rebuild contrib and other libs you may be trying to load
09:46AWizzArdok
09:49AWizzArdMaybe Clojure Contrib is not compatible with the current NEW branch?
09:50chouseroh, right. sorry. http://groups.google.com/group/clojure-dev/browse_thread/thread/91ca1a8b524b7349?hl=en
09:50chouserso for now just don't use contrib.
09:50AWizzArdOne example Exception: Name conflict, can't def deftype because namespace: clojure.contrib.pprint.PrettyWriter refers to:#'clojure.core/deftype (PrettyWriter.clj:51)
09:51gerry_deftype name conflict exists
09:51AWizzArdyes, I see
09:52AWizzArdbut well, for testing purposes I could just modify my own checkout of contrib, maybe by fully qualifying those few cases
09:53chouseror just add (:refer-clojure :exclude [deftype])
09:53ysmolskywhat special name can i use to test that this file is being run through clojure.main? something *...*
09:57jdz,(find-doc "compiling")
09:57clojurebot------------------------- clojure.core/*compile-files* nil Set to true when compiling files, false otherwise. ------------------------- clojure.core/gen-class ([& options]) Macro When compiling, generates compiled bytecode for a class with the given package-qualified :name (which, as all names in these parameters, can be a string or symbol), and writes the .class file to the *compile-path* directory. When not compiling, d
10:12AWizzArdIs there already a code example of where deftype is used?
10:18gerry_i think no
10:20gerry_you may use it as defstruct at least
10:24haptiKhi
10:25AWizzArdrhickey: I tried: (deftype person [name age]) And when I then do (person 1 2) I get: No message. [Thrown class java.lang.StackOverflowError]
10:26gerry_:)
10:27chouserAWizzArd: printing doesn't work at the moment. do (def p (person 1 2)) then you can use p, just don't print it.
10:28lpetitchouser: can printing already be extended via protocols ? :-)
10:30chouserheh
10:33chouser(defmethod print-method :user/Person [o w] (.write w (str "#<Person " (:title o) " " (:age o) ">")))
10:37AWizzArdyes
10:38rhickeyprinting is todo
10:39rhickeywill eventually be a protocol once there are protocols
10:40AWizzArdrhickey: In my tokenization module I had to make only small fixes at two places and got a 40% speedup. Thank you!! *handshaking*
10:40rhickeyso, today I think even less of ASsociative support being the default. If I still had defstruct available I'd probably have a 3rd version deftype/class/struct, although you might want expando classes and types. In any case, I think opt in might be better than opt out
10:40rhickeyAWizzArd: that's great!
10:41rhickeyAWizzArd: this vs defstructs?
10:41AWizzArdIn other places I still use maps instead of deftyped objects, so I can speed up it even more. So far the results look all correct and I can't see a problem.
10:41AWizzArdYes
10:41chouserAWizzArd: you're using deftype or defclass?
10:41AWizzArdThe main container was changed. In the next days I can try to replace other throw-away objects by types. Looks really promising I must say.
10:42AWizzArddeyftype
10:42AWizzArddeftype
10:42chouserso cool.
10:42AWizzArdI just don't have so much time today, and it already took some time to get Slime running, and to compile contrib. But now I made the most obvious test.
10:43cemerickAWizzArd: whoa, good to know
10:43AWizzArddeftype/defclass is exactly the functionality we needed to speed up the very important core routines. Now I will see where I can stil use it.
10:44AWizzArdBut this is a real nice speedup, with basically no real changes.
10:44cemerickrhickey: can I lobby you for a deftype-time flag or somesuch, rather than the conj > assoc, getx morass?
10:45rhickeycemerick: ?
10:45cemerickrhickey: w.r.t. opt-in expando
10:46rhickeyopt-in just means that deftype won;t give you expando by default, but when you get expando (how tbd) it will be just like now (which is just like defstruct)
10:46rhickeyno morass
10:46gerry_AWizzArd: do you use primitive type in your module with deftype?
10:48shmichaelI'm trying to check performance for an implementation of a fibonacci sequence. However, it seems I am not getting a linear computation time.
10:48shmichael(def fib (lazy-seq (for [x (iterate inc 0)] (if (< x 2) x (+ (nth fib (- x 2)) (nth fib (- x 1)))))))
10:48shmichaelThis is odd, since lazy-seq should cache values
10:49shmichaelOn the other hand, the following implementation demonstrates linear time:
10:49shmichael(def fib-seq (lazy-cat [0 1] (map + (rest fib-seq) fib-seq)))
10:49jdzshmichael: nth is linear time
10:49jdzshmichael: and you have 2 of them
10:49AWizzArdgerry_: well, as I understand it deftype gives my indeed a pojo. But I did not have to write a .java file.
10:49chouserIn (lazy-seq (for ...)), lazy-seq isn't doing anything for you. 'for' already returns a lazy seq
10:50shmichaeljdz: that would make the running time 2n
10:50AWizzArdBefore deftype I had to write a class in Java for my short lived objects. I need to create millions of those, and it just is a bit expensive to create the powerful Clojure structs.
10:50jdzshmichael: not if you do that for every next number in your sequence
10:52shmichaeljdz: Agreed. So I have to use a hash-map?
10:52jdzshmichael: why? why don't you use the second version you pasted?
10:53shmichaeljdz: Because I'm trying to understand all the nooks and crannies
10:53shmichaelIt's just educational
10:55rhickeyprimitives don't help deftype when used with :field access
10:56cemerickoh, that's a good point
10:56chousermaybe help with memory usage or cache lines, just not avoiding box/unbox?
10:56cemerickrhickey: does that change with the planned case support?
10:56AWizzArdbetter (. field my-object)?
10:56cemerickno, probably not
10:57chouserAWizzArd: yes, but you only get that with defclass not deftype
10:57chouser(.field my-objecT)
10:57rhickeyprimitives might help inside any methods defined
10:57rhickeycemerick: which help, primitives? - no, case is about the keyword lookup
11:00gerry_rhickey: could i just compile defclass in repl with (compile (defclass ...)) and not put it to file?
11:01gerry_shortcut compile
11:03rhickeygerry_: that's not how compile works
11:05gerry_put compiled class file to default/setting Dir and i can use it just like in java.lang or something alike?
11:06rhickeygerry_: I don't want to talk about premature optimization :)
11:07gerry_just my fancifulness :)
11:09rhickeyso, I can auto-gen accessors even for deftype, that internally use .field, for another 15-20% boost, but would like to do that with deterministic names, like Foo-a, Foo-b etc rather than make you do that manually or having a bunch of naming options
11:09rhickeyat that point there might not be a significant benefit to case, or even to .field directly
11:10rhickeythe only caveat being that on re-eval, the Foo-a accessors will no longer work on old instances
11:11rhickeydoes anyone want this?
11:13cemerickhard to know at this point. The re-eval issue is unfortunate, since deftype should be re-eval safe otherwise.
11:15rhickeycemerick: right, it is otherwise (but old instances won't have new fields etc), of course no one is forcing you to call these
11:15gerry_15-20% boost is worth
11:16rhickeybut I imagine this explicit accessor use might be limited to module internals... still won't help old instances
11:17cemerickof course, the first thing I'd do is redef Foo-a to just about anything else. ;-)
11:18rhickeycemerick: like what?
11:19sraderno way to have .field access with deftype?
11:19cemerickrhickey: hrm, perhaps not. There'll likely be multiple types in each namespace. I've got my head stuck in gen-class.
11:19rhickeysrader: no
11:20rhickeysrader: but this accessor Foo-a I have been talking about will do that for you
11:21sraderthe speed up sounds good
11:21rhickeyCL has a :conc-name option to set a prefix (other than the default struct name) for all accessors
11:23cemerickyeah, I vaguely remember a bewildering set of options for defclass in CL
11:23rhickeycemerick: oh yeah, defclass even worse than defstruct
11:24cemerickI thankfully only lost ~6 mo. to that years ago.
11:24rhickeybut standard names have value in that they are predictable, given a Type T you know how to create/access
11:25cemerickdefinitely. I'm always a little shy of autogenerated names, though of course it's unavoidable sometimes.
11:25rhickeywell, I've got it written already, so I'll put them in
11:26rhickeywould like so input on how people would like to opt-in for Associative/struct-map-like
11:26rhickeysome input
11:27AWizzArdCould this be a parameter for deftype? :eval-safe true
11:33rhickeyAWizzArd: what would that mean?
11:34notallamaa choice between the fast version and the reeval-safe version, i'm assuming
11:35AWizzArdThe auto-generated accessors that you can offer even with deftype that internally use .field
11:36rhickeynotallama: :field is re-eval safe, accessors wrapping :field when eval-safe?
11:36rhickeyI hate having lots of options
11:37rhickeyand the most important right now is opt-in for expando
11:38AWizzArdso you will keep the :field accessor
11:38rhickeyAWizzArd: oh yes, this is not instead of that
11:38AWizzArdk, that is configurable enough imo
11:40rhickeyFoo:a for accessors? so when you want to speed up (:field x) code just do (Foo:field x)
11:41chouserI still have an inappropriate affinity for little bits of syntax like that.
11:41rhickeychouser: is that a positive statement? :)
11:42chouserheh
11:42AWizzArdSo (:field x) will make a little lookup and (.field x) will only work for the latest evaled version, but may be 10-20% faster.
11:43rhickeyAWizzArd: .field is not a deftype feature
11:43rhickey(Foo:field x)
11:44chouser(user/Foo:field x) ?
11:44chouseroh, sure it's still just in whatever namespace, so either wya
11:44chouserway
11:44rhickeychouser: outside of the namesapce, yes
11:45sraderwhy not just have :field use the accessor function?
11:46ordnungswidrigis it good style for a function to return either a string or a map? The function will be passed as a handler-type-function in my rest library.
11:47ordnungswidriga handler-function shall be allowed to either return a body or a map with {:headers {..} :body the-body-value}
11:47rhickeysrader: (:field x) ==> (get x :field), it's inherently a lookup
11:48ordnungswidrigthe calling function will have to analyze the type of the returned value. This smells, I think. But I have no better idea.
11:48gerry_(Foo-field x) maybe better ,x:y:z could be reserved
11:48cemerickrhickey: the question is, do you have other, better plans for colon-delimited symbols?
11:48cemerickI do like the colon better than a dash.
11:49AWizzArdso, (Foo:field x) for a deftype would be as efficient like a (.field x) for a defclass?
11:49rhickeyAWizzArd: tbd if HotSpot does something different with them, one being wrapped
11:50AWizzArdCan you make (Foo:field x) also available for defclasses?
11:50rhickeycemerick: opened up a while ago - http://clojure.org/reader - "A symbol can contain one or more non-repeating ':'s."
11:50AWizzArdcemerick: yes, I also like the colon better.
11:56The-Kennyhm... will it be possible to use defclass in the repl? (Without compiling the sources etc.)
12:01rhickeyThe-Kenny: use deftype
12:02rhickeydoes someone want to do simple (non-readable) print while I do case?
12:15mikehincheyrhickey: I have a patch that fixes contrib, by adding exclude deftype to all of the broken namespaces. Would that be easier than getting individual authors?
12:16rhickeymikehinchey: sure, I'll try it
12:16rhickeycould you please post it on assembla?
12:17djork_,"yay for clojurebot from my phone"
12:17clojurebot"yay for clojurebot from my phone"
12:17djpowellI'm a bit confused. (.field o) currently works on deftype instances. Is that just an accident?
12:18rhickeydjpowell: that will use reflection
12:18rhickeyand thus be much slower than (:field o)
12:18djpowellah - cause o can't easily be type hinted once it crosses function boundaries and stuff?
12:19djpowellcause it uses an anonymous class
12:19rhickeydjpowell: the type is anonymous, generated anew each time you evaluate the deftype
12:20djpowellyeah, I see now
12:22rhickeyso more syntax options for those playing along:
12:23rhickeycase will basically look like this:
12:23rhickey(case x
12:23rhickey :k (foo)
12:23rhickey :j (bar)
12:23rhickey (baz))
12:23chouseryummy
12:23rhickeywhere :j and :k can be at leasy symbols/keywords/string, but possibly others like vectors etc
12:24rhickeyhowever sometimes you want more than one constant to map to the same outcome
12:24rhickeythus they need to be grouped
12:24mikehincheyrhickey: I put it on assembla for clojure, exclude-deftype.patch
12:25rhickeymikehinchey: thanks!
12:25rhickeymikehinchey: where?
12:25rhickeyoh, assembla for clojure, not contrib?
12:26mikehincheyyes, contrib would have made more sense
12:27chouserdo you have a plan for how the deftype obj will hook into print-method
12:27djpowellsry, what is case? is this something related to deftype?
12:29chouserrhickey: like will deftype types all derive from :clojure.core/deftype? or just provide .toString on the deftype?
12:30Chousukewhat about C-switch-style fall-through for case? The proposed syntax wouldn't support it, but... hmm.
12:30rhickeymikehinchey: applied -thanks very much!
12:30Chousukeit'd get repetitive to write (case :x a :y a :z :a :w :b :default)
12:30Chousukewith the actual variable there :P
12:31hiredmanso :z :a :w :b all fall through?
12:32mikehincheyrhickey: you're welcome
12:32Chousukeno
12:32rhickeychouser: should be inside the deftype/defclass, generate print-method based on type tag or class respectively
12:32Chousukehiredman: I meant you should have been able to write something like (case x [:x :y :z] a, ...)
12:32Chousukebut that would mean x can
12:32Chousukecan't be a vector
12:33rhickeychouser: in general, it will be bad to base anything off of implementation detail class of generated deftype/classs since they are being used by users to define classes with their own semantics
12:35AWizzArdrhickey: will this case construct be used for hashes?
12:35chouserrhickey: ok, so a custom defmethod for each deftype
12:35rhickeychouser: I think so
12:36rhickeythere can be some implementation helper function
12:36chousersure
12:36rhickey(print-me me fields)
12:37rhickeyshould just print #:Foo{:a 1 :b 2 :c 3 :extra1 4 :extra2 5}
12:37rhickeyso, back to case:
12:37rhickey(case x
12:37rhickey (:i :k) (foo)
12:37rhickey :j (bar)
12:37rhickey (baz))
12:38rhickeyhere, is (:i :j) a single data structure or a group of 2 keys?
12:38rhickeypresuming we definitely want case for vectors if any aggregate
12:39Chousukewhat about a set?
12:39Chousukedoes order matter if the end result is going to be the same?
12:39djorkjust curious here. what's the case for having both (:foo some-map) and (some-map :foo) be valid
12:39rhickeyChousuke: whatever aggregate is used for grouping will no longer be available for switching
12:40rhickeydjork: well, some maps are not keyed by keywords, so you have to have (map akey)
12:40djorkright
12:41Chousukeand :foo as a function works for sets/java maps too, right?
12:41djorkor can a keyword be a function of other types?
12:41rhickeybut some maps are used more like objects than collections, where (field-of x) makes more sense than (find-in-x key)
12:42hiredmana keyword can be a function of any ILookup, right?
12:43AWizzArdrhickey: one option for case could be to add explicit separators. That may be useful anyway to make it visually more clear where the "when" part is and where the "then" part is.
12:43rhickeyAWizzArd: sounds icky
12:43hiredman~def c.l.RT
12:43RaynesIs there anyway to 'unuse' something in the REPL?
12:44hiredmanaround like 616 is the get method keywords use
12:44AWizzArdRaynes: you an ns-unmap things
12:44rhickeyhiredman: right now the promise is vague
12:44RaynesThanks. :)
12:44chouser(case x (:a a) (:a :b :c a-or-b-or-c))
12:45hiredmannot overspecified
12:45rhickeyactually it promises get, but I'd like to narrow that
12:45rhickeychouser: aargh, the grouping parens are back!
12:45rhickeyI got rid of them everywhere else
12:45chouseryes. but only one level -- don't others do 2?
12:46chouserno, I hate it nevermind.
12:46chouserat least use vectors there if anything
12:46chouser(case x [:a a] [:a :b :c a-or-b-or-c])
12:46Chousukeyeah. looks like function calls :(
12:46rhickeychouser: I hate always grouping like that
12:47rhickeyso, let's presume we want to avoid it
12:47rhickeyIt's a matter of sacrificing some data structure, sets or lists would be prime candidates in my book
12:48rhickey(case x
12:48rhickey #{:i :k} (foo)
12:48rhickey :j (bar)
12:48rhickey (baz))
12:49rhickeywe haven't used sets as syntax yet
12:52gerry_if x itself is one set?
12:52rhickeygerry_: you wouldn't be able to case on sets
12:53woobyit's cool to be a fly on the wall and watch awesomeness unfold, the case form looks fantastic
12:54gerry_then, use sets not bad
12:58chouser#{#{:i :k}} could match a set
12:58chouserin which case I'd vote for vectors instead
12:58chouserand suddenly this sounds very familier.
12:59chouser(case [:a :b] [[:a :b] [:b :c]] ab-or-bc)
13:01rhickeychouser: how would you match a set of one set/ vector of one vector?
13:01mikehincheyor: (case [:a :b] ([:a :b] [:b :c]) ab-or-bc)
13:01chouserlike (case [[:a]] ...) right?
13:01RaynesI thought deftype was in Clojure now?
13:02chouserRaynes: 'new' branch only
13:02rhickeyright
13:02RaynesOh, I see.
13:02AWizzArd(case x [:a -> 1] [:b -> 2] [:c :d -> 3] [[:x :y] -> 4] [[1 2 #{3 4}] :clojure -> 5])
13:02chouserI know I've done this, I just can't find where.
13:02rhickeyRaynes: snatch latest contrib as well
13:03Raynesrhickey: Already did. :)
13:03chouseranyway, the logic is: case will wrap an implied [] around every test expression unless it's already a vector
13:03chouserso, (case [[:a]] [[[:a]]] got-it)
13:03mikehincheyI meant: (case :a a ([:a :b] [:b :c]) ab-or-bc) - the () doesn't conflict with any data structure
13:04chousermikehinchey: it conflicts with lists. plus it looks like you're looking something up in the [:a :b] vector unless you look carefully to see this is an unevaluated from in a case expression.
13:04chouserunevaluated form in a case form
13:04rhickeychouser: I know we've had this conversation before, but I wouldn't want to have to explain that
13:05chouserI just explained it. one line!
13:05chouser:-)
13:05chouserI guess that might be an argument for using literal set intead of vector -- just less likely you'll be using it for anything other than grouping your tests.
13:06mtmhmm, I'm not seeing deftype in my latest pull from github; is this on a different branch than 'master'?
13:06chouserone way of looking at it is that you can pretend that collection type can't be matched, but if you really need to you actually can do it.
13:06rhickeychouser: the problem is (case [[:a]] [[[:a]]] got-it) will haveto be explained over and over, even if it is one line
13:06somnium(case x :a : 1 :b : 2 [:c :d] : 3 #{:e :f} : :g)
13:06rhickeybut yes, I see sets as much less likely
13:07chousermaybe inside case "," is not whitespace.
13:07chouser:-) :-)
13:07chouser(case x :a 1, :b 2, :c :d :e 3)
13:10rhickeychouser: so, set of one set to match a set?
13:11rhickeyall questions go to you? :)
13:11rhickeyusing sets, it may never come up
13:11chouserthey all do anyway, don't they? ;-)
13:11chouserright
13:12chouserwith vectors people are going to trip over it
13:12chouser...be surprised that (case [:a :b] [:a :b] match) fails
13:12Licenserhmm a curiose question, the clojure book says: Clojure does not optimize tail recursion because java can't do that. But as it strikes me can't the optimisation be done before java ever sees the bytecode?
13:13rhickeychouser: I think so, vectors probably the most popular aggregate-as-key
13:13chouserrhickey: right.
13:13chouserlists would not match vectors in a case?
13:14Raynesmtm: It's on the 'new' branch.
13:14chouser(case x '(:a) :list [:a] :vector) ?
13:14rhickeyactually they will, it will be based on hash for table lookup, then equals for confirmation
13:14mtmRaynes: thanks
13:14RaynesHrm. It appears that the new branch breaks slime.
13:14RaynesOr kind of breaks something related to slime.
13:14kefkaI've got a question: what Errors can be thrown by a clojure function (assume I haven't created new Exception or Error classes) that should not be caught, but require process shutdown?
13:15kefkaOutOfMemoryError is obviously fatal, while StackOverflowError is not, for example.
13:15rhickeychouser: the quote not need - keys are unevaluated, must be constants
13:15kefka(the fn that caused the StackOverflow is terminated, but the process keeps running)
13:15rhickeybut who uses lists?
13:15chouserLicenser: yes, clojure could take some occurances of self-calls and turn them into 'recur'. But it would make (foo a b) behave differently depending on where it appears in a single function -- would actually be *more* confusing that current behavior.
13:16ordnungswidrigkefka: anything that extends java.lang.Error is considered unrecoverable
13:16Licenserhmm so how is tail call optimisation actually done usually?
13:16Licenserand chouser thanks for the answer ;)
13:16chouserrhickey: if lists match vectors, then lists could actually be used for grouping tests -- the only drawback then being it looks like a call.
13:16rhickeyI knew you would say that :)
13:16mikehinchey:)
13:16chouserrhickey: of course you did.
13:17rhickeythat was the first grouping example I posted, but you didn't take the bait
13:17mikehincheyand if lists are unevaluated, not used for grouping, they also look strange
13:18somniumwould the set notation only be used to distinguish groupings? (case x :a 1 :b 2 #{:c :d} 3 :e 4)?
13:18kefkaordnungswidrig: How unrecoverable? For example, if a thread goes off and does a computation, and that computation throws StackOverflowError, the computation should die, but does the whole process need to be killed?
13:19chouserarg. gah. grrrr. () is better than the other options is so many ways...
13:19chouserin so many
13:19Rayneshttp://gist.github.com/221618 with 'new' Clojure. It then polls slime forever. Not sure if I'm the only one who got this. Just throwing it out there.
13:20chouser(case x (one-of :a :b) a-or-b)
13:20chouserhehe
13:20ordnungswidrigkefka: javadoc says: "An Error is a subclass of Throwable that indicates serious problems that a reasonable application should not try to catch. Most such errors are abnormal conditions. The ThreadDeath error, though a "normal" condition, is also a subclass of Error because most applications should not try to catch it. "
13:20chouserRaynes: welcome to the experimental branches. -)
13:20rhickeychouser: I think a lot of the groups will look like obvious non-functions -> (:a :b :c) ([1 2] [3 4])
13:21Rayneschouser: I'm not complaining. Just letting you guys know that it does that, in case you didn't know about it. :)
13:21chouserI think AWizzArd said he got slime working
13:23mikehincheyRaynes: slime works for me, but my swank-clojure is old. is it looking for pprint, or something else in contrib?
13:23ordnungswidrigkefka: this might be enlighting: http://stackoverflow.com/questions/951635/how-to-handle-stackoverflowerror-in-java/951672#951672
13:23chouserfn arity overloads, letfn, proxy, defclass, deftype, case
13:23kefkaordnungswidrig: Thanks
13:23Raynesmikehinchey: I think so.
13:25kefkaordnungswidrig: And certainly the point is relevant that AssertionFailedErrors and StackOverflowErrors won't occur in reasonable code.
13:25kefkaOn the other hand, I don't want to do a System shutdown when they occur.
13:26ordnungswidrigWhat is the recommented cure against let/if/let/if/let staircasing?
13:26drewrordnungswidrig: there's if-let
13:27drewrif you're staircasing that then you probably need to break your fn apart
13:27Licenserhrm fnparse is broken :/
13:27chousergot it. double parens. that looks even less like a fn call
13:27ordnungswidrigdrewr: can if-let destructurize?
13:27chouser(case x ((:a :b)) aorb)
13:27chouseror maybe (case x ([(:a :b)]) aorb)
13:28Chousukeergh
13:28drewr,(if-let [foo false] :foo :bar)
13:28clojurebot:bar
13:28drewr,(if-let [[foo bar] [false true]] :foo :bar)
13:28clojurebot:foo
13:28krumholthi i have a question. i wanted to make a stream that only one agent would print on. i implemented it like this http://paste.lisp.org/display/89509 the agents value is the stream it should write on. but it is not writing on the correct stream. can anyone see an obvious error?
13:28somniumwhat if one is an expression? (case x (((:a {:a 1}))) 2) ?
13:28drewrordnungswidrig: it depends on what you're trying to express
13:28ordnungswidrig,(if-let [[foo bar] [false :qux]] bar :baz)
13:28clojurebot:qux
13:29ordnungswidrig,(if-let [[foo bar] [true :qux]] bar :baz)
13:29clojurebot:qux
13:29mikehincheyRaynes: did you get the recent commit for contrib to fix for new?
13:29chouserkrumholt: use 'binding' not 'let'
13:30krumholti'll try that
13:30chouserrhickey: I gotta get lunch, but think on ([()]) ...it'll grow on you, I'm sure of it.
13:31Raynesmikehinchey: Yep.
13:31ordnungswidrigdrewr: I have (let [[t val] (f)] (if-not t :fail (let [[t val2] (g val)] (if t :fail-other val2))))
13:31AWizzArdif you want to allow case that it can on the one hand allow complex structures as keys, such as the vector [1 2 3], but on the other hand also allow the user to list many keys on which a "then" part can fire, then a separating construct would be needed.
13:32rhickeyAWizzArd: not so, see above
13:32hiredmanit occurs to me that a MetaException might be useful
13:33djpowellhmm, defclass can't extend classes? is that temporary?
13:33hiredmanan exception that supports the alter-meta!
13:33hiredman(I'd really like to get rid of ReaderException)
13:34krumholtis it possible that if you use (println) in an agent it is not printing to *out*?
13:35mikehincheyrhickey: a quoted vector or set? so the case macro looks for quote. Or maybe ~ unquote would be more clear.
13:35hiredman*out* might have a different value in the thread the agent action is running on
13:36AWizzArdA very efficient (case ...) construct might get us a step closer to pattern matching.
13:36rhickeymikehinchey: then you can't match a list starting with quote
13:36hiredmanAWizzArd: you've seen the match macro?
13:37krumholthiredman: i thought of that and did (binding [*out* my-stream] ...) in the agent but it's still printing to the wrong stream
13:37AWizzArdhiredman: no
13:37mikehincheybut unquote isn't legal unless the macro looks for it to use it
13:37hiredman~google clojure pattern matching
13:37clojurebotFirst, out of 1700 results is:
13:37clojurebotbrool » Pattern Matching In Clojure
13:37clojurebothttp://www.brool.com/index.php/pattern-matching-in-clojure
13:38mikehinchey(case x :a a ~[:b :c] b-or-c)
13:38rhickey(case '(unquote ...) ...)
13:39rhickeya copiler might have that
13:39rhickeycompiler
13:39AWizzArdanyway, i was aiming a bit at the efficiency.
13:40AWizzArdrhickey: would this case construct be used in conjunction with perfect hashes?
13:45drewrordnungswidrig: I don't immediately see a way to clean that up
13:45LicenserWoooh I managed to join the google group with my own email address
13:51Licenserordnungswidrig: does (f) always return only 2 values?
13:57fabehi
13:58fabehow do i best access a value of a primitave java array?
13:58somnium ,(doc aget)
13:58somnium,(doc aget)
13:58clojurebot"([array idx] [array idx & idxs]); Returns the value at the index/indices. Works on Java arrays of all types."
13:59chouserfabe: http://clojure.org/java_interop#toc27
13:59fabethx
14:10somniumis it possible to define type-overloaded methods with gen-class?
14:11somniumor only object || one type hint?
14:14Fossiclojurebot: gen-class
14:14clojurebotNo, Fossi, you want gen-interface + proxy
14:14Fossisomnium: there you have it ;)
14:17somnium:)
14:18somniumI can't wait for 1.1 ...
14:19Raynes(doc aget)
14:19clojurebot"([array idx] [array idx & idxs]); Returns the value at the index/indices. Works on Java arrays of all types."
14:20Raynessomnium: When doing (doc ..), it appears you can leave out the comma.
14:21somniumah, creature of habit I guess
14:21woobytrying to compile fnparse, get "Could not find clojure.lang.Compile" whilst clojure.jar is most definitely on my classpath... anyone know whats up?
14:24somniumI think someone else mentioned that ^^
14:28duncanmhmm, how do i use condp again?
14:28duncanm,(let [s "foo"]
14:28duncanm (condp #(.equals s %2)
14:28duncanm "foo" "Win"
14:28duncanm :else "Lose"))
14:28clojurebotEOF while reading
14:28duncanmhmm
14:28duncanmwhy didn't that work?
14:29duncanmin emacs, i get :else
14:29somniumhe can't handle newlines
14:29duncanmoh
14:29duncanm, (let [s "foo"] (condp #(.equals s %2) "foo" "Win" :else "Lose"))
14:29clojurebot:else
14:29duncanmoh
14:30duncanmaha
14:30duncanm,(let [s "foo"] (condp #(.equals s %2) s "foo" "Win" :else "Lose"))
14:30clojurebot"Win"
14:31rhickey,(let [s "foo"] (condp = s "foo" "Win" :else "Lose"))
14:31clojurebot"Win"
14:31duncanmoh nice
14:33rhickey,(let [s "foo"] (condp = s "foo" "Win" "Lose"))
14:33clojurebot"Win"
14:33duncanmheh
14:33rhickey,(let [s "foops"] (condp = s "foo" "Win" "Lose"))
14:33clojurebot"Lose"
15:00duncanmis there a reason why I can't use vars this way? http://gist.github.com/221708
15:00duncanmit says Exception in thread "main" java.lang.IllegalArgumentException: Invalid assignment target (FileMonitor.clj:135)
15:00duncanmoh, there's a stray unref there, i was trying out refs
15:04hiredmanduncanm: I am pretty sure set! is only for setting fields (java interop)
15:04duncanmhiredman: it says "Note - you cannot assign to function params or local bindings. Only Java fields, Vars, Refs and Agents are mutable in Clojure."
15:04hiredmanyeah
15:04duncanmhiredman: for this sort of thing, what's the more idiomatic way of doing it?
15:04hiredmanmutable doesn't mean you can use set!
15:04duncanmuse a ref?
15:05hiredmanwhat is workers?
15:05hiredmanoh
15:05duncanmmonitor and pyramid are SwingWorkers
15:05hiredmanworkers is nil
15:05hiredmannothing
15:05hiredmanso you can do nothing to it
15:05duncanmoh, but if it's an empty list
15:06hiredmanso?
15:06hiredmanlists are immutable
15:06duncanmright
15:06hiredmanand nil is not an empty list
15:06hiredmanno is nothing
15:06hiredmannil
15:07duncanmhiredman: so what's the idiomatic way to do something like this in clojure?
15:07woobyhiredman: how do i start clojurebot? i'd like to run it on a different network
15:07hiredmanwooby: rlwrap java -server -Djava.security.manager -cp $CLASSPATH:./clojurebot/ clojure.main -i clojurebot/hiredman/clojurebot.clj -r
15:08namorIs there a library to transform/simplify boolean terms in Clojure?
15:08hiredmanduncanm: I don't know what you are doing
15:08woobyhiredman: thank you, is there some way to configure it?
15:09duncanmhiredman: i want to toggle these workers, when i call this function the first time, it'll start the workers, if i call it again, it'll terminate the workers
15:09hiredmanwooby: clojurebot/hiredman/clojurebot.clj
15:09Chousukeduncanm: you need a global ref holding the workers
15:09woobyhiredman: got it, thanks again
15:10hiredman:(
15:11hiredmanwooby: there is alot of #clojure specific stuff
15:13hiredmanthe list of all the required namespaces in clojurebot.clj are almost all different plugins, when you load the plugin's namespace it registers it wires in
15:13hiredmanso by taking things out of that list, you can disable plugins
15:13woobyi see
15:13woobyit sure does a lot of stuff, holy crap man
15:14hiredman:D
15:16hiredmana lot of stuff is bit rot, like the svn stuff
15:16hiredmanthe twitter stuff, I should find something to do with clojurebot's twitter account
15:18Chousukeduncanm: http://gist.github.com/221716 something like this?
15:18Chousukeoops, forgot the stars from one 'workers' :/
15:19duncanmChousuke: i made it work without a global
15:19Chousukewell, a closed-over ref will do too I guess.
15:19duncanmChousuke: http://gist.github.com/221718
15:19duncanmright
15:20Chousukethose multiple dereferencing operations are somewhat dangerous
15:20duncanmChousuke: why is that?
15:21hiredmanyou should turn the whole thing into a single transaction
15:21woobyhiredman: woo runninng! had to excise a lot of clojurebot's brain though
15:21Chousukeif you run the function simultaneously in multiple threads you will likely get a non-empty result from the first deref, but an empty one from the next.
15:21hiredmanwooby: yeah
15:21Chousukehiredman: can't. it has side-effects.
15:21woobyhiredman: it's awesome though, what a cool program, thanks
15:21hiredmanChousuke: send the side effects off to an agent
15:22Chousukeor you could just read the ref once so there's no problem :/
15:22hiredmanhmm
15:23hiredmanor, you could make two functions
15:23Chousukeactually, I'm not sure if that model for queuing workers is good.
15:23hiredmanone that returns a vector of spun up workers
15:23Chousukeit looks like you should use an agent or something :/
15:23hiredmanand another that spins down a vector of workers
15:23Chousukeand send it "stop" and "go" :P
15:24duncanmhmm, actually, it'd be fun to write a blog post detailing how to use the techniques of clojure's STM for writing GUI programs
15:25hiredmanwell, you can treat the EDT sort of like an agent
15:25duncanmhiredman, Chousuke: i'm sure what i'm doing now (having a toggle button that fires off some job) is a pretty common thing to do in GUI programs.
15:25Chousukeduncanm: I would use an agent for that.
15:25Chousukeor just a thread.
15:25Chousukethat runs and then dies.
15:25duncanmSwingWorker is some sort of thread, right?
15:25hiredmanand you use blockingqueues for eventhandlers
15:26Chousukeis there a need to store the swingworkers somewhere?
15:26hiredmanand you turn the events into an infinite lazy seq
15:26duncanmChousuke: it's for cancelling the job
15:26Chousukehm.
15:26duncanmhiredman: that reminds me of the Rx framework stuff Erik Meijer is doing for .NET
15:26hiredmanyeah
15:27hiredmanthat is what made me do it :P
15:27hiredmanclojurebot: hydra?
15:27clojurebotPardon?
15:27duncanmhiredman: do you have some sketches of code for doing that?
15:27duncanmhiredman: i'd love to compile a list of 'best practices' for writing Swing code using Clojure
15:27hiredmanduncanm: http://paste.lisp.org/display/87611
15:27Chousukeduncanm: the toggling nature of the function just doesn't please me :P
15:27hiredmanI dunno if it as a best practice
15:27hiredmanI just think it's neat
15:29duncanmhiredman: looks interesting, i had a glance, but i need to look into it more deeply
15:29duncanmi'm new to all the Concurrency APIs in Java
15:30hiredmanhydra is like a multicast que, you stick stuff in, and it comes out multiple places
15:30hiredmanthe fancy stuff is derefing a hydra produces an end point, which is an infite sequence of stuff that is put into the hydra
15:31hiredmanand the hydra is an IFn, so you can all it as a function, and any arguments you pass it get put in the hydra
15:32hiredmanthere is a (uneeded) delay in there, but, meh
15:32Chousukecan you ever stop the queue? :P
15:33hiredmannot as currently implemented
15:36hiredmanso you just do filters, maps, and doseqs over the infinite sequence of events
15:37duncanmsigh, i feel like i'm such a naughty boy for writing all this code with SET!s
15:38Chousukeheh.
15:38Chousukeyou'll get over it.
15:38Chousukehopefully :P
15:38duncanmhiredman: i have this script that has a handful of globals, and I wrote an INITIALIZE! function, but now it says I can't use SET! to alter root bindings
15:38hiredmancorrect
15:38hiredmanyou can't use set!
15:38hiredmanever
15:38duncanmChousuke: no, i know, i mean, i wrote Scheme before, but in Scheme, i don't get yelled at when I use SET! - i feel a bit dirty, but no yelling ;-P
15:39hiredman(except to set fields)
15:39chouserand thread-bound vars
15:39duncanmso i have to change them all to refs, and add deref to all the places that use the value
15:39hiredmanchouser: :(
15:39hiredmanduncanm: just don't mutate stuff
15:40duncanmhiredman: well, i want some state that's closed over a bunch of functions
15:40hiredman:(
15:40Chousukeheh.
15:40duncanmeither i write all of them as internal defines, or i have to do this, right?
15:40hiredmanstate is bad
15:41duncanmhiredman: state is useful, it just needs to be managed properly (which i'm not doing) ;-P
15:41Chousukewith Clojure, the mutable stuff is (almost) all java. And who learns Clojure to write Java? :)
15:41duncanmChousuke: i do ;-) i use clojure to write portable shell scripts ;-)
15:41ambientwell, writing java with clojure is still better than writing java with java imho
15:41hiredmanduncanm: no, managing state can help mitigate it, but it is still bad
15:42Chousukeit's also necessary :)
15:42Chousukethough people tend to use it even when it's not :/
15:43rhickeyaargh - contrib defines case!
15:43chouserrhickey: do you want deftype and defclass objects to print the same?
15:43Chousukerhickey: :/
15:43duncanmrhickey: stuartsierra's fcase.clj?
15:43hiredmancontrib has a lot of stuff in it
15:44rhickeychouser: for now, sure, anything is better than stack overflow :)
15:44ChousukeWonder if it'd help to segment the core namespace a bit? it's getting quite large :(
15:44rhickeyduncanm: yep
15:45chouserrhickey: is there a way to opt out of IObj and ILookup? I'm not seeing it.
15:45Chousukeif you split it up, by default you could still import all the subnamespaces to keep compatibility... hm.
15:45rhickeychouser: there are no opts yet in or out
15:45rhickeybut you can't rely on them
15:45rhickeysince one out is just for user to define same interfaces
15:45chouserright, I think I'm relying on both and wanted to opt out to see the failure.
15:46chouserI'll hack it. thanks.
15:47rhickeyyou should have full access to the fields, and you will have access to the class by name while in those macros
15:47rhickeylots of the generated code does that
15:47AWizzArdis there a way to get a seq of all fields of a deftype?
15:47rhickeyso it's not really anonymous for you. also can rely on __meta and __extmap
15:48hiredmanAWizzArd: implement ISeq :P
15:49rhickey(deftype Foo [a b c])
15:49rhickey(seq (Foo 1 2 3))
15:49rhickey([:a 1] [:b 2] [:c 3])
15:49chouserthat's exactly what I'm relying on now, and shouldn't.
15:49rhickeyright
15:50rhickeythere is also IDynamicType but you shouldn't need it
15:50chouseryep
15:52chouser__meta and __extmap may not exist, right? what do you mean I can rely on them?
15:55rhickeychouser: they will exist
15:55chousereven on defclass?
15:55rhickeythey may not be used, but will be null
15:55rhickeychouser: yes, defclass no different in terms of expando and meta
15:56chouserok, thanks.
15:58chouserbut those fields are only accessible via reflection
15:58wagjohi there, I'm trying to make a lazy seq, which returns characters from file. I open a file with (with-open [r (reader file)] .... ) but I don't know how to transform it into lazy seq, any hints?
15:58wagjosomething like line-seq but returning individual characters instead of lines
15:59chouserwagjo: maybe something like (repeatedly #(.read r))
16:01hiredman((fn me [rdr] (lazy-seq (cons (.read rdr) (me rdr)))) r)
16:02wagjothank you, gonna try
16:02chouserpretty much the same, aren't they? Neither quits at eof.
16:03hiredmanyes
16:04chouser(take-while #(> % -1) (repeatedly #(.read r)))
16:04chouser(map char (take-while #(> % -1) (repeatedly #(.read r))))
16:04rhickeychouser: which only by reflection?
16:04chouser(->> #(.read r) repeatedly (take-while #(> % -1)) (map char))
16:05chouserrhickey: .__meta and .__extmap only by reflection
16:05chouseroh
16:05chouserno, you said I have the classname.
16:05chouserso I can hint to that. sorry.
16:07rhickeyright
16:08rhickeyalthough by doing so you'll have the same brittleness on re-eval
16:09chouserhm.. the old instances will have the old type, and so will use the old print-method.
16:09rhickeyso better to rely on IMeta and IDynamicType/getExtensionMap for deftypes
16:09rhickeychouser: you should be binding the print method to type, not class, for deftypes
16:09rhickeyi.e. the tag
16:10chouseroh. indeed I am. sheesh. You can see I barely have my head around this if at all.
16:10rhickeythe type function ties into deftype types already
16:10chouserso: brittleness.
16:10rhickeywill be gone if you use IMeta and IDynamicType/getExtensionMap for deftypes
16:11chouserso deftype and defclass instances can look the same (for now anyway) but should be generated differently
16:11rhickeyyou'll need IDynamicType/getDynamicField as well
16:12chouserdefclass using direct hinted field access, deftype using IMeta (IObj?) and getExtensionMap
16:12rhickeychouser: yes
16:12rhickeygetDynamicField will get you out of ILookup
16:12rhickeymetadata will not be opt-outable I think
16:13chouserI can assume extmap has no keys that match a field?
16:14rhickeychouser: won't matter will it, for printing?
16:14rhickeyyou can just seq that onto the end
16:15chouseryep, np.
16:16chouser:-)
16:19chouserit's ok to assume deftypes implement IObj?
16:19rhickeyIMeta
16:20rhickeyshould be enough
16:20chouseroh. sorry, had those swapped in my head
16:20duncanmchouser: i'm looking over your gist to me earlier, where's the test in the IF-LET form?
16:20rhickeyyes, IMeta
16:20duncanmchouser: http://gist.github.com/221716
16:20chouserduncanm: not me. Maybe Chousuke?
16:21duncanmoh sorry
16:21duncanmchouser: misfired ;-P
16:21duncanmChousuke: ping
16:21chouserlowercase is insufficient apparently. ;-)
16:21duncanmi wonder when the videos from this year's JVM summit will be out
16:23hiredmanduncanm: (seq @*workers*) is the test
16:23hiredmanif let does something, and binds the result to a name, and then (if that-name something something-else)
16:25duncanmhiredman: is there a shorter form for writing this? http://gist.github.com/221780
16:25ordnungswidrighow can I filter a map on the values?
16:25duncanmordnungswidrig: use filter
16:26duncanmoh
16:26duncanm,(vals {:a :b :c :d})
16:26clojurebot(:b :d)
16:26duncanmlike that
16:26ordnungswidrigduncanm: but I need a map
16:27duncanmyou want to get {:b :d} back?
16:27hiredmanif you call seq on the output of .listFiles you don't need to call empty?
16:27kotarak,(into {} (filter (fn [[_ v]] (even? v)) {:a 1 :b 2 :c 4 :d 3}))
16:27clojurebot{:b 2, :c 4}
16:27ordnungswidrigkotarak: yes, like that
16:27kotarakordnungswidrig: there you go.
16:28duncanmhiredman: why is that?
16:28robewaldhi, what version of clojure does the API on the web refer to?
16:28hiredman,(seq [])
16:28duncanmhiredman: oh well, it's okay, i'm fine with that function, i was hoping i can learn some new clojure idioms
16:28clojurebotnil
16:29duncanmhiredman: but i still have the method call .getAbsolutePath
16:29hiredmanyou could use juxt (my new favorite function) to get a pair of :width and :height instead of a map
16:29hiredmanduncanm: correct
16:30hiredman,(if (seq []) :foo :bar)
16:30clojurebot:bar
16:30hiredman,(if (seq [1]) :foo :bar)
16:30clojurebot:foo
16:30ordnungswidrigkotarak: thanks
16:30duncanmhow does juxt work? it's not in the api page
16:30hiredman,(doc juxt)
16:30clojurebot"([f] [f g] [f g h] [f g h & fs]); Alpha - name subject to change. Takes a set of functions and returns a fn that is the juxtaposition of those fns. The returned fn takes a variable number of args, and returns a vector containing the result of applying each fn to the args (left-to-right). ((juxt a b c) x) => [(a x) (b x) (c x)]"
16:31kotarak,((juxt inc dec) 2)
16:31hiredmandunno if that is an actual improvement
16:31clojurebot[3 1]
16:31somniumis there any obvious reason why this won't compile <- http://paste.lisp.org/display/89523 ?
16:31robewaldor more specifically which git branch. SVN seems to be deprecated.
16:31somniumit compiles in slime, but when I do (compile ...) I get cannot create ISeq from Symbol ...
16:31kotarakhiredman: well, it generates 3 more functions: the one by juxt and #(.getWidth %) and #(.getHeight %)....
16:32hiredmankotarak: *shrug*
16:32hiredmanrhickey: I have to ask, is there a reason there is no 'flip' in core?
16:34rhickeyhiredman: have you needed it?
16:34rhickeyI haven't
16:34hiredmanhmmm
16:34kotarakWhat does flip do?
16:34somniumhiredman: I think there's one in contrib
16:35hiredmanI wrote one, but yes, I don't think I really used it for anything
16:35hiredmankotarak: reverse the order of arguments
16:35kotarakah ok.
16:35hiredman,((flip /) 3 8)
16:35clojurebot8/3
16:38hiredman,(pl (⌽/ 3 8))
16:38clojurebotInvalid token: ⌽/
16:38hiredman:(
16:38hiredman,(pl (⌽vector 3 8))
16:38clojurebot#<sandbox$uncurry__4597$uc__4599 sandbox$uncurry__4597$uc__4599@c64bc2>
16:38hiredmanhuh
16:39hiredmanoh, right, wrong symbol
16:39hiredman,(pl (↕vector 3 8))
16:39clojurebot[8 3]
16:39hiredmanand you wonder why all the symbols never caught on
16:40ordnungswidrighuh, there's unicode in my irc
16:40kotarakEs geschehen noch Zeichen und Wunder.. ;)
16:40ordnungswidrig,(doc pl)
16:40clojurebot"([& forms]); replaces a $ b with (a b) walking right to left replaces a · b with (comp a b) left to right ⌽a with (uncurry a) left to right ↕a with (flip a) left to right"
16:41hiredman~translate from de: Es geschehen noch Zeichen und Wunder
16:41clojurebotIt happened before signs and wonders
16:41ordnungswidrighiredman: that's translated a little too literally
16:42kotarakhehe
16:42hiredman~translate to de: ok
16:42clojurebotOK
16:43spuzI'm looking at some clojure contrib code and I see a lot of ::state ::result etc. what does :: mean?
16:43ordnungswidrighiredman: leo.org suggests "Well, Miracles do happen!"
16:43hiredman,::state
16:43clojurebot:sandbox/state
16:43hiredman,:state
16:43clojurebot:state
16:43kotarakhiredman: "There are still miracels and wonders..." maybe more useful translation. An exclamation if something improbable happens.
16:44kotarak,`cons
16:44clojurebotclojure.core/cons
16:44kotarak,'cons
16:44clojurebotcons
16:44hiredman:: namespace qualifies a keyword with the currect namespace
16:44hiredmanit also lets you use alias
16:45ordnungswidrigkotarak: not necessarily improbable but sth. you don't expect to happen anymore. Like a decision of a municipal authority.
16:45hiredmanif you foo.bar alias as bar in your current namespace, ::bar/foo will be :foo.bar/foo
16:48somniumdoes every function in a gen-class have to take a 'this argument or only methods?
16:49kotaraksomnium: gen-class is independent of the namespace. Only methods take this.
16:49somniumkotarak: thank you.
16:51somniumI keep getting unable to resolve symbol this when I take them out of the non methods...
16:52hiredmanwell, uh, stop trying to use names you haven't bound to a value
16:52kotaraksomnium: well, you use it there, you have to pass it as an argument.
16:52somniumok, that's how it was, and it could load the namespace, but I got an error on (compile my-namespace)
16:53lisppaste8Chouser pasted "deftype redef-and-print anomoly" at http://paste.lisp.org/display/89526
16:53kotaraksomnium: what might "an error" be?
16:53hiredmanchouser: arraymap strikes again?
16:53somniumcannot create ISeq from Symbol, or vice versa
16:54chouserrhickey: is that good or would it be better to merge the extmap with the dynamicfields?
16:54hiredmanwell, stop trying to make an iseq from a symbol
16:54kotaraksomnium: you quoted something, which you should not. probably somewhere in the ns clause
16:54somniumah, I hope so :)
16:55chouserhiredman: nope, overlap between extmap and fields -- can't get there without chanding a deftype on the fly and then poking around at old objects.
16:57hiredmanOh
16:58rhickeychouser: I think it tells the user something important
16:58chouserok. it's not entirely accurate -- I mean the value isn't actually stored twice.
16:58somniumkotarak: I'm sorry, I'm out of my depth. It compiles in slime but not with (compile). perhaps my mistake will be clear here? http://paste.lisp.org/display/89523
16:58chouserAnyway, that works, including metadata, for deftype.
16:58rhickeylooks nice, maybe we should elide the namespace/package for this non-readable print?
16:59chouserdefclass isn't there yet.
16:59chouserok.
17:00chouserI gotta go blow leaves around -- you want that patch as-is, or wait for defclass?
17:01scottjWhat higher level good alternatives are there to SQL? (in general, no specific application atm)
17:02ordnungswidrigwhat would be the easiest way to make a date string according to rfc1123 (used in SMTP/Mail and HTTP): Sun, 06 Nov 1994 08:49:37 GMT
17:03ordnungswidrigis there a lib or must I go via java?
17:03hiredmanthere is some java class
17:03hiredmansimpl date formater?
17:04hiredmanhttp://java.sun.com/javase/6/docs/api/java/text/SimpleDateFormat.html
17:04ordnungswidrighiredman: I know the java :-)
17:04hiredmanwell, there you go
17:05ordnungswidrighiredman: but I avoid it because I managed to go without calling java until now. But now is the time to learn how to do it.
17:05somniumscottj: there is contrib.sql and also higher level clojureql
17:05hiredmanare you kidding me?
17:05hiredmancalling java is nothing
17:05chouserrhickey: print-deftype.diff
17:05chouserrhickey: on clojure assembla. bbl.
17:06ordnungswidrighiredman: a little :-)
17:06rhickeychouser: cool - thanks!
17:07hiredman,(import '(java.text SimpleDateFormat))
17:07clojurebotjava.text.SimpleDateFormat
17:09hiredmanordnungswidrig: http://github.com/hiredman/clojurebot/blob/master/hiredman/clojurebot/github.clj has some date format snippets
17:12ordnungswidrighiredman: I made it :-) http://gist.github.com/221836
17:31qedmmmmm, map!
17:32hiredman,(bean (Date.))
17:32clojurebot{:seconds 43, :date 29, :class java.util.Date, :minutes 32, :hours 14, :year 109, :timezoneOffset 420, :month 9, :day 4, :time 1256851963466}
17:34hiredman,(-> (Date.) bean ((juxt :date (comp (partial + 1900) :year) :month)))
17:34clojurebot[29 2009 9]
17:37hiredman,(into {} (map (juxt class identity) '({} [] #{})))
17:37clojurebot{clojure.lang.PersistentArrayMap {}, clojure.lang.PersistentVector [], clojure.lang.PersistentHashSet #{}}
17:43wooby(doc juxt)
17:43clojurebot"([f] [f g] [f g h] [f g h & fs]); Alpha - name subject to change. Takes a set of functions and returns a fn that is the juxtaposition of those fns. The returned fn takes a variable number of args, and returns a vector containing the result of applying each fn to the args (left-to-right). ((juxt a b c) x) => [(a x) (b x) (c x)]"
17:43woobyawesome
17:47wooby,(juxt (+ 1) (+ 2) 3)
17:47clojurebot#<core$juxt__4916$fn__4934 clojure.core$juxt__4916$fn__4934@9458ea>
17:47hiredman,((juxt (partial + 1) (partial + 2)) 3)
17:47clojurebot[4 5]
17:47woobyaha
17:48ordnungswidrigit's like map but applying a list of functions to a value instead of an function to a list of values?
17:51kotarak,(map #(% 3) [(partial + 1) (partial + 2)])
17:51clojurebot(4 5)
17:51qedwhat are partials
17:52kotarakqed: partial makes a new function function which calls the given function with the provided arguments + any additional arguments: ((partial + 1) 2) <=> (+ 1 2)
17:53qedkotarak: ahh i see
17:53kotarak(partial f arg1 arg2) is equivalent to #(apply f arg1 arg2 %&)
17:54qedthanks for that :)
18:03wooby,(-> {:one {:two "X"}} (:one) (:two))
18:03clojurebot"X"
18:15rhickeycase is alive!! http://github.com/richhickey/clojure/commit/5ebed57e1d6d7dc8230fa51e6cd34e22dc1f3a42
18:16AWizzArdyay, grats
18:17AWizzArdbtw, I find it good that there now is case.. but I am curious why you added it now. Will it be of use for implementing Clojure in Clojure?
18:17chouserAWizzArd: deftype will use case internally for fast lookup when you do (:myfield deftype-obj)
18:17kotarakWhat is it with emacs, that it can't add a trailing newline?
18:18AWizzArdchouser: good
18:19AWizzArdkotarak: do you try it with Strg+o ?
18:19kotarakAWizzArd: what?
18:20AWizzArdkannst Steuerung + o drücken, das fügt eine neue Zeile ein
18:21kotarakAWizzArd: I don't use emacs. But I noticed that often files have only an incomplete line at the end, when they come from emacs users.
18:21drewrkotarak: yes, you have to hit return after adding a line at the end
18:22drewryou're talking about text files ending with \n instead of \n\n?
18:22drewror no newline at all?
18:23chouser:-( case groups with ()
18:23AWizzArdWhy should they end with \n\n? From a windows pov I could understand \r\n.
18:23kotarakdrewr: no newline at all
18:23AWizzArdchouser: can you show a minimal example?
18:23kotarakBut this is rather off-topic. Just some observation.
18:27rhickeychouser: sorry
18:29chouserAWizzArd: (map #(case % (1 2) :a (3) :b 4 :c (5 6 7) :d :other) (range 10)) ==> (:other :a :a :b :c :d :d :d :other :other)
18:31duncanmit'd be nice if range can generating a descend seq
18:31duncanms/generating/generate/
18:31AWizzArdduncanm: maybe you can use iterate?
18:32AWizzArd,(take 10 (iterate dec 20))
18:32clojurebot(20 19 18 17 16 15 14 13 12 11)
18:32duncanmah
18:32cemerick,(range 10 0 -1)
18:32clojurebot(10 9 8 7 6 5 4 3 2 1)
18:32duncanmoh!
18:32cemerick,(range 50 0 3/5)
18:32clojurebot()
18:33wooby,(range 1 0 -0.1)
18:33clojurebot(1 0.9 0.8 0.7000000000000001 0.6000000000000001 0.5000000000000001 0.40000000000000013 0.30000000000000016 0.20000000000000015 0.10000000000000014 1.3877787807814457E-16)
18:36kefka,(range 0 1 0.1)
18:36clojurebot(0 0.1 0.2 0.30000000000000004 0.4 0.5 0.6 0.7 0.7999999999999999 0.8999999999999999 0.9999999999999999)
18:36woobystrange
18:37wooby,(map #(/ 10 %) (range 0 10 1))
18:37clojurebotjava.lang.ArithmeticException: Divide by zero
18:38wooby,(map irc://irc.freenode.net/#(/ 10 %) (range 1 11 1))
18:38clojurebotjava.lang.ClassNotFoundException: irc://irc.freenode.net
18:38chouser(map #(case % 1 2 (map inc[1 2]) (range 3) (range 4) (+ 1 2) (inc x) :y) '(map inc range))
18:38djorkhah
18:39djork,(map #(/ 10 %) (range 1 10 0.1))
18:39clojurebot(10 9.09090909090909 8.333333333333332 7.692307692307691 7.1428571428571415 6.666666666666664 6.249999999999998 5.882352941176468 5.555555555555554 5.26315789473684 4.999999999999998 4.76190476190476 4.545454545454543 4.34782608695652 4.166666666666664 3.999999999999998 3.846153846153844 3.7037037037037015 3.5714285714285694 3.4482758620689635 3.3333333333333313 3.2258064516129012 3.1249999999999982 3.0303030303030285 2.9
18:39djork,(map #(/ 10 %) (range 8 11 0.1))
18:39clojurebot(5/4 1.234567901234568 1.2195121951219514 1.2048192771084338 1.1904761904761907 1.1764705882352944 1.162790697674419 1.1494252873563222 1.1363636363636367 1.1235955056179778 1.1111111111111116 1.0989010989010994 1.086956521739131 1.0752688172043017 1.0638297872340432 1.052631578947369 1.0416666666666672 1.030927835051547 1.0204081632653068 1.0101010101010108 1.0000000000000007 0.9900990099009909 0.9803921568627458 0.97087
18:39djorkerr sorry, I'm just spamming onw
18:39woobylol
18:40chouser,(range 0 1 1/9)
18:40clojurebot(0 1/9 2/9 1/3 4/9 5/9 2/3 7/9 8/9)
18:41spuzHas anyone used clojure.contrib.http.agent?
18:42spuzI'm having some really strange problems with the library. Appear to be concurrency issues :o
18:44spuzThe following just hangs on my REPL: (println (string(http-agent "http://www.google.com&quot; :method "POST" :body "param=true")))
18:44spuz,(println (string(http-agent "http://www.google.com&quot; :method "POST" :body "param=true")))
18:44clojurebotjava.lang.Exception: Unable to resolve symbol: string in this context
18:45spuz,(println (clojure.contrib.http.agent/string(clojure.contrib.http.agent/http-agent "http://www.google.com&quot; :method "POST" :body "param=true")))
18:45clojurebotjava.lang.ClassNotFoundException: clojure.contrib.http.agent
18:45spuzI guess clojurebot doesn't use the contrib libraries
18:55woobyhiredman: is there a way to send a message via clojurebot from vimclojure or whatever?
18:56AWizzArdspuz: I am using it
18:57AWizzArdspuz: yes, (string ...) hangs
18:57AWizzArdYou can write your own my-string
18:57hiredmanwooby: you could run clojurebot via vimclojure
18:57AWizzArd(let [a (http-agent ...)] (await-for a 2000) (string a))
18:57The-Kennywooby: I think that would result in spam... You could ask the guys from codepad.org very nicely to include clojure-support. There is a vim-plugin which handles codepad.org
18:57hiredmanor start clojurebot via the same nailgun instance as vimclojure
18:58hiredmanoh
18:58woobyhiredman: that's what i have going on
18:58woobyhiredman: it's really cool
18:58woobyhiredman: i think sendMsg is my guy, but I can't figure out what to feed it for the first arg
18:59hiredmanfrom core?
18:59woobylooks like the pircobj is in a ref maybe?
18:59woobycorrect
18:59spuzAWizzArd: I don't get it, the doc says the string function will block until the response is completed, but in this case the response never completes
18:59spuzrequest even
18:59hiredmanwooby: yeah
18:59hiredmansendMsg is pretty old and low level
19:00hiredmanit is really just a wrapper over pircbot's sendMessage method
19:00hiredmanthe first arg is a instance of Pircbot
19:00spuzfor example, this returns fine: (println (result (http-agent "http://www.google.com&quot; :method "POST" :body "param=true")))
19:00hiredmanwhich is the :this key in the map that is the bot
19:01spuzso maybe something is broken with (string ...)
19:01AWizzArdspuz: I also don't understand why string is broken, it looked fine at a first glimpse.
19:01cemerickDoes pmap ever run ahead of its consumer? I'd like to ensure I'm squeezing everything I can from my cores...
19:01wooby(:this @*bots*) ?
19:01hiredmancemerick: yes
19:02hiredmanwooby: no, when you run run-clojurebot the result is map {} which is The Bot
19:02hiredmanthis gets but into @*bots*, I guess
19:02hiredmanbut I've never really used that at all, Chousuke added it
19:03hiredmanI gotta run
19:03woobyhiredman: alrighty, thakns for your help, this is a lot of fun to play around with
19:09konrDo you use scrum or any other methodology to write software?
19:26woobywhat's the reason for using defonce?
19:35cemerickwooby: so reloading a file doesn't clobber any established bindings
19:35woobythanks
19:57cddrany examples of using compojure to write out some POST'ed XML to a file?
20:17sdeobald_Hey folks. I'm naively about to attempt to port a Ruby library (xml-to-hash) we've built at work to Clojure. Seems like the Clojure version will be much cleaner than the Ruby version.
20:17sdeobald_With that in mind, it seems like it would be clean enough that someone may have written it already.
20:18sdeobald_Has anyone seen a function that would turn this: {:tag :TestElement, :attrs {:name "pat", :value "ok"}, :content nil} into this? {:TestElement {:name "pat" :value "ok"}}
20:20djorkhmm
20:20djorkdestructuring would go a long way there
20:22wooby{(:tag thing) (:attrs thing)}
20:22wooby?
20:22woobyor rather
20:22woobyno, that's right i guess
20:22woobywhere 'thing' is your hash there
20:23djork,((defn foo [thing] {(:tag thing) (:attrs thing)}) {:tag :TestElement, :attrs {:name "pat", :value "ok"})
20:23clojurebotUnmatched delimiter: )
20:23djorkoops
20:23djork,((defn foo [thing] {(:tag thing) (:attrs thing)}) {:tag :TestElement, :attrs {:name "pat", :value "ok"}})
20:23clojurebotDENIED
20:23djorkhuh
20:24woobyclojurebot doesn't let you defn
20:24djorkoh
20:24djorkright
20:24djorkthat was stupid code anyway
20:24djorkI mean to just use fn
20:25wooby,(let [thing {:tag :TestElement, :attrs {:name "pat", :value "ok"}, :content nil}] {(:tag thing) (:attrs thing)})
20:25clojurebot{:TestElement {:name "pat", :value "ok"}}
20:25djorkclojurebot: I love you.
20:25clojurebotIt's greek to me.
20:25woobylol
20:25djork:( our love can never be
20:26sdeobald_Ah, sorry. TestElement was just an example.
20:26sdeobald_I basically want to follow that same pattern for any arbitrary xml struct-map that comes out of clojure.xml/parse
20:28woobysdeobald_: so you could use something like clojure.contrib.lazy-xml and lazily map nodes to the format you need
20:31sdeobald_wooby: Thanks, I'll check it out.
20:31woobynp
20:39chouserthat's nice, but it's not destructuring
20:40chouser,(let [t {:tag :TestElement, :attrs {:name "pat", :value "ok"}, :content nil}, {:keys [tag attrs]} t] {tag attrs})
20:40clojurebot{:TestElement {:name "pat", :value "ok"}}
20:53gregoryg(message "hello")
21:00woobydoes anyone have a link to that clojure reading list that rich posted? i'm having trouble finding it
21:02chouserwooby: http://www.amazon.com/Clojure-Bookshelf/lm/R3LG3ZBZS4GCTH
21:03woobythank you
21:10woobyi've heard good things about this PAIP book
21:17tomojany clojure.http.agent user's around?
21:18tomojif I call stream on an agent that uses the default handler, I can read bytes out of the response just fine
21:18tomojif I use a custom handler which calls stream on the agent and returns it, it EOFs immediately
21:20tomojman
21:21tomojmyself asking this question yesterday is in the google results today
21:28konrWhat methodology do you use to program in non-OO languages, like Clojure?
21:31woobykonr: bottom up and functional
21:31konrwooby: but how do you do things like estimate the cost of creating the software
21:32konrwooby: the methodology I'm using for Java uses things like the number of classes
21:32konrwooby: I wonder if there is anything outside that mentality
21:33woobykonr: well typically in languages like clojure your development iterations are faster, because you're developing interactively
21:33woobykonr: i'm not very experienced but that methodology seems to fit well with all the agile approaches to doing things
21:35woobykonr: in general you'd spend less time planning and UMLing and more time trying things out, working toward the simplest working thing possible
21:35woobykonr: then after that your dev becomes functionality driven, and you can do bug fix accounting and stuff to estimate progress
21:46tomojI think you estimate the same way you'd estimate before
21:47tomojwhy should OOP have anything to do with your estimation?
21:47rhickeydeftype/class now use case
21:47rhickeyno more need for Foo:blah accessors, will be removing
21:47rhickey(:field x) is faster
21:48chouserhah. nice.
21:49chouseris case doing "perfect hashes"? I can't tell by looking.
21:49rhickeychouser: yes, the min-hash code here: http://github.com/richhickey/clojure/commit/5ebed57e1d6d7dc8230fa51e6cd34e22dc1f3a42
21:50chouserit's short
21:50rhickeyfigures out the smallest masked/shifted set of bits that is unique amongst the key set
21:50cemerickthat's stellar
21:50rhickeythen inside the compiler it builds a tableswitch instruction, filling in any blanks with the default
21:51cemerickrhickey: you said this would be applicable to isa?, etc as well?
21:51rhickeywell, case is there for all purposes now
21:51rhickeyits quite neat, works with everything thanks to the pervasive immutability and plentiful literals
21:52rhickeycemerick: but this isn't the DIY perfect hash dispatch that will be needed for protocols
21:52rhickeyI'm not sure if I can get that to map to tableswitch or not
21:53cemerickI see how it'd work for exact matches, but I don't see the connection to a-la-carté hierarchies.
21:53rhickeybut my last patch generally tweaked keyword lookup as well, so all of Clojure should be a tad faster
21:53cemerickrhickey: were you surprised by AWizzArd's 40% figure, or no?
21:54rhickeycemerick: you just figure out the answer once, then rebuild the perfect hash, i.e. you cache the results of lookup
21:54rhickeycemerick: no, I saw that here first
21:54cemerickoooh, I get it now
21:54rhickeydefstruct was never about perf, it was about reducing the waste given lots of instances with the same key set
21:55cemerickrhickey: right, I was wondering if 40% is a differential you'd expect, compared to structs / maps
21:55rhickeymore surprising was just now where (:field x) is faster than (Foo:field x)
21:56rhickeycemerick: its easy to get speed by leveraging specificity - after all tese are now classes generated per use, vs one-class-fits-all
21:56rhickeythese are
21:57rhickeyI haven't done any comparisons to defclass (.field x), I imagine HotSpot can do more with that, but very happy with the all-dynamic perf
21:59rhickeycemerick: I didn't know what to expect, in absolute terms, other than faster
22:09churibwhy returns (take (/ 10 3) '(1 2 3 4) --> (1 2 3 4) four elements?
22:10tomoj~def take
22:11tomojit keeps subtracting 1 until the number is zero or negative
22:11tomojand (/ 10 3) is not 3
22:11clojurebotis is
22:13churibah, thanks!
22:13digash,(take 5 (iterate dec (/ 10 3)))
22:13clojurebot(10/3 7/3 4/3 1/3 -2/3)
23:52gerry_(time (dotimes [i 50000]
23:52gerry_(let [b (struct Person1 (str "ok" i) i)]
23:52gerry_(println (:name b)))))
23:53gerry_=>2833 mmsecs
23:53gerry_(time (dotimes [i 50000]
23:53gerry_(let [b (Person (str "ok" i) i)]
23:53gerry_(println (:name b)))))
23:54gerry_=>2790 msecs
23:54gerry_not much perf improvement??
23:55gerry_(deftype Person [#^String name #^int age])
23:55tomojmaybe most of your time is spent printlning?
23:55gerry_(defstruct Person1 :name :age)
23:58gerry_time of printing should be same
23:59gerry_but this little benchmark isnot useful anyways
23:59Knekkgerry_: if println is the bulk of your time you might still have made significant gains, but println is obscuring them