#clojure log - Nov 04 2009

The Joy of Clojure
Main Clojure site
Google Group
List of all logged dates

0:00 Puzzler: I think he's saying he likes it so far, but finds it intimidating to get started and wishes it were easier to jump in.

0:00 G0SUB: Puzzler: hmm, I am sure you are right.

0:01 tomoj: hmm

0:01 I can barely remember what it was like for clojure to feel intimidating

0:02 G0SUB: (ns foo (:use [clojure.contrib.str-utils :only (str-join)]) vs. (ns foo (:use [clojure.contrib.str-utils :only [str-join]])

0:02 somnium: ,(take 50 (clojure.contrib.seq-utils/shuffle (take 100 (iterate inc 1))))

0:02 clojurebot: (78 58 85 53 60 83 45 50 56 20 31 92 62 10 57 30 80 43 6 18 97 96 55 72 8 88 12 17 7 19 26 42 64 67 46 39 21 54 27 4 47 84 93 1 87 100 25 81 33 59)

0:03 G0SUB: both of them work, why is the first preferred over the second?

0:04 why use a list instead of a vector as an arg to :only?

0:04 somnium: G0SUB: not an answer, but (ns foo (use bar)) is also valid

0:04 tomoj: who says the first is preferred?

0:04 somnium: the macro doesn't seem to care as long as it get some kind of string and some kind of seq in the right places

0:05 tomoj: I think I like the first because it helps make the list of symbols look different than the vector wrapping the libspec

0:05 but really it is absolutely only a stylistic matter

0:10 hiredman: ugh

0:15 tomoj: what's an efficient way to take a seq like '([a b] [c d] [e f]) and get '(a c e) and '(b d f)

0:16 somnium: ,(map first '([a b] [c d]))

0:16 clojurebot: (a c)

0:16 tomoj: sure

0:16 but then we have to crawl the seq twice

0:17 somnium: ah, you probably need to reduce then, but only one return val

0:17 is [[a c e] [b d f]] ok?

0:18 tomoj: well I could see how to do that with a reduce

0:18 but I'd rather have a pair of lazy seqs

0:20 hmm, I think I'm not thinking straight

0:20 somnium: not sure I understand what return val is the goal

0:20 tomoj: if you have a pair of lazy seqs as the return val, then they will crawl separately, and so you'll crawl the original seq twice

0:20 somnium: you could use something mutable like an array and a doseq, but I don't think thats what youre after

0:22 maybe one lazy seq that conses onto n lists?

0:22 that way you only crawl once

0:22 so returns [[lazy-a ...] [lazy-b ...]]

0:23 tomoj: I don't see how to do it with one lazy seq

0:23 I'm being given a seq like [[key1, val1], [key2, val2], ...] and I want a lazy seq of keys and a lazy seq of vals

0:24 somnium: (map #(list (first %) (last %)) (...))

0:24 you still have to split them out, but each node gets processed only once, closer?

0:24 tomoj: that's pretty much the identity

0:24 somnium: er

0:27 tomoj: ,(map #(list (first %) (last %)) '([a b] [c d]))

0:27 clojurebot: ((a b) (c d))

0:27 somnium: reduce isn't lazy is it...

0:28 tomoj: nope

0:28 maybe I'm talking nonsense

0:29 somnium: can you do it with lazy-seq and cons somehow?

0:29 tomoj: seems like it might be impossible to split a seq of [[key, val], ..] into two lazy seqs of (key, ..) and (val, ..)

0:29 I mean, without having each lazy seq crawl the seq on its own

0:30 maybe having each lazy seq crawl the seq on its own is OK

0:30 somnium: (nth keyseq n) would have to get (nth valseq n) if they crawl together?

0:32 tomoj: hmm

0:32 you know you may be right

0:32 if you close over a lazy-seq of the keyval pairs

0:33 and have each of the lazy seqs keep a reference to that

0:35 I am utterly confused

0:35 somnium: I'm guessing laziness is key? if they both close over it will it ever get GCed?

0:36 I need to try out the new branch, been frustrated with performance of gen-class vs. java

0:36 tomoj: well i was thinking you could return a pair of lazy-seqs

0:36 but they both reference the same lazy-seq in the background through the closure

0:38 well

0:38 then they both will crawl it separately anyway I guess

0:40 somnium: could you lazily reduce onto two lists? something like (cons n (reduce #(...) (take n key-vals)))?

0:41 er, the first n should be a list with the transformed lists, and you cons on them as needed with reduce,

0:42 tomoj: its been a nice break from my problem domain, what's it for, out of curiosity?

0:43 tomoj: well

0:44 couchdb sends a list like [[key, val], ..] to the view server

0:44 but the javascript view server calls reduce functions with a list of keys and a list of vals as parameters

0:47 of course I don't have to make my clojure reduce functions act like javascript reduce functions, hmm

1:55 kjacs: Hello, I am trying to run the Norvig Spelling Corrector example and I'm running into issues with (or). What should (or () () '(1 2 3)) eval to? The example assumes '(1 2 3) but I am getting ().

1:56 arbscht: kjacs: that is CL code. in clojure, () is not NIL.

1:57 ,(or () true)

1:57 clojurebot: ()

1:57 arbscht: ,(or nil true)

1:57 clojurebot: true

1:57 arbscht: ,(nil? ())

1:57 clojurebot: false

1:58 kjacs: hrm, is the example (http://en.wikibooks.org/wiki/Clojure_Programming/Examples/Norvig_Spelling_Corrector) incorrect or am I doing something wrong?

1:59 noidi: ,(not (not ()))

1:59 clojurebot: true

1:59 arbscht: kjacs: I think that code may be obsolete. () used to be nil in clojure

1:59 kjacs: ah ok

2:07 arbscht: thanks for your help. I found my problem. The example I posted actually works. I was using the example on (http://en.wikibooks.org/wiki/Learning_Clojure). The working example wraps the for loop in a seq returning nil and not ().

2:17 tomoj: I think the idiomatic way is to call seq in the test

2:18 kjacs: tomoj: ah, so (or (seq (fn1)) (seq (fn2))) ?

2:28 tomoj: I guess

2:28 I mean, if you use seq in the test it will work no matter what sequential thing is passed in

2:29 if you put it in the functions which generate the seq, then your test will only be guaranteed to work when it takes the results of those functions as input

3:34 what should the type be for into-array when making an array of arrays of doubles?

3:36 oh, it can figure it out on its own

3:45 hiredman: damn

3:45 you cannot call clojure.xml/parse on appengine

3:46 tomoj: Double/TYPE

3:46 tomoj: the type of an array of doubles is Double/TYPE?

3:46 hiredman: not really, but it is what you put in the type slot

3:47 ,(make-array Double/TYPE 1)

3:47 clojurebot: #<double[] [D@1021e58>

3:47 tomoj: but that's an array of doubles

3:47 I'm making an array of array of doubles

3:47 hiredman: Oh

3:47 use into-array :P

3:48 tomoj: (into-array (map #(into-array Double/TYPE %) ...)) works

3:48 hiredman: well there you go

3:48 if clojure.xml/parse doesn't work, I guess I'll switch to json

3:48 hmm

3:49 I must be doing something wrong

3:49 ,(doc clojure.xml/parse)

3:49 clojurebot: "([s] [s startparse]); Parses and loads the source s, which can be a File, InputStream or String naming a URI. Returns a tree of the xml/element struct-map, which has the keys :tag, :attrs, and :content. and accessor fns tag, attrs, and content. Other parsers can be supplied by passing startparse, a fn taking a source and a ContentHandler and returning a parser"

3:51 hiredman: there we go

3:52 I was passing it a string that was not a url, which caused it to do something appengine did not like

4:21 ,(doc merge-with)

4:21 clojurebot: "([f & maps]); Returns a map that consists of the rest of the maps conj-ed onto the first. If a key occurs in more than one map, the mapping(s) from the latter (left-to-right) will be combined with the mapping in the result by calling (f val-in-result val-in-latter)."

4:49 hiredman: ~hiredman

4:49 clojurebot: hiredman is an evil genius.

4:49 hiredman: ~hiredman

4:49 clojurebot: hiredman is slightly retarded

4:49 hiredman: theres the one

5:36 stephenj: #clojure

5:37 (+ 1 2)

5:37 clojurebot: 3

5:37 stephenj: ~*ns*

5:37 clojurebot: No entiendo

5:37 stephenj: *ns*

5:41 tomoj: why did clojurebot eval that?

5:41 (+ 1 2)

5:41 clojurebot: 3

5:41 tomoj: weird..

5:42 hiredman: I have got a facebook app up and running on appengine in clojure

5:42 (+ 2 3)

5:42 clojurebot: *suffusion of yellow*

5:43 hiredman: that was painful

5:43 took me aroudn five hours

5:44 for so little

5:44 http://apps.facebook.com/agegraph/

5:45 CalJunior: So facebookers are either 24, 28 or 43 (or don't know their age) :-)

5:46 right, I guess I have very few friends on facebook

5:47 hiredman: how did you go about it. where was the pain?

5:47 hiredman: mine are mostly unkown

5:47 which is annoying because I made the app because I wanted to know

5:47 CalJunior: the facebook api seems to be very php centric

5:48 CalJunior: now you know they don't want you to know. there's information in that.

5:49 hiredman: the range is 14 to 64 with a hump at around 20 for the known ages

5:49 CalJunior: Any pain in getting Clojure to play nice with GAE?

5:49 hiredman: not too much

5:50 I wrote an appengine helper ant thing a while back, I did have to rip the multipart mime stuff out of compojure

5:50 I should feed this stuff back into appengine-helper sometime

5:51 http://github.com/hiredman/appengine-helper

5:52 and appengine-helper needs a deploy target

5:55 CalJunior: thanks for the link.

5:56 hiredman: *cough* it hasn't had much testing

6:01 now that I've finished that, it's 3am and I'm all keyed up

6:17 stephenj: (+ 1 1)

6:17 clojurebot: 2

6:17 ordnungswidrig: (+ 1)

6:17 clojurebot: 1

6:17 ordnungswidrig: ()

6:17 clojurebot: when do you eval?

6:17 clojurebot: eval is evil

6:19 hiredman: clojurebot: how much wood would a wood chuck chuck if a wood chuck could chuck wood?

6:20 * hiredman watches java spin out of control while clojurebot tries to figure out how to respond

6:21 hiredman: clojurebot: well?

6:21 clojurebot: No entiendo

6:24 hoeck: maybe clojurebot is confused when to treat `,' as whitespace

6:24 hiredman: I doubt that

6:50 AWizzArd_: Is there an easy way to take a subarray of an array?

6:52 AWizzArd: ,(into-array Byte/TYPE [10 20 30])

6:52 clojurebot: java.lang.IllegalArgumentException: argument type mismatch

6:52 tomoj: ,(into-array Byte/TYPE (map byte [10 20 30]))

6:52 clojurebot: #<byte[] [B@1a59727>

6:53 hiredman: you could use byte buffers to do it

6:53 (I think)

6:53 AWizzArd: oki, I will have a look, thx

7:04 cemerick: rhickey: would you prefer early deftype/class feedback here or on the list?

7:06 avital: Hi. Just installed clojure-mode using ELPA and I can't seem to use clojure-contrib. I am trying to eval (use 'clojure.contrib.json.read) and I get a FileNotFoundException. Anything from clojure core works. It was my understanding that clojure-mode should support clojure-contrib immediately. I searched google and couldn't find any record of such an issue. Anyone have an idea?

7:11 liwp: avital: make sure that clojure-contrib has been installed

7:11 I can't remmeber is the clojure-mode installer installs it or not

7:12 avital: liwp: In src/ (the directory clojure-mode puts all the installation stuff) there is a clojure-contrib directory. Where else should I check?

7:12 liwp: avital: hmm, check that it's on your class path

7:13 try this in the repl: (println (seq (.getURLs (java.lang.ClassLoader/getSystemClassLoader))))

7:13 you should see clojure-contrib in the output

7:13 tomoj: did you use clojure-install?

7:13 avital: Hmm. it's there

7:13 tomoj: Yes

7:14 tomoj: and you added the config they told you to add?

7:14 liwp: avital: then check that it's been built

7:14 avital: Let me check the actual file it points to.

7:14 tomoj: I added (clojure-slime-config)

7:14 tomoj: I guess if your src/ is in the default place that should work

7:15 avital: It points to a JAR that exists: ~/src/clojure-contrib/clojure-contrib.jar

7:15 A friend just also did clojure-install and gets the same error.

7:16 tomoj: C-h v swank-clojure-classpath

7:16 liwp: avital: try running the repl from the command line using both the clojure.jar and clojure-contrib.jar that were installed by clojure-mode

7:16 tomoj: the correct path to clojure-contrib.jar is there?

7:17 avital: tomoj: It's there and I checked - the file is really there.

7:17 liwp: Good idea, one minute.

7:18 liwp: FYI: my swank-clojure-classpath points to both the src and classes dirs in contrib, but not to the jar

7:18 tomoj: does clojure-install still install old stuff?

7:18 maybe it got the 1.0 branch and that doesn't have json stuff? I dunno

7:20 liwp: avital: try also loading some other contrib stuff, maybe it's an issue with the json lib, like tomoj suggested

7:21 avital: Hmm.

7:21 java -cp ../clojure-contrib/clojure-contrib.jar -jar clojure.jar

7:21 I still don't have clojure.contrib.json.read

7:21 liwp: avital: the (use...) form works for me, but I'm not using the clojure-mode install

7:21 avital: I also tried clojure.contrib.monads

7:21 Also fails

7:21 tomoj: jar -tf .../clojure-contrib.jar and see if json stuff is in there

7:21 liwp: avital: try putting both jars in the -cp option

7:22 avital: tomoj: json is there

7:22 hiredman: -jar and -cp are mutually exclusive , btw

7:23 liwp: avital: are the clojure and contrib directories git checkouts? maybe you can try moving to HEAD if they are checkouts of the 1.0 tag or something...

7:23 avital: liwp: Still doesn't work.

7:23 hiredman: if you use -jar java silently ignores -cp

7:23 avital: liwp: They are git checkouts, I think they are the 1.0 tag indeed.

7:24 hiredman: I tried with just -cp on both and specifying clojure.main as the class to run.

7:24 hiredman: still doesn't work

7:24 liwp: But I see clojure.contrib.json.read is there...

7:24 tomoj: like java -cp .../clojure.jar:.../clojure-contrib.jar clojure.main ?

7:25 avital: avital@avital-laptop-2:~/src/clojure$ java -cp ../clojure-contrib/clojure-contrib.jar:clojure.jar clojure.main Clojure 1.0.0--SNAPSHOT user=> (use 'clojure.contrib.json.read) java.io.FileNotFoundException: Could not locate clojure/test__init.class or clojure/test.clj on classpath: (read.clj:0)

7:25 hiredman: oh

7:25 you have an old version of clojure and a new version of contrib maybe

7:25 avital: Oh I just notices it's not json.read that it can't find!

7:26 tomoj: why would clojure-install check out mismatched versions?

7:26 hiredman: *shrug*

7:26 I'm not an emacs user

7:26 tomoj: unless there's some reason you want to be on 1.0, check out master on both repos and rebuild

7:27 hiredman: clean and rebuild

7:28 tomoj: default target cleans for me

7:28 avital: oh wow i rebuilt clojure and now when i rebuild clojure-contrib i get errors

7:28 let me try switching to head

7:29 tomoj: isn't switching to head like walking to here?

7:32 avital: I think they are on head. Is it possible that clojure-contrib is currently broken? Or did someone just say they tested it and it works?

7:32 (when I run ant -Dclojure.jar=../clojure/clojure.jar in clojure-contrib I get errors)

7:33 [btw thanks for all the help!]

7:33 tomoj: how did you get them to be "on head" ?

7:34 avital: I just looked at .git/config and it seems that they are already on head (how would you say that other than 'on head'?)

7:34 [remote "origin"] fetch = +refs/heads/*:refs/remotes/origin/* url = git://github.com/richhickey/clojure-contrib.git [branch "master"] remote = origin merge = refs/heads/master

7:34 tomoj: .git/config is irrelevant

7:34 avital: oh ok

7:34 liwp: avital: what does git branch -a say?

7:34 tomoj: I believe HEAD is whereever you currently are

7:34 do git checkout master

7:35 perhaps also git pull, though you should already have the latest

7:37 avital: oh wow clojure wasn't on head. now that it is clojure-contrib doesn't have compilation errors!

7:37 let me try json.read again

7:38 liwp: avital: you should check if your contrib checkout is on clojure-1.0-compatible or on master

7:38 avital: liwp: it was and is on master

7:38 liwp: avital: ok


7:38 WOWOW



7:39 ok

7:39 liwp: avital: that definitely won't work then if you had a 1.0 clojure

7:39 np

7:39 avital: to whom to i send the bug report about clojure-install?

7:39 or a patch

7:47 liwp: avital: I think technomancy (Phil Hagelberg?) is the maintainer these days

7:50 patricius_: is there some clever way to reset the Clojure REPL without restarting clojure (and java potentially)?

7:50 avital: liwp: Ok thanks, I'll send him a message on GitHub

7:51 noidi: patricius_, why do you need to reset it completely?

7:51 patricius_: just to ensure that no agents are running and that all previous definitions have gone away... maybe that is a complete non-issue?

7:53 tomoj: patricius_: certainly not a non-issue

7:53 developing on the repl can hide bugs that won't show up until you restart

7:54 from moving/renaming/deleting functions

7:55 patricius_: tomoj: yeah... that was what I was thinking

7:55 so the best thing to do is just restarting the REPL?

7:56 tomoj: that's what I do

7:56 patricius_: ok

7:56 cool

7:56 tomoj: I think there could be a clever way to crawl through and unbind everything

7:56 but I don't know of anything clever to do about agents

7:56 patricius_: that's allright

7:57 I am asking because I have started using a SLIME-like thing for Vim, and I didn't want to have to restart clojure all the time to be sure that things would work right

7:57 tomoj: I tend to restart the repl often anyway since I work on a bunch of different things and use swank-clojure-project to get a repl for each different thing

7:57 patricius_: and by the way, this SLIME-like thing works really well and is MUCH easier to setup than VimClojure in my opinion

7:57 oh ok

7:58 tomoj: what's this SLIME-like thing called?

7:58 patricius_: slime.vim :)

7:59 it essentially just sends stuff to a screen session, so you don't run the REPL inside vim

7:59 but for me that doesn't matter

8:39 dabd: The ant build script does not include clj source files in clojure.jar so 'clojure.contrib.repl-utils/source' doesn't work. What can I include the sources? thx

8:39 Sorry I meant 'How can I include the sources?' thx

8:50 chouser: I usually just include the src dir in my classpath. Sorry that doesn't answer your question.

8:52 * rhickey sees sources in his clojure.jar

8:54 rhickey: in fact, I thought they were left there specifically for tools

8:54 dabd: well I am using enclojure and I get this error: http://paste.lisp.org/+1X9T

8:55 chouser: sure enough -- clojure.jar and clojure-slim.jar both seem to have the .clj files

8:55 rhickey: can't find clojure.contrib.repl-utils

8:56 chouser: dabd: you do need to 'require' a namespace before you use it

8:57 this is unlike Java classes that can be used without previous ceremony as long as you fully-qualify the class name.

8:57 cemerick: dabd: right, what chouser said: (require 'clojure.contrib.repl-utils), then (clojure.contrib.repl-utils/source reduce)

8:58 dabd: ok it works now. thanks

8:59 rhickey: or maybe (require '[clojure.contrib.repl-utils :as repl]) ... (repl/source reduce)

8:59 chouser: I'm going to have to find a way to subdivide the daily #clojure logs. total average daily traffic is definitely on an upward trend.

9:00 cemerick: dabd: in a real app, you'd put such requires, etc., in an ns declaration at the top of your source file, aliasing the namespace as rhickey did just now

9:00 dabd: ok I understand

9:00 thanks

9:00 chouser: rhickey: do you have any thoughts about default namespace aliases that would somehow still present a clear link between the usage of the alias and the actual namespace providing it?

9:01 rhickey: chouser: in favor of default aliases, unclear about what you mean by clear link

9:03 chouser: I mean if (uses com.foo.bar) (cfb/do-it) works, it's not at all obvious that cfb is the same as com.foo.bar.

9:04 rhickey: chouser: seems a general problem of nicknames, smaller, more likely to collide, less descriptive

9:05 do you have ideas?

9:05 chouser: the explicit :as avoids the problem now, but I'd also like default aliases.

9:05 not good ideas, no.

9:05 cemerick: seems like c.f.bar is reasonable for com.foo.bar

9:05 assuming the namespace components are longer than that :-)

9:06 rhickey: cemerick: that will drive people to very short namespace names

9:06 for the last segment I mean

9:07 cemerick: yeah. I almost uniformly just alias the last component of the ns name, but that's obviously not a general approach.

9:07 chouser: generating the default alias is interesting though

9:07 cemerick: I'm not entirely sure default aliases are necessary, anyway.

9:08 chouser: one benefit of default aliases is that it would encourage everyone to use the same alias for common namespaces, which would have benefits across the board.

9:09 cemerick: it only matters within each namespace -- do I care what you alias seq-utils to in your ns?

9:09 chouser: cemerick: if you're reading a snippet of my code, yes.

9:09 if I alias it the same as you do, you won't even have to go look at the 'ns' block to know what's going on.

9:10 rhickey: (just musing here) - could do - not an exact classname ?, then is it an unambiguous shortening of a referenced ns?

9:11 c.c.repl enough for repl utils

9:11 cemerick: :as is pretty darn easy, and idiomatic usage is, too. If auto aliasing could work well and be generally applicable, then we might as well make all namespaces one level deep.

9:11 rhickey: or even repl

9:11 chouser: like the last component? bar for com.foo.bar? or more general -- ah. hm.

9:12 rhickey: doesn't give you consistency

9:12 chouser: why does that remind me of VMS?

9:12 rhickey: but need not be declared nick, no conflicts possible

9:14 any feedback on deftype/class/reify?

9:14 chouser: ship it

9:14 rhickey: heh

9:15 cemerick: rhickey: I've got a bunch...want it here or on list?

9:15 rhickey: that's another issue, whither 1.1?

9:15 cemerick: either, short version here would be a good start, before I move deep into protocols

9:16 I think we need to get a 1.1. out before pulling new into master

9:16 chouser: ah, interesting.

9:17 rhickey: only master gets the workout needed for pre-release

9:18 fogus_: cemerick: If it's all the same, feedback is more easily consumed outside of IRC

9:19 rhickey: oh yes, not trying to discourage that, please post to group also

9:20 just, we're both sitting here...

9:21 fogus_: Understood. My IRC connection is perilous... so I would hate to miss something. :)

9:23 ordnungswidrig: fogus_: there is a irc log, isn't it :->

9:24 cemerick: rhickey: I'll do a quick rundown here, and post if anything significant comes out of it. I'm recording a podcast at the moment. :-)

9:25 chouser: haha!

9:37 tknudsen: /home/tknudsen/Desktop/Working/enclojure/build.xml:2: Problem: failed to create task or type antlib:org.apache.ivy.ant:settings

9:38 Cause: The name is undefined.

9:38 peeps, any ideas?

9:39 fogus_: ordnungswidrig: Yes, on chouser's site... but there is a lot of noise to filter through.

9:40 * chouser doesn't have the IRC auto-threading working yet

9:43 chouser: that would be a brilliant way to split up each day -- a list of threads at the top of the page.

9:46 fogus_: chouser: I like that idea... it would make the IRC logs an invaluable resource. (more so than they are already)

9:49 cemerick: rhickey: so, my first question: was it intentional to make all non-primitive args into defclass ctors Object?

9:51 rhickey: there isn't yet the plumbing under the hood to distinguish locals of non-primitive types, but eventually I'd like to enforce via explicit types for construction and storage

9:53 cemerick: rhickey: FWIW, I'd be very happy with two ctors: one typed, and one untyped. The reason being, I'd like to be able to drop IDerefs into those ctors as desired, and I'd make the associated .field getters unpack those IDerefs as necessary. Perhaps stuff like that should go into a layer on top of defclass, but that's one aspect of our typical usage.

9:55 rhickey: cemerick: I don't get that, you couldn't put the IDeref into a field of the type of the thing it held

9:56 what is the type of the field?

9:56 cemerick: rhickey: to be clear, we wouldn't be accessing fields anyway -- we have a set of interfaces that declare getter methods (without the "get" part) for each slot, and those are typed.

9:56 So, we might end up just typing everything as Object.

9:56 rhickey: ok, then I don't see the typed/untyped ctor use case

9:57 cemerick: rhickey: That's for the impl of those interfaces for use by our Java-using customers :-)

9:57 rhickey: I wonder about a defstatic for factories etc. Exposing ctors is always a problem

9:58 cemerick: Yeah, that's a route we've experimented with using genclass, which seems to work very well.

9:59 rhickey: defstatic could be a great target for some higher-level 'package my Clojure up for Java' thing

9:59 cemerick: right

9:59 anyway, the types on the ctor are irrelevant compared to my #2: please oh please provide a ctor that defaults metadata and expando maps to nil.

10:00 adding two nils or ", null, null" in java to every defstruct ctor invocation is unpleasant :-)

10:00 chouser: cemerick: I'm pretty sure that's planned just not done yet.

10:01 rhickey: cemerick: I hear you on that, always trips me up and an asymmetry with deftype factory fns

10:01 cemerick: That's great.

10:01 chouser: oh, maybe I'm confusing with the factory fns.

10:01 rhickey: right now just a side effect of the ctor-generating code being on the Java side and completely ignorant of metadata etc

10:02 the __ stuff is a bit precious, but I am already leveraging that in generating lookup thunks (I don't gen for __meta and __extmap)

10:03 * cemerick is still blissfully ignorant of the impl details :-)

10:03 rhickey: chouser: right, factory fns have 2 arities right now, ctors only one

10:03 very convenient to sat (deftype Foo [a b c]) ... (Foo 1 2 3)

10:03 cemerick: so next up is: it's worth noting in the docs that arity overloads in method impls are broken out in the new regime, which is different from typical fns

10:04 AWizzArd: Does .read of an InputStream block until the data is available?

10:05 rhickey: cemerick: ah, is noted here: https://www.assembla.com/wiki/show/clojure/Datatypes

10:05 "If a method is overloaded in an interface, multiple independent method definitions must be supplied."

10:05 cemerick: ah, I only skimmed reify, went straight to deftype/class

10:07 my #4 is: all methods on defclasses are declared as throwing Exception. This is really, *really* painful on the Java side, and incongruent with the interfaces the defclasses are implementing.

10:08 chouser: :-(

10:09 rhickey: cemerick: that's a bug, see //todo don't hardwire this

10:09 cemerick: Nice, very good to hear.

10:10 rhickey: finally, why specify interfaces after fields? That seems totally backwards to me (and putting the shorter vector after the longer one, which doesn't help readability).

10:11 rhickey: cemerick: because I hope for many use cases with no interfaces or methods at all

10:11 simple struct-like things extended via protocols

10:12 cemerick: OK, I can get along with that. :-)

10:12 rhickey: that's all I've got for now. I've dumped most usages of our PSM macros overboard, and all our tests are green. :-)

10:13 rhickey: great! and perf?

10:13 I've got:

10:13 interface methods should have interface exception types, not hardwired

10:13 ctor without meta and extmap

10:13 typed non-primitive fields

10:14 cemerick: yup, that's all of it

10:15 only a slight bump in perf (maybe 5%?), but the hottest usage of the PSM macros hasn't yet been replaced, because it's particularly gnarly. I'm hoping to cut that knot this morning.

10:16 I'm really looking forward to dumping that code, though. That'll be a big load off.

10:17 Producing a couple of *simple* macros for autogenerating accessors and bean-compliant getters, etc., will be super-easy, I'm looking forward to that.

10:18 I had stopped adding to our PSM macros because they became far too complicated to touch :-( gen-class is a beast!

10:19 liwp: cemerick: what's PSM?

10:20 chouser: PersistentStructMap

10:20 liwp: thank you

10:30 cemerick: using (.methodName) in reify, et al. was a great move

10:33 rhickey: it would be convenient if (defclass Foo ...) were to emit an implicit (import 'my.ns.Foo)

10:50 manby-ace: Has anyone done any work getting slime / swank going with ClojureCLR?

10:51 liwp: manby-ace: I think swank-clojure supports only the JVM implementation of clojure

10:52 so you'd need a clojureclr implementation of swank, and I haven't heard of one

10:52 manby-ace: llwp: cheers, just wondering if that might have already been started. I'll commence hacking then :-)

10:52 liwp: manby-ace: carry on

10:53 manby-ace: I should add that I haven't really been following the ClojureCLR world at all, so there might be an impl, but I just haven't heard about it

11:01 cemerick: rhickey: just FYI, I just replaced the Java class that is instantiated and accessed the most in our main project (a simple rectangle struct) with defclass, and perf is identical.

11:02 I think that's the only part of our data model that was still in Java.

11:05 rhickey: cool

11:08 danlarkin: awesome!

11:08 arohner: cemerick: was it in java because you needed the performance?

11:08 cemerick: arohner: yes. We were taking a 10-30% hit on perf if we used the gen-class version of the struct.

11:08 (depending on the dataset benchmarked)

11:09 arohner: great

11:12 cemerick: reify should be quite a bit faster than proxy all around, correct?

11:12 rhickey: cemerick: oh yeah

11:13 cemerick: OK. I'm trying to prioritize the porting :-)

11:13 basically: turn over everything!

11:13 rhickey: cemerick: matching exception types is up

11:16 cemerick: rhickey: excellent, thank you

11:16 rhickey: thanks for the feedback

11:17 cemerick: rhickey: thank you very much for the wonderful tools! :-D

11:18 what does this indicate: Mismatched return type: containedBy, expected: java.util.Collection, had: java.lang.Object

11:19 FWIW, containedBy is defined by an interface, as a return type of Collection

11:19 rhickey: cemerick: is it overloaded?

11:19 or, derived from another interface with covariant return type?

11:19 cemerick: rhickey: no -- there are other methods on that interface that are overloaded, but not containedBy

11:20 rhickey: are you supplying type hints?

11:20 cemerick: not on any returned values, etc.

11:20 rhickey: at all on containedBy?

11:21 i.e. on the signature

11:22 cemerick: rhickey: Yes, I had a type hint on the single argument. Removing it eliminated the exception. The type hint was correct, FWIW.

11:22 Obviously not needed in reify, but should it cause an exception?

11:22 rhickey: cemerick: once you type hint anything you must get all the hints right, leaving off the return hint defaults to Object

11:22 cemerick: ah-ha

11:23 even if the method isn't overloaded?

11:23 rhickey: yes

11:23 why hint at all then?

11:23 cemerick: well, I had to with proxy :-)

11:24 rhickey: that was the old days

11:24 cemerick: a lot of stuff is going away with the porting

11:24 yeah

11:24 I'd update the docs to indicate that any type hinting requires complete hinting. Right now, my read of them is that they say that only incomplete hints on overloaded methods will cause problems.

11:26 rhickey: cemerick: its doesn't actually require complete hinting, just correct hinting, i.e. default of Object ok if Object - clarifying now

11:26 fradiavalo: Hi guys, I am having some trouble with re-matches..not sure why (re-matches #"ab+" "abc") returns nil, where as (re-matches #"[-+]?[0-9]+/[0-9]+" "22/7") returns "22/7"

11:28 rhickey: "if you supply any hints at all, no inference is done, so all hints (or default of Object) must be correct, for both arguments and return type"

11:28 cemerick: yeah, that's better :-)

11:29 anything involving JIT is tough to peg, but my impression so far is that perf is plateauing a lot faster now (i.e. less warm-up to get JIT'ed code).

11:31 fradiavalo: ugh, I figured it out, I had a buggy regex. Sorry for the noise.

12:31 rhickey: cemerick: fields-only ctor is up

12:44 hiredman: clojurebot: max people?

12:44 clojurebot: max people is 255

12:44 hiredman: clojurebot: really?

12:44 clojurebot: Huh?

12:46 cemerick: rhickey: gorgeous, thank you.

12:47 rhickey: is there any perf penalty associated with the default IPersistentMap impl?

12:47 on deftype/class, that is

12:56 chouser: optional interfaces list could come before a required fields list. ...is that too magical?

13:03 AWizzArd: hiredman: no, it's not true

13:03 someone cheated and changed that var

13:05 cemerick: chouser: I suggested that earlier, but I think rhickey is expecting a lot of types unassociated with interfaces

13:05 chouser: sure, it can still be optional

13:06 hiredman: clojurebot: max people is 180ish

13:06 clojurebot: Ik begrijp

13:06 cemerick: I think it would read better with interfaces first (I like to have shorter forms before longer ones, etc), but it's fundamentally unimportant to me.

13:06 chouser: I saw you suggest changing the order, I'm just saying I don't see why the interfaces list being optional mean is has to come later.

13:06 cemerick: ah

13:06 hiredman: ,(Integer/parseInt "180ish")

13:06 clojurebot: java.lang.NumberFormatException: For input string: "180ish"

13:06 hiredman: nuts

13:06 chouser: ,(read-string "180ish")

13:06 clojurebot: java.lang.RuntimeException: java.lang.NumberFormatException: Invalid number: 180ish

13:07 chouser: ,(read-string "180 ...ish")

13:07 clojurebot: 180

13:07 rsynnott: heh

13:07 hiredman: ,(Integer/valueOf "180ish")

13:07 clojurebot: java.lang.NumberFormatException: For input string: "180ish"

13:08 hiredman: clojurebot: max people?

13:08 clojurebot: max people is 255

13:09 hiredman: haha

13:11 AWizzArd: clojurebot: max people is 188

13:11 clojurebot: 'Sea, mhuise.

13:12 AWizzArd: ~max people

13:12 clojurebot: max people is 188

14:16 ordnungswidrig: typing with my is still very hard...

14:17 Chousuke: typing with your?

14:17 ordnungswidrig: argh, my alphagrip i mean

14:17 bgb

14:18 ...but fun!

14:22 patrkris: A question I want to ask to ensure that I understand Clojure correctly: It doesn't make much sense to have a reference (be that a var, a ref or an agent) to an object from Java-world, since that object can mutate, and thus we cannot get a consistent "snapshot" of that object's state/value?

14:27 chouser: patrkris: you're thinking about it correctly, but the answer may depend. For example if you can treat that java object as if it were immutable (copy on write, for example) it might be useful to keep in a reference object.

14:28 Or if the object is immutable despite coming from Java-world, like java.lang.String.

14:28 patrkris: chouser: yeah ok, I see your point

14:29 chouser: but yes, if it's a big ol' regular Java application object with pile of getters and setters and no sane way to make copies ... Clojure can't do much to help you with the concurrency nightmare that will ensue.

14:29 maybe you can put it in an agent and promise not to use the mutators directly (even though nothing is actually stopping you) and *maybe* that'll be better than a lock.

14:34 patrkris: yeah, it's not something I plan on trying :)

14:34 chouser: :-) good

14:36 patrkris: If i establish a root-binding for a var called A, and in an agent's action say (def A "someothervalue"), that will establish a new root binding, changing the value for all threads?

14:36 chouser: yes. don't do that either. :-)

14:36 using 'def' anywhere other than the top level of a .clj file is at least a yellow flag if not red.

14:37 patrkris: good... just adding to my understanding :)

14:37 chouser: (loop [] ... (def x ...)) ; do not want!

14:37 ordnungswidrig: re

14:38 chouser: the change is atomic via lock on the var, so you're never going to see a half-updated var, but that's as far as the safety goes.

14:38 Chousuke: a slightly better way to redef vars is to use alter-var-root! I suppose

14:38 chouser: alter-var-root is slightly more idiomatic, but I'm not sure I've ever seen it used.

14:39 ordnungswidrig: what is the idiom for a changed variable x? x_ x+ x1 x_ ??

14:40 The-Kenny: I remember there was a convention in haskell for this... I would use it in clojure too.

14:40 ordnungswidrig: The-Kenny: i think in haskell it's x' but this is not allowed in clojure

14:41 I've seen x, x+, x++ but I don't like it.

14:41 The-Kenny: ordnungswidrig: Oh yes, that was the convention.

14:41 djork: is cond not tail-recursive?

14:42 Chousuke: what do you mean?

14:42 The-Kenny: I would prefer x_ from the list you've mentioned.

14:42 chouser: djork: use :else for the default condition

14:42 djork: yes but I mean the cond macro itself seems like it may not use tail-call

14:42 chouser: The-Kenny: what do you mean a changed variable? you can re-use the same name in a series of bindings in a let

14:42 The-Kenny: djork: As far as I know, there is no tail-recursion in the jvm.

14:43 djork: yeah but there is in Clojure

14:43 Chousuke: djork: if cond itself is in the tail position, then all the branches are in tail position as well

14:43 djork: it just expands to a series of ifs

14:43 djork: it doesn't seem to be

14:43 patrkris: there isn't, and rhickey has been explicit about clojure not using tail-call optimization

14:43 The-Kenny: chouser: I think you want to highlight ordnungswidrig ;)

14:43 chouser: djork: each value of a cond form is a tail position iff the cond itself is in a tail position.

14:43 ordnungswidrig: what The-Kenny said. ;-)

14:44 djork: oh, so recur in the tail position is not tail call optimization?

14:44 I thought it was

14:44 it avoids blowing the stack

14:44 right?

14:44 ordnungswidrig: huh?

14:44 chouser: ordnungswidrig: what do you mean a changed variable? you can re-use the same name in a series of bindings in a let

14:44 Chousuke: djork: TCO and recur are different things.

14:44 patrkris: djork: sorry, i probably misunderstood then

14:44 chouser: patrkris: you're correct

14:44 ordnungswidrig: Chousuke: really? that'd be both nice and weired

14:45 chouser: djork: you're probably correct but you might be using the wrong words.

14:45 Chousuke: djork: but recur *is* a tail call. it's just to to an arbitrary function.

14:45 twbray: djork: recur achieves the same effect as a recursive call to the function it's in when it's in tail position and TCO is applied.

14:45 The-Kenny: ordnungswidrig: (let [a 42] (let [a (inc a)] a)) is valid, as far as I know

14:45 (and it will return 43)

14:45 ordnungswidrig: ,(let [a 1 a (inc a) a (inc a)] a)

14:45 clojurebot: 3

14:45 ordnungswidrig: ah.

14:46 djork: recur is manual tail call optimization

14:46 chouser: ,(-> 1 inc inc)

14:46 clojurebot: 3

14:46 chouser: djork: yes

14:46 djork: k

14:46 Chousuke: an easy way to determine is some expression is in tail position: try replacing it with a suitable recur and see if you get an exception :P

14:46 djork: yes :)

14:46 but let me try to test my assumptions here...

14:46 Chousuke: it's easy

14:46 chouser: well, manual tail self-call optimization

14:46 Chousuke: ,(fn foo [] (foo))

14:46 clojurebot: #<sandbox$eval__3597$foo__3599 sandbox$eval__3597$foo__3599@8c3770>

14:47 Chousuke: ,((fn foo [] (foo)))

14:47 clojurebot: java.lang.StackOverflowError

14:47 Chousuke: ,((fn foo [] (recur)))

14:47 ordnungswidrig: chouser: that makes me wonder why the compiler does not offer an option for it.

14:47 clojurebot: Execution Timed Out

14:47 ordnungswidrig: Chousuke: for automatic tail self-call optimization. Or is it a runtime exception that'll occur?

14:47 s/Chousuke/chouser/

14:47 rhickey: cemerick: no perf penalty on default IPersistentMap impl

14:48 cemerick: rhickey: OK, good to know.

14:48 ordnungswidrig: is flip in contrib?

14:48 chouser: ordnungswidrig: the compiler could replace some self-calls with 'recur' automatically, but recur does not act the same as a self call (different stack impact) so it'd be up to the programmer to correctly understand the meaning the compiler would assign in each case.

14:49 ordnungswidrig: chouser: that's why clojure does no optimization? The provide clear semantics, right?

14:49 cemerick: rhickey: is this 'default implementation' injection something that will be opened up eventually. Magic markers like the IPM interface are handy, but...magical. :-)

14:49 chouser: ordnungswidrig: rhickey has correctly determined this is undesirable. :-) 'recur' is clear, specific, and what it can and can't do is easy to understand.

14:50 rhickey: cemerick: how that will work is still TBD

14:50 cemerick: would you rather defstruct2 that had map impl?

14:52 we also had chouser's keywords-as-triggers (def Foo [a b c] [:map IThis IThat] ...)

14:52 cemerick: rhickey: I would think that deftype + default IPM impl would simply replace defstruct *shrug*

14:52 chouser: cemerick: excellent blog post.

14:53 cemerick: chouser: ah, thanks. I'm glad I didn't get anything obviously wrong.

14:53 I tripped over the lazy-seq binding capture issue on Monday, after a solid 3 hrs of debugging, so I figured I'd really boil the fundamentals into my head through writing.

14:54 Chousuke: rhickey: I suppose keywords would at least be more portable if the interface names ever change, like in port to a new platform or if they get refined or something

14:54 +a

14:54 chouser: it's interesting (to me anyway) to trace the potential problems to any combination of closure and dynamic binding

14:55 cemerick: rhickey: well, I don't really see :map there as anything like IThis or IThat. The latter just adds an interface, the former actually injects implementations. The two are totally separate beasts in my head.

14:55 rhickey: cemerick: presuming deftype won't have IPM as default (it won't, because making your types map when they are not otherwise collections is a big deal that will eventually bite you once you have more protocols in play), something that *did* have it by default might qualify for another name. I'd love to replace defstruct with defstruct on deftype but it has a few capabilities that don't work well

14:56 one problem is that anything like that will need 2 version (type and class)

14:56 cemerick: I think it's worth thinking about whether lazy-seq and friends should automatically capture the bindings of the current thread-local. I'm sure that's something that's been mulled over; I'm not sure I have an opinion at the moment.

14:56 rhickey: well, there's always the option of simply eliminating defstruct.

14:57 chouser: lazy-seqs and high-order functions all use closures, and we think of closures in terms of their lexical scope, but once they're getting passed around their dynamic scope can be who-knows-what (other thread, outside the (binding ...), on a different terracotta server, etc.)

14:57 rhickey: cemerick: you will run interference on that? :)

14:57 cemerick: I suppose some people like the error-on-dissoc

14:58 rhickey: are people really that attached to it, and its slowness and inflexibility? ;-)

14:58 djork: I actually like recur over optimizing for tail calls, as it is more explicit and I think it makes for better reading.

14:58 rhickey: cemerick: I'm sure they will switch to deftype, but forcing them to is another story

14:59 cemerick: FWIW, if the magic behind IPM injection were more generalized, then we could have an IPersistentStruct (or whatever) that injected an impl that errors on dissoc'ing a core slot.

14:59 rhickey: cemerick: but people have been using defstruct without any type tags other than convention - once they have them they'll think twice about being IPM

14:59 chouser: djork: yes, me too

14:59 Kjellski: Hiho =)

14:59 Chousuke: cemerick: but what if your lazy-seq-function does something like (defn make-lazy-seq [...] (let [foo (do-something-with *var*)] (when blah (lazy-seq (cons (operate-on foo) (make-lazy-seq ...)))?

14:59 djork: I'm just trying to understand the source of cond

14:59 the code

14:59 technomancy: I've started seeing errors like "java.lang.NoSuchMethodError: clojure.lang.RestFn: method <init>()V not found"; I may have screwed my build up (using git master). any idea what kind of problem would cause an exception like that?

14:59 Chousuke: cemerick: if the var access were inside lazy-seq, something could be done, but...

14:59 djork: I should be macroexpand'ing it

15:00 rhickey: cemerick: yes, certainly, and many other auto-implementors , just haven't generalized it yet

15:00 cemerick: technomancy: you have to rebuild any sources built with older clojure versions...any classfiles are sorta hosed with HEAD.

15:00 Raynes: technomancy: That's the exact error I receive in Slime when I use the experimental Clojure branch.

15:00 technomancy: cemerick: ah... actually the stack trace looks like it's coming from loading contrib; didn't think to double-check that.

15:00 thanks.

15:00 cemerick: Chousuke: Yeah, I have no suggestions about how to actually go about it.

15:01 technomancy: Raynes: you mean the maven branch of swank-clojure?

15:01 Raynes: technomancy: Not sure. The swank-clojure that was installed by clojure-install about a week ago.

15:01 cemerick: rhickey: I think my only point is that, if there were such a generalization, then people could compose whatever set of impls and therefore semantics on top of deftype without having all these siloed def-* sitting around.

15:02 rhickey: cemerick: I'm not diasgreeing

15:02 have you got a generalized mechanism?

15:02 cemerick: rhickey: I know, just clarifying my position, if only to myself. :-)

15:02 technomancy: Raynes: should work better on the maven branch; if you still run into problems could you report them on http://groups.google.com/group/swank-clojure ?

15:02 Raynes: Sure thing. I'll note that. I have to leave right now, but I'll try that out later.

15:02 rhickey: cemerick: it's really quite complex, as any set of such auto-impls won;t necessarily compose

15:03 and the presumptions made might also conflict

15:03 Chousuke: cemerick: though I think there is a ticket on assembla about providing a function wrapper that captures the dynamic environment and re-establishes it when the function gets called

15:03 rhickey: cemerick: so overall, I don't think injection should be emphasized

15:04 cemerick: rhickey: Yeah, I know. I presume we wade straight into the maw of trait-like issues. My talk about having a generalized mechanism is pretty much hand-waving, hoping you'll pull another rabbit out of your hat.

15:04 drewr: what's the safest way to do (read-string ":foo")?

15:04 rhickey: and tempted by chouser's suggestion to leave it out

15:04 djork: drewr: what's wrong with the way you're doing it

15:04 Chousuke: drewr: bind *read-eval* to false first.

15:05 cemerick: Chousuke: yeah, I saw that some time ago, but didn't really grok what was going on there at the time

15:05 rhickey: cemerick: for now, I'm standing pat until protocols are inplace

15:05 cemerick: Sounds good to me. I'm in a happy place. :-)

15:06 drewr: Chousuke: ah, I didn't see that arbitrary sexps had to be in #=()

15:06 wait no, that's not correct

15:06 they're just not evaled after reading

15:06 patrkris: is using release-pending-sends bad practice?

15:07 Chousuke: drewr: nothing is evaled by default when reading, except if you use the #= reader macro.

15:07 drewr: but setting *read-eval* to false disables that.

15:08 ordnungswidrig: still didn't find a "flip"

15:08 drewr: ,(binding [*read-eval* false] (read-string "(+ 1 1)"))

15:08 Chousuke: flip? as in, a function to reverse argument order?

15:08 clojurebot: (+ 1 1)

15:08 drewr: ,(binding [*read-eval* true] (read-string "(+ 1 1)"))

15:08 clojurebot: (+ 1 1)

15:09 Chousuke: drewr: there's no difference in that case.

15:09 drewr: ,(binding [*read-eval* true] (read-string "#=(+ 1 1)"))

15:09 clojurebot: 2

15:09 drewr: that's what I meant :-)

15:09 ordnungswidrig: Chousuke: yes ((flip f) a b) is (f b a)

15:09 Chousuke: ordnungswidrig: there's flip in contrib I think

15:10 ,`flip

15:10 clojurebot: sandbox/flip

15:10 Chousuke: (doc flip)

15:10 clojurebot: It's greek to me.

15:10 Chousuke: hm, apparently not.

15:10 Kjellski: What is the best way to sum the values of a map?

15:10 ordnungswidrig: flip is from hiredman's odds-and-ends as it seems

15:10 http://github.com/hiredman/odds-and-ends/blob/8a84e6ddbad9d71f714ba16c3e1239633228a7eb/functional.clj

15:11 hiredman: klafter (comp (partial reduce +) values)

15:11 chouser: #(f %2 %1)

15:12 hiredman: flip works for than two args

15:12 chouser: does it reverse them?

15:12 ordnungswidrig: hiredman: I need it just for two

15:12 chouser: or put the last one first?

15:12 or the first one last?

15:12 hiredman: chouser: it reverse the order of all the args

15:12 ordnungswidrig: or swap to last and the first

15:12 what would haskell do?

15:13 hiredman: (fn [fn] (fn [& args] (apply fn (reverse args))))

15:13 er

15:13 (fn [fn-] (fn [& args] (apply fn- (reverse args))))

15:13 the pointfree lib on github has a fn that just flips the first two args

15:13 Chousuke: Kjellski: (apply + (vals themap)) :P

15:14 hiredman: right

15:14 vals not values

15:14 Chousuke: you take that pointfree thing too far sometimes.

15:14 hiredman: ,((comp (partial reduce +) vals) {:a 1 :b 2})

15:14 clojurebot: 3

15:14 Kjellski: Chousuke : once again... sometimes it just hurts how easy things are... but, rewireing is on the go... thanks!

15:15 ordnungswidrig: hiredman: what is then the "official" source for a decent flip? Your functional.clj?

15:15 hiredman: ordnungswidrig: I dunno that there is one, if you need one you might ask rhickey about adding one to core, when I asked he said he had never needed one, and I realized I never used it outside of golfing

15:16 ordnungswidrig: hmm

15:17 hiredman: I have a function that takes to args and I want to partial it but I need to fix the second arg so (partial (flip f) a) would be a perfect fit. I realize that (fn [b] (f a b)) would work also.

15:18 hiredman: so you and rhickey might be right

15:18 hiredman: well no, I still want flip, I just am unable to argue with rhickey about it :P

15:19 Kjellski: djork: Do you remember the bacteria thing? Maybe there is a much smarter way, but finally I´ve got it...

15:19 ordnungswidrig: hiredman: but then partial could be dropped too. Dear develier: "usage of partial is considered golfing"

15:19 djork: oh boy :)

15:19 ordnungswidrig: s/develier/developer/

15:19 djork: Kjellski: still having fun with Clojure though?

15:19 I have been doing Project Euler

15:19 a few problems here and there

15:19 will be firing up LWJGL soon

15:19 real work gets in the way too often

15:19 Kjellski: djork : for sure... I´ll use that as my general purpose in the master studies...

15:21 djork: coolness

15:21 rhickey: ordnungswidrig: Haskell would balk at variable arity

15:22 Kjellski: djork: what is LWJGL ? And btw: http://pastebin.com/m351fa2d ...

15:22 djork : If you´ve got time to review my code and tell me it´s just shit... ^^

15:22 djork: Lightweight Java Game Library

15:23 Kjellski: djork : something in the direction of PyGame?

15:24 ordnungswidrig: mixing destructurizing binding forms and simple ones in a single let can be confusing. lots brackets and unusual indenting

15:26 djork: Kjellski: it's lower level than that

15:27 but yeah kind of

15:27 in fact, I think it could be a great way to do multimedia apps

15:27 games of course

15:27 Kjellski: djork : okay, I would try it for fun if it´s showable...

15:28 djork: it's someone else's project

15:28 but a clojure wrapper might be in the pipeline from me

15:30 Kjellski: I´ve asked some time ago I think, but is someone arround that has a lazy-seq implementation of PI digits?

15:31 Chousuke: hm.

15:32 The idea of a very lazy seq just popped into my mind for some reason.

15:33 basically, it's so lazy that the computer refuses to do any works and the programmer has to add the items.

15:33 ordnungswidrig: why does slime-edit-definition doesn't work. Is it a known limitation of swank-clojure=

15:33 Chousuke: work*

15:33 ordnungswidrig: s/=/?/

15:34 djork: Kjellski: destructuring will help your code a bit

15:34 for instance, if you have a population count vector with the population by age in each slot of the vector...

15:34 (defn day [[day-1 day-2 day-3 day-4]] [(+ day-1 day-2) day-1 day-2 day-3])

15:34 that replaces your live-day

15:34 except it takes a vector

15:35 Chousuke: (defn day [{:keys day-1 day-2 day-3 day-4}] ...)

15:35 map destructuring!

15:36 Kjellski: Chousuke : huh? What would that produce? a vec with a map that contains only keys?

15:37 Chousuke: no, it's the argument list of the function. :)

15:37 chouser: (import 'java.util.concurrent.TimeUnit)

15:37 ,(import 'java.util.concurrent.TimeUnit)

15:37 clojurebot: java.util.concurrent.TimeUnit

15:37 twbray: Have a program that sends off a bunch of I/O intensive functions with send-off, they grind away and something reports a NPE with the helpful label (NO_SOURCE_FILE:0). What are some digging tools to find out what's blowing up?

15:37 chouser: ,(let [deref-timeout (fn [p t u & [f]] (if (.await (.d ((proxy-mappings p) "invoke")) t u) @p f))] (deref-timeout (promise) 2 TimeUnit/SECONDS :not-delivered))

15:37 Chousuke: it takes a single map with the keys :day-1, :day-2 etc. and destructures them into the variables day-1, day-2 ...

15:37 clojurebot: :not-delivered

15:37 Kjellski: djork : Thanks a lot, that never came in my mind...

15:38 djork: this is quite a quick solution compared to building the actual populations :)

15:39 chouser: cemerick: I believe you've asked for that.

15:39 Kjellski: djork : It´s not that I don´t have a solution for that, but this will blow your heap, until it´s pretty memory intense to build up a vec that contains 1,000,000,000,000 items...

15:40 Chousuke : thanks for the explanation, I´ll try that version too.

15:40 cemerick: chouser: ah, the agent error handling stuff?

15:40 chouser: cemerick: no sorry, the deref-timeout. That one only works on 'promise' before the 'new' branch.

15:40 cemerick: oh, oh, right

15:41 chouser: probably 'await-promise' would be a better name

15:41 djork: ,((fn [[first second]] (println first) (println second)) ["foo" "bar"])

15:41 clojurebot: foo bar

15:41 chouser: and of course nobody should use it because it depends on several internal details of promise. :-P

15:41 Chousuke: you could possibly build a lazy seq of the days. (defn foo [prev-day today] (lazy-seq (cons today (foo today (+ today prev-day)))

15:42 cemerick: chouser: timeouts aren't really a concern for me. My pet request would be an available? predicate for delays.

15:42 chouser: timeout of zero

15:42 hm, I think. I should check.

15:42 Chousuke: ,(letfn [(foo [prev-day today] (lazy-seq (cons today (foo today (+ prev-day today)))))] (take 5 (foo 0 1)))

15:42 clojurebot: (1 1 2 3 5)

15:43 cemerick: Super-easy to add, of course, just haven't gotten around to it.

15:43 Chousuke: ,(letfn [(foo [prev-day today] (lazy-seq (cons today (foo today (+ prev-day today)))))] (take 2 (partition 5 1 (foo 0 1))))

15:43 clojurebot: ((1 1 2 3 5) (1 2 3 5 8))

15:43 cemerick: chouser: the issue is, in certain cases, I don't want the delay to be realized at all.

15:44 Kjellski: Chousuke : *reading*, *thinking*

15:44 chouser: ohhh. yeah, that's different.

15:44 hiredman: if you deref the delay in a future you can check to see if the future is done, I believe

15:45 http://java.sun.com/javase/6/docs/api/java/util/concurrent/Future.html#isDone%28%29

15:45 Chousuke: there was also a cleverer way to form the fibonacci sequence...

15:46 hiredman: a haskell way, if I recall

15:49 Chousuke: (let [fibos (concat [0 1] (map + fibos (drop 1 fibos))] (take 5 fibos)); something like this?

15:49 ,(let [fibos (concat [0 1] (map + fibos (drop 1 fibos))] (take 5 fibos));let's see :P

15:49 clojurebot: Unmatched delimiter: ]

15:49 Chousuke: gah.

15:49 ,(let [fibos (concat [0 1] (map + fibos (drop 1 fibos)))] (take 5 fibos))

15:49 clojurebot: java.lang.Exception: Unable to resolve symbol: fibos in this context

15:49 Chousuke: meh.

15:49 hiredman: fibs = 0 : 1 : zipWith (+) fibs (tail fibs)

15:52 djork: hmm

15:54 chouser: ,(let [fibos (atom nil)] (reset! fibos (lazy-cat [0 1] (map + @fibos (rest @fibos)))) (take 10 @fibos))

15:54 clojurebot: (0 1 1 2 3 5 8 13 21 34)

15:55 chouser: That's Chousuke's solution, poorly rendered to be clojurebot-compatible.

15:55 Chousuke: heh.

15:55 djork: ouch

15:55 Chousuke: lazy-cat still amuses me.

15:56 djork: lazy-cat is lazy

15:56 Chousuke: I can't help but think of felines.

16:09 djork: http://media.bigoo.ws/content/image/funny/funny_259.jpg

16:10 as an easter-egg in the graphical version of a repl, lazy-cat should be replaced with a tiny version of that image

16:15 annealer: if somebody would help me, that would be fabulous. im trying to programatically call a macro. the name is in a string, like "GET". i would like to somehow call that macro. i cant figure it out. eval complains it cant find it in the current namespace

16:16 hiredman: :(

16:16 why would you programatically call a macro?

16:17 annealer: that's a good question

16:17 so

16:17 djork: because you can't pass the value of a macro, I presume

16:17 annealer: the web framework compojure defines some handy macros

16:17 like GET, POST, PUT, DELETE

16:17 chouser: (defmacro foo [] "foo") (eval (read-string "(foo)")) ...works for me.

16:17 hiredman: annealer: I'm pretty sure it defines them as macros for a reason

16:17 annealer: i am new to clojure, so i'm more than happy to be convinced this is the Wrong Thing

16:17 chouser: oh.

16:17 This is the Wrong Thing.

16:18 :-)

16:18 hiredman: macros happen before runtime, and "programatically" calling stuff is certainlly a runtime thing

16:18 annealer: so this is bad mojo and i should not be doing it, essentially?

16:18 hiredman: so calling macro's programatically is a red flag

16:18 chouser: annealer: well, tell us what you're trying to do

16:18 arohner: annealer: you want to programmatically generate several routes?

16:18 annealer: arohner: precisely

16:18 i know i can do it with 'compile-route'

16:18 i was just wondering if using the macros was wrong or right

16:18 chouser: ah... you want to write a macro yourself then.

16:18 arohner: you can also specify your own regex

16:19 chouser: 'eval' is definitely not right in this case.

16:19 arohner: just (GET #"/")

16:19 annealer: arohner: im doing rails-style resource routing, essentially. so i wanted a call to "resources" to actually use those macros. so i guess i should make a resources macro?

16:20 or just use the compile-route function the macro uses under the scenes?

16:20 chouser: both those options sound more sensible than using 'eval'

16:20 annealer: (p.s. thanks for being the most helpful programming language irc channel i've stumbled into for a while)

16:20 aces

16:20 Licenser: hmm can someone help me what this: Exception in thread "main" java.lang.ClassCastException: clojure.lang.Keyword cannot be cast to clojure.lang.PersistentStructMap$Def means?

16:20 annealer: i'll go the non-hilariously-bad route then

16:20 chouser: annealer: :-)

16:21 Licenser: ah found it

16:21 arohner: in one case, I generated the regex

16:21 i.e.

16:21 (GET (my-regex-returning-fn) ...)

16:22 (defn my-regex-returning-fn [] (regex (str-join "|" "js" "swf" "css")))

16:22 err (str-join "|" ["js "swf" "css"]))

16:26 I can paste the whole thing if you're interested

16:27 chouser: arohner: is that not working because GET doesn't evaluate the route form?

16:27 arohner: that was pseudo-code

16:27 my production one works

16:33 ordnungswidrig: how did the idion go to check for list containment using some?

16:34 arohner: ,(doc some)

16:34 clojurebot: "([pred coll]); Returns the first logical true value of (pred x) for any x in coll, else nil. One common idiom is to use a set as pred, for example this will return true if :fred is in the sequence, otherwise nil: (some #{:fred} coll)"

16:34 ordnungswidrig: thanks

16:35 chouser: ,(some #{:a} [:a :b])

16:35 clojurebot: :a

16:35 djork: huh

16:37 lpetit: ,(some #{nil} [:a :b])

16:37 clojurebot: nil

16:37 lpetit: ,(some #{nil} [nil :a])

16:37 clojurebot: nil

16:39 chouser: ,(some nil? [nil :a])

16:39 clojurebot: true

16:39 chouser: ,(some nil? [:a :b])

16:39 clojurebot: nil

16:40 lpetit: ,(some #{false} [true true])

16:40 clojurebot: nil

16:40 lpetit: ,(some #{false} [true false])

16:40 clojurebot: nil

16:41 lpetit: one better has to know what is placed in the set

16:41 djork: wow seriously... NetBeans mpkg failed to install in OS X?

16:41 chouser: yes, collections that may contain false or nil have to be treated somewhat more carefully

16:43 djork: huh, I had to quit my repl

16:43 * cddr` is browsing zip.clj and wonders what "^" before a symbol means

16:43 chouser: cddr`: reader shortcut for (meta ...)

16:43 cddr`: chouser: thanks

16:44 chouser: ,' ^foo

16:44 clojurebot: (clojure.core/meta foo)

17:01 patrkris: what is the easiest way to get a random element from a vector?

17:01 Kjellski: ,(apply str (partition 1 3 "123456789"))

17:01 clojurebot: "clojure.lang.LazySeq@50clojure.lang.LazySeq@53clojure.lang.LazySeq@56"

17:01 Kjellski: Sorry...

17:02 hiredman: ,(apply pr-str (partition 1 3 "123456789"))

17:02 clojurebot: "(\\1) (\\4) (\\7)"

17:02 hiredman: ,(apply str (map pr-str (partition 1 3 "123456789")))

17:02 clojurebot: "(\\1)(\\4)(\\7)"

17:02 chouser: ,(clojure.contrib.seq-utils/rand-elt '(a b c d e))

17:02 clojurebot: e

17:03 hiredman: (doc rend-elt)

17:03 clojurebot: Huh?

17:03 chouser: ,(clojure.contrib.seq-utils/rand-elt '(a b c d e))

17:03 clojurebot: e

17:03 chouser: ,(clojure.contrib.seq-utils/rand-elt '(a b c d e))

17:03 hiredman: (doc rand-elt)

17:03 clojurebot: c

17:03 "clojure.contrib.seq-utils/rand-elt;[[s]]; Return a random element of this seq"

17:03 hiredman: element

17:03 chouser: seq

17:03 hiredman: elt => element

17:03 chouser: ,(clojure.contrib.seq-utils/rand-elt {1 2 3 4 5 6})

17:03 clojurebot: java.lang.UnsupportedOperationException: nth not supported on this type: PersistentArrayMap

17:03 patrkris: t

17:03 thanks

17:04 Kjellski: hiredman : how can I put the numbers itself into a str?

17:04 hiredman : without all the other stuff?

17:05 hiredman: ,(map first (partition 1 3 "123456789"))

17:05 clojurebot: (\1 \4 \7)

17:05 hiredman: ,(apply str (map first (partition 1 3 "123456789")))

17:05 clojurebot: "147"

17:05 Kjellski: hiredman : ty

17:05 hiredman: I dunno if I would use partition for that

17:05 but, I guess

17:06 chouser: ,(apply str (take-nth 3 "123456789"))

17:06 clojurebot: "147"

17:09 Kjellski: chouser : is that more efficient? or just sugar?

17:10 hiredman: should be more efficient

17:11 partion cuts the seq up into a seq of seqs, and then you have to map first over each seq

17:12 chouser: less code and less processing -- what's not to like? :-)

17:13 Kjellski: hiredman: perfect. So I´ll use that... is there a oneliner to "spit" a string into a file?

17:13 chouser: when we have fully hyperlinked api docs, there should definitely be cross references between take-nth and partition.

17:13 Kjellski: I mean with no "extra-using" or so?

17:14 chouser : /signed

17:14 hiredman: ,(doc spit)

17:14 clojurebot: "clojure.contrib.duck-streams/spit;[[f content]]; Opposite of slurp. Opens f with writer, writes content, then closes f."

17:15 Kjellski: hiredman : I´m sometimes just banging my head against my table. But maybe, sometime in some future, my questions will take another stage...

17:17 hiredman: it will take a use of duck-streams to use spit

17:17 ,(with-open [f (-> filename File. FileWriter.)] (.write f some-string))

17:17 clojurebot: java.lang.IllegalArgumentException: Unable to resolve classname: FileWriter

17:19 djork: Kjellski: what are you trying to do there?

17:20 (with the partition and string)

17:20 Kjellski: taking every 20000th digit of the 1500000th fib number...

17:20 @ djork

17:20 djork: hah wow

17:21 hiredman: yeah, you want take-nth

17:21 djork: is that a Project Euler problem?

17:21 Kjellski: djork : nope, hacker.org ... for me that´s more fun because it´s not _only_ math...

17:21 djork: yeah, interesting

17:22 Kjellski: djork : trying be learn more in practical usage... ^^ and this problem was solved much more fast than the bac thing...

17:23 djork : 1161269686625383 is the answer...

17:23 djork: heh don't give it away :)

17:24 Kjellski: djork: huh, sorry... just for prooving correct answers... if you don´t want to play the whole puzzles to that challenge...

17:24 djork : on hacker.org not all challenges are accessible...

17:25 djork: ah

17:26 http://sixrevisions.com/resources/10-puzzle-websites-to-sharpen-your-programming-skills/

17:31 Kjellski: Nice page, so far pretty good if someday my challenges are beaten on hacker.org... =)

17:33 ordnungswidrig: pushed my first project to github. ok, more the beginnings of a project :-) Please have a look at compojure-rest. I'd welcome feedback.

17:34 Kjellski: djork: Uhh... now, bigger fib says: take the log of the 150,000,000th fib number and round to two digits...

17:34 ordnungswidrig : link?

17:35 ordnungswidrig: http://github.com/ordnungswidrig/compojure-rest

17:36 Kjellski: thanks

17:37 ordnungswidrig: Kjellski: that fib challenge sounds tough

17:39 Kjellski: ordnungswidrig: I don´t think so at all... doesn´t that calculation go linear? So just more computation before going to log that?

17:41 djork: assuming you can take the log of a number that big in clojure

17:41 Kjellski: Uh, got me?

17:41 *grin*

17:42 ordnungswidrig: nope.

17:42 djork: ,(Math/log (read-string "1293871924879182379182739817294879871948723948719283759814739487239487918274987912734"))

17:42 clojurebot: 193.67478702654344

17:43 ordnungswidrig: but the 150.000.000th fib will be a little longer ;-)

17:43 I don't see how to chop the log on this one.

17:44 Kjellski: djork : actually the other one was 20000 times the number of digits I posted as the answer... ^^

17:44 djork: oh awesome :)

17:44 ordnungswidrig: Kjellski: you actually feed the whole number to clojure?

17:44 Kjellski: ordnungswidrig : nope, I´m cheating here, using the great lazy-seq-fibo from stuarts book ...

17:45 ordnungswidrig : but just feeding it feels a lot more "cheating" for me...

17:45 ordnungswidrig: Kjellski: which creates a lazy seq of ?

17:45 Kjellski: ordnungswidrig : the fibonaccy sequence...?

17:46 djork: hmm this is kind of cool

17:46 ordnungswidrig: Kjellski: but so you actually calculated the 150.000.000th fib?!

17:46 djork: ,(BigInteger/probablePrime 128)

17:46 clojurebot: java.lang.IllegalArgumentException: No matching method: probablePrime

17:46 djork: huh

17:46 oh

17:47 ,(BigInteger/probablePrime 128 (Random.))

17:47 clojurebot: java.lang.IllegalArgumentException: Unable to resolve classname: Random

17:47 djork: oh

17:47 Kjellski: ordnungswidrig : nope, I did that for the 1500,000th one...

17:48 djork: ,(BigInteger/probablePrime 128 (java.util.Random.))

17:48 clojurebot: 283136236335513942374424665513338827589

17:48 ordnungswidrig: Kjellski: that sounds more reasonable

17:48 djork: ,(BigInteger/probablePrime 128 (java.util.Random.))

17:48 clojurebot: 247135970708632709525958798945080490857

17:48 djork: verry interesting

17:49 Kjellski: djork : what is that doing there?

17:49 ordnungswidrig: Kjellski: there is a non-recursive expresion for the fibs one could use.

17:49 djork: ,(.nextProbablePrime (bigint 1234))

17:49 clojurebot: 1237

17:49 djork: ,(.nextProbablePrime (bigint 1237))

17:49 clojurebot: 1249

17:50 djork: hmm, interesting implications there

17:50 saves me a lot of work :)

17:50 Kjellski: djork : what does that "probable" mean for real?

17:50 djork: dunno

17:50 chouser: "not divisible by 2"

17:50 Kjellski: *laughing*

17:50 djork: "The probability that the number returned by this method is composite does not exceed 2-100."

17:50 2^-100

17:51 so pretty probable

17:51 not sure what method they are using

17:51 but it would probably speed up creating lists of primes

17:51 now who said the Java class library sucks :)

17:51 Kjellski: This is going to be a quote chouser ... can´t get over it...

17:54 chouser: http://bash.org/?907358 needs to be moderated...

17:55 chouser: wow. bash.org

17:55 ordnungswidrig: djork: gnu classpath uses rabin-miller

17:59 Kjellski: So, good night then... cya

18:03 ordnungswidrig: good night be me, too.

18:14 esj: guys, if I have sequence, and I want to 'modify' the last element, is it efficient/idiomatic to go: (conj (drop-last seq) new-element), or is there a better way ?

18:16 hiredman: :(

18:17 thats not something a seq will be good at

18:18 esj: yeah, that's kinda why I brought it up

18:20 I'm trying to do a cumulative sum of a sequence, with the twist that I want each the summed sequence to add up to a threshold, and then roll to the next element. IE, if my threshold is 10, I want the elements of the returned sequence to be the cumulative sum since the last element, until that reaches 10, then I want a new element.

18:20 Ugh, that sounds ugly.

18:21 its like, I'm packing boxes, and the first sequence contains elements with mass, and the second sequence is boxes, packed with those elements, such that no box weighs more than some threshold

18:22 but growing the 'box' sequence from the first sequence is proving painful.

18:42 _ato: esj: should the numbers be less than n or the first value that is over 10?

18:50 actually.. I guess it won't work if the output should be less than 10 and theres an input greater than 10

18:50 so lets assume the other way

18:52 esj: yeah, lets assume that for now

18:53 its not super critical in the application, i'm more concerned about how I build this sequence sensibly

18:54 at the moment I'm reducing along the first sequence, and either amending the last element of the 2nd sequence, or conjing to it, based on the total weight of the bax

18:54 s/bax/box/

18:58 _ato: http://gist.github.com/226530

18:58 I just did it with recursion and lazy-seq, I couldn't think of a nice way to do it with higher-level functions

18:59 esj: *reading*

19:01 yeah, I get it

19:05 so, here's an equally daft question, but why, if it is efficient to add to the end

19:05 of a vector (for arguments sake) is removing and the adding to it not ?

19:06 or, is it because we're dealing with general sequences that we don't want to make such assumptions ?

19:09 Chousuke: some kind of a "partial reduce" could be useful.

19:10 _ato: err.. I don't get what you mean, it should be reasonably efficient, it's going to have to copy the whole last node though (clojure vectors are implemented as 32-way trees)

19:10 but you could get around that with transients

19:11 Chousuke: yeah, something like reduce-while, that performs a test and returns [reduced-value remaining-seq] when the test fails

19:12 bradford: when i eval exprs in a remore repl using contrib.server-socket, the text going to the output stream for the remore process can be valid exprs, or string repreentations fo java objects or exceptions. the latter can not be read with (read %). what is the best strategy for reading input from the strem from the remote repl?

19:12 esj: sadly everything I say is badly distorted by misunderstanding. What I mean is, my solution was to reduce the first sequence, and do the binding to the last element of the growing 'reduced' sequence with the (conj (drop-last seq) new), which was said to be bad ? Why so ?

19:14 Chousuke: drop-last of a sequence needs to walk the entire sequence.

19:14 so that it can find the end.

19:14 and drop it :P

19:15 _ato: so eg if your seq is really large, you might run out of memory

19:15 but with a vector it should be fine

19:15 Chousuke: a vector is not a sequence though.

19:15 (doc drop-last)

19:15 clojurebot: "([s] [n s]); Return a lazy sequence of all but the last n (default 1) items in coll"

19:15 Chousuke: ah, hm, it's lazy. never mind :)

19:15 _ato: ah true

19:15 hehe

19:15 Chousuke: butlast is the slow function.

19:16 (doc butlast)

19:16 clojurebot: "([coll]); Return a seq of all but the last item in coll, in linear time"

19:17 Chousuke: _ato: btw, instead of (if (nil? (seq s)) ...) I think it'd be more idiomatic to just use (if-not (seq s) ...)

19:18 _ato: Chousuke: ah yeah true

19:18 Chousuke: and (cons n nil) is probably better as (list n)

19:18 or just [n]

19:19 hmm

19:19 (cons 1 [2])

19:19 ,(cons 1 [2])

19:19 clojurebot: (1 2)

19:19 _ato: ,(next (cons 1 [2]))

19:19 clojurebot: (2)

19:19 esj: Chousuke: yikes, that makes in n! complex, nastiness :)

19:20 Chousuke: (doc cons)

19:20 clojurebot: "([x seq]); Returns a new seq where x is the first element and seq is the rest."

19:20 esj: so there is no way to kill the end of the sequence in O(1) ?

19:20 Chousuke: well, drop-last is lazy so you get the sequence in O(1)

19:21 but if you walk to the end it also needs to realise the n items you're dropping.

19:21 (otherwise it won't know the seq has ended)

19:22 esj: sorry, I misread you (its pretty late for me now)

19:23 Chousuke: but if you have a (drop-last 20000 some-source) where some-source has 40k items, and then only process the first 10000, it's going to realise only the first 30000

19:24 though in that case just processing (take 10000 some-source) would be more efficient.

19:24 but I guess sometimes you might not know how much you need to process, but still want to make sure some stuff at the end is excluded...

19:26 _ato: esj: I think with the way you're using it, it should be fine. The main difference between your way and mine (if I'm understanding yours correctly) is mine is lazy and yours is eager. Either might be better depending on what you want to do with the result

19:35 esj: ok, here is what it looks like

19:35 http://pastie.org/684209

19:36 i know i could avoid the '() by checking (empty? .)

19:39 _ato: I think the problem there is going to be (last product)

19:40 that's going to be O(length(product))

19:40 Chousuke: esj: http://gist.github.com/226553

19:40 esj: _ato: yeah, coz its going to have to walk the length of the growing sequence each time

19:41 Chousuke: that's probably not perfect though :P

19:42 esj: Chousuke: that's really nice !

19:42 I was led astray by insisting on using a reduce

19:43 _ato: Chousuke: neat idea

19:43 esj: much to learn... thanks for the help.

19:44 Chousuke: well, the condensator is basically reduce (it reduces to reduce!) if the predicate is always true

19:44 though it also needs to check if coll actually has any items left.

19:46 sleep for me.

19:46 good night. :)

19:46 esj: another good idea. good night !

20:21 notallama: would parcomp be a better name for juxt? i noticed that the docstring says "name subject to change".

21:36 hiredman: http://gist.github.com/226651

21:36 gar

21:36 http://gist.github.com/226651 <-- appegine + facebook app

22:48 djork: man, I feel like this is cheating

22:48 (take 10 (fn [] (iterate #(.nextProbablePrime %) (bigint 3))))

22:48 ,(take 10 ((fn [] (iterate #(.nextProbablePrime %) (bigint 3)))))

22:48 clojurebot: (3 5 7 11 13 17 19 23 29 31)

22:49 djork: ,(nth ((fn [] (iterate #(.nextProbablePrime %) (bigint 1)))) 1000)

22:49 clojurebot: 7919

22:49 hiredman: ~cheating

22:49 clojurebot: I don't understand.

22:49 hiredman: clojurebot: clojure?

22:49 clojurebot: clojure is the best way to learn java

22:49 hiredman: clojurebot: clojure?

22:49 clojurebot: clojure is not scheme

22:49 hiredman: :|

22:49 clojurebot: clojure?

22:49 clojurebot: clojure is a language to use if you want to up your game

22:50 hiredman: clojurebot: clojure?

22:50 clojurebot: "[Clojure ...] feels like a general-purpose language beamed back from the near future."

22:50 hiredman: somewhere in there it says clojure is cheating

22:50 djork: hah

22:51 hiredman: clojurebot: clojure?

22:51 clojurebot: clojure > scheme

22:51 djork: clojure?

22:51 hiredman: clojurebot: clojure?

22:51 djork: oh

22:51 clojurebot: clojure is like life: you make trade-offs

22:51 djork: I trust you

22:51 hiredman: clojurebot: clojure?

22:51 clojurebot: clojure > scheme

22:51 hiredman: ok

22:51 hmmm

22:57 solussd: is there an alternative to (get-in coll [...]) that returns nil instead of a null pointer exception if the index is out of range?

22:58 im mapping it to a bunch of indices

23:00 chouser: get-in doesn't throw NPE for me.

23:03 solussd: youre right- i'm derefing a nil returned by get-in

23:03 thanks

23:04 djork: what's the best way to get a Java null

23:04 solussd: is there a != in clojure?

23:04 chouser: nil is null

23:04 solussd: e.g. #(!= nill %)

23:05 notallama: not=

23:05 chouser: ,(not= nil 5)

23:05 clojurebot: true

23:05 chouser: ,(nil? nil)

23:05 clojurebot: true

23:08 chouser: ~deftype

23:08 clojurebot: deftype is see datatype

23:09 chouser: ~datatype

23:09 clojurebot: datatype is see datatypes

23:09 chouser: ~datatypes

23:09 clojurebot: http://www.assembla.com/wiki/show/clojure/Datatypes

23:09 chouser: clojurebot: thanks! have a botsnack

23:09 clojurebot: thanks; that was delicious. (nom nom nom)

23:09 fatelang: ~..

23:10 gilbertleung: hi

23:11 i'm extending a class called "com.wowza.wms.module.ModuleBase" which has a protected static method called "getLogger"

23:11 chouser: gilbertleung: was it you that asked on the google group?

23:12 gilbertleung: yah

23:12 fatelang: Is it possible to .. inside a doto or otherwise call a method of a returned object? Something like (doto f (.. .method-of-f (method-of-returned-object args)) ...)

23:13 gilbertleung: to summarize, my question is: how can I call the parent's static method from a child instance?

23:13 chouser: gilbertleung: I'm not sure, but I think it may be impossible without writing some .java.

23:13 gilbertleung: did you try using gen-class's exposes-methods?

23:14 gilbertleung: chouser: nope, i didn't know there was such a thing

23:14 chouser: lemme read up on in the docs

23:14 chouser: gilbertleung: well, it's worth a try, but I'm afraid it may only work on instance methods.

23:15 hiredman: chouser: he could use wallhack!

23:15 gilbertleung: hiredman: what's that?

23:15 chouser: gilbertleung: listen to hiredman

23:16 it's ugly but you've got to do what you've got to do.

23:16 hiredman: gilbertleung: lemme find some code

23:16 gilbertleung: hiredman: aite

23:16 chouser: fatelang: did you try that? seems like it might work.

23:17 hiredman: http://gist.github.com/226726 wallhack-method

23:18 (wallhack-method some.class.Name :someMethod [Types Method Takes] nil arg1 arg2)

23:18 nil is for a static method, the object instance for a non-static method

23:22 gilbertleung: hiredman: could you clarify what would be passed into [Types Method Takes] ?

23:23 fatelang: chouser: What I tried and it error is at http://paste.lisp.org/+1XAR.

23:27 arohner: are there built in function for doing map and filter on maps?

23:27 i.e. map/filter on the keys/values of a map?

23:27 I feel like I'm missing something for writing my own

23:29 tomoj: I wish we had those too

23:30 arohner: ok, I'm not crazy. I already have map-keys, map-values

23:30 I'm writing filter-keys right now

23:30 I'll write a patch

23:30 tomoj: as it is you can (into {} (for [[k v] the-map] ...))

23:30 arohner: yeah, that's too verbose for me

23:30 tomoj: I don't think you can do anything much faster than that, realy

23:31 unless the map function is the identity in most places

23:31 arohner: I'm not looking for speed, just less typing and more readability

23:31 tomoj: what does map-keys do when two keys in the original map get mapped to the same key in the result?

23:32 arohner: what do you want it to do? :-)

23:32 right now it does whatever (apply hash-map seq) does

23:34 tomoj: would be unpredictable if the original hash-map is unordered

23:34 guess if you're going to map keys to the same thing you deserve what you get

23:35 arohner: yeah

23:35 don't do that :-)

23:37 gilbertleung: hiredman: anyways, thanks alot; i'll play round with it soon when my hands are not tied

23:40 arohner: hah: http://groups.google.com/group/clojure-dev/browse_thread/thread/4b20e40d83095c67#

23:40 hiredman: gilbertleung: it;s a vector of classes

23:40 if the method takes a string it would be [String]

23:42 _ato: ,(clojure.contrib.generic.functor/fmap inc {:a 1, :b 2})

23:42 clojurebot: {:a 2, :b 3}

23:42 gilbertleung: hiredman: great. Thanks alot!

23:46 _ato: arohner: before writing your patch, check out: http://groups.google.com/group/clojure-dev/browse_thread/thread/4b20e40d83095c67#

23:47 arohner: _ato: yeah, I just linked to it

23:47 I visited the dev group to post about writing my patch, and saw that

23:47 _ato: ah oops, missed that :)

23:48 arohner: not that it would really save me effort. I already have the fns written, because I need them now :-)

23:48 _ato: yeah, I meant more in the sense that there was some discussion going on about it

Logging service provided by n01se.net