#clojure logs

2009-07-20

03:17yasonVkthkstt!
03:28yasondang
03:28yasonwriting passwords blinded with a dead display is bad :)
06:09Fossihi
06:10Fossii just stumbled over another piece of lisp-1 fun again: having a struct named foo and normally calling your variables foo as well
06:11Fossimake a typo in the parameter list and it won't even fail on you, only retun nil for a value of the struct
06:11Fossiso, note to self: name structs struct-foo
06:29AWizzArdFossi: yes, I also stumpled over that some months ago. But I did not decide yet if this has more to do with Clojure being Lisp-1 or being dynamically typed.
06:29AWizzArdWhy would one name variables after their type in statically typed langs?
06:51ckyFossi: I can't comment on Clojure convention, because I'm new to it, but in Scheme, record type objects are usually bracketed with angle brackets.
06:51ckye.g., <foo>
06:55AWizzArdcky: in Clojure it would not be typical to put names of structures into angle brackets.
06:57cemerickalthough I smile a little every time I'm reminded that clojure is perfectly happy with symbols like <foo>...forgive me for my java/python background :-)
06:58AWizzArdIt could be the convention for a project. If it is used consistently then I wouldn't mind.
06:59AWizzArdFor example, we use fnparse (thanks for the tip hiredman) and all rules begin with a !.
07:05Chousukecemerick: I think clojure is fine with any unicode character :P
07:06cemerickyeah, almost :-)
07:06Chousukeactually, it even accepts ' ' as a symbol character
07:06cemerickright, just not through the reader
07:06Chousukeyes it does.
07:07Chousukethat's a double-width space :)
07:07cemerickah, couldn't tell that in irc :-)
07:07Chousukeuser=> (def funky symbol 5)
07:07Chousuke#'user/funky symbol
07:07Chousukeuser=> funky symbol
07:07Chousuke5
07:07Chousuke:P
07:07ChousukeI think that's a bug, though.
07:08AWizzArdThe biggest problem with that will be actually *typing* these unicode chars.
07:08Chousukeit's not too difficult with an input method editor :P
07:10Fossiworse i've seen was sql which had right-tp-left markers in it
07:11Fossi*t
07:11Fossiinit was like: insert into foo values (";("somestring
07:12Fossimakes you go 'wtf?'
07:12AWizzArd(def √² 1.4142135)
07:16cemerickAWizzArd: if you're on a mac, then typing such things is incredibly simple (e.g. no alt+... codes to remember)
07:17AWizzArdi see
07:17cemerick√ is just option-v for example -- there are even some mac keyboards that have the 'special' characters printed on the front face of the key
07:17Fossionly that all the other letters are on a weird comb
07:17Fossikey combo
07:20cemerickah, this is the one I was thinking of: http://matias.ca/tactilepro
07:20ChousukeFossi: job security? :p
07:21Fossiand the infallable apple-q
07:21Chousukemy mac layout has no quick key for lambda :(
07:21Chousukeopt-l gives fi
07:21rysheh, the unicode chars in my term while we discuss this made cemerick's 2nd to last comment appear to come from me
07:21cemerickChousuke: that's easy to change
07:21rys(for me at least)
07:22Fossiso my keylayout is totally different anyway :)
07:22AWizzArdI am using the NEO layout (not qwerty), and with it I also have easy access to greek symbols and mathmatical symbols and programmers symbols.
07:23Fossiyeah, neo is nice as well
07:23Chousukebut does it support APL?
07:23AWizzArdFossi: it is following the same ideas like dvorak, but more specialized on german, while dvorak is a bit better for english.
07:25AWizzArdAh ok, that's why you know neo
07:25ckyHehehehe. :-)
07:25Fossii decided to learn dvorak though because it's better supported by hardware manufacturers
07:25Fossiand the difference is not as big with a nice layout like this keyboard has
07:26AWizzArdWell, my keyboard also has good support: http://www.daskeyboard.com/
07:26Fossiif you haven't you should check it out. best ever :)
07:26Chousukethere's a Finnish optimised layout called DAS. It has some characters that are officially used in Finnish for certain loanwords but which no-one really uses :P
07:26AWizzArdAs it does not show any printings on the keys... it fits perfectly.
07:26FossiAWizzArd: well, i would annoy my collegues to death with that
07:26Fossipair programming gets kinda hard :)
07:26Chousukepartly because they're impossible to type with Finnish qwerty.
07:26AWizzArdI ask my workmates to type blind *g*
07:26ckyAWizzArd: That's the real way to type! :-)
07:27cemerickhrm, we should do a poll of clojure programmers' nationality
07:27Fossiactually i find it easier to type dvorak on daskeyboard then on a qwerty
07:27ckyMy keyboard still has qwerty keycaps printed on, so it doubly confuses my workmates, who cannot hunt-and-peck. :-P
07:27AWizzArdvery good
07:28rysI can't remember the last time I looked at my keyboard to type anything
07:28ckyrys: Exactly!!
07:28rysThe keys could be blank
07:29ckyWhereas, back when I was learning Dvorak, I shifted the keys on my laptop at the time, with the severe downside that the home keys aren't where they are supposed to be. :-(
07:29Fossinow it's much better
07:30ckyBy home keys, I mean the bumpy keys where U and H are in Dvorak. :-)
07:30Fossihuh? i though you meant physically
07:30Fossiah, ok
07:30Fossinever had a problem with that really
07:30ckyWell, without the bumpy keys, my hands tend to drift too much.
07:31Fossithen again a divider in the middle helps a whole lot
07:31cky...that is true.
07:31Fossiextra points for it being the enter key :D
07:31cky:-)
07:32ckyWell, here in the US it's not easy to find a Dvorak keyboard, but that doesn't mean I will use any layout other than Dvorak (if I ever learn German I'll learn NEO too :-P).
07:33Fossii ordered mine from the us actually
07:33cky*nods* Yes, I suppose I should find some suppliers.
07:33Fossiit's not like they have them in store
07:33cky*nods*
07:33Fossias said: reallt check out typematrix
07:33Fossiit's *awesome*
07:34ckyThanks! :-)
07:38AWizzArdFossi: try this one please: http://schnell-schreiben.de/stv2/
07:38fsmHi, I have made a raytracer as a project to learn cloure. Here is a pic. http://solardriftwood.com/aa.png
07:38AWizzArdOr the english version (measuring typing speed): http://speedtest.10-fast-fingers.com/
07:38fsmclojure*
07:39AWizzArdfsm: did you write the RT from scratch? Or used Harrops version?
07:39fsmI wrote it from scratch
07:39fsmI do not know what Harrops refers to
07:39cemerickfsm: very nice! :-D
07:40AWizzArdfsm: good good
07:40fsmSince then it does texture mapping and bump mapping, but I don't have a nice image of that yet
07:40fsmBut, I have a performance issue relating to boxed primitives
07:41fsmI have profiled and most of the bottlenecks are in operations of vectors of doubles [x y z] and I am trying to find the fastest representation
07:41fsmWhen I converted to using make-array and aget, instead of [] and nth, I lost 30% performance
07:41AWizzArdyou probably introduced reflection then
07:42fsmWhen I profile, I see millions of calls to Number.ops methods where I would hope for native arithmetic
07:42fsmI turned on reflection warnings, there's no reflection
07:42fsmThe other weird thing, is I tried making some vector math into macros instead of functions, that caused a 20% slowdown
07:42fsmI guess the java hotspot optimizer is very clever if you call the same function a lot
07:43cemerickfsm: perhaps the unchecked math fns are appropriate?
07:43cemerick,(doc unchecked-add)
07:43clojurebot"([x y]); Returns the sum of x and y, both int or long. Note - uses a primitive operator subject to overflow."
07:43cemericketc....
07:43fsmI saw that, but i am using floating point unfortunately
07:43fsmI tried adding type hints also, but that seemed to cause a performance hit, i guess more redundant boxing/unboxing was introduced
07:44carkdo you coerce your floats ?
07:44fsmSay I have two vectors [1.0 2.0 3.0] and [4.0 5.0 6.0] and I want to add them together, is there a faster way to access the variables than nth
07:44fsmI tried coercing the floats, that caused a small performance drop
07:45fsmI am perplexed that using make-array to make a double array is so slow
07:45Chousukeit's slow because it does a full copy :/
07:46cemerickthat, or the array is java.lang.Float[] instead of float[]
07:46fsmI was using make-array Double/TYPE which refers to double
07:46fsmUnless I am mistaken
07:46cemerickno, you're not :-)
07:46carknope this is correct
07:47fsmSo, even when I use macros and everything expands out to just basic arithmetic and aget, or to using nth, millions of calls to Numbers.obs.* show up
07:47fsmops
07:47fsmI mean
07:47Chousukehmm
07:47carkand you're using the -server flag when starting java ?
07:48Chousukeare you passing more than two arguments to +?
07:48fsmI have nested my operator +, that caused a big speed boost
07:48fsmI have not been using -server flag
07:48carkah, this should help a lot
07:48fsmOK I will research that
07:48cemerickyeah, the client compiler is completely different
07:49cemerickhrm, the only thing preventing support for unchecked ops in Numbers are more overloads :-)
07:49fsmBack in a minute, going to do a performance check
07:50carkyou need to take the warm up into account, compilatin only occurs after quite a few runs of each function
07:50fsmYep, I have written a timer macro that times only the actual executions
07:51fsmAnyway, I must say that writing this project is a very rewarding experience
07:52fsmThe tools of functional programming are like having a CNC machine compared to hammer and chisel
07:52cemerickfsm: In general, you need to let whatever code paths you're benchmarking "warm up" at least a half-dozen times before most of the compiler optimizations have been baked in.
07:53fsmYes, with raytracing the same routine is called for each pixel on the screen, causing a great many runs
07:54ChousukeIt sounds to me that dealing with arrays in Clojure is somehow unnecessarily difficult :/
07:57fsmOK, using -server results in a consistent 3% speed boost
07:58fsmAnyway, I will clean up the code and post it somewhere in the next day or two
07:59fsmMeanwhile my algorithmically equivalent Objective-C version was on the order of 10x faster
08:00fsmBut Clojure is an excellent project, I look forward to solving this problem
08:01ChousukeIs there any easy way of determining where boxing happens? :/
08:02cemerickessentially at any function boundary, aside from unchecked-* ops AFAIK
08:02fsmDoes that include aget
08:02AWizzArdfsm: maybe you can inline here and there
08:03AWizzArd,(doc definline)
08:03clojurebot"([name & decl]); Experimental - like defmacro, except defines a named function whose body is the expansion, calls to which may be expanded inline as if it were a macro. Cannot be used with variadic (&) args."
08:03Chousukecemerick: can you tag functions to tell clojure that they return primitive values? :/
08:03fsmI tried converting everything to macros already, unfortunately that reduced performance, I think by reducing the effectiveness of the hotspot optimizer
08:04cemericknot that I know of, no
08:04fsmBut if aget is boxing the value it returns, that could be the crux of the problem i am having
08:05Chousukefsm: are you doing (let [foo (double (aget ...))])? or something
08:05cemerickfsm: macros don't necessarily impact the optimizer -- that is determined by the code that your macros emit. So, unless the code they're emitting is more efficient than your normal fns, the macro usage will be slower.
08:05Chousukecemerick: expanding macros bloats the code though.
08:06fsmI am not using that let syntax, because it would mean I have to unpack and repack my vectors to do operations on them.
08:06cemerickI think the bottom line issue here is that there's no unchecked math for floating points / doubles
08:06fsmWhich is not very lispy
08:06AWizzArdfsm: do you have a short and simple example where a macro slowed down your code?
08:06Chousukefsm: IIRC the optimisation tips page recommends that all primitive "casts" be done in a let, though :/
08:06AWizzArdThe funny thing is that in the compiled version that you execute no macros exist anymore.
08:07fsm(defn dot [v1 v2] (+ (+ (* (vx v1) (vx v2)) (* (vy v1) (vy v2))) (* (vz v1) (vz v2)))))
08:07fsm^^ rewriting that to be a macro slowed down my code
08:08cemerickChousuke: the perf of the fns emitted by the macro is way more important than the 'size' of what it's emitting, though.
08:08fsmthe vx/vy/vz are wrappers for either nth or aget - vx v1 = (aget v1 0)
08:08fsmand when I make vx/vy/vz into macros too, even more performance drop, but only 5% or so
08:08Chousukecemerick: well, more code equals less effective use of cache.
08:08Chousukecemerick: which may make a huge difference, if you're unlucky.
08:08fsmI tried representing my vectors as [1.0 2.0 3.0] and as make-array
08:09cemerickChousuke: true, true.
08:09fsmusing make-array/aget instead of [] and nth caused an overall 30% speed drop
08:09Chousukefsm: that dot function you pasted is not doing primitive math, though :/
08:10cemerickChousuke: which isn't avail. for floats/doubles
08:10fsmI wrote a version that was (defn dot [#^doubles v1 #^doubles v2]
08:10fsmand that was slower
08:11Chousukecemerick: hm :/
08:11fsmif i define vx/vy/vz to be macros that resolve to (aget v1 n), I get bad performance but it should be operating on primitives
08:11fsmbut in the profiler i see Number.ops being called
08:12Chousukebut if what cemerick says is true and primitive ops are not available for doubles, then boxing is inevitable :/
08:12Chousukebut, raaah
08:12fsmoh, I misread that
08:12ChousukeGHC took over an HOUR to compile and then it dared fail at the end.
08:12cemerickwell, there's no overloads for the unchecked math in Numbers *shrug*
08:13cemerickthere may be a good reason for that that I'm not thinking of, I suppose
08:14fsmThe java_interop page shows an example working on a java array of primitive floats, supposedly
08:14fsmAnyway, thanks to everyone
08:15fsmI will post the code tomorrow and if anyone wants to experiment on it, they are welcome
08:24fsmHmm in RT.java, aget takes an array of primitives and returns a primitive
08:24fsmand in core.clj, aget is defined as {:inline (fn [a i] `(. clojure.lang.RT (aget ~a ~i)))
08:24fsmdoes that call into clojure.lang.RT cause the return value to get boxed?
08:25fsmThe docs suggest that values passed to a function are boxed, so perhaps the return value is too?
08:25Chousergenerally, yes. but macros and :inline are an exception.
08:26Chousukemacros don't get the actual value anyway :)
08:26Chouserright. both macros and :inline expand at compile time and thus the call "disappears"
08:27Chouserin this case what's left is a Java interop call which is not necessarily boxes.
08:27Chouserboxed
08:28fsmAnyway it be super fast, it boils down to a static function that does only return xs[i];
08:28fsmshould be*
08:29fsmIt's getting too late for abstract thinking, time for sleep.
08:29fsmThanks to everyone for your help.
08:38Fossiis it bad to (apply str (rest word))?
08:38Fossis/word/some-string/
08:38AWizzArdnot if you need the result
08:39Chousuke,(doc subs)
08:39clojurebot"([s start] [s start end]); Returns the substring of s beginning at start inclusive, and ending at end (defaults to length of string), exclusive."
08:39Chousukeprobably a fair bit faster :P
08:39Fossithat kinda was the question, sorry
08:41Chousukethough sometimes you do need to work with char sequences. str uses a StringBuilder internally so at least it's faster than naive string concatenation in java :)
08:42Fossiso (str (Character/toUpperCase (first "foo")) (subs "foo" 1)) should be better then (apply str (Character/toUpperCase (first "foo")) (rest "foo"))
08:42Fossi*than
08:42Fossimy engllish is so borked today
08:43ChouserI'd recommend shooting for clarity and maintainability first -- worry about speed only if you have to.
08:44Fossiwell, imho they are kinda both readable, i do not wonder about performance so much, but rather about which would be considered better style
08:47Chousukehmh
08:48ChousukeI wonder which of my installed ports depends on x11 :P
08:49ChouserI think 'str' is less complex than 'apply str', and you don't have to think about whether the use of 'rest' vs. 'next' is important, etc. I'd vote for the first form.
08:50Chousukekind of annoying, trying to upgrade ports and then something tries to install all of X11
09:11Fossialthough they are kinda 'slacking off' lately
09:13Jomyootdo you guys prefer light on dark or dark on light?
09:13jdzdark on light is usually easier on the eyes
09:14Jomyootwhy do the textmate geeks use light on dark then?
09:14weissjcan someone tell me the easiest way to "un"-lazy a sequence? the laziness is causing this not to work: (map await (map #(send-off (agent %) do-one-file targetDir) mylist)))
09:14jdzthey are geeks?
09:14JomyootI followed their convention for years
09:14Jomyootkiddies
09:14Jomyootwhat u call them
09:14jdzwell, i meant that as an answer
09:15cemerickweissj: you probably want doall
09:15weissj,(doc doall)
09:15clojurebot"([coll] [n coll]); When lazy sequences are produced via functions that have side effects, any effects other than those needed to produce the first element in the seq do not occur until the seq is consumed. doall can be used to force any effects. Walks through the successive nexts of the seq, retains the head and returns it, thus causing the entire seq to reside in memory at one time."
09:15chessguy_workthe first two test functions on http://blog.objectmentor.com/articles/2009/07/19/uncle-bob-jsps-learning-clojure are basically reduce and map, respectively, right?
09:15cemerickor maybe dorun, if you don't care about the results of the map
09:16weissjcemerick: i care about getting the entire seq from the inner map
09:17weissjin other words i want the entire inner map calculated before any awaits are done
09:17chessguy_work,(reduce + [1 2 3])
09:17clojurebot6
09:18jdzgood thing i can easily change the brightness of the screen
09:18jdzand my laptop actually does it automatically
09:19Fossii had a script a while back that switched between light and dark mode :)
09:20chessguy_worki think it's something like (defn roll-list [game list] (reduce roll (conj game list))) but i don't have an interpreter in front of me
09:20cemerickweissj: then I think it'd be (map await (doall (map #(send-off ...))))
09:20cemerickI've never used agents though, so that's just a guess, really
09:20weissjcemerick: i'll give it a try, thanks!
09:21chessguy_work(crickets chirping)
09:24chessguy_work,(let [x 3] x)
09:24clojurebot3
09:25angermanhow do i cast a class to a different interface?
09:25chessguy_work,(let [roll (fn [g p] (conj g p))] (roll [2] 3)
09:25clojurebotEOF while reading
09:25angermane.g. JRubyScriptEngine to Invocable
09:25chessguy_work,(let [roll (fn [g p] (conj g p))] (roll [2] 3))
09:25clojurebot[2 3]
09:27Chouserweissj: when creating/sending/awaiting an agent all at once like that, you might prefer 'future'
09:27chessguy_work,(let [roll (fn [g p] (conj g p)), roll-list (fn [g l] (reduce roll (conj g l)))] (roll-list [] [1 2 3]))
09:27clojurebot[1 2 3]
09:27angermanwhile in java i"d just do (Invocable)variable ...
09:28Chouserangerman: you generally don't need to cast. what are you trying to do?
09:28cemerickangerman: why are you looking to perform a cast? Such a thing is essentially not present in clojure, as it's dynamically typed.
09:28weissjChouser: i will look into 'future', thanks :)
09:28angermanChouser, cemerick that's what I expected
09:29angermanI'm trying to call invokeFunction on a jruby Script Engine
09:29cemerickangerman: if you're looking to invoke a method on an object, and you want to avoid reflection, you can type-hint the object
09:30cemerick(.invokeFunction script-engine-obj ...more-args...) will do it
09:30cemerick(.invokeFunction #^ JRubyScriptEngine script-engine-obj ...more-args...) if you want to avoid reflection
09:30cemerickbah: (.invokeFunction #^JRubyScriptEngine script-engine-obj ...more-args...)
09:32chessguy_workhow would i apply a function to something n times?
09:33Chouser,(map inc (repeat 5 2))
09:33clojurebot(3 3 3 3 3)
09:33chessguy_workermm, sorry, i'd want 10 there
09:33chessguy_workthough i'd want to pass in the 0 too
09:34ChouserI'm afraid I don't understand the question at all.
09:34Chousukeiterate?
09:34chessguy_worksorry, i'm trying to get rid of a for-like loop
09:34chessguy_work(defn roll-many [game n pins]
09:34chessguy_work (loop [i n g game]
09:34chessguy_work (if (zero? i)
09:34chessguy_work g
09:34chessguy_work (recur (dec i) (roll g pins)))))
09:35Chousukeiterate returns a seq though
09:35Chousuke,(drop 9 (take 10 (iterate inc 0)))
09:35clojurebot(9)
09:35chessguy_workyeah this is more like a reduce over a range, where the index is ignored
09:35angermancemerick: hmm it seems the arguments are my problem
09:36cemerickangerman: you're getting an error?
09:36angermanit expects a java.lang.Object and I was giving it a String
09:36angermanCaused by: java.lang.ClassCastException: java.lang.String cannot be cast to [Ljava.lang.Object
09:36cemerickit's expecting an Object[]
09:36Chousermaybe varargs?
09:36cemerick(probably the arguments to the jruby fn?)
09:36Chouserooh
09:36chessguy_work,(nth (iterate inc 0) 9)
09:36clojurebot9
09:37angermancemerick: yes
09:37cemerickangerman: in that case, (into-array ["some" "args"]) might be what you want
09:37angermancemerick: using a vector doesn't resolve it :/
09:37angermanhmm into-array
09:37cemerickvectors aren't arrays
09:37cemerickangerman: :-)
09:37Chouseractually, if it wants Object[], try (to-array ["some" "args"])
09:38cemerickyeah, I can never remember in what contexts a String[] isn't useful as an Object[]
09:38rhickey_chessguy_work: (reduce roll game (range 1 n))
09:39jdzrhickey_: nice one!
09:39rhickey_oh, you're not using n
09:39cemerickthe fact that uncle bob is interested in clojure is interesting
09:39jdza bit confusing, though
09:39chessguy_workrhickey_, yeah, i don't want the index
09:41chessguy_work,(let [roll (fn [g p] (conj g p)), roll-many (fn [g n p] (nth (iterate (roll g p)) n)] (roll-many [] 20 0))
09:41clojurebotUnmatched delimiter: ]
09:41chessguy_work,(let [roll (fn [g p] (conj g p)), roll-many (fn [g n p] (nth (iterate (roll g p)) n))] (roll-many [] 20 0))
09:41clojurebotjava.lang.IllegalArgumentException: Wrong number of args passed to: core$iterate
09:43rhickey_(nth (iterate #(roll % pins) game) n)
09:44rhickey_the best thing to do with that bowling game is to step far away from that original logic
09:45chessguy_work,(let [roll (fn [g p] (conj g p)), roll-many (fn [g n p] (nth (iterate #(roll % p) g) n))] (roll-many [] 20 0))
09:45clojurebot[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
09:45chessguy_workshazam :)
09:46rhickey_the 'kata' is almost a poster child for what I think is wrong with TDD and OO today
09:46rhickey_http://butunclebob.com/ArticleS.UncleBob.TheBowlingGameKata
09:48rhickey_Write a class named “Game” that has two methods
09:48rhickey_roll(pins : int) is called each time the player rolls a ball. The argument is the number of pins knocked down.
09:48rhickey_score() int is called only at the very end of the game. It returns the total score for that game.
09:48drewrugh, he distributes it in a ppt
09:49rhickey_the roll method returns void!!, so right away we have a stateful object. The score method is only valid at certain times.
09:49chessguy_workrhickey_, not in the clojure version
09:49chessguy_work:)
09:49rhickey_So with this awful premise, we start TDD, our system for robust and responsible programming - yikes
09:50rhickey_chessguy_work: yes, the CLojure version should be much different. It's just the point I;ve tried to make about OO and TDD, people are starting with faulty premises and never questioning them
09:51rhickey_3rd slie - "Clearly we need the Game class"
09:51rhickey_slide
09:51angermancemerick: thanks.
09:51chessguy_worki think TDD and functional programming are approaching the problem from different directions and can meet in the middle
09:51angermancemerick: whee, I can now call maruku (ruby) from clojure ... still need to work on the return type though :/
09:51chessguy_work(the problem of code quality in a stateful reality)
09:53rhickey_chessguy_work: well, there's reality and our representation of it in our programs - the latter need not be stateful to the degree it normally is in OO
09:54chessguy_workrhickey_, agreed, but there need not be the lack of testing of functional programs that there is either
09:55AWizzArdtypically it is easier to test functional programs
09:55chessguy_workbut it's done a lot less, i think
09:56rhickey_chessguy_work: sure, but my key point is the unquestioned presumption of stateful objects by TDD advocates using traditional OO langs - building on sand
09:56rhickey_but feeling good about it due to the tests
09:57chessguy_workwell, i guess for a non-parallel project it's ok
09:57rhickey_chessguy_work: seriously not ok
09:58rhickey_I think there a lot of Clojure users now who'll testify to the increased robustness of their non-concurrent programs
09:58chessguy_workanyway, i think TDD leads to a lot less stateful design in general than non-TDD
09:59rhickey_I'd hate for people to think that FP is only for concurrency
09:59AWizzArdI absolutely test nearly everything.
10:00AWizzArdIt is not responsible to not write tests (with some few exceptions).
10:00chessguy_worknot _only_ but that's certainly a place where it thrives
10:00ChouserI still have only dabbled in Clojure's concurrency support.
10:00AWizzArdWhen writing professional code for applications one wants to sell means one should test-is it.
10:01drewrmy programs are much better by not even thinking about state until forced to
10:01drewr...which is usually much later
10:01chessguy_workrhickey_, part of the premise of TDD is that it leads to code that's easier to test (because it's less stateful, though that's not usually stated) and, thus, more flexible
10:02rhickey_AWizzArd: I'm not trying to be anti-testing, this just seemed a good example of a conundrum I have with people advocating TDD and not questioning mutable OO - discipline on top of spaghetti
10:03chessguy_worki agree that it could be made more explicit, but it's there
10:03rhickey_chessguy_work: I haven't seen any connection whatsoever between the two - lots of examples just like this one - pokeable things with tests that poke them
10:04rhickey_and mock pokeable things of course
10:04Chouser/topic discipline on top of spaghetti ... seriously not ok
10:05rhickey_the only thing I want on spaghetti is a good red sauce :)
10:05jackdempseyhehe
10:05drewrChouser: +1
10:05clojurebotWhy are you asking *him*
10:05chessguy_workaww, man, now you guys are making me hungry
10:05jackdempseyhaha
10:05carkyou're missing on spaghetti carbonara !
10:05carknot red at all
10:06carkon topic, i mostly unit test data structures, and then lots of repl testing and end product testing
10:08carkmost of the things we (i anyways) do aren't that hard to do, how wrong can you be summin an invoice from a database table ?
10:09jdzdoing read-only stuff has some benefits
10:10chessguy_workoh well, back to the real world
10:10kylesmithquick question for someone: I'm blowing the stack on the defn on large data (> 1000), why? (defn get-bounds [objects coordinate-func]
10:10kylesmith "Returns a seq of the min and max coordinates"
10:10kylesmith (let [coords (map coordinate-func objects)]
10:10kylesmith (reduce #(list (map min (first %1) %2)
10:10kylesmith (map max (second %1) %2))
10:10kylesmith (list (first coords) (first coords)) coords)))
10:10drewrlisppaste8: url
10:10lisppaste8To use the lisppaste bot, visit http://paste.lisp.org/new/clojure and enter your paste.
10:11kylesmithsorry, I'm relatively new to irc.
10:11drewrkylesmith: np
10:11Chousukehm
10:13Chousukeyou could probably make that clearer if you used destructuring and vectors instead of the list function.
10:13kylesmithyes, of course. I'll do that.
10:16AWizzArdrhickey_: yes, I understood you. Automatic tests are also helpful in functional programming to protect from changes. A new coder in the company changes an old side-effect free function which still works for most cases, but for one important part it doesn't. Via Contribs test-is this can sometimes be caught.
10:17Chousukekylesmith: the coordinate-function returns a seq of pairs?
10:17lisppaste8kylesmith pasted "get-bounds" at http://paste.lisp.org/display/83852
10:18kylesmiththat docstring isn't the best; just a list of [[x y z] [x y z]] representing min and max
10:18rhickey_has everyone been ok with chunked map et al in master?
10:18Chousukekylesmith: hmm
10:19drewrrhickey_: no issues so far
10:19Chousukewhat kind of an object is a coordinate?
10:21kylesmithwell, I pass in a seq containing sets of atoms, and get the center of mass. but that part works just fine. you can just pass in the coordinates directly and use identity or whatever.
10:21rhickey_any git fu
10:22Chousergit branch -m chunks scratchpad ...I think
10:23kylesmithOh, and technically, the initial value to reduce is arbitrary, but it should get overwritten by the end.
10:23jackdempseyyea that should do it
10:23jackdempseygit branch (-m | -M) [<oldbranch>] <newbranch>
10:23jackdempsey-M forces even if newbranch exists
10:26Chousukekylesmith: something like http://gist.github.com/150361 ?
10:27Chousukedidn't work so well, though. no syntax colouring and I had to dig up the URL from the *messages* buffer
10:28kylesmithChosuke: Yes, that is identical to my version, except for variable names. And it still works for 1500 elements and crashes for 2000.
10:29drewrkylesmith: Can you annotate with an example of call? What's a coordinate-func do?
10:29drewrs/of call/call/
10:29Chousukekylesmith: maybe it's coordinate-func that's crashing?
10:30kylesmithokay, give me a second
10:31Chousukecoords holds on to most of the seq, too.
10:32rhickey_Chouser: afaik, -m is only for local branch renaming
10:33ChousukeI don't think it's possible to rename public branches without confusing the repositories of people who have pulled it previously
10:33Chouserrhickey_: hm. http://kerneltrap.org/mailarchive/git/2008/6/9/2070944
10:33Chousukeit's fairly simple to fix though
10:34rhickey_ParallelArray (used by clojure.parallel) is not making it into JDK7, so I've been playing with using forkjoin directly and supporting parallel ops for pvector et al
10:34drewrgit push origin :chunks && git branch -m scratchpad chunks && git push origin scratchpad
10:34drewrthat's destructive though, as Chousuke said
10:35drewralso assumes origin is the remote
10:36lisppaste8kylesmith pasted "get-bounds example" at http://paste.lisp.org/display/83853
10:36rhickey_so far so good, pvmap (maps a fn on a vector returning a new vector) is only 20 lines of Clojure, shows linear speedup vs (into [] (map f v)), this being the latest new improved 'into' here
10:36drewryou could leave the remote chunks and push a duplicate scratchpad (safest) but in this case it wouldn't matter
10:37jackdempseynice rich
10:39rhickey_which mean on this machine (quad core) now 3.5x as fast as j.u.ArrayList
10:39rhickey_and in the latter case you only end up with a dangerous ArrayList, not a persistent vector
10:40rhickey_I'll try http://github.com/guides/rename-a-remote-branch if no one has a better idea
10:40kylesmithnicely done
10:40Chousukerhickey_: maybe you should have multiple scratchpad branches instead of one though. it would be easier to merge the bits that are deemed good enough to go into master.
10:41rhickey_overall I think adding parallel ops to the Clojure data structures is going to be a huge win
10:42Chousukeif you had all your experiments separated as scratchpad/chunks, scratchpad/pvector, scratchpad/other-cool-thing etc, you could easily combine them by just creating a test branch and doing git merge sp/foo sp/bar (providing they don't conflict)
10:44rhickey_can do vectors and maps: map, reduce, possibly parallel map merge, parallel remove-keys, select-keys
10:46Chousukedoes it parallelise a chunk at a time or something?
10:46rhickey_one nice thing, the new forkjoin (jsr166y) jar is only 53k
10:46rhickey_Chousuke: it splits up the tree recursively
10:50lisppaste8kylesmith pasted "get-bounds loop-recur" at http://paste.lisp.org/display/83854
10:50kylesmithstill no luck
10:52sh10151xml emit functions seem to strip whitespace
10:52sh10151is there a way to avoid this?
10:52Chouserxml parse strips whitespace, and xml emit adds new different whitespace
10:52sh10151oh ok
10:53sh10151so xml parse strips whitespace
10:53sh10151is there a way to avoid this?
10:53sh10151:)
10:53Chouserclojure.contrib.lazy-xml has an emit that doesn't insert new whitespace
10:53ChouserI feel like a politician.
10:53sh10151that doesn't bother me as much as the missing whitespace
10:54Chouseranswering different questions than are being asked.
10:54kylesmithI need to leave soon, so if anyone figures out the solution to my problem, please email me.
10:54sh10151all righty then
10:54sh10151xslt it is
10:54sh10151:-/
10:55sh10151groovy had this same asinine problem
10:55Chousersh10151: afaict, both clojure high-level parsers trim whitespace
10:55sh10151clojure should be better than groovy, right? :-D
10:55Chousersh10151: you can use java xml parsers directly (I'd recommend http://www.extreme.indiana.edu/xgws/xsoap/xpp/)
10:56sh10151i don't really want to parse much, just substitute in some values
10:56sh10151can use Transformer and set some input parameters
10:56sh10151so much boilerplate though
10:56Chouseror you can look at fixing the clojure parsers. I'd welcome a patch to lazy_xml.clj and lazy_xml/with_pull.clj that added a paramter to turn off whitespace trimming
10:56Chousukekylesmith: I think I get the problem
10:57Chousukekylesmith: try wrapping the map in the reduced function into doall
10:57kylesmithI just did that 1 second before you said, and it works!
10:57sh10151the default should be whitespace preservation
10:57sh10151otherwise you are changing the data
10:57Chousukekylesmith: It just dawned on me that with a thousand coordinate, you're basically generating a lazy seq that has a thousand thunks wrapping it
10:58Chousersh10151: I agree
10:58kylesmithyep, came to the same conclusion
10:58rhickey_Chouser: I think cgrand might have done that at one point...
10:59Chouserhttp://www.mail-archive.com/clojure@googlegroups.com/msg13009.html
10:59Chouserrhickey_: apparently so
10:59kylesmiththanks, Chousuke and goodnight all
11:05lisppaste8rottcodd pasted "object-seq" at http://paste.lisp.org/display/83855
11:05rottcodd is there something like object-seq built-in? I couldn't find anything
11:07Chouserthat's a beautiful paste. Thanks for the complete working example!
11:07ChouserI don't know of any such function.
11:08ChouserDid you notice yours halts on a nil form?
11:08Chouser(object-seq (java.io.PushbackReader. (java.io.StringReader. "1 nil #{bar foo}"))) => (1)
11:08rottcodddidn't notice that
11:08drewrrottcodd: interesting, I have a use for that right now
11:08drewrhadn't thought about it that way
11:12Chousukehmm
11:12lisppaste8rhickey annotated #83855 "object-seq w/nils" at http://paste.lisp.org/display/83855#1
11:17JomyootWhat's a nice EMACS theme for working with Clojure?
11:18drewri find the default colors quite attractive
11:18Chousukehmm... (let [eos (Object.)] (take-while #(not (identical? % eos)) (repeatedly #(read reader nil eos))))
11:18Chousukenot much gain from using higher-order functions in this case I suppose
11:20ChouserChousuke: your version would be indentical pre-lazier
11:20ChouserI guess that still doesn't count as much gain. :-)
11:21Chousukeit does read a bit better though.
11:22Chousuke"take while not end of stream from <seq-of-stuff-when-read-repeately> "
11:22Chousuke+d
11:27achimyou could save ~10 chars by replacing "(not (identical?" with "(not="
11:28achimif you're playing golf ;)
11:28Chousukethat's not the same.
11:28achimbut for (Object.), it should be
11:29ChousukeI wonder if Object falls back to an identity comparison ./
11:31achimChousuke: i believe, = falls back to .equals, which (again, i believe) should be identity comparison for Objects
11:32Chousercouldn't Foo.equals(x) do whatever Foo wants, even if x is just an Object?
11:33achimhttp://java.sun.com/j2se/1.5.0/docs/api/java/lang/Object.html#equals(java.lang.Object)
11:33ChousukeChouser: no
11:33ChousukeChouser: if x.equals(y), then it must be that y.equals(x)
11:34achimIIRC, (= x y) maps to (.equals x y) in the end
11:34achimfor non-clojure things, that is
11:35achimChousuke: the order matters, .equals isn't necessarily symmetric in java-land.
11:35achimbut if you ask "eos", you won't get any false positives, because you can be sure it's nothing but an Object
11:37rhickey_I think identical? makes it clearer that this is a sentinel - i.e. we don't care about value at all
11:38rhickey_we are not testing for equality but identity - is this the eos sentinel?
11:40rhickey_but Java does guarantee (not= (Object.) anything-else)
12:05Fossias much as i like "Programming Clojure", it's horrible for looking up things
12:09ieureIt’s not really a reference book, is it?
12:14Fossinot so much
12:16angermanI'm trying to compile a script using ant
12:16angermannow my script uses javax.script.ScriptEngineManager, which I think should be in the JDK
12:16angermanbut I fail to build the correct target :/
12:17Fossimaybe your jdk isn't set to the correct path?
12:17angermanhow do I tell ant to instruct clojure to compile using the JDK?
12:19Fossihow can i access static public inner enums?
12:19ChouserOuterClass$EnumClass/ValueName
12:19Fossiah. $
12:20ChouserIt's just the JVM's internal representation for inner classes
12:20Fossieh. weird.
12:20Fossii mean to access it that way then
12:21angermanFossi:maybe I'm too stupid to get ant to do it :/
12:21Fossiangerman: worked for me out of the box, so i don't really know
12:21Chouserjava thinks it's good for . to mean lots of different things (sub-package, inner class, instance member, class member, etc.) Clojure not so much.
12:21Fossithe jdk path thing was just a wild guess
12:27JomyootDoes Clojure have special theme support in emacs?
12:27Jomyootfor specific elements to clojure
12:27ieureJomyoot, There’s clojure-mode.
12:28Fossithere's an emacs mode if that's what you mean
12:28Fossiwith syntax highlighting
12:28Jomyootis there some intersting light theme?
12:28Jomyootother than than those in emacs-theme?
12:28Fossimore like keyword highlighting really :D
12:29dgfitchclojure/java newb alert: I'm trying to compile the HEAD of clojure-contrib on github, and getting [java] java.io.FileNotFoundException: Could not locate clojure/walk__init.class or clojure/walk.clj on classpath: (dataflow.clj:17)
12:29angermanhmm should not (compile 'foo) compile foo.clj
12:29angermanI get java.io.IOException: No such file or directory (maruku.clj:34)
12:30Jomyootwell clojure is more syntax lisp than emacs lisp
12:30Jomyootclojure is more sytnax rich
12:30Jomyooti meant
12:30Jomyootso i hope for more highlighting capability
12:31angermannow that like 34 does not make any sense to me: http://gist.github.com/150429
12:34Chouserangerman: you got compile to work and now you're asking about line 34 of that gist?
12:34angermanChouser: no, compile breaks stops with java.io.IOException: No such file or directory (maruku.clj:34)
12:35Chouserhm. you've got a 'classes' directory and its in your classpath?
12:36angermanno.
12:36angermanso I need that ... hmm
12:36Chouser,(doc compile)
12:36clojurebot"([lib]); Compiles the namespace named by the symbol lib into a set of classfiles. The source for the lib must be in a proper classpath-relative directory. The output files will go into the directory specified by *compile-path*, and that directory too must be in the classpath."
12:37Chouser,*compile-path*
12:37clojurebotnil
12:37Chouser,(doc *compile-path*)
12:37clojurebot"; Specifies the directory where 'compile' will write out .class files. This directory must be in the classpath for 'compile' to work. Defaults to \"classes\""
12:37angermanhmm ok
12:38Chouserwhen you try to create a file in a directory that doesn't exist, unix kicks back a "No such file or directory"
12:39Fossithat one got me as well :)
12:40angermanChouser: thanks I'm getting closer
12:40angermannow I have the following issue: java.lang.RuntimeException: java.lang.ClassNotFoundException: maruku$render__34 (NO_SOURCE_FILE:0)
12:41Chouseryou're sure that 'classes' dir is in your classpath? you restarted your jvm?
12:42angermanyes
12:42angermani simply create a classes folder
12:42angermanand there is a maruku$... in that folder now
12:43Chouseryes, but in order to find that .class file after clojure creates it, 'classes' must be in your classpath
12:44Chousera normal directory layout is for you to have src/survey/maruku.clj and classes/, and to have src and classes in your classpath
12:45Chouserthen when you compile you should end up with a bunch of files like classes/survey/maruku*.class
12:45angermanmagic
12:45angermanit did work
12:45Chousergreat.
12:46angermannow I need to find out why I can't compile it with ant ...
12:58angermanhow do i figure out the default classpath?
13:19Lau_of_DKdefault?
13:23Lau_of_DKAnyone using a Macbook Pro here tonight?
13:25sh10151I use one at home
13:26sh10151but I am at work right now and don't have one on me
13:26Lau_of_DKOk - It doesnt matter if you have it now - I just need someone who can answer a few questions in private about it
13:26sh10151knock yourself out
13:27Lau_of_DKIt does
13:55angermanwhat does this cause and how do i fix it? java.lang.Exception: namespace 'survey.maruku' not found after loading '/survey/maruku'
13:56erohtarangerman: it means that the namespace being defined in the file is not what it is supposed to be
13:57erohtarangerman: i suspect it should be survey.maraku
13:57angermanerohtar: hmm. ok, how am I supposed to name it?
13:57erohtarangerman: (ns survey.maraku)
13:57erohtarangerman: assuming that the survey directory is on ur classpath
13:58Chouserthe directory containing survey is on your classpath
14:03cemerickyet again, I'll meaninglessly rededicate myself to posting our ant build process
14:04cemerick(which now only compiles clojure files that have changed since the last build -- dropped our full build time from ~60s to 10s)
14:09weissjI am using lancet ant stuff, but the ant functions are created by 'define-all-ant-tasks' function which repeatedly calls defmacro. but my own code isn't read properly because it calls ant functions and they aren't defined at read time. how do i fix this? i need to run 'define-all-ant-tasks' at read time, somehow.
14:10Chousercemerick: not using lancet?
14:11cemerickno. We'll check it out at some point, but innovating in build processes is pretty low on my priority list. I've been hacking ant files for 10 years, so it's a pretty productive environment for me.
14:12weissjcemerick: i'm sorry :) xml as code is terrible
14:12weissjthat's why i like lancet. groovy has a similar thing called AntBuilder.
14:12cemerickeh, it's horrible, but better than all the rest
14:12cemerick(or, all the rest that I've ever bothered to look at)
14:12weissjcemerick: i disagree, lancet and AntBuilder are much better.
14:13weissjit's real code
14:13cemerickright, that's where the "...that I've bothered to look at..." part comes in.
14:14weissjcemerick: ah. well i am trying out lancet. it's not 100% complete, but even a beginner like me can see how to get the last little bits working
14:15weissjanyway, can someone point me to how to get a function to run at read-time?
14:15weissji know lisps are supposed to be able to do that 'whole language all the time' thing.
14:16ieureweissj, (defn foo [] …) (foo) ?
14:16cemerickweissj: you mean reader macros, I presume?
14:16weissjieure: uh, how does that run the function at read time?
14:16weissjcemerick: i guess
14:16cemerickuser-defined reader macros are not supported by clojure at the moment
14:16cemerickit's a topic of some debate, yet
14:16Chouserweissj: macros run at a time slightly after read, but before compile
14:18weissjok, so my code "requires" lancet. lancet has a function 'define-all-ant-tasks' that defmacro's in a loop.
14:18Chousukehm, wasn't there some reader form that gets evaluated at read time?
14:18weissjbut my code doesnt' compile because it calls the functions defined by those macros that haven't been created yet.
14:19Chouserweissj: ah.. can you call those macros before your functions are defined?
14:19weissjnow i can manually call 'define-all-ant-tasks' in a repl before i load my file, and that works, but that seems hackish
14:19weissjChouser: but my file won't even be read in properly.
14:19Chousukecan't you call the macro at the top of the file?
14:19weissjit refers to functions that don't exist
14:20weissj(at read time, anyway)
14:20weissjor compile time, for that matter
14:20Chousercompile time isn't instantaneous
14:20Chouserearlier top-level forms are evaluated before later top-level forms are compiled.
14:20Chousertry it
14:20weissjChouser: oh, ok, i didn't know that's how it worked. let me try.
14:24weissjChouser: putting '(define-all-ant-tasks)' at the bottom of lancet.clj seems to fix it. i wonder why it wasn't already there?
14:25Chouserweissj: good question
14:25ChouserI guess you might want to define your own ant tasks first or something?
14:26weissjChouser: it has a '-main' defined so i guess it was meant to run standalone instead of as a lib... not sure. seemsa lot more useful to me as a lib.
14:28weissjso, i've added some fixes to lancet, some ant stuff doesn't work without it. who do i submit patches to?
14:29Chouserlancet's not in contrib, right? So it's just Halloway and however he wants to handle it.
14:30Chouseryou could try writing to the clojure google group, or to Halloway directly. Or fork the github repo. Not sure what he'd want.
14:30weissjChouser: ok thanks
15:34rhickey_name game again, need a naming pattern for vector fns, and parallel vector fns, taking and possibly returning vectors, e.g. (pvmap f v) -> v and (pvreduce f v) -> x
15:34weissjcan someone explain to me what 'partial' does? the doc doesn't make sense to me. it seems like both the function you pass in and the function it creates end up being called the same way?
15:34hiredmancouldn't they just go in clojure.vector?
15:35hiredman,(partial + 1)
15:35clojurebot#<core$partial__4401$fn__4403 clojure.core$partial__4401$fn__4403@8ff944>
15:35hiredman,((partial + 1) 2)
15:35clojurebot3
15:35cemerickrhickey_: pvmap and pvreduce are no good?
15:35weissjoh! yeah. that's what i want. i want to use map but my function takes 2 args. i want one to come from the list i pass to map, and the other to always be the same
15:36kotarakdv pv ...
15:36rhickey_cemerick: I like them, just checking
15:36cemerick+1 for me
15:36hiredman,(map (partial + 5) (range 5))
15:36clojurebot(5 6 7 8 9)
15:36kotarakweissj: there is also #(): (map #(+ % 5) (range 5)) partial only works for the #(+ 5 %) case.
15:37weissjkotarak: i was about to ask, what if my partial arg isn't the first one :)
15:37weissjthanks
15:37rhickey_with a 10-line helper, pvmap and pvreduce are 10 lines each, and have no forkjoin code in them
15:37cemerickI'm intrigued
15:38lisppaste8rhickey pasted "pvmap pvreduce work in progress" at http://paste.lisp.org/display/83874
15:39kotarakDoes .. have some advantage over ->?
15:42rhickey_I'm trying to get rid of most of the details, but you'll still have to know a little bit about the representation of the vectors in order to define new parallel ops
15:43rhickey_kotarak: not really
15:43weissjhow come (map #(future (do-one-file % targetDir)) mylist) blocks until all the 'do-one-file' (which download and unzips a zip file) have completed? i would think by the doc of future, it would return right away bc it spawns threads.
15:44kotarakrhickey_: it's pretty much obsolete then, because -> is more general...
15:44hiredmanweissj: because you are printing the result
15:44drewrweissj: you're not passing the fn, you're passing the value
15:44hiredmanand keep in mind that map is lazy
15:44kotarakweissj: (def x (map ...))
15:44rhickey_kotarak: it's classic
15:44kotarakarchaic? ;)
15:44weissjer, so which is it?
15:45drewrer, sorry, I was wrong
15:45drewrforgot future is a macro
15:45weissjah ok, i hoped so because it really did spawn threads
15:46drewr:-)
15:46weissjso then it only blocked because i used the repl?
15:46hiredmanweissj: and map is lazy, so unless you force the map somehow, the futures will not be generated
15:46kotarakweissj: you probably want something like (def x (reduce #(conj %1 (future (do-one-file %2 target-dir))) [] mylist)
15:47drewrweissj: what happens when you wrap it with a doall?
15:47hiredmanor use doall, or vec, or etc etc
15:48weissjhiredman wins. it's because the repl printed the return value. it doesn't block if i put a 'nil' at the end of the function that calls that stuff
15:48weissjactually that is not quite true - it doesn't do anything either because the list is not consumed
15:49weissjso yeah, doall is prob the answer
15:50weissjnow, that answers why it didn't behave like i expected in the repl. but i DO want it to block. so i just need to (doall (map (deref xx))) on it?
15:53hiredmanoh
15:53hiredmanweissj: you want pmap
15:53hiredman,(doc pmap)
15:53clojurebot"([f coll] [f coll & colls]); Like map, except f is applied in parallel. Semi-lazy in that the parallel computation stays ahead of the consumption, but doesn't realize the entire result unless required. Only useful for computationally intensive functions where the time of f dominates the coordination overhead."
15:54weissjhiredman: ooh, sweet. this function is now getting trivially short. love it :)
15:58weissjone thing I'm having difficulty with is 1) knowing there's already a function that does what I want and 2) even if I suppose there must be one, finding it. find-doc only gets you so far.
16:04Chousukehmm
16:05ChousukeClojurebot need a more sophisticated AI so you could ask it about the API :P
16:15weissji suppose that is a problem with any language. all you can do is search the api and hope for a hit. half the time you don't even know the right term to search for.
16:16weissji would never have known about pmap. after reading about agents, i wouldn't have thought to search for a parallel map function.
16:17weissji guess we need to just read the doc on everything :)
16:17ChouserI recommend: reading other people's code (such as core.clj, stuff in contrib), hanging out here (watch other people's answers, ask your own questions), and finally start answering questions here.
16:17Chouserthat last step is when you really start to learn... :-)
16:18weissjChouser: yeah, i've only been at it about 2 weeks, and i already see people coming in here behind me asking even more newb questions that i already know the answer to :)
16:18TheArthurcan I create a sparse vector in clojure?
16:18weissjthis channel is a great resource, plus the clojure.org website and stuart halloway's book
16:19TheArthurand is there an easy way to create a vector full of 0 s?
16:19Chouserfor somewhat faster bootstrapping, you can look at the couple of places that have categorized functions, to help you find fns "near" other ones in conseptual space.
16:20Chouserweissj: for example, 'map' and 'pmap' appear next to each other here: http://clojure.org/sequences
16:20ChouserTheArthur: vectors are not sparse. For that, use a sorted-map or hash-map.
16:20Chouser,(vec (repeat 20 0))
16:20clojurebot[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
16:21Chouserbut there's a vector of zeros, length 20.
17:53ieureI’m trying to do some shebang scripting with Clojure, but I keep getting this error.
17:53ieurehttp://gist.github.com/150935
17:53ieureThe code: http://gist.github.com/150933
17:53ieureI don’t get it. The code is runs, then I get an exception.
17:55Chousuketry removing the ns declaration
17:55ieureChousuke, Same error.
17:56Chousukehmh
17:57technomancyieure: are you using the bash script from contrib?
17:57ieuretechnomancy, No, it’s whatever wrapper MacPorts has.
17:58ieureIndeed.
17:58ieureIt would also be nice if it wasn’t insane to package up CLI tools in JARs.
17:58ieureUnless there’s a better way of doing it than what’s listed on WikiBooks.
17:59technomancyyeah, the JDK is positively useless when it comes to CLI integration
17:59Chousukehm, I can't even use my clj script as an interpreter :/
17:59ieureYou could have left out from "when" on.
17:59technomancyieure: a friend of mine was working on a project to make that a little less painless: http://github.com/dkellum/hashdot
18:00technomancykinda rough around the edges in terms of installation, but it is worlds better than the "java" launcher
18:00ieureI think the best thing about Clojure is that it leverages everything in the JDK. As opposed to it’s downside, which is that it leverages the JDK.
18:00Chousukeheh
18:00ieureSeriously, I hate Java.
18:00ieuretechnomancy, 404.
18:01technomancyieure: right; that should be https://github.com/dekellum/hashdot/tree
18:01ieureThanks.
18:01technomancyit's a command-line tool that's written by someone who's actually used a terminal before! amazing.
18:02technomancy<insert rant about single-dash-full-word arguments />
18:03technomancythe cool thing about hashdot is that you install it once and symlink it to clj, jruby, rhino, etc; and it loads different property profiles based on what symlink it was invoked with.
18:10ieurehashdot looks nice, thought it doesn’t solve the .jar issue.
18:10technomancynope. =\
18:10technomancyit's focused more on server-side JVM than distribution
19:00krumholt_i have this list '(a a a b b c c c c d a a) and i want => ((a 3) (b 2) (c 4) (d 1) (a 2)) anyone knows a clever way to do this?
19:01technomancyare you sure you want a list and not a map as the return value?
19:01krumholt_they have to be ordered
19:02krumholt_i dont want to know how many a's where in the list. i want to know how many where there in a row
19:03krumholt_like (a a a b a a a) => ((a 3) (b 1) (a 3)) the order of the elements is still there it is just mor compact
19:08replacakrumholt_: I would write a little func that used (take-while #(= (first foo) %) foo), count, drop and loop/recur to build the list
19:08replacakrumholt_: more clojure-y to build the result as a vec (and it lets you use cnj and get the right order)
19:09replacabut there might be a better way
19:10krumholt_a take-while looks usefull thanks
20:07technomancyieure: I'm not using the http client for authenticated requests, but if you're seeing arguments ignored I will try to fix that.
20:08ieuretechnomancy, Your HTTP client worked fine. The contrib one ignored the :headers I gave it.
20:08technomancyoh gotcha
20:09technomancyyeah, I've found it's a bad idea to implement features I don't use, but I'm happy to answer questions if you've got ideas for a patch.
20:09ieureI just had to generate the authtoken myself. And I guess there isn’t anything standard that does Base64 the way HTTP wants it.
20:09ieuretechnomancy, Maybe, I’m really not comfortable enough with Clojure to go hacking on it just yet.
20:10ieureFrom what I saw, I’d need some way to frobnicate the connection before sending the request.
20:11ieureMaybe a (with-connection) macro that I could call (request) inside of. Not rally sure.
20:12technomancyieure: something like that is probably needed for connection pooling anyway
20:12technomancybut I haven't been doing much HTTP work these days
20:33ieureHmm, the whole contrib.http.agent stuff seems to be pretty broken. This should work, right?
20:33ieure(use 'clojure.contrib.http.agent)
20:33ieure(let [a (http-agent "http://google.com&quot;)]
20:33ieure (response-body-str a))
20:33ieureIt returns nil. Same for response-body-bytes.
20:33ieureBut I can get the headers okay.
21:06duncanmbecause of Clojure, i started looking into Swing this weekend
21:07duncanmit's really not that bad, right? in fact, it's a pretty powerful toolkit
21:10drewrduncanm: it's tedious, but much more fun with clojure
21:10duncanmyeah, with Clojure, i think it's not a bad toolkit at all
21:37uninvertedDoes Clojure have any way to get the length of a sequence? I can't see anything in the docs.
21:42mudphoneuniverted: try count
22:07weissjis there a way to give a function param a default value, other than just adding a new section without that param, and just calling the first section with the default value?
22:08weissjie like (defn x ([y z] (str y z)) ([y] (x "yo")))
22:09weissjthat would give z a default of "yo"
22:17drewrweissj: defnk in clojure.contrib.def gives you keyword args that have default values
22:30duncanmhave any of you looked into JavaFX? i'm confused as to what it is
22:30duncanmi thought it's a new language with a set of Java libraries (built on top of Swing)
22:31duncanmbut i can't find any resource on using the JavaFX libraries using something other than JavaFX script
22:31cemerickweissj: using map destructuring with a default value is more idiomatic, and doesn't require an external lib
22:32cemerickduncanm: sun hasn't followed through on their prior statements about supporting using javafx libs from other languages
22:33cemerickthey're supposedly going to open things up eventually, but it's in the air at this point
22:34duncanmahh
22:34duncanmbut it's still possible, right? it's just yet another jar
22:48cemerickyeah, I've read of people figuring some stuff out (using jruby, I think?). A lot of the API is reflection-driven though, so it's not as straightforward as running javap and backing into things.
23:13JomyootDo you guys prefer light on dark or dark on light background?
23:14skalnikDepends on what
23:14skalnikCode I like light on dark, everything else, dark on light
23:19scottjJomyoot: dark on light because I have a bright work environment and I like all my windows to be consistent, and its much easier ot have everything light than everything dark (webpages don't convert well)
23:24Chouseragriffis (who's apparently not here at the moment) has a script which switches all his xterms and gvim windows between light-on-dark and vice-versa based on the time of day.
23:30duncanm Chouser: that's cute
23:44fsmHello everyone, I am back with my double primitive performance issue
23:45fsmI have a test case if anyone wants to look http://solardriftwood.com/testdouble.clj
23:45fsmThis test tries various methods of storing and accessing arrays of doubles
23:45fsmBut, looking in the profiler, all the math is done using Numbers.add instead of native ops, no matter what
23:46fsmAm I doing something wrong?
23:47hiredmanfsm: have you set warn-on-reflection?
23:47hiredmanclojurebot: performance
23:47clojurebotGabh mo leithscéal?
23:47fsmYes, I have set warn-on-reflection, there is no reflection
23:47hiredmanbah
23:47hiredmanclojurebot: you worthless bag of bones
23:47clojurebotI don't understand.
23:48fsmI am quite perplexed about why nth and [] is as fast as using native double arrays
23:48fsmand I am a bit perplexed why none of my math is done with primitives
23:48fsmI have been through the whole range of tips on the java_interop page
23:49fsmClojure is great but having virtual method calls inside my arithmetic is slowing down my raytracer alot
23:49hiredmanfsm: I am fairly certain (+ (vxfn vectPrim) 1.0) should result in a reflecton warning
23:49fsmSample image here btw: http://solardriftwood.com/aa.png
23:50fsmI just ran again with warn-on-reflection, no reflection occurs
23:50rhickeyfsm: you've read this carefully? http://clojure.org/java_interop#primitives
23:51hiredmanfsm: reflection warnings do not happen when you run code
23:51rhickeyand: http://clojure.org/java_interop#optimization
23:51fsmYes, I believe I have tried every trick in the book
23:51hiredmanthe happen at compile time, when you paste code into the repl for example
23:51fsmMy test case is here: http://solardriftwood.com/testdouble.clj
23:52fsmI have seen refl warnings before in my other code, no refl warnings in this code
23:52fsmMy issue is that Number.ops is being called for what should be primitive arithmetic by my understanding
23:52rhickeynothing in the optimization section says use aset-double, it's slow
23:52fsmaset-double is only used three times, outside the performance loops
23:53fsmI have also tried into-array, no difference
23:53rhickey"aget/aset are overloaded for arrays of primitives"
23:53fsmI am enjoying Clojure greatly, I am just a bit perplexed on this issue
23:53fsmThat is, if I have a macro that uses aget, why is Number.ops used on the resulting double, instead of native operator +
23:54fsmIn the profiler, I can see that Number.ops is called for every single arithmetic in that test case
23:55fsmBasically, for my raytracer I am seeking the most efficient way to represent vectors of 3 doubles (x, y, z)
23:55rhickeyyou'v e built all of this macro stuff - you shouldn't macro-ize until you have a hand-written thing you want to generate
23:55fsmI did that to test the performance of macro vs function
23:55fsmI found that macro-izing actually caused about 30% speed drop in my raytracer
23:56fsmNonetheless, I wish to get rid of all these Number.ops
23:56fsmThe test case compares macro and function versions, but either way, Number.ops is used
23:57fsmI have looked at the implementation and found that aget turns into a static method that has the body return xs[i]
23:57fsmIs the return value of aget boxed?
23:58hiredmanfsm: first line of http://clojure.org/java_interop#optimization
23:58fsmYes, does that apply to return values as well? That is the thing I couldn't work out myself.
23:59rhickeyyou need to use primitive locals, as described in those sections, and primitive arrays, and the primitive array constructors double-array etc