2009-07-20
| 03:17 | yason | Vkthkstt! |
| 03:28 | yason | dang |
| 03:28 | yason | writing passwords blinded with a dead display is bad :) |
| 06:09 | Fossi | hi |
| 06:10 | Fossi | i just stumbled over another piece of lisp-1 fun again: having a struct named foo and normally calling your variables foo as well |
| 06:11 | Fossi | make a typo in the parameter list and it won't even fail on you, only retun nil for a value of the struct |
| 06:11 | Fossi | so, note to self: name structs struct-foo |
| 06:29 | AWizzArd | Fossi: 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:29 | AWizzArd | Why would one name variables after their type in statically typed langs? |
| 06:51 | cky | Fossi: 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:51 | cky | e.g., <foo> |
| 06:55 | AWizzArd | cky: in Clojure it would not be typical to put names of structures into angle brackets. |
| 06:57 | cemerick | although 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:58 | AWizzArd | It could be the convention for a project. If it is used consistently then I wouldn't mind. |
| 06:59 | AWizzArd | For example, we use fnparse (thanks for the tip hiredman) and all rules begin with a !. |
| 07:05 | Chousuke | cemerick: I think clojure is fine with any unicode character :P |
| 07:06 | cemerick | yeah, almost :-) |
| 07:06 | Chousuke | actually, it even accepts ' ' as a symbol character |
| 07:06 | cemerick | right, just not through the reader |
| 07:06 | Chousuke | yes it does. |
| 07:07 | Chousuke | that's a double-width space :) |
| 07:07 | cemerick | ah, couldn't tell that in irc :-) |
| 07:07 | Chousuke | user=> (def funky symbol 5) |
| 07:07 | Chousuke | #'user/funky symbol |
| 07:07 | Chousuke | user=> funky symbol |
| 07:07 | Chousuke | 5 |
| 07:07 | Chousuke | :P |
| 07:07 | Chousuke | I think that's a bug, though. |
| 07:08 | AWizzArd | The biggest problem with that will be actually *typing* these unicode chars. |
| 07:08 | Chousuke | it's not too difficult with an input method editor :P |
| 07:10 | Fossi | worse i've seen was sql which had right-tp-left markers in it |
| 07:11 | Fossi | *t |
| 07:11 | Fossi | init was like: insert into foo values (";("somestring |
| 07:12 | Fossi | makes you go 'wtf?' |
| 07:12 | AWizzArd | (def √² 1.4142135) |
| 07:16 | cemerick | AWizzArd: if you're on a mac, then typing such things is incredibly simple (e.g. no alt+... codes to remember) |
| 07:17 | AWizzArd | i see |
| 07:17 | cemerick | √ 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:17 | Fossi | only that all the other letters are on a weird comb |
| 07:17 | Fossi | key combo |
| 07:20 | cemerick | ah, this is the one I was thinking of: http://matias.ca/tactilepro |
| 07:20 | Chousuke | Fossi: job security? :p |
| 07:21 | Fossi | and the infallable apple-q |
| 07:21 | Chousuke | my mac layout has no quick key for lambda :( |
| 07:21 | Chousuke | opt-l gives fi |
| 07:21 | rys | heh, the unicode chars in my term while we discuss this made cemerick's 2nd to last comment appear to come from me |
| 07:21 | cemerick | Chousuke: that's easy to change |
| 07:21 | rys | (for me at least) |
| 07:22 | Fossi | so my keylayout is totally different anyway :) |
| 07:22 | AWizzArd | I 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:23 | Fossi | yeah, neo is nice as well |
| 07:23 | Chousuke | but does it support APL? |
| 07:23 | AWizzArd | Fossi: it is following the same ideas like dvorak, but more specialized on german, while dvorak is a bit better for english. |
| 07:25 | AWizzArd | Ah ok, that's why you know neo |
| 07:25 | cky | Hehehehe. :-) |
| 07:25 | Fossi | i decided to learn dvorak though because it's better supported by hardware manufacturers |
| 07:25 | Fossi | and the difference is not as big with a nice layout like this keyboard has |
| 07:26 | AWizzArd | Well, my keyboard also has good support: http://www.daskeyboard.com/ |
| 07:26 | Fossi | if you haven't you should check it out. best ever :) |
| 07:26 | Chousuke | there'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:26 | AWizzArd | As it does not show any printings on the keys... it fits perfectly. |
| 07:26 | Fossi | AWizzArd: well, i would annoy my collegues to death with that |
| 07:26 | Fossi | pair programming gets kinda hard :) |
| 07:26 | Chousuke | partly because they're impossible to type with Finnish qwerty. |
| 07:26 | AWizzArd | I ask my workmates to type blind *g* |
| 07:26 | cky | AWizzArd: That's the real way to type! :-) |
| 07:27 | cemerick | hrm, we should do a poll of clojure programmers' nationality |
| 07:27 | Fossi | actually i find it easier to type dvorak on daskeyboard then on a qwerty |
| 07:27 | cky | My keyboard still has qwerty keycaps printed on, so it doubly confuses my workmates, who cannot hunt-and-peck. :-P |
| 07:27 | AWizzArd | very good |
| 07:28 | rys | I can't remember the last time I looked at my keyboard to type anything |
| 07:28 | cky | rys: Exactly!! |
| 07:28 | rys | The keys could be blank |
| 07:29 | cky | Whereas, 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:29 | Fossi | now it's much better |
| 07:30 | cky | By home keys, I mean the bumpy keys where U and H are in Dvorak. :-) |
| 07:30 | Fossi | huh? i though you meant physically |
| 07:30 | Fossi | ah, ok |
| 07:30 | Fossi | never had a problem with that really |
| 07:30 | cky | Well, without the bumpy keys, my hands tend to drift too much. |
| 07:31 | Fossi | then again a divider in the middle helps a whole lot |
| 07:31 | cky | ...that is true. |
| 07:31 | Fossi | extra points for it being the enter key :D |
| 07:31 | cky | :-) |
| 07:32 | cky | Well, 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:33 | Fossi | i ordered mine from the us actually |
| 07:33 | cky | *nods* Yes, I suppose I should find some suppliers. |
| 07:33 | Fossi | it's not like they have them in store |
| 07:33 | cky | *nods* |
| 07:33 | Fossi | as said: reallt check out typematrix |
| 07:33 | Fossi | it's *awesome* |
| 07:34 | cky | Thanks! :-) |
| 07:38 | AWizzArd | Fossi: try this one please: http://schnell-schreiben.de/stv2/ |
| 07:38 | fsm | Hi, I have made a raytracer as a project to learn cloure. Here is a pic. http://solardriftwood.com/aa.png |
| 07:38 | AWizzArd | Or the english version (measuring typing speed): http://speedtest.10-fast-fingers.com/ |
| 07:38 | fsm | clojure* |
| 07:39 | AWizzArd | fsm: did you write the RT from scratch? Or used Harrops version? |
| 07:39 | fsm | I wrote it from scratch |
| 07:39 | fsm | I do not know what Harrops refers to |
| 07:39 | cemerick | fsm: very nice! :-D |
| 07:40 | AWizzArd | fsm: good good |
| 07:40 | fsm | Since then it does texture mapping and bump mapping, but I don't have a nice image of that yet |
| 07:40 | fsm | But, I have a performance issue relating to boxed primitives |
| 07:41 | fsm | I 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:41 | fsm | When I converted to using make-array and aget, instead of [] and nth, I lost 30% performance |
| 07:41 | AWizzArd | you probably introduced reflection then |
| 07:42 | fsm | When I profile, I see millions of calls to Number.ops methods where I would hope for native arithmetic |
| 07:42 | fsm | I turned on reflection warnings, there's no reflection |
| 07:42 | fsm | The other weird thing, is I tried making some vector math into macros instead of functions, that caused a 20% slowdown |
| 07:42 | fsm | I guess the java hotspot optimizer is very clever if you call the same function a lot |
| 07:43 | cemerick | fsm: perhaps the unchecked math fns are appropriate? |
| 07:43 | cemerick | ,(doc unchecked-add) |
| 07:43 | clojurebot | "([x y]); Returns the sum of x and y, both int or long. Note - uses a primitive operator subject to overflow." |
| 07:43 | cemerick | etc.... |
| 07:43 | fsm | I saw that, but i am using floating point unfortunately |
| 07:43 | fsm | I tried adding type hints also, but that seemed to cause a performance hit, i guess more redundant boxing/unboxing was introduced |
| 07:44 | cark | do you coerce your floats ? |
| 07:44 | fsm | Say 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:44 | fsm | I tried coercing the floats, that caused a small performance drop |
| 07:45 | fsm | I am perplexed that using make-array to make a double array is so slow |
| 07:45 | Chousuke | it's slow because it does a full copy :/ |
| 07:46 | cemerick | that, or the array is java.lang.Float[] instead of float[] |
| 07:46 | fsm | I was using make-array Double/TYPE which refers to double |
| 07:46 | fsm | Unless I am mistaken |
| 07:46 | cemerick | no, you're not :-) |
| 07:46 | cark | nope this is correct |
| 07:47 | fsm | So, 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:47 | fsm | ops |
| 07:47 | fsm | I mean |
| 07:47 | Chousuke | hmm |
| 07:47 | cark | and you're using the -server flag when starting java ? |
| 07:48 | Chousuke | are you passing more than two arguments to +? |
| 07:48 | fsm | I have nested my operator +, that caused a big speed boost |
| 07:48 | fsm | I have not been using -server flag |
| 07:48 | cark | ah, this should help a lot |
| 07:48 | fsm | OK I will research that |
| 07:48 | cemerick | yeah, the client compiler is completely different |
| 07:49 | cemerick | hrm, the only thing preventing support for unchecked ops in Numbers are more overloads :-) |
| 07:49 | fsm | Back in a minute, going to do a performance check |
| 07:50 | cark | you need to take the warm up into account, compilatin only occurs after quite a few runs of each function |
| 07:50 | fsm | Yep, I have written a timer macro that times only the actual executions |
| 07:51 | fsm | Anyway, I must say that writing this project is a very rewarding experience |
| 07:52 | fsm | The tools of functional programming are like having a CNC machine compared to hammer and chisel |
| 07:52 | cemerick | fsm: 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:53 | fsm | Yes, with raytracing the same routine is called for each pixel on the screen, causing a great many runs |
| 07:54 | Chousuke | It sounds to me that dealing with arrays in Clojure is somehow unnecessarily difficult :/ |
| 07:57 | fsm | OK, using -server results in a consistent 3% speed boost |
| 07:58 | fsm | Anyway, I will clean up the code and post it somewhere in the next day or two |
| 07:59 | fsm | Meanwhile my algorithmically equivalent Objective-C version was on the order of 10x faster |
| 08:00 | fsm | But Clojure is an excellent project, I look forward to solving this problem |
| 08:01 | Chousuke | Is there any easy way of determining where boxing happens? :/ |
| 08:02 | cemerick | essentially at any function boundary, aside from unchecked-* ops AFAIK |
| 08:02 | fsm | Does that include aget |
| 08:02 | AWizzArd | fsm: maybe you can inline here and there |
| 08:03 | AWizzArd | ,(doc definline) |
| 08:03 | clojurebot | "([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:03 | Chousuke | cemerick: can you tag functions to tell clojure that they return primitive values? :/ |
| 08:03 | fsm | I tried converting everything to macros already, unfortunately that reduced performance, I think by reducing the effectiveness of the hotspot optimizer |
| 08:04 | cemerick | not that I know of, no |
| 08:04 | fsm | But if aget is boxing the value it returns, that could be the crux of the problem i am having |
| 08:05 | Chousuke | fsm: are you doing (let [foo (double (aget ...))])? or something |
| 08:05 | cemerick | fsm: 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:05 | Chousuke | cemerick: expanding macros bloats the code though. |
| 08:06 | fsm | I am not using that let syntax, because it would mean I have to unpack and repack my vectors to do operations on them. |
| 08:06 | cemerick | I think the bottom line issue here is that there's no unchecked math for floating points / doubles |
| 08:06 | fsm | Which is not very lispy |
| 08:06 | AWizzArd | fsm: do you have a short and simple example where a macro slowed down your code? |
| 08:06 | Chousuke | fsm: IIRC the optimisation tips page recommends that all primitive "casts" be done in a let, though :/ |
| 08:06 | AWizzArd | The funny thing is that in the compiled version that you execute no macros exist anymore. |
| 08:07 | fsm | (defn dot [v1 v2] (+ (+ (* (vx v1) (vx v2)) (* (vy v1) (vy v2))) (* (vz v1) (vz v2))))) |
| 08:07 | fsm | ^^ rewriting that to be a macro slowed down my code |
| 08:08 | cemerick | Chousuke: the perf of the fns emitted by the macro is way more important than the 'size' of what it's emitting, though. |
| 08:08 | fsm | the vx/vy/vz are wrappers for either nth or aget - vx v1 = (aget v1 0) |
| 08:08 | fsm | and when I make vx/vy/vz into macros too, even more performance drop, but only 5% or so |
| 08:08 | Chousuke | cemerick: well, more code equals less effective use of cache. |
| 08:08 | Chousuke | cemerick: which may make a huge difference, if you're unlucky. |
| 08:08 | fsm | I tried representing my vectors as [1.0 2.0 3.0] and as make-array |
| 08:09 | cemerick | Chousuke: true, true. |
| 08:09 | fsm | using make-array/aget instead of [] and nth caused an overall 30% speed drop |
| 08:09 | Chousuke | fsm: that dot function you pasted is not doing primitive math, though :/ |
| 08:10 | cemerick | Chousuke: which isn't avail. for floats/doubles |
| 08:10 | fsm | I wrote a version that was (defn dot [#^doubles v1 #^doubles v2] |
| 08:10 | fsm | and that was slower |
| 08:11 | Chousuke | cemerick: hm :/ |
| 08:11 | fsm | if 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:11 | fsm | but in the profiler i see Number.ops being called |
| 08:12 | Chousuke | but if what cemerick says is true and primitive ops are not available for doubles, then boxing is inevitable :/ |
| 08:12 | Chousuke | but, raaah |
| 08:12 | fsm | oh, I misread that |
| 08:12 | Chousuke | GHC took over an HOUR to compile and then it dared fail at the end. |
| 08:12 | cemerick | well, there's no overloads for the unchecked math in Numbers *shrug* |
| 08:13 | cemerick | there may be a good reason for that that I'm not thinking of, I suppose |
| 08:14 | fsm | The java_interop page shows an example working on a java array of primitive floats, supposedly |
| 08:14 | fsm | Anyway, thanks to everyone |
| 08:15 | fsm | I will post the code tomorrow and if anyone wants to experiment on it, they are welcome |
| 08:24 | fsm | Hmm in RT.java, aget takes an array of primitives and returns a primitive |
| 08:24 | fsm | and in core.clj, aget is defined as {:inline (fn [a i] `(. clojure.lang.RT (aget ~a ~i))) |
| 08:24 | fsm | does that call into clojure.lang.RT cause the return value to get boxed? |
| 08:25 | fsm | The docs suggest that values passed to a function are boxed, so perhaps the return value is too? |
| 08:25 | Chouser | generally, yes. but macros and :inline are an exception. |
| 08:26 | Chousuke | macros don't get the actual value anyway :) |
| 08:26 | Chouser | right. both macros and :inline expand at compile time and thus the call "disappears" |
| 08:27 | Chouser | in this case what's left is a Java interop call which is not necessarily boxes. |
| 08:27 | Chouser | boxed |
| 08:28 | fsm | Anyway it be super fast, it boils down to a static function that does only return xs[i]; |
| 08:28 | fsm | should be* |
| 08:29 | fsm | It's getting too late for abstract thinking, time for sleep. |
| 08:29 | fsm | Thanks to everyone for your help. |
| 08:38 | Fossi | is it bad to (apply str (rest word))? |
| 08:38 | Fossi | s/word/some-string/ |
| 08:38 | AWizzArd | not if you need the result |
| 08:39 | Chousuke | ,(doc subs) |
| 08:39 | clojurebot | "([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:39 | Chousuke | probably a fair bit faster :P |
| 08:39 | Fossi | that kinda was the question, sorry |
| 08:41 | Chousuke | though 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:42 | Fossi | so (str (Character/toUpperCase (first "foo")) (subs "foo" 1)) should be better then (apply str (Character/toUpperCase (first "foo")) (rest "foo")) |
| 08:42 | Fossi | *than |
| 08:42 | Fossi | my engllish is so borked today |
| 08:43 | Chouser | I'd recommend shooting for clarity and maintainability first -- worry about speed only if you have to. |
| 08:44 | Fossi | well, imho they are kinda both readable, i do not wonder about performance so much, but rather about which would be considered better style |
| 08:47 | Chousuke | hmh |
| 08:48 | Chousuke | I wonder which of my installed ports depends on x11 :P |
| 08:49 | Chouser | I 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:50 | Chousuke | kind of annoying, trying to upgrade ports and then something tries to install all of X11 |
| 09:11 | Fossi | although they are kinda 'slacking off' lately |
| 09:13 | Jomyoot | do you guys prefer light on dark or dark on light? |
| 09:13 | jdz | dark on light is usually easier on the eyes |
| 09:14 | Jomyoot | why do the textmate geeks use light on dark then? |
| 09:14 | weissj | can 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:14 | jdz | they are geeks? |
| 09:14 | Jomyoot | I followed their convention for years |
| 09:14 | Jomyoot | kiddies |
| 09:14 | Jomyoot | what u call them |
| 09:14 | jdz | well, i meant that as an answer |
| 09:15 | cemerick | weissj: you probably want doall |
| 09:15 | weissj | ,(doc doall) |
| 09:15 | clojurebot | "([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:15 | chessguy_work | the 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:15 | cemerick | or maybe dorun, if you don't care about the results of the map |
| 09:16 | weissj | cemerick: i care about getting the entire seq from the inner map |
| 09:17 | weissj | in other words i want the entire inner map calculated before any awaits are done |
| 09:17 | chessguy_work | ,(reduce + [1 2 3]) |
| 09:17 | clojurebot | 6 |
| 09:18 | jdz | good thing i can easily change the brightness of the screen |
| 09:18 | jdz | and my laptop actually does it automatically |
| 09:19 | Fossi | i had a script a while back that switched between light and dark mode :) |
| 09:20 | chessguy_work | i 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:20 | cemerick | weissj: then I think it'd be (map await (doall (map #(send-off ...)))) |
| 09:20 | cemerick | I've never used agents though, so that's just a guess, really |
| 09:20 | weissj | cemerick: i'll give it a try, thanks! |
| 09:21 | chessguy_work | (crickets chirping) |
| 09:24 | chessguy_work | ,(let [x 3] x) |
| 09:24 | clojurebot | 3 |
| 09:25 | angerman | how do i cast a class to a different interface? |
| 09:25 | chessguy_work | ,(let [roll (fn [g p] (conj g p))] (roll [2] 3) |
| 09:25 | clojurebot | EOF while reading |
| 09:25 | angerman | e.g. JRubyScriptEngine to Invocable |
| 09:25 | chessguy_work | ,(let [roll (fn [g p] (conj g p))] (roll [2] 3)) |
| 09:25 | clojurebot | [2 3] |
| 09:27 | Chouser | weissj: when creating/sending/awaiting an agent all at once like that, you might prefer 'future' |
| 09:27 | chessguy_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:27 | clojurebot | [1 2 3] |
| 09:27 | angerman | while in java i"d just do (Invocable)variable ... |
| 09:28 | Chouser | angerman: you generally don't need to cast. what are you trying to do? |
| 09:28 | cemerick | angerman: why are you looking to perform a cast? Such a thing is essentially not present in clojure, as it's dynamically typed. |
| 09:28 | weissj | Chouser: i will look into 'future', thanks :) |
| 09:28 | angerman | Chouser, cemerick that's what I expected |
| 09:29 | angerman | I'm trying to call invokeFunction on a jruby Script Engine |
| 09:29 | cemerick | angerman: if you're looking to invoke a method on an object, and you want to avoid reflection, you can type-hint the object |
| 09:30 | cemerick | (.invokeFunction script-engine-obj ...more-args...) will do it |
| 09:30 | cemerick | (.invokeFunction #^ JRubyScriptEngine script-engine-obj ...more-args...) if you want to avoid reflection |
| 09:30 | cemerick | bah: (.invokeFunction #^JRubyScriptEngine script-engine-obj ...more-args...) |
| 09:32 | chessguy_work | how would i apply a function to something n times? |
| 09:33 | Chouser | ,(map inc (repeat 5 2)) |
| 09:33 | clojurebot | (3 3 3 3 3) |
| 09:33 | chessguy_work | ermm, sorry, i'd want 10 there |
| 09:33 | chessguy_work | though i'd want to pass in the 0 too |
| 09:34 | Chouser | I'm afraid I don't understand the question at all. |
| 09:34 | Chousuke | iterate? |
| 09:34 | chessguy_work | sorry, i'm trying to get rid of a for-like loop |
| 09:34 | chessguy_work | (defn roll-many [game n pins] |
| 09:34 | chessguy_work | (loop [i n g game] |
| 09:34 | chessguy_work | (if (zero? i) |
| 09:34 | chessguy_work | g |
| 09:34 | chessguy_work | (recur (dec i) (roll g pins))))) |
| 09:35 | Chousuke | iterate returns a seq though |
| 09:35 | Chousuke | ,(drop 9 (take 10 (iterate inc 0))) |
| 09:35 | clojurebot | (9) |
| 09:35 | chessguy_work | yeah this is more like a reduce over a range, where the index is ignored |
| 09:35 | angerman | cemerick: hmm it seems the arguments are my problem |
| 09:36 | cemerick | angerman: you're getting an error? |
| 09:36 | angerman | it expects a java.lang.Object and I was giving it a String |
| 09:36 | angerman | Caused by: java.lang.ClassCastException: java.lang.String cannot be cast to [Ljava.lang.Object |
| 09:36 | cemerick | it's expecting an Object[] |
| 09:36 | Chouser | maybe varargs? |
| 09:36 | cemerick | (probably the arguments to the jruby fn?) |
| 09:36 | Chouser | ooh |
| 09:36 | chessguy_work | ,(nth (iterate inc 0) 9) |
| 09:36 | clojurebot | 9 |
| 09:37 | angerman | cemerick: yes |
| 09:37 | cemerick | angerman: in that case, (into-array ["some" "args"]) might be what you want |
| 09:37 | angerman | cemerick: using a vector doesn't resolve it :/ |
| 09:37 | angerman | hmm into-array |
| 09:37 | cemerick | vectors aren't arrays |
| 09:37 | cemerick | angerman: :-) |
| 09:37 | Chouser | actually, if it wants Object[], try (to-array ["some" "args"]) |
| 09:38 | cemerick | yeah, I can never remember in what contexts a String[] isn't useful as an Object[] |
| 09:38 | rhickey_ | chessguy_work: (reduce roll game (range 1 n)) |
| 09:39 | jdz | rhickey_: nice one! |
| 09:39 | rhickey_ | oh, you're not using n |
| 09:39 | cemerick | the fact that uncle bob is interested in clojure is interesting |
| 09:39 | jdz | a bit confusing, though |
| 09:39 | chessguy_work | rhickey_, yeah, i don't want the index |
| 09:41 | chessguy_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:41 | clojurebot | Unmatched delimiter: ] |
| 09:41 | chessguy_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:41 | clojurebot | java.lang.IllegalArgumentException: Wrong number of args passed to: core$iterate |
| 09:43 | rhickey_ | (nth (iterate #(roll % pins) game) n) |
| 09:44 | rhickey_ | the best thing to do with that bowling game is to step far away from that original logic |
| 09:45 | chessguy_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:45 | clojurebot | [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0] |
| 09:45 | chessguy_work | shazam :) |
| 09:46 | rhickey_ | the 'kata' is almost a poster child for what I think is wrong with TDD and OO today |
| 09:46 | rhickey_ | http://butunclebob.com/ArticleS.UncleBob.TheBowlingGameKata |
| 09:48 | rhickey_ | Write a class named “Game” that has two methods |
| 09:48 | rhickey_ | roll(pins : int) is called each time the player rolls a ball. The argument is the number of pins knocked down. |
| 09:48 | rhickey_ | score() int is called only at the very end of the game. It returns the total score for that game. |
| 09:48 | drewr | ugh, he distributes it in a ppt |
| 09:49 | rhickey_ | the roll method returns void!!, so right away we have a stateful object. The score method is only valid at certain times. |
| 09:49 | chessguy_work | rhickey_, not in the clojure version |
| 09:49 | chessguy_work | :) |
| 09:49 | rhickey_ | So with this awful premise, we start TDD, our system for robust and responsible programming - yikes |
| 09:50 | rhickey_ | 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:51 | rhickey_ | 3rd slie - "Clearly we need the Game class" |
| 09:51 | rhickey_ | slide |
| 09:51 | angerman | cemerick: thanks. |
| 09:51 | chessguy_work | i think TDD and functional programming are approaching the problem from different directions and can meet in the middle |
| 09:51 | angerman | cemerick: whee, I can now call maruku (ruby) from clojure ... still need to work on the return type though :/ |
| 09:51 | chessguy_work | (the problem of code quality in a stateful reality) |
| 09:53 | rhickey_ | 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:54 | chessguy_work | rhickey_, agreed, but there need not be the lack of testing of functional programs that there is either |
| 09:55 | AWizzArd | typically it is easier to test functional programs |
| 09:55 | chessguy_work | but it's done a lot less, i think |
| 09:56 | rhickey_ | 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:56 | rhickey_ | but feeling good about it due to the tests |
| 09:57 | chessguy_work | well, i guess for a non-parallel project it's ok |
| 09:57 | rhickey_ | chessguy_work: seriously not ok |
| 09:58 | rhickey_ | I think there a lot of Clojure users now who'll testify to the increased robustness of their non-concurrent programs |
| 09:58 | chessguy_work | anyway, i think TDD leads to a lot less stateful design in general than non-TDD |
| 09:59 | rhickey_ | I'd hate for people to think that FP is only for concurrency |
| 09:59 | AWizzArd | I absolutely test nearly everything. |
| 10:00 | AWizzArd | It is not responsible to not write tests (with some few exceptions). |
| 10:00 | chessguy_work | not _only_ but that's certainly a place where it thrives |
| 10:00 | Chouser | I still have only dabbled in Clojure's concurrency support. |
| 10:00 | AWizzArd | When writing professional code for applications one wants to sell means one should test-is it. |
| 10:01 | drewr | my programs are much better by not even thinking about state until forced to |
| 10:01 | drewr | ...which is usually much later |
| 10:01 | chessguy_work | rhickey_, 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:02 | rhickey_ | 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:03 | chessguy_work | i agree that it could be made more explicit, but it's there |
| 10:03 | rhickey_ | 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:04 | rhickey_ | and mock pokeable things of course |
| 10:04 | Chouser | /topic discipline on top of spaghetti ... seriously not ok |
| 10:05 | rhickey_ | the only thing I want on spaghetti is a good red sauce :) |
| 10:05 | jackdempsey | hehe |
| 10:05 | drewr | Chouser: +1 |
| 10:05 | clojurebot | Why are you asking *him* |
| 10:05 | chessguy_work | aww, man, now you guys are making me hungry |
| 10:05 | jackdempsey | haha |
| 10:05 | cark | you're missing on spaghetti carbonara ! |
| 10:05 | cark | not red at all |
| 10:06 | cark | on topic, i mostly unit test data structures, and then lots of repl testing and end product testing |
| 10:08 | cark | most 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:09 | jdz | doing read-only stuff has some benefits |
| 10:10 | chessguy_work | oh well, back to the real world |
| 10:10 | kylesmith | quick question for someone: I'm blowing the stack on the defn on large data (> 1000), why? (defn get-bounds [objects coordinate-func] |
| 10:10 | kylesmith | "Returns a seq of the min and max coordinates" |
| 10:10 | kylesmith | (let [coords (map coordinate-func objects)] |
| 10:10 | kylesmith | (reduce #(list (map min (first %1) %2) |
| 10:10 | kylesmith | (map max (second %1) %2)) |
| 10:10 | kylesmith | (list (first coords) (first coords)) coords))) |
| 10:10 | drewr | lisppaste8: url |
| 10:10 | lisppaste8 | To use the lisppaste bot, visit http://paste.lisp.org/new/clojure and enter your paste. |
| 10:11 | kylesmith | sorry, I'm relatively new to irc. |
| 10:11 | drewr | kylesmith: np |
| 10:11 | Chousuke | hm |
| 10:13 | Chousuke | you could probably make that clearer if you used destructuring and vectors instead of the list function. |
| 10:13 | kylesmith | yes, of course. I'll do that. |
| 10:16 | AWizzArd | rhickey_: 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:17 | Chousuke | kylesmith: the coordinate-function returns a seq of pairs? |
| 10:17 | lisppaste8 | kylesmith pasted "get-bounds" at http://paste.lisp.org/display/83852 |
| 10:18 | kylesmith | that docstring isn't the best; just a list of [[x y z] [x y z]] representing min and max |
| 10:18 | rhickey_ | has everyone been ok with chunked map et al in master? |
| 10:18 | Chousuke | kylesmith: hmm |
| 10:19 | drewr | rhickey_: no issues so far |
| 10:19 | Chousuke | what kind of an object is a coordinate? |
| 10:21 | kylesmith | well, 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:21 | rhickey_ | any git fu |
| 10:22 | Chouser | git branch -m chunks scratchpad ...I think |
| 10:23 | kylesmith | Oh, and technically, the initial value to reduce is arbitrary, but it should get overwritten by the end. |
| 10:23 | jackdempsey | yea that should do it |
| 10:23 | jackdempsey | git branch (-m | -M) [<oldbranch>] <newbranch> |
| 10:23 | jackdempsey | -M forces even if newbranch exists |
| 10:26 | Chousuke | kylesmith: something like http://gist.github.com/150361 ? |
| 10:27 | Chousuke | didn't work so well, though. no syntax colouring and I had to dig up the URL from the *messages* buffer |
| 10:28 | kylesmith | Chosuke: Yes, that is identical to my version, except for variable names. And it still works for 1500 elements and crashes for 2000. |
| 10:29 | drewr | kylesmith: Can you annotate with an example of call? What's a coordinate-func do? |
| 10:29 | drewr | s/of call/call/ |
| 10:29 | Chousuke | kylesmith: maybe it's coordinate-func that's crashing? |
| 10:30 | kylesmith | okay, give me a second |
| 10:31 | Chousuke | coords holds on to most of the seq, too. |
| 10:32 | rhickey_ | Chouser: afaik, -m is only for local branch renaming |
| 10:33 | Chousuke | I don't think it's possible to rename public branches without confusing the repositories of people who have pulled it previously |
| 10:33 | Chouser | rhickey_: hm. http://kerneltrap.org/mailarchive/git/2008/6/9/2070944 |
| 10:33 | Chousuke | it's fairly simple to fix though |
| 10:34 | rhickey_ | 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:34 | drewr | git push origin :chunks && git branch -m scratchpad chunks && git push origin scratchpad |
| 10:34 | drewr | that's destructive though, as Chousuke said |
| 10:35 | drewr | also assumes origin is the remote |
| 10:36 | lisppaste8 | kylesmith pasted "get-bounds example" at http://paste.lisp.org/display/83853 |
| 10:36 | rhickey_ | 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:36 | drewr | you could leave the remote chunks and push a duplicate scratchpad (safest) but in this case it wouldn't matter |
| 10:37 | jackdempsey | nice rich |
| 10:39 | rhickey_ | which mean on this machine (quad core) now 3.5x as fast as j.u.ArrayList |
| 10:39 | rhickey_ | and in the latter case you only end up with a dangerous ArrayList, not a persistent vector |
| 10:40 | rhickey_ | I'll try http://github.com/guides/rename-a-remote-branch if no one has a better idea |
| 10:40 | kylesmith | nicely done |
| 10:40 | Chousuke | rhickey_: 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:41 | rhickey_ | overall I think adding parallel ops to the Clojure data structures is going to be a huge win |
| 10:42 | Chousuke | if 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:44 | rhickey_ | can do vectors and maps: map, reduce, possibly parallel map merge, parallel remove-keys, select-keys |
| 10:46 | Chousuke | does it parallelise a chunk at a time or something? |
| 10:46 | rhickey_ | one nice thing, the new forkjoin (jsr166y) jar is only 53k |
| 10:46 | rhickey_ | Chousuke: it splits up the tree recursively |
| 10:50 | lisppaste8 | kylesmith pasted "get-bounds loop-recur" at http://paste.lisp.org/display/83854 |
| 10:50 | kylesmith | still no luck |
| 10:52 | sh10151 | xml emit functions seem to strip whitespace |
| 10:52 | sh10151 | is there a way to avoid this? |
| 10:52 | Chouser | xml parse strips whitespace, and xml emit adds new different whitespace |
| 10:52 | sh10151 | oh ok |
| 10:53 | sh10151 | so xml parse strips whitespace |
| 10:53 | sh10151 | is there a way to avoid this? |
| 10:53 | sh10151 | :) |
| 10:53 | Chouser | clojure.contrib.lazy-xml has an emit that doesn't insert new whitespace |
| 10:53 | Chouser | I feel like a politician. |
| 10:53 | sh10151 | that doesn't bother me as much as the missing whitespace |
| 10:54 | Chouser | answering different questions than are being asked. |
| 10:54 | kylesmith | I need to leave soon, so if anyone figures out the solution to my problem, please email me. |
| 10:54 | sh10151 | all righty then |
| 10:54 | sh10151 | xslt it is |
| 10:54 | sh10151 | :-/ |
| 10:55 | sh10151 | groovy had this same asinine problem |
| 10:55 | Chouser | sh10151: afaict, both clojure high-level parsers trim whitespace |
| 10:55 | sh10151 | clojure should be better than groovy, right? :-D |
| 10:55 | Chouser | sh10151: you can use java xml parsers directly (I'd recommend http://www.extreme.indiana.edu/xgws/xsoap/xpp/) |
| 10:56 | sh10151 | i don't really want to parse much, just substitute in some values |
| 10:56 | sh10151 | can use Transformer and set some input parameters |
| 10:56 | sh10151 | so much boilerplate though |
| 10:56 | Chouser | or 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:56 | Chousuke | kylesmith: I think I get the problem |
| 10:57 | Chousuke | kylesmith: try wrapping the map in the reduced function into doall |
| 10:57 | kylesmith | I just did that 1 second before you said, and it works! |
| 10:57 | sh10151 | the default should be whitespace preservation |
| 10:57 | sh10151 | otherwise you are changing the data |
| 10:57 | Chousuke | kylesmith: 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:58 | Chouser | sh10151: I agree |
| 10:58 | kylesmith | yep, came to the same conclusion |
| 10:58 | rhickey_ | Chouser: I think cgrand might have done that at one point... |
| 10:59 | Chouser | http://www.mail-archive.com/clojure@googlegroups.com/msg13009.html |
| 10:59 | Chouser | rhickey_: apparently so |
| 10:59 | kylesmith | thanks, Chousuke and goodnight all |
| 11:05 | lisppaste8 | rottcodd pasted "object-seq" at http://paste.lisp.org/display/83855 |
| 11:05 | rottcodd | is there something like object-seq built-in? I couldn't find anything |
| 11:07 | Chouser | that's a beautiful paste. Thanks for the complete working example! |
| 11:07 | Chouser | I don't know of any such function. |
| 11:08 | Chouser | Did you notice yours halts on a nil form? |
| 11:08 | Chouser | (object-seq (java.io.PushbackReader. (java.io.StringReader. "1 nil #{bar foo}"))) => (1) |
| 11:08 | rottcodd | didn't notice that |
| 11:08 | drewr | rottcodd: interesting, I have a use for that right now |
| 11:08 | drewr | hadn't thought about it that way |
| 11:12 | Chousuke | hmm |
| 11:12 | lisppaste8 | rhickey annotated #83855 "object-seq w/nils" at http://paste.lisp.org/display/83855#1 |
| 11:17 | Jomyoot | What's a nice EMACS theme for working with Clojure? |
| 11:18 | drewr | i find the default colors quite attractive |
| 11:18 | Chousuke | hmm... (let [eos (Object.)] (take-while #(not (identical? % eos)) (repeatedly #(read reader nil eos)))) |
| 11:18 | Chousuke | not much gain from using higher-order functions in this case I suppose |
| 11:20 | Chouser | Chousuke: your version would be indentical pre-lazier |
| 11:20 | Chouser | I guess that still doesn't count as much gain. :-) |
| 11:21 | Chousuke | it does read a bit better though. |
| 11:22 | Chousuke | "take while not end of stream from <seq-of-stuff-when-read-repeately> " |
| 11:22 | Chousuke | +d |
| 11:27 | achim | you could save ~10 chars by replacing "(not (identical?" with "(not=" |
| 11:28 | achim | if you're playing golf ;) |
| 11:28 | Chousuke | that's not the same. |
| 11:28 | achim | but for (Object.), it should be |
| 11:29 | Chousuke | I wonder if Object falls back to an identity comparison ./ |
| 11:31 | achim | Chousuke: i believe, = falls back to .equals, which (again, i believe) should be identity comparison for Objects |
| 11:32 | Chouser | couldn't Foo.equals(x) do whatever Foo wants, even if x is just an Object? |
| 11:33 | achim | http://java.sun.com/j2se/1.5.0/docs/api/java/lang/Object.html#equals(java.lang.Object) |
| 11:33 | Chousuke | Chouser: no |
| 11:33 | Chousuke | Chouser: if x.equals(y), then it must be that y.equals(x) |
| 11:34 | achim | IIRC, (= x y) maps to (.equals x y) in the end |
| 11:34 | achim | for non-clojure things, that is |
| 11:35 | achim | Chousuke: the order matters, .equals isn't necessarily symmetric in java-land. |
| 11:35 | achim | but if you ask "eos", you won't get any false positives, because you can be sure it's nothing but an Object |
| 11:37 | rhickey_ | I think identical? makes it clearer that this is a sentinel - i.e. we don't care about value at all |
| 11:38 | rhickey_ | we are not testing for equality but identity - is this the eos sentinel? |
| 11:40 | rhickey_ | but Java does guarantee (not= (Object.) anything-else) |
| 12:05 | Fossi | as much as i like "Programming Clojure", it's horrible for looking up things |
| 12:09 | ieure | It’s not really a reference book, is it? |
| 12:14 | Fossi | not so much |
| 12:16 | angerman | I'm trying to compile a script using ant |
| 12:16 | angerman | now my script uses javax.script.ScriptEngineManager, which I think should be in the JDK |
| 12:16 | angerman | but I fail to build the correct target :/ |
| 12:17 | Fossi | maybe your jdk isn't set to the correct path? |
| 12:17 | angerman | how do I tell ant to instruct clojure to compile using the JDK? |
| 12:19 | Fossi | how can i access static public inner enums? |
| 12:19 | Chouser | OuterClass$EnumClass/ValueName |
| 12:19 | Fossi | ah. $ |
| 12:20 | Chouser | It's just the JVM's internal representation for inner classes |
| 12:20 | Fossi | eh. weird. |
| 12:20 | Fossi | i mean to access it that way then |
| 12:21 | angerman | Fossi:maybe I'm too stupid to get ant to do it :/ |
| 12:21 | Fossi | angerman: worked for me out of the box, so i don't really know |
| 12:21 | Chouser | java 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:21 | Fossi | the jdk path thing was just a wild guess |
| 12:27 | Jomyoot | Does Clojure have special theme support in emacs? |
| 12:27 | Jomyoot | for specific elements to clojure |
| 12:27 | ieure | Jomyoot, There’s clojure-mode. |
| 12:28 | Fossi | there's an emacs mode if that's what you mean |
| 12:28 | Fossi | with syntax highlighting |
| 12:28 | Jomyoot | is there some intersting light theme? |
| 12:28 | Jomyoot | other than than those in emacs-theme? |
| 12:28 | Fossi | more like keyword highlighting really :D |
| 12:29 | dgfitch | clojure/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:29 | angerman | hmm should not (compile 'foo) compile foo.clj |
| 12:29 | angerman | I get java.io.IOException: No such file or directory (maruku.clj:34) |
| 12:30 | Jomyoot | well clojure is more syntax lisp than emacs lisp |
| 12:30 | Jomyoot | clojure is more sytnax rich |
| 12:30 | Jomyoot | i meant |
| 12:30 | Jomyoot | so i hope for more highlighting capability |
| 12:31 | angerman | now that like 34 does not make any sense to me: http://gist.github.com/150429 |
| 12:34 | Chouser | angerman: you got compile to work and now you're asking about line 34 of that gist? |
| 12:34 | angerman | Chouser: no, compile breaks stops with java.io.IOException: No such file or directory (maruku.clj:34) |
| 12:35 | Chouser | hm. you've got a 'classes' directory and its in your classpath? |
| 12:36 | angerman | no. |
| 12:36 | angerman | so I need that ... hmm |
| 12:36 | Chouser | ,(doc compile) |
| 12:36 | clojurebot | "([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:37 | Chouser | ,*compile-path* |
| 12:37 | clojurebot | nil |
| 12:37 | Chouser | ,(doc *compile-path*) |
| 12:37 | clojurebot | "; 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:37 | angerman | hmm ok |
| 12:38 | Chouser | when you try to create a file in a directory that doesn't exist, unix kicks back a "No such file or directory" |
| 12:39 | Fossi | that one got me as well :) |
| 12:40 | angerman | Chouser: thanks I'm getting closer |
| 12:40 | angerman | now I have the following issue: java.lang.RuntimeException: java.lang.ClassNotFoundException: maruku$render__34 (NO_SOURCE_FILE:0) |
| 12:41 | Chouser | you're sure that 'classes' dir is in your classpath? you restarted your jvm? |
| 12:42 | angerman | yes |
| 12:42 | angerman | i simply create a classes folder |
| 12:42 | angerman | and there is a maruku$... in that folder now |
| 12:43 | Chouser | yes, but in order to find that .class file after clojure creates it, 'classes' must be in your classpath |
| 12:44 | Chouser | a normal directory layout is for you to have src/survey/maruku.clj and classes/, and to have src and classes in your classpath |
| 12:45 | Chouser | then when you compile you should end up with a bunch of files like classes/survey/maruku*.class |
| 12:45 | angerman | magic |
| 12:45 | angerman | it did work |
| 12:45 | Chouser | great. |
| 12:46 | angerman | now I need to find out why I can't compile it with ant ... |
| 12:58 | angerman | how do i figure out the default classpath? |
| 13:19 | Lau_of_DK | default? |
| 13:23 | Lau_of_DK | Anyone using a Macbook Pro here tonight? |
| 13:25 | sh10151 | I use one at home |
| 13:26 | sh10151 | but I am at work right now and don't have one on me |
| 13:26 | Lau_of_DK | Ok - It doesnt matter if you have it now - I just need someone who can answer a few questions in private about it |
| 13:26 | sh10151 | knock yourself out |
| 13:27 | Lau_of_DK | It does |
| 13:55 | angerman | what does this cause and how do i fix it? java.lang.Exception: namespace 'survey.maruku' not found after loading '/survey/maruku' |
| 13:56 | erohtar | angerman: it means that the namespace being defined in the file is not what it is supposed to be |
| 13:57 | erohtar | angerman: i suspect it should be survey.maraku |
| 13:57 | angerman | erohtar: hmm. ok, how am I supposed to name it? |
| 13:57 | erohtar | angerman: (ns survey.maraku) |
| 13:57 | erohtar | angerman: assuming that the survey directory is on ur classpath |
| 13:58 | Chouser | the directory containing survey is on your classpath |
| 14:03 | cemerick | yet again, I'll meaninglessly rededicate myself to posting our ant build process |
| 14:04 | cemerick | (which now only compiles clojure files that have changed since the last build -- dropped our full build time from ~60s to 10s) |
| 14:09 | weissj | I 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:10 | Chouser | cemerick: not using lancet? |
| 14:11 | cemerick | no. 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:12 | weissj | cemerick: i'm sorry :) xml as code is terrible |
| 14:12 | weissj | that's why i like lancet. groovy has a similar thing called AntBuilder. |
| 14:12 | cemerick | eh, it's horrible, but better than all the rest |
| 14:12 | cemerick | (or, all the rest that I've ever bothered to look at) |
| 14:12 | weissj | cemerick: i disagree, lancet and AntBuilder are much better. |
| 14:13 | weissj | it's real code |
| 14:13 | cemerick | right, that's where the "...that I've bothered to look at..." part comes in. |
| 14:14 | weissj | cemerick: 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:15 | weissj | anyway, can someone point me to how to get a function to run at read-time? |
| 14:15 | weissj | i know lisps are supposed to be able to do that 'whole language all the time' thing. |
| 14:16 | ieure | weissj, (defn foo [] …) (foo) ? |
| 14:16 | cemerick | weissj: you mean reader macros, I presume? |
| 14:16 | weissj | ieure: uh, how does that run the function at read time? |
| 14:16 | weissj | cemerick: i guess |
| 14:16 | cemerick | user-defined reader macros are not supported by clojure at the moment |
| 14:16 | cemerick | it's a topic of some debate, yet |
| 14:16 | Chouser | weissj: macros run at a time slightly after read, but before compile |
| 14:18 | weissj | ok, so my code "requires" lancet. lancet has a function 'define-all-ant-tasks' that defmacro's in a loop. |
| 14:18 | Chousuke | hm, wasn't there some reader form that gets evaluated at read time? |
| 14:18 | weissj | but my code doesnt' compile because it calls the functions defined by those macros that haven't been created yet. |
| 14:19 | Chouser | weissj: ah.. can you call those macros before your functions are defined? |
| 14:19 | weissj | now i can manually call 'define-all-ant-tasks' in a repl before i load my file, and that works, but that seems hackish |
| 14:19 | weissj | Chouser: but my file won't even be read in properly. |
| 14:19 | Chousuke | can't you call the macro at the top of the file? |
| 14:19 | weissj | it refers to functions that don't exist |
| 14:20 | weissj | (at read time, anyway) |
| 14:20 | weissj | or compile time, for that matter |
| 14:20 | Chouser | compile time isn't instantaneous |
| 14:20 | Chouser | earlier top-level forms are evaluated before later top-level forms are compiled. |
| 14:20 | Chouser | try it |
| 14:20 | weissj | Chouser: oh, ok, i didn't know that's how it worked. let me try. |
| 14:24 | weissj | Chouser: putting '(define-all-ant-tasks)' at the bottom of lancet.clj seems to fix it. i wonder why it wasn't already there? |
| 14:25 | Chouser | weissj: good question |
| 14:25 | Chouser | I guess you might want to define your own ant tasks first or something? |
| 14:26 | weissj | Chouser: 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:28 | weissj | so, i've added some fixes to lancet, some ant stuff doesn't work without it. who do i submit patches to? |
| 14:29 | Chouser | lancet's not in contrib, right? So it's just Halloway and however he wants to handle it. |
| 14:30 | Chouser | you could try writing to the clojure google group, or to Halloway directly. Or fork the github repo. Not sure what he'd want. |
| 14:30 | weissj | Chouser: ok thanks |
| 15:34 | rhickey_ | 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:34 | weissj | can 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:34 | hiredman | couldn't they just go in clojure.vector? |
| 15:35 | hiredman | ,(partial + 1) |
| 15:35 | clojurebot | #<core$partial__4401$fn__4403 clojure.core$partial__4401$fn__4403@8ff944> |
| 15:35 | hiredman | ,((partial + 1) 2) |
| 15:35 | clojurebot | 3 |
| 15:35 | cemerick | rhickey_: pvmap and pvreduce are no good? |
| 15:35 | weissj | oh! 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:36 | kotarak | dv pv ... |
| 15:36 | rhickey_ | cemerick: I like them, just checking |
| 15:36 | cemerick | +1 for me |
| 15:36 | hiredman | ,(map (partial + 5) (range 5)) |
| 15:36 | clojurebot | (5 6 7 8 9) |
| 15:36 | kotarak | weissj: there is also #(): (map #(+ % 5) (range 5)) partial only works for the #(+ 5 %) case. |
| 15:37 | weissj | kotarak: i was about to ask, what if my partial arg isn't the first one :) |
| 15:37 | weissj | thanks |
| 15:37 | rhickey_ | with a 10-line helper, pvmap and pvreduce are 10 lines each, and have no forkjoin code in them |
| 15:37 | cemerick | I'm intrigued |
| 15:38 | lisppaste8 | rhickey pasted "pvmap pvreduce work in progress" at http://paste.lisp.org/display/83874 |
| 15:39 | kotarak | Does .. have some advantage over ->? |
| 15:42 | rhickey_ | 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:43 | rhickey_ | kotarak: not really |
| 15:43 | weissj | how 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:44 | kotarak | rhickey_: it's pretty much obsolete then, because -> is more general... |
| 15:44 | hiredman | weissj: because you are printing the result |
| 15:44 | drewr | weissj: you're not passing the fn, you're passing the value |
| 15:44 | hiredman | and keep in mind that map is lazy |
| 15:44 | kotarak | weissj: (def x (map ...)) |
| 15:44 | rhickey_ | kotarak: it's classic |
| 15:44 | kotarak | archaic? ;) |
| 15:44 | weissj | er, so which is it? |
| 15:45 | drewr | er, sorry, I was wrong |
| 15:45 | drewr | forgot future is a macro |
| 15:45 | weissj | ah ok, i hoped so because it really did spawn threads |
| 15:46 | drewr | :-) |
| 15:46 | weissj | so then it only blocked because i used the repl? |
| 15:46 | hiredman | weissj: and map is lazy, so unless you force the map somehow, the futures will not be generated |
| 15:46 | kotarak | weissj: you probably want something like (def x (reduce #(conj %1 (future (do-one-file %2 target-dir))) [] mylist) |
| 15:47 | drewr | weissj: what happens when you wrap it with a doall? |
| 15:47 | hiredman | or use doall, or vec, or etc etc |
| 15:48 | weissj | hiredman 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:48 | weissj | actually that is not quite true - it doesn't do anything either because the list is not consumed |
| 15:49 | weissj | so yeah, doall is prob the answer |
| 15:50 | weissj | now, 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:53 | hiredman | oh |
| 15:53 | hiredman | weissj: you want pmap |
| 15:53 | hiredman | ,(doc pmap) |
| 15:53 | clojurebot | "([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:54 | weissj | hiredman: ooh, sweet. this function is now getting trivially short. love it :) |
| 15:58 | weissj | one 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:04 | Chousuke | hmm |
| 16:05 | Chousuke | Clojurebot need a more sophisticated AI so you could ask it about the API :P |
| 16:15 | weissj | i 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:16 | weissj | i would never have known about pmap. after reading about agents, i wouldn't have thought to search for a parallel map function. |
| 16:17 | weissj | i guess we need to just read the doc on everything :) |
| 16:17 | Chouser | I 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:17 | Chouser | that last step is when you really start to learn... :-) |
| 16:18 | weissj | Chouser: 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:18 | TheArthur | can I create a sparse vector in clojure? |
| 16:18 | weissj | this channel is a great resource, plus the clojure.org website and stuart halloway's book |
| 16:19 | TheArthur | and is there an easy way to create a vector full of 0 s? |
| 16:19 | Chouser | for 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:20 | Chouser | weissj: for example, 'map' and 'pmap' appear next to each other here: http://clojure.org/sequences |
| 16:20 | Chouser | TheArthur: vectors are not sparse. For that, use a sorted-map or hash-map. |
| 16:20 | Chouser | ,(vec (repeat 20 0)) |
| 16:20 | clojurebot | [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0] |
| 16:21 | Chouser | but there's a vector of zeros, length 20. |
| 17:53 | ieure | I’m trying to do some shebang scripting with Clojure, but I keep getting this error. |
| 17:53 | ieure | http://gist.github.com/150935 |
| 17:53 | ieure | The code: http://gist.github.com/150933 |
| 17:53 | ieure | I don’t get it. The code is runs, then I get an exception. |
| 17:55 | Chousuke | try removing the ns declaration |
| 17:55 | ieure | Chousuke, Same error. |
| 17:56 | Chousuke | hmh |
| 17:57 | technomancy | ieure: are you using the bash script from contrib? |
| 17:57 | ieure | technomancy, No, it’s whatever wrapper MacPorts has. |
| 17:58 | ieure | Indeed. |
| 17:58 | ieure | It would also be nice if it wasn’t insane to package up CLI tools in JARs. |
| 17:58 | ieure | Unless there’s a better way of doing it than what’s listed on WikiBooks. |
| 17:59 | technomancy | yeah, the JDK is positively useless when it comes to CLI integration |
| 17:59 | Chousuke | hm, I can't even use my clj script as an interpreter :/ |
| 17:59 | ieure | You could have left out from "when" on. |
| 17:59 | technomancy | ieure: a friend of mine was working on a project to make that a little less painless: http://github.com/dkellum/hashdot |
| 18:00 | technomancy | kinda rough around the edges in terms of installation, but it is worlds better than the "java" launcher |
| 18:00 | ieure | I 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:00 | Chousuke | heh |
| 18:00 | ieure | Seriously, I hate Java. |
| 18:00 | ieure | technomancy, 404. |
| 18:01 | technomancy | ieure: right; that should be https://github.com/dekellum/hashdot/tree |
| 18:01 | ieure | Thanks. |
| 18:01 | technomancy | it's a command-line tool that's written by someone who's actually used a terminal before! amazing. |
| 18:02 | technomancy | <insert rant about single-dash-full-word arguments /> |
| 18:03 | technomancy | the 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:10 | ieure | hashdot looks nice, thought it doesn’t solve the .jar issue. |
| 18:10 | technomancy | nope. =\ |
| 18:10 | technomancy | it's focused more on server-side JVM than distribution |
| 19:00 | krumholt_ | 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:01 | technomancy | are you sure you want a list and not a map as the return value? |
| 19:01 | krumholt_ | they have to be ordered |
| 19:02 | krumholt_ | 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:03 | krumholt_ | 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:08 | replaca | krumholt_: I would write a little func that used (take-while #(= (first foo) %) foo), count, drop and loop/recur to build the list |
| 19:08 | replaca | krumholt_: more clojure-y to build the result as a vec (and it lets you use cnj and get the right order) |
| 19:09 | replaca | but there might be a better way |
| 19:10 | krumholt_ | a take-while looks usefull thanks |
| 20:07 | technomancy | ieure: I'm not using the http client for authenticated requests, but if you're seeing arguments ignored I will try to fix that. |
| 20:08 | ieure | technomancy, Your HTTP client worked fine. The contrib one ignored the :headers I gave it. |
| 20:08 | technomancy | oh gotcha |
| 20:09 | technomancy | yeah, 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:09 | ieure | I just had to generate the authtoken myself. And I guess there isn’t anything standard that does Base64 the way HTTP wants it. |
| 20:09 | ieure | technomancy, Maybe, I’m really not comfortable enough with Clojure to go hacking on it just yet. |
| 20:10 | ieure | From what I saw, I’d need some way to frobnicate the connection before sending the request. |
| 20:11 | ieure | Maybe a (with-connection) macro that I could call (request) inside of. Not rally sure. |
| 20:12 | technomancy | ieure: something like that is probably needed for connection pooling anyway |
| 20:12 | technomancy | but I haven't been doing much HTTP work these days |
| 20:33 | ieure | Hmm, the whole contrib.http.agent stuff seems to be pretty broken. This should work, right? |
| 20:33 | ieure | (use 'clojure.contrib.http.agent) |
| 20:33 | ieure | (let [a (http-agent "http://google.com")] |
| 20:33 | ieure | (response-body-str a)) |
| 20:33 | ieure | It returns nil. Same for response-body-bytes. |
| 20:33 | ieure | But I can get the headers okay. |
| 21:06 | duncanm | because of Clojure, i started looking into Swing this weekend |
| 21:07 | duncanm | it's really not that bad, right? in fact, it's a pretty powerful toolkit |
| 21:10 | drewr | duncanm: it's tedious, but much more fun with clojure |
| 21:10 | duncanm | yeah, with Clojure, i think it's not a bad toolkit at all |
| 21:37 | uninverted | Does Clojure have any way to get the length of a sequence? I can't see anything in the docs. |
| 21:42 | mudphone | univerted: try count |
| 22:07 | weissj | is 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:08 | weissj | ie like (defn x ([y z] (str y z)) ([y] (x "yo"))) |
| 22:09 | weissj | that would give z a default of "yo" |
| 22:17 | drewr | weissj: defnk in clojure.contrib.def gives you keyword args that have default values |
| 22:30 | duncanm | have any of you looked into JavaFX? i'm confused as to what it is |
| 22:30 | duncanm | i thought it's a new language with a set of Java libraries (built on top of Swing) |
| 22:31 | duncanm | but i can't find any resource on using the JavaFX libraries using something other than JavaFX script |
| 22:31 | cemerick | weissj: using map destructuring with a default value is more idiomatic, and doesn't require an external lib |
| 22:32 | cemerick | duncanm: sun hasn't followed through on their prior statements about supporting using javafx libs from other languages |
| 22:33 | cemerick | they're supposedly going to open things up eventually, but it's in the air at this point |
| 22:34 | duncanm | ahh |
| 22:34 | duncanm | but it's still possible, right? it's just yet another jar |
| 22:48 | cemerick | yeah, 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:13 | Jomyoot | Do you guys prefer light on dark or dark on light background? |
| 23:14 | skalnik | Depends on what |
| 23:14 | skalnik | Code I like light on dark, everything else, dark on light |
| 23:19 | scottj | Jomyoot: 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:24 | Chouser | agriffis (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:30 | duncanm | Chouser: that's cute |
| 23:44 | fsm | Hello everyone, I am back with my double primitive performance issue |
| 23:45 | fsm | I have a test case if anyone wants to look http://solardriftwood.com/testdouble.clj |
| 23:45 | fsm | This test tries various methods of storing and accessing arrays of doubles |
| 23:45 | fsm | But, looking in the profiler, all the math is done using Numbers.add instead of native ops, no matter what |
| 23:46 | fsm | Am I doing something wrong? |
| 23:47 | hiredman | fsm: have you set warn-on-reflection? |
| 23:47 | hiredman | clojurebot: performance |
| 23:47 | clojurebot | Gabh mo leithscéal? |
| 23:47 | fsm | Yes, I have set warn-on-reflection, there is no reflection |
| 23:47 | hiredman | bah |
| 23:47 | hiredman | clojurebot: you worthless bag of bones |
| 23:47 | clojurebot | I don't understand. |
| 23:48 | fsm | I am quite perplexed about why nth and [] is as fast as using native double arrays |
| 23:48 | fsm | and I am a bit perplexed why none of my math is done with primitives |
| 23:48 | fsm | I have been through the whole range of tips on the java_interop page |
| 23:49 | fsm | Clojure is great but having virtual method calls inside my arithmetic is slowing down my raytracer alot |
| 23:49 | hiredman | fsm: I am fairly certain (+ (vxfn vectPrim) 1.0) should result in a reflecton warning |
| 23:49 | fsm | Sample image here btw: http://solardriftwood.com/aa.png |
| 23:50 | fsm | I just ran again with warn-on-reflection, no reflection occurs |
| 23:50 | rhickey | fsm: you've read this carefully? http://clojure.org/java_interop#primitives |
| 23:51 | hiredman | fsm: reflection warnings do not happen when you run code |
| 23:51 | rhickey | and: http://clojure.org/java_interop#optimization |
| 23:51 | fsm | Yes, I believe I have tried every trick in the book |
| 23:51 | hiredman | the happen at compile time, when you paste code into the repl for example |
| 23:51 | fsm | My test case is here: http://solardriftwood.com/testdouble.clj |
| 23:52 | fsm | I have seen refl warnings before in my other code, no refl warnings in this code |
| 23:52 | fsm | My issue is that Number.ops is being called for what should be primitive arithmetic by my understanding |
| 23:52 | rhickey | nothing in the optimization section says use aset-double, it's slow |
| 23:52 | fsm | aset-double is only used three times, outside the performance loops |
| 23:53 | fsm | I have also tried into-array, no difference |
| 23:53 | rhickey | "aget/aset are overloaded for arrays of primitives" |
| 23:53 | fsm | I am enjoying Clojure greatly, I am just a bit perplexed on this issue |
| 23:53 | fsm | That is, if I have a macro that uses aget, why is Number.ops used on the resulting double, instead of native operator + |
| 23:54 | fsm | In the profiler, I can see that Number.ops is called for every single arithmetic in that test case |
| 23:55 | fsm | Basically, for my raytracer I am seeking the most efficient way to represent vectors of 3 doubles (x, y, z) |
| 23:55 | rhickey | you'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:55 | fsm | I did that to test the performance of macro vs function |
| 23:55 | fsm | I found that macro-izing actually caused about 30% speed drop in my raytracer |
| 23:56 | fsm | Nonetheless, I wish to get rid of all these Number.ops |
| 23:56 | fsm | The test case compares macro and function versions, but either way, Number.ops is used |
| 23:57 | fsm | I have looked at the implementation and found that aget turns into a static method that has the body return xs[i] |
| 23:57 | fsm | Is the return value of aget boxed? |
| 23:58 | hiredman | fsm: first line of http://clojure.org/java_interop#optimization |
| 23:58 | fsm | Yes, does that apply to return values as well? That is the thing I couldn't work out myself. |
| 23:59 | rhickey | you need to use primitive locals, as described in those sections, and primitive arrays, and the primitive array constructors double-array etc |