#clojure logs

2010-10-14

00:05amalloykmc: hotspot's jit is pretty good, i think. but i'm not a performance expert by any means
00:12rplevyhow far can one elaborate on something like this do you think? (defmacro with-turbo [turbo-on & body] `(let [~'map ~(if turbo-on `clojure.core/pmap `clojure.core/map)] ~@body))
00:12rplevyit's kind of the opposite of the Macintosh turbo button ;)
00:13amalloyrplevy: not sure what you mean by elaborate
00:13rplevysay if you don't know whether your code will be running on a quad core machine or a netbook and you want to provide an option
00:14rplevyamalloy: I mean, add more conditional stuff to take advantage of parallelism for free
00:14amalloytaking advantage of parallelism for free turns out to be a lot more difficult than it looks (cf kmc's efforts a few nights ago)
00:15rplevyamalloy: I'll take a look, sounds interesting
00:15amalloyrplevy: the main issue is that pmap needs to be given a smallish number of large tasks in order to be useful, because it spawns a thread for each task
00:15amalloy(it doesn't run all the threads at once, but it does create a new thread for each task)
00:16rplevyamalloy: what day's log is kmc's experiment in?
00:16amalloyuhhhhh
00:16amalloysec
00:16amalloymon oct 11
00:17amalloyon my computer, anyway, which is pacific time
00:17amalloy:P
00:17amalloyso in greenwich it's probably tuesday morning
00:18amalloyrplevy: search for pmap to find it quickly within the log file
00:18rplevyamalloy: yeah, so of course there is no free lunch, but still useful on occasion to wrapp small things in something like this, using judgment for specific cases
00:19amalloyrplevy: yes, clojure certainly provides a good groundwork for writing sensible parallel tasks
00:22chousermap has defined different semantics when the function you give it has side effects. pmap doesn't, I think.
00:22chouserclojure's got a lot more tools around concurrency at this point than it does around parallelism
00:23_rata__hi
00:23amalloychouser: you don't think it's defined as "totally arbitrary and don't rely on it"?
00:23amalloyi mean, that's sorta the same as totally undefined, i guess
00:24_rata__records are persistent, right?
00:25rplevychouser: interesting, it seems inevitable then for more high-level abstractions for parallelism to enter the language
00:27amalloy_rata__: yes, they are immutable, if that's what you mean
00:27_rata__amalloy, i mean, is it ok to use them with STM?
00:28amalloy_rata__: yes, because they are immutable. they implement java.util.map, which has a put() method, but if you actually call it they throw an exception
00:30_rata__i asked because of the optimization STM can do using persistent vectors/maps/lists
00:30amalloywhat optimization is that?
00:30_rata__STM can do that optimization using any immutable data?
00:30amalloy(records implement IPersistentMap, so whatever they are it seems likely that STM can use them on records)
00:30_rata__not having to do copies
00:31_rata__ok
00:31_rata__*to make copies
00:31_rata__thanks
00:31_rata__I was unsure
00:31amalloy_rata__: i can't defrecord on clojurebot, but you can try (supers (class x)), where x is some defrecord'ed object
00:31_rata__ok
00:34_rata__good night
00:47LauJensenGood morning all
00:50amalloymorning lau. up early today?
00:51amalloy(note: i don't actually know what time it is where you are, but you're usually not around for two more hours or so)
00:52LauJensenamalloy: Yea I usually get here by 9AM but todays its 6:50AM now
00:54notsonerdysunnyhow can one create a soft-link in a cake-task?
00:55LauJensensoft link?
00:55amalloyas in the $ ln -s variety?
00:55notsonerdysunnyLauJensen: yes soft link
00:55LauJensenamalloy: thats a symlink
00:55KirinDaveAnyone here good with enlive?
00:55notsonerdysunny:) yes symlink
00:56amalloyLauJensen: i know, but it was likely to be what he meant
00:56KirinDaveHaving problems with nth-of-type.
00:56LauJensen(sh "ln" "-s" "src" "dest")
00:56amalloyi think you have to launch the shell; java doesn't have symlink feature
00:56LauJensenamalloy: yea you're just a lot smarter than me it seems :)
00:56lancepantznah, you should use the ant task
00:56amalloyLauJensen: perhaps a lot dumber!
00:56lancepantznotsonerdysunny: http://ant.apache.org/manual/Tasks/symlink.html
00:56lancepantzso you would use cake's ant helper fn
00:57LauJensenlancepantz: any idea what that does on Windows?
00:58amalloyLauJensen: i wouldn't be surprised if it did what cygwin does
00:58LauJensenWhich is?
00:58notsonerdysunnylancepantz: can you please give me the syntax for the cake's ant helper function to create a symlink
00:58amalloywhich iirc is create a .lnk (windows shortcut file), with metadata attached to it that lets other cygwin processes treat it as a symlink
00:58LauJensenah ok
00:58notsonerdysunnyI think Windows 7 and vista support link
00:58lancepantz(ant Symlink {:link "foo" :resource "bar"})
00:59notsonerdysunnythanks lancepantz
00:59lancepantzLauJensen: there's a disclaimer at the end of the above link
01:00amalloyLauJensen: yeah, just checked my windows machine. ln -s creates a .lnk with some kind of special metadata
01:00LauJensengreat.
01:01amalloy(on my 5-year-old XP system. sunny seems to think vista/7 are smarter)
01:11notsonerdysunnyamalloy: I read about it some-where .. not very positive though
01:13BahmanHi all!
01:14LauJensenMorning Bahman
01:14BahmanHi there LauJensen!
01:21chouserNTFS has supported links forever, I think, but the rest of the OS and the applications all get very confused.
01:26notsonerdysunnychouser: so what is the command to create a symlink or hardlink in windows/NTFS then?
01:30amalloychouser: this seems to be true. my ubuntu system can create a hardlink on the mounted ntfs drive that windows uses. whether or not windows can understand it i haven't tested
01:50sandGorgonis there any way for me to figure out what is the exact java command used by lein when I do "lein repl" in a project ? is there any verbose setting for example
01:52LauJensensandGorgon: Well, there is an environment variable which you can set, to make it more verbose, it outputs the classpath at least. But I'd just run ps ax |grep java if I wanted to know
01:54kmcyou could use strace
01:54sandGorgonkmc, how do I use strace for that ?
01:55amalloysandGorgon: or jps and then look at /proc/xxxxx/cmdline
01:55kmcstrace -f -e execve -s 99999999 lein repl
01:57sandGorgonkmc, wow.. thanks that was great.
01:57sandGorgonLauJensen, thanks.. that worked as well ;)
01:59LauJensennp
02:05sandGorgonhas anyone looked at the source code of cake ? it is kinda funky - for e.g. src/cake/tasks/jar.clj:53 why is "(ns cake)" a string, which is written into a file called build/jar/cake.clj when cake is invoked ?
02:09notsonerdysunnydoes the reader macro #' have a corresponding function
02:09lancepantzsandGorgon: yeah, so cake actually runs in two jvms
02:09amalloy,(get-var 'clojure.core/first)
02:09clojurebotjava.lang.Exception: Unable to resolve symbol: get-var in this context
02:09lancepantzonce for your project, and one that processes cake commands
02:09amalloy,(ns-resolve 'clojure.core 'first)
02:09clojurebot#'clojure.core/first
02:10amalloynotsonerdysunny: there's one that's more convenient than that, lemme go find it
02:10lancepantzthen there is a ruby script that sits in front of those two, sending forms over the socket to get evaled in the jvms
02:10LauJensen,(= (var test) #'test)
02:10clojurebottrue
02:10notsonerdysunny,(doc var)
02:10clojurebotnotsonerdysunny: I don't understand.
02:10notsonerdysunny->(doc var)
02:10sexpbot⟹ "Special Form: Please see http://clojure.org/special_forms#var"
02:10amalloy,(var-get 'clojure.core/first)
02:10clojurebotjava.lang.ClassCastException: clojure.lang.Symbol cannot be cast to clojure.lang.Var
02:11kmcwhat does sexpbot do?
02:11notsonerdysunny->(doc var-get)
02:11sexpbotjava.lang.SecurityException: Code did not pass sandbox guidelines: (#'clojure.core/var-get)
02:11LauJensen,(-> #'var meta :doc println)
02:11clojurebotjava.lang.Exception: Unable to resolve var: var in this context
02:11amalloyroughly the same as clojurebot, with a different codebase
02:12notsonerdysunnyvar is a special form ..
02:12notsonerdysunnyso I guess we can't do #'var
02:12sandGorgonlancepantz, all right, but then why isnt there an inherent cake.clj in the project itself ? I dont think cake can be run from the commandline (using java commandline) because there is no cake.clj
02:12notsonerdysunnyLauJensen: *
02:13LauJensen,(-> #'loop meta :doc println)
02:13clojurebotEvaluates the exprs in a lexical context in which the symbols in the binding-forms are bound to their respective init-exprs or parts therein. Acts as a recur target.
02:13LauJensen-> (doc loop)
02:13sexpbot⟹ "Special Form: Please see http://clojure.org/special_forms#loop"
02:13amalloy,(find-var 'clojure.core/first)
02:13clojurebot#'clojure.core/first
02:13LauJensennotsonerdysunny: ^^
02:14amalloynotsonerdysunny: the functions you probably want are intern, find-var, and ns-resolve
02:15notsonerdysunnythanks amalloy and LauJensen
02:25amalloy,(zipmap (map (juxt identity -) (range 4)))
02:25clojurebotjava.lang.IllegalArgumentException: Wrong number of args (1) passed to: core$zipmap
02:25amalloy,(apply zipmap (map (juxt identity -) (range 4)))
02:25clojurebotjava.lang.IllegalArgumentException: Wrong number of args (4) passed to: core$zipmap
02:25amalloyblahhhh
02:26amalloy,(apply hash-map (map (juxt identity -) (range 4)))
02:26clojurebot{[0 0] [1 -1], [2 -2] [3 -3]}
02:27LauJensenamalloy: let me guess, you used to do a lot of perl ? :)
02:27kmc,(doc juxt)
02:27clojurebot"([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)]"
02:27amalloyLauJensen: hah, not actually very much. why, am i trying to do something like perl?
02:27kmccool function
02:28amalloykmc: yes, it's one to keep in mind. it turns out to be useful in a lot of interesting ways
02:28LauJensenamalloy: I once did something like what you just did, ie. tweaking until something working came out. Someone rebuked me saying "You need to understand what you're doing, not just tweak until it works, thats perl development"
02:28amalloy,(map (juxt inc dec) (range 5))
02:28clojurebot([1 -1] [2 0] [3 1] [4 2] [5 3])
02:28kmcamalloy, yeah, i've used something similar in Haskell
02:29amalloyLauJensen: in perl, tweaking is your only option. clojure gives you the choice to understand what you're doing...or just keep pounding on the keyboard like i was doing
02:29kmcheh
02:29LauJensenamalloy: well, im just gla you're not in charge of marketing
02:29kmcthem's fightin' words
02:29amalloyi always have trouble creating a hash-map out of a map
02:29LauJensenkmc: naah, all the fighting words are on my blog :)
02:29amalloy,(apply hash-map (mapcat (juxt identity -) (range 4)))
02:29clojurebot{0 0, 1 -1, 2 -2, 3 -3}
02:30amalloythere we go
02:30amalloykmc, what time zone are you in, if you don't mind?
02:30kmcEDT
02:30LauJensen,(map (juxt (comp inc rand-int) +) (range 10))
02:30kmcGMT-4
02:30clojurebot([1 0] [1 1] [1 2] [1 3] [1 4] [5 5] [2 6] [5 7] [7 8] [8 9])
02:31kmccomp is function composition?
02:31amalloyyes
02:31LauJensenyes
02:31amalloyblurgh. i used to stay up that late, but now that i have a job i can't stay up past like 1 without killing myself (pacific time)
02:31LauJensen(comp f g) = (f (g x))
02:31LauJensenamalloy: you're getting older :)
02:31amalloyLauJensen: not so. ((comp f g) x) = (f (g x))
02:32LauJensentsk
02:32amalloyLauJensen: and yeah, getting older, but mostly getting up earlier
02:33amalloy(or at least that's what i tell myself)
02:34LauJensenI really would like to know what they eat, the guys who run on 4 hours of sleep every night, that must be great
02:34kmc,((comp inc *) 5 4)
02:34clojurebot21
02:35kmcsweet
02:35amalloyLauJensen: future years of their lives
02:36bobo_and efficency of the ours they are awake
02:37bobo_they probably get less done in more time
02:37LauJensenbobo_: Tell that to Obama, Denmarks former Primeminister and Dana White, who all seem to get a lot done
02:37amalloyi get about six hours a night, and ten hours once a week when i realize i'm exhausted :P
02:38kmc((comp + *) 5 4)
02:38kmc,((comp + *) 5 4)
02:38clojurebot20
02:38LauJensenamalloy: yea I used to do that, if was just 5 and 10
02:38kmc,((comp (partial + 1) *) 5 4)
02:38clojurebot21
02:38amalloy,((juxt + *) 5 4)
02:38clojurebot[9 20]
02:44notsonerdysunnycan anybody help me figure out why #(-> % second :name) goes through fine while #(-> % second (fn [x] (:name x))) does not .. both seem identical to me...
02:45amalloy,(macroexpand '(-> % (fn [x] (:name x))))
02:45clojurebot(fn* % ([x] (:name x)))
02:45amalloy,(macroexpand '(-> % ((fn [x] (:name x)))))
02:45clojurebot((fn [x] (:name x)) %)
02:45amalloynotsonerdysunny: you want the second of these
02:47amalloy(though what you *actually* want is (comp :name second))
02:47notsonerdysunnyamalloy: aha .. I think I see what is happening .. thanks .. :)
02:48notsonerdysunnyyea you are right comp is a better way of doing it
02:48amalloy,((comp :name second) [{:name 10} {:name 15}])
02:48clojurebot15
02:51LauJensen,15
02:51clojurebot15
02:51LauJensenmuch easier
02:51amalloyLauJensen: you're right. i don't know why i bother writing any programs; i should just figure things out by hand and then write the answer in a clj file
02:51notsonerdysunnyLauJensen: :)
02:51amalloy,(identical? 15 15)
02:51clojurebottrue
02:52LauJensen,(identical? 130 130)
02:52clojurebotfalse
02:52amalloythat's the result i would have expected
02:52amalloywhy did i get true?
02:52kmchaha
02:52kmcinterning of small integers?
02:52kmc,(doc identical?)
02:52LauJensenamalloy: The first 128 integers are hardcoded in the jvm
02:52clojurebot"([x y]); Tests if 2 arguments are the same object"
02:52amalloy,(identical? -5 -5)
02:52clojurebottrue
02:53kmc,(let [x 130] (identical? x x))
02:53clojurebottrue
02:53amalloyLauJensen: the first 256 :P
02:53kmcthe first 127 and the last 128
02:53LauJensensure
02:53LauJensenpunks
02:53LauJensen:)
02:53amalloykmc: that adds up to 255. you have to include 0 in one of the two sets
02:54LauJensen,(true? (Boolean. "true"))
02:54clojurebotfalse
02:54kmcthat constructs a Java Boolean from the string "true"?
02:54kmcis there a better way to write #(identical? % %) ?
02:54LauJensen,(Boolean. "true")
02:54clojurebottrue
02:54kmc,(Boolean.)
02:54clojurebotjava.lang.IllegalArgumentException: No matching ctor found for class java.lang.Boolean
02:54amalloykmc: identical?
02:54amalloyoh
02:54kmc,(new Boolean)
02:54clojurebotjava.lang.IllegalArgumentException: No matching ctor found for class java.lang.Boolean
02:55kmc,(new Boolean "true")
02:55clojurebottrue
02:55kmcin general, is there a better way to write #(f % %)
02:55lypanov,(new Boolean TRUE)
02:55clojurebotjava.lang.Exception: Unable to resolve symbol: TRUE in this context
02:55LauJensen(new Boolean "true") == (Boolean. "true")
02:55LauJensenlypanov: You're thinking of Boolean/TRUE
02:55lypanovah, thats the one. forgot the syntax.
02:55kmc,Boolean/TRUE
02:55clojurebottrue
02:55kmcand that's a static field of the Boolean Java class?
02:55kmc,(Integer. 3)
02:55clojurebot3
02:56amalloykmc: i'm not sure, about (f x x). there must be an easy way
02:56LauJensen,(set (range 32))
02:56clojurebot#{0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31}
02:56LauJensen,(set (range 33))
02:56clojurebot#{0 32 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31}
02:56kmcheh
02:56lypanovcute
02:56kmc,(class 5)
02:56clojurebotjava.lang.Integer
02:56kmc,(class 5000000000000000000000000)
02:56clojurebotjava.lang.ExceptionInInitializerError
02:57amalloy!
02:57kmc;P
02:57lypanovhuh
02:57LauJensenThis is almost better than PHP :)
02:57amalloyoh
02:57kmc,(Bignum. 500000 500000)
02:57clojurebotjava.lang.IllegalArgumentException: Unable to resolve classname: Bignum
02:57kmc,(java.lang/Bignum. 500000 500000)
02:57clojurebotjava.lang.ClassNotFoundException: java.lang
02:57kmchrm
02:57LauJensenkmc: in 1.3 you can to (class 5000000000000000000N)
02:57amalloy,(class 500000000000000000L)
02:57clojurebotInvalid number: 500000000000000000L
02:57amalloy,(class 500000000000000000M)
02:57clojurebotjava.math.BigDecimal
02:58kmccool
02:58LauJensen,(class (bigint 5000000000000000000000000))
02:58clojurebotjava.lang.ExceptionInInitializerError
02:58LauJenseneh?
02:58LauJensen,(clojure-version)
02:58clojurebot"1.2.0-master-SNAPSHOT"
02:58LauJensen-> (class (bigint 5000000000000000000000000))
02:58amalloy,(doc bigint)
02:58sexpbotjava.lang.Exception: EvalReader not allowed when *read-eval* is false.
02:58clojurebot"([x]); Coerce to BigInteger"
02:58LauJensen,*read-eval*
02:58clojurebotfalse
02:58amalloyLauJensen: (bigint) doesn't get called until 50000000000000 is evaluated, and it's an illegal integer literal
02:59LauJensenanyway, I should really do some work
02:59amalloy,100N
02:59lypanovhehe
02:59clojurebotInvalid number: 100N
02:59LauJensenamalloy: works in the repl here though
02:59amalloyhm
02:59LauJensensame clojure version
03:00kryftDoes this just destructure the value of the function neighbors? ([size yx] (neighbors [[-1 0] [1 0] [0 -1] [0 1]] size yx))
03:00kryft(Looking at listing 5.1 in JoC)
03:01amalloykryft: no, that code is doing no destructuring
03:01amalloyit is treating the vector [size yx] as a function, and calling it with the result of (neighbors ...)
03:01amalloywhen vectors are called as functions, they treat their argument as an index
03:02amalloy,([\a '- "qqq"] 1)
03:02clojurebot-
03:02Chousukethat looks more like a variadic function definition for the [size yx] parameter vector
03:02Chousuketaken out of context :P
03:02amalloyhowever, if there's a (fn) lurking around near the code that you didn't show us...
03:03amalloy(and i agree with Chousuke, it looks like it is)
03:06kryftamalloy: http://pastebin.com/YTPJ8iUq (Listing 5.1 in Joy of Clojure)
03:06amalloykryft: Chousuke is correct
03:06Chousukeyeah. it calls the 3-arg version of neighbor from the 2-arg version
03:06amalloyit's saying that neighbors can take 2 or 3 arguments. the 2-argument version calls the 3-arg version
03:06Chousukethe first arg is just a vector of vectors.
03:07kryftAh, ok, I don't think that was covered in the book yet. :)
03:08kryftI forgot about that syntax for indexing vectors even though I just read about it. :P
03:10amalloykryft: see 2.3.2
03:10amalloydiscussing variadic args
03:14tomojanyone using octobot in clojure yet?
03:22amalloyah, kryft, he does mention using vectors as functions in chapter 5, but it's hidden so well i had to reread the whole damn chapter to find it
03:22amalloyit's in 5.2.2
03:30bartj,([1 2 3] 0)
03:30clojurebot1
03:33tomojztellman is my hero
03:33amalloy,([1 2 3] -1)
03:33clojurebotjava.lang.IndexOutOfBoundsException
03:33amalloy:(
03:33LauJensentomoj: why?
03:35tomojhttp://github.com/ztellman/gloss
03:35tomojnot to mention aleph
03:36zkimand penumbra
03:38LauJensenYea he's a cool and crafty guy, no doubt
03:42kmccool
03:42kmcembedded gpgpu programming for clojure
03:42kmci like that a lot
03:42LauJensenkmc: Yea he's done 2 amazing ports of my blogposts to Penumbra
03:43LauJensenFirst Brians Brain, when in optimized Clojure it does a 160x160 board in 1.6ms, Zach kept it at 1.6ms per iteration, but on a 2000x2000 board. My Fluid sim ran about 35 fps (I think) on a 80x80 board, Zach had it on 55 fps on a 800x600 board.
03:43kmcnice
03:43kmci love GPU programming
03:43kmcneed to get back into it
03:44kmci was doing fractal video feedback loops at 4096 x 4096 x 60fps, in 2007, without particularly optimizing my code
03:44kmcthere's just so much power there
03:44kmcthat card is probably in every midrange machine now
03:44LauJensenI read that the largest supercomputer in 1998 had the same power as a 500$ graphics card today
03:44kmchehe
03:45hiredmanthats a hell of a screensaver
03:45kmcwell, i'd bet that supercomputer had more ability to do *different* things at once
03:45LauJensenno
03:45LauJensenit would only solve solitaire puzzles
03:45kmchaha
03:45LauJensenj/k ofc :)
03:46kmchttp://en.wikipedia.org/wiki/Semi_Automatic_Ground_Environment ← the largest computer, ever
04:37jjidono clojurebot today
04:37LauJensenjjido: ?
04:38jjido,true
04:38LauJensenclojurebot: where are you ?
04:38LauJensen-> true
04:38sexpbot⟹ true
04:38LauJensenWell, there are alternatives
04:46jjido-> (:foo nil)
04:46sexpbot⟹ nil
04:52jjidokillall -s java | wc -l --> 6
04:52jjidokillall java
04:52jjidohow many stray processes do I have?
04:57jjidoIs there a string representation of Clojure objects which is resilient to structural loops (with an atom)?
05:01notsonerdysunnythanks raek
05:01notsonerdysunnythat actually highlights the use of atom
05:01notsonerdysunny:)
05:02raeksorry for being offensive about the def thing... I should have mentioned what "the right way" was, rather than just saying "you're doing it wrong"
05:04bmhdear #clojure -- I love clojure so much. The Java interop makes me so happy
05:04jjido-> (take 10 (.toString first))
05:04sexpbotjava.lang.SecurityException: Tried to call: toString on clojure.core$first@137e670 which is not allowed.
05:06notsonerdysunnyraek: no problem ... being critical is what makes this fun.. :)
05:06esjbmh: absolutely, playing with libraries like JFreeChart from a repl makes me uncommonly happy
05:07bmhesj: I found a C++ library that did the things I wanted it to do, but bugger, it's written in C++. I found a Java library that did some of the things I want to do, so bam. I can use the Java bits to port the C++ code I need!
05:07bmh(sorry if that was incoherent)
05:07esjbmh: not at all
05:07raeknotsonerdysunny: actually, thing the counter example would be a good example to have on clojuredocs. it very clearly shows how the function is applied to the data structure
05:09jjido-> (take 10 (str first))
05:09sexpbot⟹ (\c \l \o \j \u \r \e \. \c \o)
05:10jjidobut I guess that won't prevent a stack overflow.
05:12raekjjido: what are you trying to do? :)
05:13jjidoraek: I want to find out what I did wrong (error), so I want to print out objects. But that goes in infinite loop because of an atom.
05:14raekjjido: does the data structure in the atom have a reference to the atom itself?
05:14jjidoyes
05:15raekthen it might be a good thing to wrap the printing code in a (binding [*print-level* 10] ...)
05:16raekwhen an atom is printed/stringified, it will turn its contents into a string first
05:16raekat the repl, you can also do a (set! *print-level* 10)
05:16jjidois that the depth or the string length?
05:17raekform depth
05:17raekthere is a *print-length* too
05:20notsonerdysunnycan somebody help me with an example for apply-macro from clojure.contrib.apply-macro
05:24notsonerdysunny(defmacro hello [x]
05:24notsonerdysunny `(sayhello ~x))
05:24notsonerdysunny(macroexpand-1 (apply-macro hello '(10)))
05:25notsonerdysunnyhttp://gist.github.com/625927 is my example .. but I keep getting a stack overflow ..
05:34jjidoraek: ok, I inadvertently shared an atom :(
05:52jjidoI see no effect of using the *print-length* binding. *print-level* works great though.
06:20raek,(binding [*print-length* 3] (println ["one" "two" "three" "four"]))
06:20clojurebot[one two three ...]
06:21raekit inly restricts the number of element printed from collections
06:21raek,(binding [*print-level* 3] (println ["one" ["two" ["three" ["four"]]]]))
06:21clojurebot[one [two [three #]]]
06:23raek*print-length* is useful when dealing with infinite or very long sequences and *print-level* when dealing with circular structures or deep trees
06:26jjidoraek: thanks
06:34rfgpfeifferhow can i give a function a fixed time to return or kill it?
06:36raekrfgpfeiffer: I know that clj-sandbox (http://github.com/Licenser/clj-sandbox) does something like that
06:37raekhttp://github.com/Licenser/clj-sandbox/blob/master/src/net/licenser/sandbox.clj#L35
06:38LauJensenrfgpfeiffer: http://gist.github.com/626002
06:38rfgpfeifferthanks
06:38LauJensennp
06:41raek,(class (future 1))
06:41clojurebotclojure.core$future_call$reify__5492
06:43raekhrm, what happens with the running code if a timeout occurs?
06:43LauJensenit gets barged
07:56tobiasraederanyone ever done anything with wings and clojure?
08:06carkhwew that wing thing is ugly
08:09LauJensencarkh: ?
08:11carkhi was reacting to tobiasraeder's query
08:11bmhI'm trying to use penumbra and the universe is exploding on me when I run 'lein test'
08:13bmhhurumph, looks like a case of a broken test
08:16LauJensencarkh: Yea, just wondering what you were looking at
08:16LauJensenie. link
08:17carkhhttp://wingsframework.org/wingset/WingSet/
08:17LauJensenbmh: just start a project vm and run the examples
08:17bmhLauJensen: I just spotted it on the bug tracker
08:17bmhthanks
08:23kumarshantanuI have a question on Java interop
08:23kumarshantanu,(. "Hello" :toLowerCase) ; this works
08:23clojurebot"hello"
08:24kumarshantanu,(. "Hello" :substring 3 4) ; but this doesn't
08:24clojurebotjava.lang.IllegalArgumentException: Malformed member expression
08:24kumarshantanucan anyone help me understand this?
08:24carkh,(. "hello" substring 3 4)
08:24clojurebot"l"
08:25carkhdon't know why using a keyword should work on the first example
08:25carkhyou're supposed to use simple symbols
08:25kumarshantanucarkh: I want to be able to compose the method name at runtime (I don't know them in advance)
08:25LauJensenkumarshantanu: The first example shouldnt work, thats just a result of how keywords are implemented
08:25carkhkumarshantanu: what's your use case ?
08:26kumarshantanuLauJensen: I see
08:26kumarshantanucarkh: I have a bunch of setter methods to be called, so want to create a helper function to call them
08:26kumarshantanubut I don't know them in advance
08:27carkhyou might have to use reflection
08:27carkhthere is a helper function somewhere in clojure (java side)
08:27carkhclojrue.lang.Reflector has it i think
08:28kumarshantanuexample: (setter! some-obj {:method1 [m1-value1] :method2 [m2-value1 m2-value2]}) --> (doto some-obj ((.method1 m1-value1) (.method2 m2-value1 m2-value2))
08:28carkh(clojure.lang.Reflector/invokeInstanceMethod instance method-name-as-string array-of-args)
08:28kumarshantanuokay *looking*
08:29carkhnote that args are an array, not a vector
08:29carkhhttp://github.com/richhickey/clojure/blob/master/src/jvm/clojure/lang/Reflector.java
08:31kumarshantanucarkh: there seems to be a c.c.reflect too -- http://richhickey.github.com/clojure-contrib/reflect-api.html
08:31carkhahyes indeed !
08:33carkhyes that would help tremendously
08:38LauJensenYou guys should use emacs, fuzzy completions expands c.c to clojure.contrib
08:40carkhi do but fuzzy completion is not perfect for namespaces
08:40carkhmaybe some setup problem
08:40carkhi walways end up with clojure.contrib.sql/<space>
08:43kumarshantanu,(clojure.contrib.reflect/call-method java.lang.String :substring [] "hello" 3 4)
08:43clojurebotjava.lang.ClassNotFoundException: clojure.contrib.reflect
08:45kumarshantanuI am still getting this error on my local REPL: java.lang.NoSuchMethodException: java.lang.String.substring()
08:46carkhthe vector should have classes inside it
08:47carkh[java.lang.String java.lang.Integer java.lang.Integer] i guess
08:47carkhi think it's easier to use (clojure.lang.Reflector/invokeInstanceMethod instance method-name-as-string array-of-args)
08:48jk_are there any old-time common lispers here who resent the mixture of messy, stateful java into lisp? i've been really interested in the controversy and when most old-timers go with clojure, it seems like it's with a shrug like it's the lesser of 2 evils (using only java, for example)
08:48jk_probably a bad question in this forum :)
08:49kumarshantanucarkh: I am passing [Integer Integer] too, but the signature accepts primitives
08:49kumarshantanunot working....I guess that might be the reason
08:50carkhjk_: well common lisp is very imperative as well
08:51carkhkumarshantanu: really you should try c.l.reflector/invokeInstanceMethod, i had success using it
08:52kumarshantanucarkh: I will use Reflector, I was just wondering the clojure.contrib version may be better supported
08:52carkhkumarshantanu: clojure itself uses reflector so i guess it's here to stay =P
08:53jk_carkh: what about exceptions? does that seriously detract?
08:54carkhjk_: conditions sure are way better, but exceptions are good enough in most cases
08:54carkhand we have a library for condition-like behaviour
08:54carkhthough i never used it
08:54kumarshantanu,(clojure.lang.Reflector/invokeInstanceMethod "Hello World" "substring" (into-array [3 4]))
08:54clojurebot"l"
08:55carkhkumarshantanu: yay !
08:56kumarshantanucarkh: invokeInstanceMethod should be promoted to c.c (!)
08:56jk_carkh: ok, one last question... do you think seq is a big win over the predominance on cons cells? as a newcomer, that shift in focus looks like an advantage
08:56carkhyes i beleive so
08:57carkhmost of the time you'll be working with vectors instead of lists
08:57carkhit's very handy to be able to use seq abstraction on these
08:57carkhand vector are _fast_
08:57carkhvectors*
08:58jk_thanks :)
08:58carkhalso they grow at the end, so you can avoid most of this reverse non-sense
09:00jk_carkh: i was watching some online lectures where they are teaching with scheme and i was wondering if lispers thought something was lost or radically different with clojure because they always had such a strong link to the cons cell data structure before
09:00carkhwell we still have cons cells
09:00carkhkinda
09:01carkhwe have single linked lists anyways, for a cons cell we use a simple vector
09:01carkhbut really i think it's a plus to have the right data structure for the right job
09:02carkhsure the jvm has its drawbacks, but it has many good features
09:03carkhand clojure is way above CL for functional purity (though not to the haskell level)
09:04carkhtake CL's hash tables for instance
09:04carkhvery imperative
09:05carkhwe have fully immutable and persistent maps in clojure for that
09:11pdk`i recall some article once whining about clojure wasnt lisp all the way down and how evil this was cause it was on the jvm
09:11pdk`though on the other hand
09:11pdk`the same person who wrote that still thought his efforts to make a multi ghz lisp machine for today's world were remotely practical
09:11carkhthere is strong opposition to clojure in the CL community
09:12_fogus_jk_: Common Lisp is not necessarily centered around the cons cell. It has a powerful sequence abstraction.
09:13carkh_fogus_: though the sequence abstraction doesn't go as far as in clojrue
09:13_fogus_carkh: I haven't noticed a very strong opposition at all.
09:13jk_pdk`: http://www.loper-os.org/?p=46 probably this guy :)
09:13carkhi guess it withered down with time, they're mostly ignoring clojure
09:13pdk`oh yeah i was just about to look for that jk
09:13_fogus_carkh: It's not as pervasive no. But the point is that the Common Lisp world does not revolve around the cons cell.
09:14pdk`but the tl;dr of it is it boiled down to whining from an ivory tower
09:14carkh_fogus_: anyways i can see their point, CL has been there for decades, clojure is but a blip on their radar
09:15BahmanHi all!
09:16jk_pdk`: well i was reading through a lot of this blogs and i don't think it's really ivory tower whining. he's claiming that something truly valuable was lost when lisp machines went away because the same abstractions when all the way down giving crystal clarity to the whole structure (that's how i read it anyway, in a nutshell)
09:16_fogus_carkh: If you're a long-time Common Lisp programmer then you're probably happy with what you have. Plus, you've seen "other Lisps" come and go numerous times. ;-)
09:16djpowellwhere should i report a clojure-clr issue?
09:17carkh_fogus_: i never was fully happy with CL, the multi-processing issues (under windows) and the impertive nature of it were always a drawback
09:17jk__fogus_: thanks for the input. i guess i was getting that feeling (re cons cell) from some of R.H.'s comments and from the SICP lectures i'm viewing
09:18pdk`are these lectures recent
09:18_fogus_jk_: Those SICP lectures are like 20 years old no?
09:18jk_pdk`: mid-80's i think
09:18jk_and it's scheme, not CL
09:20_fogus_That's not to say that cons cells are not used in CL, they are an incredibly robust structure. Only, that they are not used exclusively.
09:21jk_gotta go to work. thanks for the insightful comments, guys.
09:21djpowell,(with-out-str (pprint {:a {:b "c"}}))
09:21clojurebotjava.lang.Exception: Unable to resolve symbol: pprint in this context
09:21djpowell,(with-out-str (clojure-version))
09:21clojurebot""
09:21djpowell,(clojure-version)
09:21clojurebot"1.2.0-master-SNAPSHOT"
09:22carkh,(with-out-str (clojure.contrib.pprint/pprint {:a {:b "c"}}))
09:22clojurebotjava.lang.RuntimeException: java.lang.RuntimeException: java.lang.RuntimeException: java.lang.ClassNotFoundException: clojure.contrib.pprint
09:22carkh=/
09:22carkh,(require 'clojure.contrib.pprint)
09:22clojurebotjava.io.FileNotFoundException: Could not locate clojure/contrib/pprint__init.class or clojure/contrib/pprint.clj on classpath:
09:22djpowellhmm, anyway pprint in clojure-clr totally mangles that expression
09:23djpowellas: {:a "c"{:b }}
09:23_fogus_,(with-out-str (clojure.pprint/pprint {:a {:b "c"}}))
09:23clojurebot"{:a {:b \"c\"}}\n"
09:26carkhah i'm still with good old 1.1 =P
10:08bmhwell this seems to be an energetic channel. Any penumbra users about, I'm trying to make sense of ztellman's marble vertex shader
10:22cemerickbmh: quiet just means work is getting done :-)
10:26hircushas anyone tried this snippet? http://gist.github.com/624638
10:26hircusI tried it with Clojure 1.2.0 on Linux x64 -- both JDK 1.6.0u22 from Sun and IcedTea from Fedora
10:27hircusand the Clojure REPL freezes at (defprotocol...) -- it returns nil but never prompts for the next command
10:36_fogus_hircus: Hrm. That'
10:36_fogus_s odd
10:37_fogus_hircus: Does it do that for every defprotocol ever?
10:39cemerickhircus: funky; works fine in both direct and ccw repls.
10:40hircus_fogus_:
10:41hircus_fogus_: I updated my comment in the gist. as it turns out it's just that the prompt is not printed after defprotocol. If I enter a simple expression (e.g. a number) then it's evaluated and the prompt is then printed
10:41hircusand it does not always happened -- I *sometimes* get the prompt back after defprotocol. odd eh
10:45kryft#(< -1 % size) <- Hmm, what does the % do?
10:46MayDaniel_,(#(- 10 %) 15)
10:46clojurebot-5
10:47kryftMayDaniel_: Duh, of course :P
10:58raekkryft: #(< -1 % size) is the same as (fn [%] (< -1 % size))
11:00kryftraek: Yeah, thanks. :) I did remember that #() was literal syntax for anonymous functions, but for some reason I didn't remember (and couldn't figure out) that naturally % must be an argument for the function.
11:03kryftThere are no stupid questions, but some days I manage to get pretty close!
11:05bhenryis there any utility that will tell you all the namespaces on the classpath in which a given function is called?
11:09raekbhenry: with emacs and swank-clojure, there is "C-c C-w c: List all callers of a given function"
11:10bhenryawesome!
11:12bhenryraek i get error in process filter: Wrong type argument: char-or-string-p, nil
11:12bhenryi'm leaving the argument as is after the command
11:15_rata_hi
11:16dpritchettdoes the newest vimclojure integrate with lein-nailgun?
11:17dpritchettI really want to like vimclojure but I haven't gotten used to classpaths... it's so nice to let leiningen deal with them for me.
11:19_rata_is there a function like tree-seq but for graphs? (i.e., the children function can give nodes already visited by the function)
11:21jkkramer_rata_: http://github.com/jkk/loom or clojure.contrib.graph
11:21_rata_clojure.contrib.graph doesn't have anything like that... I've already checked
11:22jkkramerlazy-walk does if you use ccg's graph structure
11:23jkkramerloom has loom.alg-generic/bf-traverse and others for general-purpose traversal
11:24_rata_to use a ccg's graph structure I'd need a function like the one I'm asking for
11:25_rata_I have my own data structure and I want to walk over it
11:26jkkramerthen loom would be a better fit. it's alpha though so the API isn't concrete
11:35fliebelHey
11:35jkkramer_rata_: if you do end up using loom, i'm interested in any feedback
11:36fliebelchouser or _fogus_: You probably know this, but the index of Joy of Clojure(which I just bought) says 'firehos', missing the 'e'.
11:37_rata_jkkramer, I think my team wouldn't be happy to include another library dep, but I can see bf-traverse is self-contained, so I'd like to copy it right into my code... don't you mind?
11:39dpritchettfirehoss
11:39jkkramer_rata_: sure, go for it. just pass along changes if you make any
11:40_rata_ok... I think that lazy-seq should go at the beginning of the step function
11:41jkkramermy reasoning for not is that the first node is always available in the queue
11:41jkkramerand subsequent nodes require some work to find
11:43jkkramerbut i'm not an expert in the subtleties of lazy-seq
11:44_rata_I think it's preferable to have a complete lazy seq than a seq that's mixed
11:45jkkrameropinions from the #clojure sages? is the form (cons x (lazy-seq ...)) discouraged?
11:46Chousukewhy would it be?
11:46_rata_also I've always seen (lazy-seq (cons x ...)) in the functions returning lazy seqs
11:46Chousukewell the latter is lazier
11:48ChousukeIf you do (defn foo [] (cons 1 (lazy-seq (foo)))) and call it it realizes the first element immediately.
11:49jkkramerright. when you have the first element in-hand that's not bad, is it?
11:49ChousukeWell, the recommendation is to make sequences as lazy as possible
11:50jkkramerif you did (member:defn foo [] (lazy-seq (cons 1 (foo)))) and (foo) takes some time to process, the first element would take longer to return
11:50KirinDaveBecause of chunking, right? It's already going to do sequences in blocks.
11:50jkkrameroops, scratch "member:"...colloquey weirdness
11:51ChousukeKirinDave: Chunking doesn't really matter here.
11:51KirinDaveChousuke: Right, but realizing the first several elements probably doesn't offer efficiency gains unless they're terribly expensive.
11:52jkkramerin the case of a graph traversal, finding neighbors not yet visited could be a less-than-fast task
11:54jkkramerand you'd be doing work for a step one farther than the consumer asked for
11:55_rata_I don't think so
11:57_rata_every function that returns a lazy-seq I've seen use the lazy-seq macro at the beginning of the function and they don't realize more elements than the ones asked for (except for chunking)
11:57ChousukeThat's what we're saying
11:57jkkramertaking pre-traverse as an example: http://github.com/jkk/loom/blob/master/src/loom/alg_generic.clj#L30 if you request the one item, no work is done -- the start node is returned. if lazy-seq was moved before cons, it would find the neighbors of the starting node but still only return the starting node. right? i fully acknowledge i mgiht be misunderstanding lazy-seq
11:59_rata_what's the difference between pre-traverse and bf-traverse? just DFS vs BFS?
11:59jkkrameryes. pre-traverse is preorder
11:59jkkramerand bfs right now has more options for filtering neighbors, depth, etc
12:00jkkramerstill messing with the API
12:00_rata_ok
12:00_rata_why preorder = DFS?
12:01_rata_it'd be more consistent to call it df-traverse
12:01jkkramerbecause dfs can be preorder or postorder
12:03_rata_ah ok
12:08dpritchettDoes anyone know how to use the vimclojure/server jar on clojars? Meikel suggests there should be a `lein run` task to start it up but that doesn't seem to be the case.
12:08dpritchett(http://groups.google.com/group/vimclojure/browse_thread/thread/69abeea9f57cb73b)
12:11_rata_jkkramer, I've tried both versions of pre-traverse, your and the one with lazy-seq at the beginning, and the later is faster when I (take 1 ...)
12:12jkkramer_rata_: how are you benchmarking?
12:12_rata_nothing serious, just (time ...) a couple of times
12:13_rata_maybe the graph I'm giving to the function is too small
12:14_rata_I'm calling it like (take 1 (pre-traverse {:a [:b :c], :b [:c], :c []} :a))
12:21jkkramer(dotimes [_ 10] (time (doall (take 1 (pre-traverse {:a [:b :c], :b [:c], :c []} :a))))) is consistently faster for me with my version -- note the doall to realize the first element
12:23jkkrameralso, (dotimes [_ 10] (time (doall (take 1 (pre-traverse #(do (Thread/sleep 100) ({:a [:b :c], :b [:c], :c []} %)) :a))))) demonstrates when the 'neighbors' function takes a long time to execute. with lazy-seq before cons, requesting the first element does the work for the second element
12:25jkkramer_rata_: ^
12:25dpritchettwoo, i figured it out!
12:25@rhickey-XX:MaxInlineSize=100 seems to help Clojure perf a good bit
12:25@rhickeyinterested in feedback from others if it helps you
12:25dpritchettadd the vimclojure/server jar to lein's dev dependencies
12:26dpritchettthen start the server with a quick alias including lein classpath
12:26dpritchettalias nailgun='java -cp "`lein classpath`" vimclojure.nailgun.NGServer 127.0.0.1'
12:27_rata_jkkramer, ok
12:28_rata_but normally no one will ask for just the first element... they already have that element
12:29jkkramer_rata_: it applies to any node. with lazy-seq before cons, work is done for nodes subsequent to the one requested
12:30_rata_that's weird... it should be lazier, but it's the other way around then?
12:32jkkramerbasically it's lazy for the nodes that require work to find
12:33jkkramerif there's a better way to do arbitrary-sized lazy graph traversal pre/post/bf, i'm very interested to know
12:35jkkramerlazy-walk from clojure.contrib.graph, which uses concat, dies on 100,000+ node graphs
12:35_rata_I've tried it and you're completely right... putting lazy-seq before cons realizes always one more than needed
14:00fliebelI'm reading Joy of Clojure, and in some of the examples some collections from java.util are used instead of clojure.lang. Why is this and what are the differences?
14:00d0m_fliebel: The goal is to be able to use both depending of when you need them
14:01nishanttest message
14:02fliebeld0m_: I see… But what are the differences? Why might you prefer one over the other?
14:03d0m_Well suppose you need to call a method on an existing Java object, but what you have available right now is a clojure list
14:03d0m_You can call directly the java method with the clojure list.. without conversion
14:04nishanthey everyone, I'm new to clojure, I've a question about java interop. I am trying to create an object of a java class using the (new Class args) form, but I get an InvocationTargetException, even after fully qualifying the name of the class, any ideas? I also verified that the constructor is visible using the show function available in repl-utils. Please help!
14:05d0m_fliebel: The list in clojure and in java are different implementations, even if they share some interfaces. So, if you're coding only in clojure, you can use only the clojure one if you like.. but then, if you have to use some java methods, it's nice to be able to convert java list to clojure list.
14:06fliebelRight :)
14:06d0m_so because of the interface they share, you can use java implementation of list in your high level function in clojure
14:06d0m_that's awesome :)
14:07hiredmanping?
14:07clojurebotPONG!
14:10raeknishant: can you paste the full stack trace somewhere?
14:11raekalso, which class do you try to instanciate
14:11nishant@raek should I paste it here?
14:12nishant@raek it's a class that I wrote and I'm importing it through lein
14:12raeknishant: put it in gist.github.com and paste the link here
14:12raeknishant: you can check whether clojure can find the class by just trying to evaluate the class name
14:12raek,java.util.ArrayList
14:12clojurebotjava.util.ArrayList
14:13nishantyeah it can find the class
14:13raek,java.util.Something
14:13clojurebotjava.lang.ClassNotFoundException: java.util.Something
14:13raekgreat
14:13nishantokay here's the stack trace git://gist.github.com/626696.git
14:14raekok, I tried http://gist.github.com/626696
14:14raek(you pasted the git url)
14:14nishantoops
14:14raekhrm, looks like it can't figure out the constructor in some way
14:15raek,(java.util.ArrayList.)
14:15clojurebot#<ArrayList []>
14:15raek,(java.util.ArrayList. "foo" "bar")
14:15clojurebotjava.lang.IllegalArgumentException: No matching ctor found for class java.util.ArrayList
14:15raekhrm, but it's not that exception..
14:16raeknishant: if you press 1 in the exception buffer (goes to the cause) what do you get?
14:16raekmy current theory is that the constructor throws an exception
14:16nishantI get No message [Thrown class.java.NullPointerException]
14:17nishantumm, let me try to see if I can use the constructor in Java
14:17raeknishant: does the class have multiple constructors that take the same number of arguments
14:17raek?
14:17nishant@raek yeah the same number, but different types
14:18raekwhat types?
14:19nishantwell there are two that take 1 argument, one of them takes a string, and the other one takes a JSON object (it's a java JSON implementation)
14:19_rata_why can't I use ^ instead of (meta ...) in a place that meta has no problems? like in ^(:a b)
14:19_rata_isn't ^ just a reader macro?
14:20raek_rata_: ^ as a shortcut for 'meta' is deprecated
14:20raekit worked up to 1.1
14:20_rata_raek, really??
14:20_rata_and what's ^ for now?
14:20raekin 1.2 ^ is the new #^
14:20raekso, use the more verbose (meta ...) for getting the metadata
14:21raekand since 1.2, you can use ^ to attach metadata and type hints
14:21_rata_mmmm... I don't get it yet
14:21raek,(meta ^{:a 1} :foo)
14:21clojurebotMetadata can only be applied to IMetas
14:22_rata_is there no shortcut for (meta ...) then?
14:22raek_rata_: not anymore...
14:22_rata_:(
14:22raekattaching meta is probably much more common
14:22nishant@raek the ctor works from Java
14:23raeknishant: can you post the stack trace of the cause?
14:23_rata_than retrieving it?? how can that be? everytime you attach metadata there will be one or more times you get it
14:24nishant@raek http://gist.github.com/626720
14:25raek_rata_: a very common usage is type hints for the compiler
14:25raekwhich only the compiler looks at
14:26raek_rata_: anyway, ^ (or #^ in 1.1) only works for literals
14:26raekif you have some data *in* your program that you want to attach metadata to, you must use with-meta
14:26_rata_mmmmm... so metadata isn't used that much.... that's a pity
14:27_rata_yeah, I'm using with-meta
14:27_rata_but the (meta ...) thing is annoying... with ^ the code would be much clearer
14:27raekwhen interfacing with clojure.core, you more often declare it than use it yes...
14:28raek,(meta (with-meta [1 2 3] {:a 1}))
14:28clojurebot{:a 1}
14:28_rata_the old shortcut could have been replaced by another one
14:30_rata_and one that could be used everywhere, not just with literals
14:31raekmeta is the "opposite" of with-meta
14:31raeknishant: is com.complabs.Annotators.EntityAnnotator the class you try to make an instance of?
14:31nishantyeah
14:32_rata_so (:changed? (meta (:volume c))) could be written as (:changed? &(:volume c)) or something similar... the later is much more readable I think, no boilerplate
14:35nishantping
14:35KirinDaveOkay, something that's been bugging me...
14:36KirinDaveDue ot profound mental deficiency, I don't know how to (require ...) a single namespace with an as without nesting. Is it possible?
14:36KirinDaveI want to say (require '([clothesline.service :as service]))
14:36KirinDaveObviously that doesn't work.
14:36KirinDaveand I know I could say (require '([clothesline [service :as service]]))
14:37raeknishant: is com.complabs.Annotators.EntityAnnotator the class you try to make an instance of?
14:37nishant@raek yes
14:37raekKirinDave: (require '[clothesline.service :as service])
14:38KirinDaveraek: Oh weird.
14:38raekthe extra parens introduce a "prefix list"
14:38KirinDaveraek: I thought require just wanted seqs.
14:38KirinDaveBut I guess lists vs vectors actually matter?
14:38raekKirinDave: it is recommended to use vectors and lists as they are used at clojure.org/libs
14:39raekother variants might work, but those are not documented
14:39raekand could be an implementation detail
14:39raekthe general syntax is:
14:39raekfoo.a
14:39raek[foo.a ... options ...]
14:40raekfoo.a foo.b foo.c --> (foo a b c)
14:40raekor combinded:
14:40KirinDaveraek: Thanks. I didn't realize the type was significant.
14:40raek[foo.a ..opts..] [foo.b ..opts..] [foo.c ..opts..] --> (foo [a ..opts..] [b ..opts..] [c ..opts..])
14:40KirinDaveraek: (btw notice I was saying (require ...) not (:require ...)
14:41KirinDaveraek: I write the way recommended by libs in ns statements because it looks good and some things parse it
14:41KirinDaveBut it felt strange to do it in an actual require statement. I should get over it.
14:41raekthe only difference between require and :require in a ns, is that the former requires you to quote the form
14:41raek(foo) is actually the degenerate case of the prefix list
14:41raekmeaning, require *nothing* with the prefix foo
14:42raekhow ever, a vector in that position simply means "no options"
14:42nishantraek: Yes I am trying to instantiate the EntityAnnotator class
14:43raekI think that is about the only case where vectors and lists are treated differently in the current implementation
14:43raeknishant: what do you pass to the constructor?
14:43jarpiainnishant: do you use the internal class name com.complabs.Annotators$EntityAnnotator ?
14:43raekis there any docs for the clas online?
14:43nishantraek: a string
14:44nishantraek: no there are no docs
14:44raekwhat jarpiain said looks interesting
14:44nishantraek: the constructor I'm trying to invoke takes a string, I tried creating an object through java code using the same ctor, and it works
14:45nishantjarplain: no I haven't tried that
14:45nishant:jarplain I get a ClassNotFound when I try that
14:46raekI think I am out of ideas...
14:47raekbut maybe one could type hint the param
14:47raek(fn [^String s] (com.complabs.Annotators$EntityAnnotator. s))
14:47raeknishant: have you tried passing a literal string or something?
14:48raekwhat value does the calling code pass?
14:50nishantI am getting a slightly different behavior when I pass a literal string (the string is supposed to be a file path)
14:50raekthe same exception?
14:51nishantthe same exception, but when I try to debug the cause I get a filenotfound exception
14:52raeknishant: can you double-check that the code you used previously used to generate the string doesn't give nil?
14:53nishantraek : I've hardcoded the string for testing
14:55raekso there is a difference whether the string is a literal or not?
14:56raekif so, could you try it with the type hint code I wrote before?
14:57nishantraek: yeah let me try that
14:59nishantraek: the behavior is same for literals and variables
15:00raekand if the file whose path is in the string exists, you get NullPointerException, otherwise FileNotFoundException?
15:01nishantraek: yes, it's weird
15:01raekshould the file contain some data in a specific format?
15:02nishantraek: the file contains a json formatted string
15:03raekI think clojure finds the correct contsructor, since you get a FileNotFoundException
15:04raekit seems unlikely that it tries to open a file using a JSON object (or whatever the other type was)
15:05nishantyeah, I think it's calling the right ctor
15:05LauJensen /whois nishant
15:06LauJensennishant: You're not the guy who used to write a ton of C# tutorials on codeproject are you?
15:06nishantLauJensen: no :)
15:06LauJensenok :(
15:07hiredman,(* 16 3)
15:07clojurebot48
15:08nishant:raek I just noticed that there might be multiple jars which contain this class, you think that could result in this behavior?
15:09raekpossibly
15:09raekI don't know, but I guess that could be worth investigating
15:09raekit can cause weird things, for sure
15:10nishantokay let me try that, thanks for your help!
15:18nishantraek: the jar was old :)
15:18nishantsorry for wasting your time
15:24raeknishant: no worries :)
15:25nishantthanks
15:49_rata_if I have a map from objects to their weights, how do I randomly choose one of those objects based on the given distribution? is make-distribution from clojure.contrib.probabilities.finite-distributions the best way?
15:56_rata_why are there two math libs in clojure.contrib?
16:15amalloy_rata_: finite-distributions, as far as i can tell, defines a way to create pdfs, but not a way to select from them, so there must be some other lib that uses them
16:16amalloyif you
16:16amalloyre interested, http://rosettacode.org/wiki/Probabilistic_choice#Clojure is an implementation of what you're doing from scratch
16:17_rata_can't I use the monad that make-distribution returns directly? (I don't know anything about monads... any reference to understand them would be appreciated :) )
16:17amalloyi don't either :P
16:18raek_rata_: rhickey's ants.clj example contains the 'wrand' function, which seems to do something similat to what you are trying to obtain: http://raek.se/ants.clj
16:21_rata_raek, oh thanks. that's something very similar to what I'm looking for
16:22_rata_"=" for refs is the same as "identical?"?
16:25amalloy,(let [[a b :as c] (repeatedly (atom 0))] (map (juxt = identical?) c))
16:25clojurebotjava.lang.RuntimeException: java.lang.ClassCastException: clojure.lang.Atom cannot be cast to clojure.lang.IFn
16:25amalloy,(let [[a b :as c] (repeatedly #(atom 0))] (map (juxt = identical?) c))
16:25clojurebotjava.lang.IllegalArgumentException: Wrong number of args (1) passed to: core$identical-QMARK-
16:25amalloybleh
16:26amalloy,(let [[a b] (repeatedly #(atom 0))] ((juxt = identical?) a b))
16:26clojurebot[false false]
16:27_rata_,(for [a (repeatedly 5 #(atom 0))] (map (juxt = identical?) a))
16:27clojurebotjava.lang.IllegalArgumentException: Don't know how to create ISeq from: clojure.lang.Atom
16:27amalloy_rata_: looks like yes
16:27_rata_,(for [a (repeatedly 5 #(atom 0))] ((juxt = identical?) a))
16:27clojurebotjava.lang.IllegalArgumentException: Wrong number of args (1) passed to: core$identical-QMARK-
16:28amalloy_rata_: you can't possibly do it with just a for. only one a is in scope at a time
16:28_rata_mmm ok
16:29amalloybut since 0 is identical to 0, and two refs to it are neither equal nor identical, it looks like equal and identical are the same for refs
16:29_rata_but anybody knows if that result is an implementation detail or I can relay on that behaviour?
16:30raek_rata_: for clojure types, = means value equality for immutables and indentity equality for mutable things (atoms/refs/agents/vars, etcs)
16:30_rata_ah ok :)
16:30raek,(= [1 2 3] '(1 2 3))
16:30clojurebottrue
16:30_rata_thank you amalloy and raek
16:40ztellmanbmh: still have questions about penumbra?
16:41BufferUnderpantsHi
16:42BufferUnderpantsI'm trying to use the ZK web framework from within Clojure and I'm having trouble with a proxy class.
16:43nishantdoes repl-utils/source not work on functions I define in the user namespace?
16:44BufferUnderpantsThe method I'm invoking receives an instance of an instance of an interface, very much like Swing.
16:44raeknishant: no, but their definitions needs to be loaded through a require
16:44raekor C-c C-k in emacs
16:45raekif you load then in the repl or with C-x C-e or C-M-x file and line metadata is not stored for them
16:45amalloyoh neat, raek, i didn't realize source worked for C-c C-k. i just knew it didn't work if you put them into the repl so i never tried
16:47nishantraek:thanks
16:48colinsteelehey folks how do I turn a string into a java.io.Reader or a java.io.InputStream??
16:48colinsteele<---- java noob, pardon my cluelessness :)
16:50lpetit,(java.io.StringReader. "a string")
16:50clojurebot#<StringReader java.io.StringReader@6d9e14>
16:50lpetitcolinstee: ^^
16:50colinsteeleahhhh
16:50colinsteelevoila, thanks
17:07hsuhhello folks... i wrote this (http://pastie.org/1221883) and thought it was too slow, what am i doing wrong ?
17:09Chousukehsuh: 7ms per database connection & query doesn't sound too bad.
17:09Chousukewell, 8ms
17:10Chousukehsuh: it opens a new connection to the database for every query, you hopefully won't be doing that in production code.
17:11arkhhow do I :use namespaces from multiple files (of my own making)?
17:11hsuhChousuke: not anymore... so what should i be doing ? (RTFM is a valid answer)
17:12Chousukehsuh: I think you'll want to open a connection and use that for all your queries. (You'll have to read the docs to find out how, though)
17:13raekarkh: other than (ns my.ns.one (:use the-ns)) (ns my.ns.two (:use the-ns)) etc, for each file that wants to use it?
17:14Chousukeit's a good habit to avoid :use though
17:14aretehsuh: you'll want to use a connection pooling ds and the :ds option for clojure.contrib.sql
17:14Chousukeat least without :only
17:14aretehttp://jdbc.postgresql.org/documentation/publicapi/org/postgresql/ds/PGConnectionPoolDataSource.html
17:14arkhraek: how do namespaces work with the class path? i.e., how does clojure know where to find namespaces in the files I make / want to load
17:14raek(I interpreted your question as that you wanted to use "the-ns" from "my.ns.one" and "my.ns.to"
17:14hsuharete: tks
17:15raekarkh: yes. (ns foo.bar.some-thing ...) corresponds to foo/bar/some_thing.clj
17:15arkhraek: cool - that's what I didn't know. Thank you
17:15raekwhere the foo/ directory should be in a directory on the class path (presumably src/)
17:15aretehsuh: actually there's an even better example here: http://en.wikibooks.org/wiki/Clojure_Programming/Examples/JDBC_Examples
17:15dpritchetthow long has leiningen had the "lein classpath" task anyway?
17:15raeknote that hyphens in namespace names correspond to underscores in file names
17:16arkhk
17:16hsuharete: otoh the datasource - postgresql example there says "Note that this is not recommended for production. Use c3p0 or similar instead."
17:17bmhztellman: missed you message an hour back. Can pixel shaders be written in java/clojure or am I tied into using C/C++?
17:17ztellmanbmh: pixel shaders have to be written in GLSL, which is a C-99 derivative
17:18areteyeah dunno why it says that, perhaps there are/were issues with the connection pooling
17:18ztellmanbut there's a Clojure DSL that offers some of the same functionality
17:18ztellmanunder the covers, it just translates into GLSL
17:18bmhztellman: hrm. Do you know a good simplex noise/fBM implementation?
17:19bmhI'm playing around with some algorithmic terrain stuff and figured I could try generating everything in the pixel shader
17:19ztellmanbmh: you were looking at the marble program, right?
17:19ztellmanthat uses perlin nosie
17:19bmhztellman: I saw. Perlin fBM. Perlin has dimensionality issues, though
17:19hsuharete: there is also http://github.com/briancarper/postgres-pool
17:20ztellmanbmh: well, it's generally difficult to use pre-existing GLSL code
17:21ztellmanperlin noise is pretty friendly to the hardware
17:21ztellmanI'm not sure about simplex noise, but it shouldn't be too hard to create your own version
17:22bmhztellman: Have you read any of the papers analyzing Perlin? It actually has some terrible characteristics
17:23ztellmanbmh: I haven't, but I'm really not an expert
17:23bmhFor example, the hash function that Perlin used is highly correlated
17:24bmhIf I was an expert I wouldn't be lurking on irc picking the brains of people more in the know than I ;-)
17:24ztellmanha, well I don't think the difference between terrains generated by perlin noise and simplex noise are all that obvious
17:25ztellmanbut if you want to pursue another fractal generator and need any pointers on using Penumbra, I'm available
17:26bmhThanks. Have you ever looked at turbulence? It works by perturbing you x,y,z coordinates with... wait for it... coherent noise
17:26edoloughlinHi, I'm trying to remove nil values from a map (I'm new to Clojure). I'm using
17:26edoloughlin(def record {:a 1 :b 2 :c nil})
17:26edoloughlin(merge (for [[k v] record :when (not (nil? v))] {k v})
17:26edoloughlinbut this gives:
17:26edoloughlin({:a 1} {:b 2})
17:26edoloughlinWhereas I would like:
17:26ztellmanbmh: I haven't but that seems very GPU friendly
17:26edoloughlin{:a 1, :b 2}
17:27bmhedoloughlin: why don't you use remove
17:27edoloughlinWow. Thanks. Will look it up!
17:27bmh(remove (fn [k v] (nil? v)) collection)
17:27bmhhttp://clojure.github.com/clojure/clojure.core-api.html#clojure.core/remove
17:27edoloughlinThanks.
17:28bmhrich & co. did a great job of getting all the functional stuff right.
17:28dpritchettwhat's the latest in clojure on AppEngine hand-holding libs?
17:28raek,(apply merge (for [[k v] {:a 1, :b 2, :c nil} :when (not (nil? v))] {k v}))
17:28clojurebot{:b 2, :a 1}
17:28raek(into {} (for [[k v] {:a 1, :b 2, :c nil} :when (not (nil? v))] [k v]))
17:29dnolen,(into {} (remove (fn [[k v]] (nil? v)) {:a 1 :b 2 :c nil}))
17:29clojurebot{:a 1, :b 2}
17:29bmhztellman: Is there any reading you could suggest for GPU programming? I'm a bioinformatician by trade, so graphics is a big, magical world to me
17:29ztellmanbmh: I haven't found a good conceptual book yet
17:30ztellmanbmh: but the orange GLSL guide isn't all that bad as a reference
17:30edoloughlinThanks everyone.
17:30ordnungswidrigis there something like zip for multiple seqs? [[1 2 3] [:a :b :c] ["!" "§" "$"]] -> [[1 :a "!"] [2 :b "§"] [3 :c "$"]]
17:31raek,(map vector [1 2 3] [:a :b :c] ["!" "§" "$"])
17:31clojurebot([1 :a "!"] [2 :b "§"] [3 :c "$"])
17:32raekmap hase the useful property of "taking one thing from each seq"
17:32bmhraek: I had an interview earlier this week. I solved one of the problems they gave me with a few applications of map, filter, and reduce.
17:33bmhWe spent the remainder of the interview discussing the finer points of roguelikes...
17:34ordnungswidrigah, cool, I didn't know this one.
17:34ordnungswidrig,(doc map)
17:34clojurebot"([f coll] [f c1 c2] [f c1 c2 c3] [f c1 c2 c3 & colls]); Returns a lazy sequence consisting of the result of applying f to the set of first items of each coll, followed by applying f to the set of second items in each coll, until any one of the colls is exhausted. Any remaining items in other colls are ignored. Function f should accept number-of-colls arguments."
17:35ordnungswidrig,(map vector [1 2] [:a :b :c])
17:35clojurebot([1 :a] [2 :b])
17:36hsuharete: 10x improvement with postgres-pool
17:37ztellmanbmh: I'm heading out, but hit me up on the penumbra mailing list with any questions you have
17:38bmhztellman: thanks. I'll subscribe.
17:39aretehsuh: sounds speedy
17:44_rata_has anybody problems with the debugger of swank-clojure and clojure 1.3?
17:45lancepantzso i was just playing around with tuning my jvm a little
17:45lancepantzi took 100m off of my Xmx, which dropped my virtual memory usage by 160m
17:46lancepantzanyone have any ideas where the extra 60 is coming from?
17:50amalloylancepantz: what was your Xmx to begin with?
17:51lancepantztook it from 500 down to 400 in this case
17:52amalloymy guess, at any rate, would be some magic mumbo-jumbo to do with powers of two
17:52_rata_has anybody experienced problems with the debugger of swank-clojure and clojure 1.3?
17:58nishantdoes clojure have something like for-each?
17:58nishantbold question
17:59AWizzArdmap, doseq, for
17:59AWizzArd,(map inc [10 20 30])
17:59clojurebot(11 21 31)
17:59nishantokay, I was looking for something that only side effects
17:59AWizzArd,(doseq [n [10 20]] (println n))
17:59clojurebot10 20
18:01kmcheh, clojurebot captures output?
18:05nishantthanks!
18:08gfrlogis there a faster way to create a map from a list of pairs aside from (apply hash-map (reduce concat pairs))?
18:08dnolengfrlog: into is your friend
18:09dnolen,(into {} [[1 2] [3 4]])
18:09clojurebot{1 2, 3 4}
18:09gfrlog,(into {} [[1 2] [3 4]])
18:09clojurebot{1 2, 3 4}
18:09gfrlogawesome, thanks
18:11kmc,(doc into)
18:11clojurebot"([to from]); Returns a new coll consisting of to-coll with all of the items of from-coll conjoined."
18:11kmc,(into [1 2] [3 4])
18:11clojurebot[1 2 3 4]
18:12kmc,(conj [1 2] 3)
18:12clojurebot[1 2 3]
18:13gfrlog(into #{} {:a 2 :c 5})
18:13gfrlog,(into #{} {:a 2 :c 5})
18:13clojurebot#{[:a 2] [:c 5]}
18:19gfrlog,(defrecord Tom [jill tim])
18:19clojurebotDENIED
18:23gfrloghmm. I do a (defrecord Graph [order edges]) in a certain namespace, (use) that namespace from the repl, but then Graph doesn't resolve
18:25KirinDaveSo
18:25Chousukegfrlog: you need to import records
18:25Chousukegfrlog: they become classes
18:25gfrlogoooh
18:26gfrlogvery good
18:26KirinDaveIt's not possible to use the extend+merge technique to simulate inheritance with (reify ...), unless you want to use a macro and promise compile-time support. Right?
18:27KirinDaveWith (extend ...) you can merge two maps together
18:28KirinDaveBut extend requires a specific type to extend.
18:28KirinDaveIf you want anonymous types to fit a protocol, you have to have the entire proposition be static, right?
18:28KirinDave(unless, of course, you want to eval a form)
18:28KirinDaveThere's no way to provide default/inherited behavior to reified objects.
18:29ChousukeI suppose you could use reflection but it'd be fragile
18:30KirinDaveChousuke: I mean, a macro is easy enough to turn {:name (fn...) ...} into a '(name (fn...))
18:30KirinDaveChousuke: But...
18:30KirinDaveThat's purely static.
18:37AWizzArdHow can I declare a deftype field as :unsynchronized-mutable and ^int at the same time?
18:43_rata_I don't get what make-distribution does
19:03gfrlogdoes (first #{2 3 4}) require the axiom of choice?
19:04amalloyAWizzArd: i think it looks something like this: (deftype a [^{:volatile-mutable true :tag int} h])
19:05amalloythat creates for me an A class, with a 1-arg int constructor. i'm not sure if it's mutable since i don't do deftypes very often, but it seems like if the tag works the mutability probly does too
19:07AWizzArdI will try that, thanks for the idea
19:15gfrlog,#{4 4 5}
19:15clojurebotDuplicate key: 4
19:19jashmennhey, im wondering if someone can help me figure out a macro problem: https://gist.github.com/fdd8b7b902b1ab8170f7
19:20jashmenni realize that macros don't evaluate their operands
19:20jashmennbut i'm wondering how i can evaluate them if i want to
19:21gfrlogjashmenn: I think you can only set them up to be evaluated
19:22gfrlogit looks like you're trying to call the function twice?
19:22jashmenni want to use the var x as an argument to defining the output of the macro
19:22jweissanyone know how to switch slime from clojure back to lisp? when i run slime it tries to load clojure
19:23jweissor better yet, be able run either one :)
19:23technomancyjweiss: getting rid of swank-clojure should help
19:23gfrlogjashmenn: could you make foo a function? maybe one that calls another macro?
19:24technomancyI don't use CL myself though, I could use some help making swank more Cl-frinedly
19:24jweisstechnomancy: so once swank-clojure is installed, it assumes you're only using clojure as inferior-lisp?
19:24dnolenjashmeen: there are two hidden params handed to macros &env and &form
19:24jweissi don't know CL much myself. i learned a bit briefly before finding clojure.
19:24technomancyjweiss: maybe? getting rid of swank-clojure.el is a good idea even if you don't use CL. it's just got some heinous hacks that were necessary when lein didn't exist, but don't make sense any more.
19:25technomancyit just complicates things
19:25jashmenndnolen: this sounds interesting. let me look that up
19:25jweisstechnomancy: so it is not necessary to run lein swank, and then slime-connect?
19:25jweissit meaning swank-clojure.el
19:25technomancycorrect
19:26jweissexcellent, that's most likely the problem then, i set up clojure dev here before lein came along (or maybe just before i discovered it)
19:27jweisstechnomancy: i have swank-clojure and clojure-mode elpa packages - do i need those?
19:28technomancyjust clojure-mode and slime-repl
19:28jashmenndnolen: okay, so i've got &env and it shows the LocalBinding. now im not exactly sure how to safely get the value of `g` out of it
19:29dnolenjashmenn: ah sorry you led you astray, &env is just so you can the surrounding context from w/in a macro
19:29jashmenndnolen: ah okay
19:30dnolenjashmenn: the only way to get at the value of something is eval, but what exactly are you trying to do?
19:31jashmenndnolen: i want to pass an argument into a macro and use the value of it (unquoted) to help build the sexp within the macro
19:33jashmennbut, like gfrlog was saying, i think i need to just set it up to be evaluated, not evaluate it early
19:35gfrlogjashmenn: can you use eval?
19:35dnolenjashmenn: curious as to the end goal, why do you need the actual value of a literal to influence the macro expansion?
19:36dnolenjashmenn: sometimes it is indeed useful to eval in a macro, but usually unnecessary.
19:36gfrlogI've never done it
19:37dnolenI've only needed once, because I was using the contents of files on disk to generate code.
19:41amalloyjashmenn: why is the value being passed in a variable instead of a literal? (not just asking to tell you you're wrong; i think you can probably make this happen)
19:49rplevyusing clojure contrib 1.1.0, I am trying out contrib.condition. it doesn't do quite what I would expect. it certainly responds to the raised condition as specified but the exception goes uncaught delivering the message in tomcat. what I need it to do and what I think the semantics of it is, is for handler-case to be like try and for handle to be like catch in the sense that I can do something with the result. Am I doing it wrong or was it jus
19:50technomancyrplevy: support for catching regular exceptions in handler-case just got committed last week IIRC
19:50technomancymight be able to backport it to 1.1, but it might be tricky; easier to just upgrade to 1.3 =)
19:53jashmenndnolen: well when i try to eval it says "can't eval a local"
19:53dnolenjashmenn: heh, yeah I forgot about that.
19:53jashmennamalloy: right, if i pass in the value as a literal it works fine
19:53jashmennbut, obviously this is just extracted from a much larger macro
19:53jashmennand `x` in this case "has to" be a variable
19:54jashmenni don't mind passing it in as a literal in the `let` if you have advice on the best way to do that
19:55amalloyis this a macro embedded within another macro?
19:55amalloyor called from another, whatever
19:55jashmennamalloy: yes
19:55amalloyokay. usually you don't need to do that
19:56amalloywrite your inner macro as a *function*, not a macro
19:56jashmennbut what if i need both inner and outer to do list destructuring like ~@body ?
19:57amalloyeg (defn foo [x] `(prn ~x))
19:57amalloybacktick is legal in functions too; the only special thing about macros is that their arguments aren't evaluated
19:57jashmenni didnt think that was possible with just a plain defn but i guess im wrong
19:57jashmennhmmm
19:58jashmennah ha
19:58jashmennokay
19:58jashmennthanks
19:58amalloy,(let [x (fn [] `(prn 1))] (x))
19:58clojurebot(clojure.core/prn 1)
19:59jashmennokay, this is very helpful. thanks amalloy (and everyone else)
19:59amalloywelcome jashmenn
19:59amalloythis is a macro "trick" that is widely applicable: don't use macros :)
20:06tomojhaha
20:08kmci see a few libraries for continuations in Clojure, implemented by performing a continuation-passing-style transform
20:08kmcbut it seems to me that CPS is fatally limited without TCO
20:08kmcis this a problem for using continuations in Clojure, or do they manage to insert trampolines cleverly to get TCO?
20:11tomojkmc: http://intensivesystems.net/tutorials/cont_m.html
20:12tomojdoes it look like that approach is limited by lack of TCO?
20:15kmcyes
20:15kmcmost of those functions end in a tail call
20:15kmcin CPS you replace "return to parent, which does something else" with "tail-call a continuation"
20:15kmcthis is going to use more stack, unless you have TCO
20:16kmchowever i bet that some clever CPS macros for Clojure could replace calls with returns and use trampoline
20:16kmcwhich is what i was asking about
20:17amalloyYou know we have trampoline, right?
20:18kmcyeah i mentioned it twice
20:18amalloyHaha, just checking that you didn't mean to implement it first
20:19tomojwould you just have to add a trampoline at every tail call site?
20:19amalloyOn my mobile atm, apologies if I miss some context
20:20kmctomoj, i'm not really sure
20:20tomojI don't understand CPS yet :(
20:20kmcother languages implemented on systems without TCO sometimes wrap the whole program in one trampoline
20:20kmcand my understanding is that Clojure could have done this to get transparent TCO
20:20kmcbut it would slow down everything
20:20tomojah, right
20:22kmctomoj, in CPS every function takes an extra argument (the continuation) and, instead of returning, calls that
20:22kmcso (fn [x] (+ x 2)) becomes (fn [x k] (k (+ x 2)))
20:22kmcexcept that in a full CPS transform, we'd CPS-transform (+) too, and eliminate every non-tail call
20:23kmc(fn [x k] (+ x 2 k))
20:24kmcand (fn [x] (* (+ x 2) 3)) becomes (fn [x k] (+ x 2 #(* % 3 k))) or some such
20:27kmcand if you carry this to its conclusion, your big nested expressions get unfolded to a linear sequence of small steps
20:27kmcwhich is why CPS transform is useful as a stage in a compiler
20:28kmcand indeed is close to the SSA form used in lots of compilers for languages not traditionally called "functional"
20:29tomojkmc: actually, doesn't the article there explain it?
20:29tomojsearch for "But why?"
20:29kmcyeah
20:29kmcthat's kind of orthogonal to what i said above
20:30tomojoh
20:30kmcthat's answering why you as the programmer should care about CPS
20:30kmcwhat extra power it gives you
20:30kmcnot why a compiler should use it internally, or mechanically how it's carried out
20:31tomojwell, doesn't that article show a way to do the trampolining to get around lack of TCO?
20:31kmcyeah i see it now
20:32tomojby placing bounces you can control which parts of the chain avoid function call overhead at the expense of stack space, I guess?
20:32kmcyeah
20:33kmcand if you baked the bounce into your monadic bind, you'd have full TCO at the expense of slower function calls
20:34tomojunrelatedly, have you seen aleph?
20:34kmcno
20:34tomojhttp://github.com/ztellman/aleph/wiki
20:34tomojbells are going off in my head but I'm too stupid to tell whether it's a false alarm
20:35kmcding
20:44kmcso how expensive are threads in Clojure?
20:45kmcare they 1:1 with Java threads or something more lightweight?
21:20amalloyi don't remember if it was tomoj or kmc who linked the intensivesystems monad tutorial, but thanks. so far i'm finding it a lot more understandable than the others i've looked at
21:21amalloyanyway, have to run, but just wanted to mention that
21:30gfrlogdoes anyone else think that c.c.sql could use an ensure-connection macro?
21:30lancepantzcc.sql could use alot of things
21:31gfrlog,(defn alot-of-things [& args])
21:31clojurebotDENIED
21:31ninjuddlike a way to load huge datasets without bringing the whole thing into memory!!!
21:31ninjudd;)
21:33lancepantzgfrlog: there is a clj-sql project that addresses alot of the shortcoming, but i don't actually use it
21:34lancepantzi usually end up calling the jdbc methods directly
21:36gfrloglancepantz: clj-sql doesn't have it -- are you suggesting that project might be easier to contribute to than cc?
21:36lancepantzgfrlog: yep
23:57yayitsweiany pointers for setting up log4j with clojure.contrib.logging? just want a simple way to append-to-file