#clojure log - Dec 01 2010

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

0:37 KirinDave: Huh, that's surprsing to me

0:38 If you say (map str (my-defrecord-thing. 1 2 3)), it says ([:a 1] [:b 2] [:c 3])

0:38 But

0:39 If you str that, it doesn't force it.

0:39 I guess because it's a lazy seq, but for some reason I had it in my head that if you str'd it'd force.

2:03 Raynes: &(str (lazy-seq [1 2 3]))

2:03 sexpbot: ⟹ "clojure.lang.LazySeq@7861"

2:06 Licenser: Raynes: yes that is annoying

2:06 Raynes: Not really.

2:06 Licenser: yes really :P

2:06 Raynes: &(pr-str (lazy-seq [1 2 3]))

2:06 sexpbot: ⟹ "(1 2 3)"

2:07 Raynes: It's only annoying if you don't know that it will happen :p

2:07 Licenser: no that just makes it barable

2:07 str of a lazy seq sgould not return some crazy object stuff

2:07 &(str '(1 2 3))

2:07 sexpbot: ⟹ "(1 2 3)"

2:08 Raynes: &(str #'str)

2:08 sexpbot: ⟹ "#'clojure.core/str"

2:08 Raynes: &(str (fn []))

2:08 sexpbot: ⟹ "sandbox4199$eval6337$fn__6338@1bcaa83"

2:08 Licenser: well worky worky time

2:09 Raynes: You work too much.

2:09 cpfr: is this good form for defining local functions? (defn foo [x] (defn bar [y] (+ y y)) (bar x))

2:09 Licenser: cpfr: look into letfn

2:09 Raynes: yes I got promoted :P

2:10 cpfr: Licenser, so always use let forms for local values?

2:10 never use def

2:10 Licenser: *nods*

2:10 that is the essence yes

2:10 Raynes: cpfr: (let [bar (fn [y] (+ y y))])

2:11 cpfr: let names values within the scope of the let. def defines a global var.

2:11 Licenser: (letfn [(bar [y] (+ y y)] (bar x))

2:11 cpfr: Raynes, bar doesn't seem to be leaking into the global context in my repl

2:12 Licenser: &(letfn [(bar [y] (+ y y)] (bar 2))

2:12 sexpbot: java.lang.Exception: Unmatched delimiter: ]

2:12 Licenser: &(letfn [(bar [y] (+ y y))] (bar 2))

2:12 sexpbot: ⟹ 4

2:12 Licenser: there we go

2:12 anyway I'm off see you later

2:12 clojurebot: It's greek to me.

2:13 koning_robot: has compojure.http.helpers been taken out? or do I need some other package than just compojure?

2:16 Raynes: cpfr: https://gist.github.com/723101

2:17 cpfr: Raynes, odd but alright let for local

2:18 too much scheming I suppose

2:18 Raynes: letfn works fine as well, as Licenser alluded to.

2:18 cpfr: well I want use letfn only for letrec situations

2:18 Raynes: letfn is actually your only option for mutually recursive local functions, IIRC.

2:20 hiredman: trampoline is the clenched fist in the gauntlet of letfn

3:34 lenw: hi all

3:35 how do i return the first match of one of the values in a vector with the values in another vector

3:36 ie (some-func ["t" "r"] ["x" "r") should give back "r"

3:36 (some-func ["t" "r"] ["x" "r"])

3:36 Raynes: lenw: Do they have to be at the same index?

3:37 lenw: cant seem to think about that in a functinal way and keep getting confused

3:37 no any match is good

3:37 like contains? but with values

3:38 (some-func ["r" "t"] ["x" "r") => "r"

3:41 Raynes: lenw: Will either one of these vectors ever contain duplicate elements?

3:42 lenw: its possible - they are lists of email adresses and users can do the most interesting things

3:46 Raynes: lenw: I came up with: (defn matches [v1 v2] (some #(some #{%} v2) v1))

3:47 user=> (matches ["r" "t" "y"] ["x" "y" "r" "e"])

3:47 "r"

3:47 lenw: Raynes: cool that looks neat - i had not got to nested some !

3:47 hoeck: lenw: sounds like you want a union of those two vectors

3:48 lenw: hoeck: yes !

3:48 Raynes: I was thinking that you could just turn the vectors into sets and union them.

3:48 hoeck: ,(clojure.set/union (set [:r :t]) (set [:x :y :r]) )

3:48 clojurebot: #{:r :y :x :t}

3:48 hoeck: damn, I meant a difference :P

3:49 ,(clojure.set/intersection (set [:r :t]) (set [:x :y :r]) )

3:49 clojurebot: #{:r}

3:49 hoeck: intersection, always getting those wrong

3:49 Raynes: hoeck: I forget those things all the time. :<

3:49 hoeck: at least I know the concepts :)

3:49 Raynes: Indeed.

3:49 lenw: thank hoeck thats goos stuff to know

3:50 Raynes: &(set ["a" "a"])

3:50 sexpbot: ⟹ #{"a"}

3:50 Raynes: That is why I tried to avoid sets in this case.

3:50 bartj: I get a wrong number of arguments to concat in the code

3:50 Raynes: But it doesn't really matter just to check for matches.

3:51 hoeck: Raynes: I can't count the times where I have read some complicated code that in fact does just some sort of set operations

3:51 bartj: but, no matter what I try during tests, it shouldn't happen because concat works without any arguments too!

3:51 , (concat)

3:51 clojurebot: ()

3:51 Raynes: hoeck: Yeah, I've been making tons of use of the set namespace lately.

3:54 raek: ,(some (set ["t" "r"]) ["x" "r"])

3:54 clojurebot: "r"

3:54 bartj: anyone?

3:54 clojurebot: Please do not ask if anyone uses, knows, is good with, can help you with <some program or library>. Instead, ask your real question and someone will answer if they can help.

3:55 bartj: clojurebot is your comment directed at me?

3:55 hoeck: bartj: can you gist the offending code?

3:55 Raynes: It's an automated response. Ignore him.

3:55 raek: ignore clojurebot in this case. you already asked a concrete question.

3:56 bartj: do you have a gist of the stacktrace?

3:56 bartj: Wrong number of args (2) passed to concat

3:56 raek: ...or a paste of the code?

3:59 bartj: I am afraid I can't paste the code

3:59 (concat list sorted-set)

3:59 raek: ,(concat (list 1 2 3) (sorted-set 1 2 3))

3:59 clojurebot: (1 2 3 1 2 3)

4:00 bartj: raek, yes, it works in test

4:00 raek: bartj: what does (resolve 'concat) return?

4:01 Raynes: Sounds like concat isn't what it should be.

4:01 bartj: whoops!

4:01 I have a user-defined function called concat

4:01 Raynes: Indeed. That'll do it!

5:09 $seen fliebel

5:09 sexpbot: fliebel was last seen quitting 11 hours and 10 minutes ago.

5:09 Raynes: 'bout due for some fliebel action.

5:15 fliebel: morning

5:16 Raynes: Hah!

5:16 <Raynes> $seen fliebel

5:16 <sexpbot> fliebel was last seen quitting 11 hours and 10 minutes ago.

5:16 <Raynes> 'bout due for some fliebel action.

5:16 That 5 minutes ago.

5:16 :)

5:17 fliebel: I just saw your pull request

5:17 I'm reading now

5:32 Raynes: I'm all for it :) Though it seems it's harder now, or I'm just sleepy :(

5:32 Raynes: fliebel: It's much harder now. :p

5:33 The confusing parts are related to avoiding duplicates and removing questions once they've been answered so that the quizes aren't infinite.

5:33 fliebel: oh, the multiple choice ones are indeed harder, but I was doing name-quiz

5:34 Raynes: Oh, you mean the quizes.

5:34 D'oh.

5:34 fliebel: yea :P Last time I tried I had like 70%, now I got 50%

5:34 Raynes: I haven't gone through an entire name-quiz yet.

5:34 I'm scared. :p

5:34 fliebel: But yea, the code is also somewhat more complicated.

5:35 Raynes: I didn;t do 100 of them either

5:35 Raynes: Well, you couldn't before. The quizes never ended!

5:35 :p

5:35 fliebel: Raynes: Last time I discovered another gem, just as beautiful as the subs thing.

5:35 Raynes: Oooh, do tell!

5:37 fliebel: &(doc memfn)

5:37 sexpbot: ⟹ "Macro ([name & args]); Expands into code that creates a fn that expects to be passed an object and any args and calls the named instance method on the object passing the args. Use when you want to treat a Java method as a first-class fn."

5:37 Raynes: Oh. That has been deprecated for quite a while.

5:37 It predates anonymous functions, and they are generally what should be used these days.

5:38 fliebel: Oh :( I quite liked the idea of creating first class functions out of java methods.

5:38 Raynes: &(meta #'memfn)

5:38 sexpbot: ⟹ {:macro true, :ns #<Namespace clojure.core>, :name memfn, :file "clojure/core.clj", :line 2949, :arglists ([name & args]), :added "1.0", :doc "Expands into code that creates a fn that expects to be passed an\n object and any args and calls the named instance method ... http://gist.github.com/723312

5:40 Raynes: Odd. I guess it isn't officially deprecated. People have been telling other people that it was and to not use it since I started with Clojure, nearly two years ago.

5:41 fliebel: So what would you do instead?

5:42 Raynes: You'd use a lambda. #(.toLowerCase %)

5:43 harishtella: Does anyone have tips on debugging clojure? Its hard to debug when i get a single line error with just "cant cast sequence to Ifn" or something like that. I wish clojure could give me a stack trace always. Is the best way to just test each function individually?

5:44 fliebel: True… Though I don't like the idea, and use real functions when possible. memfn would go nicely with partial, comp and juxt.

5:45 Raynes: harishtella: In an REPL, when it only prints a single line you can do (.printStackTrace *e) to see the stacktrace.

5:45 fliebel: harishtella: (.printStackTrace *e) on the repl will give you one

5:45 oh to slow :(

5:45 Raynes: *e is always bound to the last stacktrace.

5:46 fliebel: $sed Raynes s/stacktrace/exception/

5:46 sexpbot: <> $sed Raynes s/exception/exception/

5:46 fliebel: hrm

5:46 harishtella: on snap, so much time wasted, lol, thanks

5:46 Raynes: fliebel: $sed -Raynes ...

5:46 harishtella: You're welcome. :(

5:46 :)*

5:46 * Raynes yawns

5:47 Raynes: fliebel: $sed is a weird command that takes weird options. I've been meaning to make improve it's weirdness.

5:51 fliebel: Raynes: What do you think about sexpbot + qlojure-quiz? For some competitive multiplayer goodness :) I could probably make that somewhere in the next 10 years… :(

5:52 Raynes: fliebel: That could be interesting. We could even make a special channel for it.

5:54 * fliebel checking reusability of clojure-quiz

6:04 Raynes: fliebel: *number* could possibly be *answers*.

6:04 *target* could maybe be *namespace*, but I haven't given it much thought. *number* is pretty unintuitive now though.

6:04 Since it can be rebound.

6:05 cemerick: Morning Mr. Emerick.

6:09 cemerick: Morning.

6:09 Grump. :-P

6:10 Raynes: fliebel: One thing I'll note: This application, however simple, will be a very, very useful tool for people in the future. I can't think of a funner way to familiarize oneself with APIs than with clojure-quiz.

6:10 Thanks for writing it. <3

6:11 cemerick: Have you ever used posterous?

6:12 I've been considering migrating my blog to either it, wordpress.com, tumblr, or something similar.

6:12 Just for the sake of not having to host it myself. I can't think of any good reason to.

6:17 cemerick: Raynes: I used it for a week or so. wordpress.com is superior in every way AFAICT.

6:18 Raynes: cemerick: I figured that. Is it relatively easy to migrate a self-hosted blog to wordpress.com?

6:18 cemerick: WP.com has supported Clojure highlighting, which is a pretty big deal, but there's lots of other advantages too

6:19 Raynes: looks like there's an import function in the admin console; sucks in wordpress .wxr files?

6:19 presumably something that you can generate from a local install.

6:20 Raynes: Neat. I'll check that out.

6:27 cemerick: Raynes: if you do join up, you can plug a bug for me :-P

6:27 Raynes: cemerick: ? :o

6:29 cemerick: Raynes: Their smiley replacement is unfortunately affecting code blocks: http://cemerick.com/2010/05/12/provisioning-administration-and-deployment-of-couchdb-java-tomcat/

6:30 Raynes: I turned off smiley replacement in my local install. You can't do that in a hosted wordpress? O.o

6:30 cemerick: They've fixed other issues I've raised in short order, but that's persisted. I presume it's just a rare enough case as far as they're concerned.

6:30 Yeah, you can.

6:31 I guess I hate compromising.

6:31 Especially when I'm not paying any money for something. :-P

6:31 Raynes: :P

6:32 cemerick: oh, actually, I guess I do pay them some small amount for the top-level domain mapping.

6:32 Raynes: Ew. They charge for that?

6:33 cemerick: Yeah. One of the few things they do charge for.

6:33 Posterous is the same IIRC.

6:33 Raynes: I haven't really looked into either yet.

6:33 I'll probably just continue to self-host in that case.

6:33 I've moved everything to a Linode, so stability shouldn't be a problem anymore.

6:34 $shell uptime

6:34 sexpbot: 03:34:37 up 2 days, 13:23, 1 user, load average: 0.02, 0.02, 0.00

6:34 Raynes: Two whole days so far!

6:34 cemerick: I'm so done with any kind of sysadmin.

6:35 Raynes: http://blog.selflanguage.org/2010/12/01/first-introspection-2010-12/ This post is very well written.

6:35 cemerick: I still have one box that isn't under proper automated admin.

6:35 Every time I log in there, the pain is tangible.

6:36 Raynes: The only thing that I've yet to automate on crisis is the startup of znc and sexpbot.

6:52 accel: Is there any clojure library / app that can do WYSIWYG math editing? (Like Realtime TeX)

7:12 bsteuber: accel: some java stuff is listed on http://en.wikipedia.org/wiki/Formula_editor, but I don't think anyone did it in clojure itself

7:17 accel: ya, was looking at that, pity the only really nice one is TeXmacs, which is C++ + guile

7:17 someone ought replae the C++ part with Java and the Guile part with Clojure

7:18 Raynes: Or replace the C++ part with Clojure and the Guile part with Clojure.

8:37 chouser: ugh, race condition leading to deadlock

8:38 rhickey: where?

8:38 clojurebot: where is log

8:39 chouser: rhickey: in my own code. Needed to add a feature to a BlockingQueue, did it with an atom, got burned. :-P

8:39 rhickey: ah

8:39 chouser: is there an existing blocking queue that has the concept of reaching the end of the input and becoming "closed"?

8:42 raek: chouser: http://clj-me.cgrand.net/2010/04/02/pipe-dreams-are-not-necessarily-made-of-promises/ and https://github.com/raek/stream-seq/blob/master/src/se/raek/stream_seq.clj#L123

8:43 the latter is my own rather hackish try to get a closable LinkedBlockingQueue

8:44 I wrote it during the summer and I would probably not implement it exactly like that if I would write it today

8:45 Islon: I just learnt that you have to :import and not :use a defrecord...

8:45 raek: cgrand's blog post basically obsoletes my whole lib...

8:49 chouser: yeah, I knew of his post, as well as fill-queue in contrib and seque in core

8:49 but none of them are sufficient, at least as they are.

8:50 I need to be able to poll the queue without blocking and know whether or not I reached the end

8:53 Raynes: Aw man. I can't find my key. :<

8:54 Islon: That's because a defrecord is just a Java class.

8:55 &(find-my-keys)

8:55 sexpbot: java.lang.Exception: Unable to resolve symbol: find-my-keys in this context

8:55 Raynes: The one thing that Clojure can't do for me. :<

8:57 rhickey: chouser: terminable queues are almost always done with 'poison' messages

8:58 chouser: rhickey: yeah. for good reason, as I see here staring at the inevitably complex coordination of two separate mutable things

8:59 rhickey: right

8:59 chouser: Maybe more careful use of a final non-blocking poll will be sufficient.

9:01 Raynes: chouser: Do you happen to know when the last time you somehow dropped from IRC was?

9:01 Don't think I've ever seen you not here at any given time.

9:03 I remember you asking me if sexpbot's logging would more stable than your irssi a while back, and I told you no. I've moved it to a lovely Linode, so, server Gods willing, I should have pleasant uptime from here on out.

9:05 chouser: Looks like I rejoined 2010-11-27.log:14:02, 2010-11-20.log:08:14, 2010-11-17.log:00:36, 2010-11-16.log:04:22, etc...

9:07 Raynes: I hereby declare War of the Logs.

9:07 chouser: I concede

9:07 Raynes: :p

10:05 fliebel: Morning! Thanks to UGT I can now have as many mornings as I want.

10:05 hoeck: fliebel: Morning, me too :)

10:07 Raynes: That's all folks! Final score: Right: 65, Wrong: 35, Percentage: 65

10:07 fliebel: ^ I'm so ashamed. x_x

10:07 Those damned atom questions got me.

10:08 fliebel: Raynes: I usually lose points on interop. proxy and such.

10:08 And of course silly typos and a missing !

10:09 I will try a full run and report...

10:09 Raynes: That 100 run took a while.

10:09 You can do 50 if you bind *number* to 50.

10:09 fliebel: I know, but that is cheating.

10:10 Raynes: Hehe

10:12 fliebel: Can I peak at the docs? :D

10:14 raek: is this some kind of clojure quiz?

10:14 fliebel: yea

10:14 raek: is it oline?

10:14 fliebel: http://github.com/pepijndevos/clojure-quiz

10:16 Oh, these kill me… rest or next returns nil, can't remeber which one

10:16 wrong :(

10:17 raek: which one of the quizes are you doing? :)

10:18 fliebel: name-wuiz

10:18 *quiz

10:21 raek: the answer to the first question was replicate. I answered repeat....

10:22 fliebel: Hrm, Are those * fns public? It asked for with-bindings*

10:24 These also feel unfair: find-namespace Incorrect! Was: find-ns

10:27 ouch, I'm falling below 50%, due to a lot of small differences, like select vs select-keys and => vs <

10:28 s/50/60/

10:28 sexpbot: <fliebel> ouch, I'm falling below 60%, due to a lot of small differences, like select vs select-keys and => vs <

10:40 raek: heh, this is fun :)

10:40 fliebel: what's your score?

10:40 raek: it would be very nice to have a web-based version of this

10:40 Raynes: raek: Are you running the latest checkout?

10:40 raek: I haven't played a whole round yet

10:41 fliebel: raek: I'm thinking of adding it to sexpbot or tryclojure

10:41 raek: I just looked at it while my code was compiling

10:41 since it was C++, I had plenty of time

10:42 Raynes: fliebel: You could do that. If you wanted, you could even make it into a standalone web application and I'd be happy to host it for you at clojure-quiz.raynes.me or similar. <3

10:43 fliebel: Whatever is best. I could easily take moustache and ring and make you some, btu tryclojure is already a place to play and leanr clojure.

10:44 Raynes: tryclojure would be an excellent place for it if you can figure it out. I'm cool with it either way.

10:44 fliebel: I never looked at it.

10:45 Damn, telling reverse/rseq, rest/next, etc is hard :(

10:46 Raynes: I knew next over rest because next can return nil while rest always returns a seq.

10:46 fliebel: I knew one of them did this...

10:47 and reverse/rseq has something in constant time.

10:47 btu which one...

10:48 Right: 64, Wrong: 36, Percentage: 64

10:48 Raynes: Quite close to yours

10:48 Raynes: "?

10:48 :>*

10:50 fliebel: I wonder how raek is doing… We really need a score board.

10:52 raek: I'm compiling again, so I guess I could give it a try... :-)

10:55 * raek (name-quiz)

11:03 Chousuke: hmm, doc-quiz is too easy :P

11:03 jaley: hi guys, question on persistent structures and memory usage: when are copies or new instances created? will the hash-map, sorted-map, function always create a full copy of the original data?

11:06 Chousuke: jaley: hash-map and sorted-map are constructors so they can't make use of structural sharing, but remember that all objects are stored by reference, not by value.

11:07 jaley: the "modifying" operators however do share structure with the original object

11:07 original data structure, rather

11:08 jaley: Chousuke: cool. so the size of (apply hash-map (map some-fn other-collection)) is going to be size-of-ref * size-of-collection, probably?

11:09 Chousuke: not sure what you mean by that.

11:09 jaley: Chousuke: well I just mean create a map from a collection of strings, for example, there will be no more copies of the strings, just references to them

11:09 Chousuke: there's also some overhead from the actual data structure

11:09 That's correct.

11:10 jaley: Chousuke: awesome, thanks. bang goes that theory on why my app is using >100mb of heap then

11:10 Chousuke: jaley: you might be holding onto a lazy seq somewhere

11:10 preventing it from being gc'd

11:11 also any substrings you might use prevent the parent string from being gc'd IIRC

11:11 jaley: Chousuke: oh that's interesting. I'm using a webservice that returns a massive mangled string that i have to split up

11:12 Chousuke: hmm

11:12 sounds like you might be holding onto the entire string if you're using substrings.

11:15 jaley: perhaps... i'll use a profiler and see what object types are occupying the heap, if i can do that somehow.

11:15 Chousuke: Clojure should work just fine with Java profilers

11:16 raek: fliebel: Raynes: "That's all folks! Final score: Right: 72, Wrong: 28, Percentage: 72"

11:16 jaley: Chousuke: cool. thanks for your advice, I'll have a look around for a profiler

11:17 _na_ka_na_: hey guys any idea how to avoid reflection on this piece of code

11:17 (defn d [coll] (java.util.Arrays/sort (into-array Object coll)))

11:17 (defn d [coll] (java.util.Arrays/sort (with-meta {:tag "[Object;"} (into-array Object coll))))

11:17 ^ doesn't work

11:18 raek: with-meta takes the args in the opposite order

11:18 also, you need to add metadata to the code that the complier receives

11:18 not to the value in runtime

11:19 _na_ka_na_: is it the java.util.Arrays/sort call it has to use reflection for?

11:19 _na_ka_na_: raek: yes

11:20 raek: you are right about with-meta, reversing the order didn't help either

11:22 cemerick: _na_ka_na_: you want: (Arrays/sort ^"[Ljava.lang.Object;" a)

11:23 raek: ah, the "L"... that's why my test in my repl didn't work...

11:23 cemerick: yup, array-of :-P

11:24 _na_ka_na_: cemerick: thanks it works! (defn d [coll] (java.util.Arrays/sort (let [^"[Ljava.lang.Object;" arr (into-array Object coll)] arr)))

11:24 any easier way to write ^

11:24 Chousuke: ^objects ?

11:24 KirinDave: Yeah doesn't ^objects work?

11:25 cemerick: Oh, sure; I figured the Object hint was just a placeholder… :-/

11:25 KirinDave: Every time I see the underlying notation I cringe. :\

11:25 _na_ka_na_: ya its a placeholder

11:25 but I mean easier way as in w/o the let

11:26 it looks ugly

11:26 cemerick: Right, so if you actually have an array of com.foo.Bar, then you really do need to use the string/hosty hint notation.

11:26 KirinDave: I can't help but think there is syntax missing there.

11:27 _na_ka_na_: this also seems to work

11:27 (defn d [coll] (java.util.Arrays/sort ^"[Ljava.lang.Object;" (into-array Object coll)))

11:27 KirinDave: That in meta decls, (array-of my.class.Name) sort of thing?

11:27 _na_ka_na_: is that syntax correct?

11:27 cemerick: _na_ka_na_: yes, that's fine

11:27 _na_ka_na_: cemerick: hmm, many thanks

11:29 bsteuber: does anyone have pointers for using clojure-1.3.0-alpha3 with swank?

11:29 cemerick: KirinDave: the :tag metadata slot can only be a string naming a class in full or a symbol naming a class imported in the current ns, IIRC.

11:29 KirinDave: cemerick: Right, but that could always be generated.

11:30 cemerick: I think the bigger problem with that oh-so-reasonable suggestion is that clojure is not a world where lexically scoped syntax extensions are the norm, or popular.

11:30 cemerick: There's a library to do it, but I have only seen that in use in the wild a half-handfull of times

11:33 cemerick: True enough…though I think we're better off for it.

11:33 KirinDave: The common lisp guys would disagree with you.

11:34 cemerick: heh, on larger things than this! :-P

11:34 The case here is an odd one, insofar as nonprimitive and non-Object arrays are relatively rare.

11:34 KirinDave: I can see the logic for not allowing symbol macros. The logic of not allowing macrolet does confuse mea little.

11:34 cemerick: Indeed.

11:35 cemerick: Some flavour of the latter is in the works, or so I heard rumored.

11:35 KirinDave: That's good. The real place I've seen macrolet used is inside of macros.

11:35 So cemerick, in line with our conversation last night, I've been thinking hard about protocols.

11:36 And I remembered a question someone on hn asked me about protocols I had mentally shelved.

11:36 jweiss: is there a recommended way to access protected fields of a java class?

11:36 KirinDave: Specifically, someone asked, "How does one go about using the current protocol system to extend existing classes? Can you?"

11:37 cemerick: jweiss: see the fns in clojure.reflect.java

11:37 KirinDave: I think he meant to ask, for example, how one might make a case insensitive string Map or something else like that

11:37 Where there is only an incremental difference from a parent class.

11:39 cemerick: KirinDave: Protocols can't override or otherwise impact the behaviour of an existing class' implementation.

11:39 KirinDave: cemerick: Right.

11:39 cemerick: So youd probably start by using a has-a relationship

11:39 cemerick: Make an internal field carrying a map and try to incercept mappy calls

11:39 cemerick: One can extend a protocol such that it will dispatch as you like for a given type, with an implementation of the fn/method in question.

11:39 KirinDave: Right

11:40 cemerick: Yeah, it's a job for proxy.

11:40 KirinDave: Oh? I didn't know proxy could operate on protocols.

11:40 cemerick: Protocols have no hand in the task at all.

11:41 Talking about changing behaviour of some extension of a concrete class and defining abstractions that can be extended to existing types never meet.

11:41 KirinDave: cemerick: Oh, I'm sorry... let me clarify. This is in the hypothetical world where protocols and types rule the roost in joint benevolence with multi-methods.

11:41 In other words, thought-experiment land.

11:41 cemerick: But, proxy can certainly participate in protocols by implementing the interfaces they generate.

11:42 KirinDave: In other words, this is thought-experiment land. )

11:43 Do you need behavior inheritence elsewhere in addition to these tools 1.2 provides, or are they sufficient on their own.

11:44 cemerick: So, if there was a Map *protocol* (rather than simply j.u.Map and c.l.IPM right now), then you could extend the get, assoc, etc fns in that protocol to your concrete existing class and get string-insensitivity on lookups, etc.

11:44 KirinDave: Right

11:44 Seems like that's a lot of work for incremental changes.

11:45 You couldn't really just do a little bit of it;

11:45 You'd have to do all of it

11:45 cemerick: Right.

11:45 Implementing core abstractions (like maps, seqs, etc) in terms of protocols is definitely on the drawing board, and it will make a *lot* of fantastic stuff possible, including the above scenario.

11:45 KirinDave: Right

11:45 I wonder if there is another structure though.

11:45 cemerick: Not in the near (or even potentially medium-) term though.

11:46 That's why I mentioned proxy.

11:46 KirinDave: A behavior, like scala traits. I understand that this is kinda against charter (which I read over again carefully)

11:46 At the very least, I've got something nearly done for clothesline that lets me write a default behavior

11:46 jfields: ,(get-in {:a :b :c :d} nil)

11:46 clojurebot: {:a :b, :c :d}

11:46 cemerick: If you're really just subclassing an existing impl, proxy will let you do the same sort of gruntwork that hosty subclassing allows.

11:46 KirinDave: Doing so was a surprisingly big job

11:46 jfields: really? get-in with nil returns all the elements?

11:47 KirinDave: For one, you have to make both a static and dynamic version of the behavior.

11:47 cemerick: jfields: as opposed to?

11:47 jfields: ,(get {:a :b :c :d} nil)

11:47 clojurebot: nil

11:48 jfields: that's what I'd expect from get-in as well.

11:48 raek: ,(get-in {:a :b :c :d} [])

11:48 clojurebot: {:a :b, :c :d}

11:49 raek: well, it "follows" zero keys into the structure...

11:49 Islon: where's the "join" or "str-join" function in clojure 1.2?

11:49 cemerick: jfields: Not sure I follow the expectation. get returns the value mapped to the given key. get-in expects a seq of keys; if you provide it with none, then it gives you what it has.

11:49 raek: Islon: clojure.string

11:50 cemerick: Islon: there's also just (apply str …) *shrug*

11:50 raek: (require '[clojure.string :as str]) (str/join ....)

11:50 jfields: cemerick, it makes sense, but I don't think it's the most obvious result.

11:51 Islon: thanks, i googled it and found lots of different stuff and namespaces

11:51 KirinDave: cemerick: It might be because #(let [something-outside nil] (get-in {:a :b :c :d} nil ::not-found))

11:51 Oh, I thought there was a bot listening for #()

11:51 ,(let [something-outside nil] (get-in {:a :b :c :d} nil ::not-found))

11:51 clojurebot: {:a :b, :c :d}

11:51 KirinDave: That can be a surprising result if it's nested deep in some code and client code passes you something you don't expect

11:51 raek: ,(let [m {:a {:b {:c 0}}}] [(get-in m [:a :b :c]) (get-in m [:a :b]) (get-in m [:a]) (get-in m [])])

11:52 clojurebot: [0 {:c 0} {:b {:c 0}} {:a {:b {:c 0}}}]

11:52 raek: I think it follows a clear pattern

11:52 cemerick: KirinDave: the not-found value isn't involved here

11:52 KirinDave: cemerick: Right.

11:53 cemerick: That's the only place where I think it might be surprising, tho.

11:53 cemerick: oh, I see what you're saying

11:54 KirinDave: The way the docs are written suggests that not-found-val will come up.

11:54 cemerick: eh, only if a given key isn't present

11:54 if you don't provide any keys, then…

11:54 raek had the progression right

11:54 joly: all (0) provided keys are present

11:55 cemerick: But then, I'm mostly alone in not really having any issue with Clojure's existing docs. :-P

11:56 KirinDave: No I agree with raek. But I also have been bitten by expecting default values when they were not actually applicable.:)

12:03 jaley: what's the "same instance" equality test?

12:04 (i mean which function)

12:07 cemerick: jaley: you probably mean identical?

12:08 jaley: cemerick: that's the one, thanks

12:36 raek: fliebel: Raynes: regarding webification of clojure-quiz, I guess 'quiz' is what needs to be replaced, correct?

12:38 or are any of you working on this now?

12:42 jweiss: i am using leiningen checkouts directory to add a dependent project. but my classpath only includes checkouts/dep/classes, not checkouts/dep/lib/*

12:42 any suggestion what might be wrong

12:42 technomancy: jweiss: no, that's correct

12:43 the checkouts dir isn't meant to replace :dependencies in project.clj; just to augment it.

12:44 jweiss: technomancy: hm, so is there some other way to get the deps in my project other than listing all the dep's deps?

12:44 technomancy: yeah, just add it to :dependencies like usual

12:45 joegallo: jweiss: that is, you have a dependency on a, and it also happens to be a checkout.

12:45 oconnore: How do I initialize a templated java class? All the java interoperability examples I can find are too simplistic. For example, (new ArrayList<Integer>) doesn't work.

12:45 jweiss: i don't think i've ever added a project as a dependency before, just libs from repos

12:47 technomancy: there's really no difference

12:48 if the project hasn't been uploaded to a public repo then you'll need to "lein install" it first; that's all

12:50 jweiss: technomancy: ah ok that is the step i was missing, thanks

12:56 oconnore: anyone?

12:56 clojurebot: Please do not ask if anyone uses, knows, is good with, can help you with <some program or library>. Instead, ask your real question and someone will answer if they can help.

12:56 oconnore: Dear clojurebot, I already did that you cheeky bastard :P

12:57 jfields: oconnore, if you want an ArrayList just use (ArrayList. )

12:58 afaik, clojure doesn't really provide support for generics

12:58 Chousuke: generics don't matter to clojure since it does no static checking anyway.

12:58 raek: oconnore: generics is checked when java code is compiled. at the JVM level, there is only ArrayList<Object>

12:59 jfields: oconnore, if you know the size and it doesn't shrink or grow you can also look at http://clojure.github.com/clojure/clojure.core-api.html#clojure.core/int-array

13:00 hiredman: oconnore: you should also do some reading so next time when you ask you can use the real name of that language feature instead of just guessing

13:00 jfields: oconnore, or you can look at http://clojure.github.com/clojure/clojure.core-api.html#clojure.core/make-array

13:02 replaca: hiredman: did you see that clojurebot was spewing nulls into the channel when checkins to clojure or clojure-contrib happen?

13:02 oconnore: ok, thanks for your help everyone

13:02 hiredman: replaca: yes, turned it off until I get time to investigate

13:05 fliebel: raek: Nice score. Nope, I'm not working on it.

13:05 replaca: hiredman: cool. just wanted to make sure you knew

13:06 hiredman: yep, thanks

13:15 benzen: hi guys

13:15 i've got a issue with the core template functions

13:16 can some one help me?

13:16 chouser: what functions in core are for templates?

13:17 benzen: i would like to use apply-template

13:17 chouser: is that in some lib? I don't see it in clojure.core

13:17 benzen: but i've got this message java.lang.Exception: Unable to resolve symbol: apply-template in this context

13:18 sorry it's in clojure.template

13:19 chouser: try this first: (use '[clojure.template :only [apply-template]])

13:21 benzen: thanks

13:21 effectivelly it work

13:21 works

13:22 an other question

13:22 I've red that it's better to use ":use" inside the ns macro over the use function/macro

13:23 chouser: sure, at the top of the file.

13:23 raek: that is where you usually put it

13:23 benzen: can you explain why it 's better please

13:25 raek: benzen: if you have a (:use ...) in your ns form it expands to a (use '...)

13:25 so they are equivalent

13:25 chouser: it's more declarative, gives you a tidy place to put all such declarations so that people and tools can find it easily

13:25 benzen: ok thanks

13:27 I,ve some diffculty to understand the ns macro

13:27 Do you know a place where it's well explained

13:27 I've seen the official api doc, but it's still some what vague to me

13:28 maybe a blog

13:28 raek: clojure.org/libs is a start

13:28 benzen: ah nice

13:29 one more time thanks

13:29 raek: 'require' makes sure that a namespace is loaded. 'use' does what require does + vars in that ns can be used without a namespace prefix

13:30 (you can always refer to a var (after it has been load) with a fully qualified symbol: clojure.core/conj)

13:31 require and use takes options

13:31 (:require foo.bar) = (:require [foo.bar])

13:32 (require [foo.bar :as fb])

13:32 benzen: you gave me good reading, i'll work on that

13:44 Raynes: raek: I'm not doing anything with it.

13:44 I'm about to pass out. I've been awake 21 hours.

13:47 LauJensen: Raynes: My record is wednesday morning at around 08:00, to monday late afternoon at about 18:00 :)

13:49 Raynes: I don't think I've ever surpassed 48 hours without being taken over by narcolepsy and hallucinations.

13:51 LauJensen: Odd. I was about your age actually. But get some sleep buddy, we'll code tomorrow :)

15:06 joshua__: How would you go about wrapping one function in a function returned by another function in clojure? Like: (create-new-function function) would be able to pass all the args to function. Really this is more about how to pass arguments than anything else.

15:08 tonyl: you could use & and apply like this (defn create-new-fn [f & args] (apply f args))

15:08 every argument passed after f (signaled by &) would be a vector of the arguments so apply would do the rest

15:09 joshua__: I mean more like.. create-new-func returns a function wrapped in another function.

15:10 Now how do I make sure that the wrapping function passes the aruments to the first function? Can you do something like (fn [& args] (apply func-from-closure args))

15:11 dnolen: (fn [f] (fn [& args] (apply f args)))

15:11 tonyl: like this? (defn make-fn [f & args] (fn [] (apply f args)))

15:12 joshua__: dnolen thank you that looks like what I'm talking about.

15:12 tonyl: dnolens example seems much closer.

15:14 Okay next question.. given (fn [f] (fn [& args] (if condition (apply f args) (recur args)))) would recur on the inner function right?

15:14 sandGorgon: are there any examples of web applications (source code I mean) written in clojure - I know of "cow-blog". It would be nice to see something using various components like Sandbar (for authentication), Enlive (for templating), etc.

15:15 tonyl: joshua__: yes, the inner fn takes preference

15:15 joshua__: alright, and its fine to pass in args? You don't need something like (apply recur args)

15:16 brehaut: sandGorgon: laujensen's site is on github

15:16 sandGorgon: it uses enlive

15:16 sandGorgon: https://github.com/LauJensen/bestinclass.dk

15:16 sandGorgon: brehaut, thanks!

15:17 brehaut: sandGorgon: no worries

15:17 LauJensen: sandGorgon: Check out admin.clj for most of the backend logic

15:17 tonyl: joshua__: no recur only needs the loop bindings or fn arguments, in this case the arguuments

15:17 sandGorgon: LauJensen, will do .. thanks!

15:17 Raynes: http://github.com/Raynes/tryclojure is a simpler example.

15:17 brehaut: sandGorgon: have you seen dnolen

15:18 s enlive tutorial?

15:18 joshua__: https://github.com/jColeChanged/mysite this is written in clojure, but by me so it is going to be really really bad.

15:18 sandGorgon: brehaut, yep

15:19 joshua__, thanks all the same ;)

15:19 brehaut: joshua__: have you realised you've been commiting your emacs backups?

15:19 joshua__: sites location is here: http://jcolessite.appspot.com/

15:20 I haven't learned how to stop that yet =p

15:20 if you read the current commit that is actually what I'm talking about..

15:20 partially

15:20 brehaut: joshua__: http://www.kernel.org/pub/software/scm/git/docs/gitignore.html

15:21 joshua__: Might as well ask the other related question. Lets say I've deleted a file, but didn't delete it by doing git remove filename.. how do I remove it now?

15:22 brehaut: git rm filename

15:22 Raynes: joshua__: https://gist.github.com/724148

15:22 brehaut: git figures out what you meant

15:23 Raynes: joshua__: That'll push all future backup files to ~/.saves

15:23 Which is a much more convenient place than all over your file system.

15:23 brehaut: Raynes: cheers :)

15:23 joshua__: Nice! I had something like that for vim, but didn't think to set it up for emacs.

15:24 Raynes: You'll still get autosave files (ones that start with # and .#) if you don't save your files quick enough, but they're automatically deleted once you do save those files.

15:25 joshua__: Raynes: Thankyou!

15:37 fliebel: raek: ping

15:51 joshua__: Alright so this is going right back to my question earlier about recur, because I'm getting an error saying that recure expected 0 arguments and only got one.

15:51 http://clojure.pastebin.com/sBZELFcq

15:51 Is the code.

15:51 Could anyone let me know why the recur call is failing?

15:52 erohtar: seems like ur calling recur with one argument - a list

15:52 hiredman: you cannot recur across a dosync like that

15:52 fliebel: and if you do it like that, I think you would at least nee something like (apply recur more)

15:53 hiredman: fliebel: also not doable

15:53 fliebel: hiredman: I guess not, but now he's passing alist right into his vararg.

15:54 hiredman: well the way you do that is (recure [more])

15:54 well the way you do that is (recur [more])

15:54 tonyl: make it a vector maybe

15:54 joshua__: [more] will fix the problem of passing a list?

15:55 hiredman: yes

15:55 joshua__: Why? Doesn't that just make it a list of a list?

15:55 tonyl: (vec more)

15:55 hiredman: no

15:55 tonyl: please stop

15:55 that is how you recur to a var args

15:56 raek: fliebel: pong

15:57 fliebel: raek: You said something about the web thing for clojure quiz, but then we missed each other.

15:57 Chousuke: the recur there doesn't work because of the dosync

15:57 joshua__: Well, now that I'm thinking about it I can see why recuring inside a dosync would be a nogo, but why is the recur saying that it expects zero arguments (regardless of whether or not it is using [more] or more). Is it trying to recur to the dosync?

15:57 hiredman: joshua__: because of the dosync

15:57 Chousuke: but in general, treat varargs as if they were a single list argument.

15:57 hiredman: the dosync is creating a thunk inside there

15:58 Chousuke: joshua__: what you can do is not have the dosync at all in the function

15:58 joshua__: is thunk a technical term I don't know about or just a figure of speech>

15:58 brehaut: its a technical term

15:58 opqdonut: techincal term

15:58 Chousuke: and just require that users do (dosync (rate-limit whatever...))

15:58 opqdonut: for an unevaluated closure

15:59 generated by a lazy computation

15:59 fliebel: raek: Did you intent to make it, or where you just informing?

15:59 raek: fliebel: I was thinking about it

15:59 hiredman: ~google thunk

15:59 clojurebot: First, out of 474000 results is:

15:59 Thunk - Wikipedia, the free encyclopedia

15:59 http://en.wikipedia.org/wiki/Thunk

15:59 raek: but not tonight

16:00 fliebel: raek: Me neither, and if you want to do it, go ahead. :)

16:01 raek: If you don't, it's on my somewhere-in-the-next-ten-years-but-brobably-earlyer list. ;)

16:01 joshua__: I'd rather hide the dosync. Could I just wrap the function that is returned in a function that calls dosync?

16:02 hiredman: sure

16:03 joshua__: Sweet. Thanks guys. This would have been so hard to figure out on my own.

16:03 hiredman: you could loop inside a dosync too

16:03 (but looping in a transaction, even recuring inside one, is a bad idea)

16:03 fliebel: hiredman: But isn't it a good idea to keep dosyncs as small as possible?

16:03 hiredman: (like really bad)

16:04 Chousuke: joshua__: don't hide dosyncs :/

16:04 explicit is good

16:04 hiredman: hiding dosyncs is fine

16:04 they are nestable

16:05 Chousuke: though honestly, that function looks complicated enough that I'm not sure of its correctness. :P

16:05 joshua__: It works. =) Sort of.

16:05 hiredman: joshua__: putting a thread sleep like that inside a transaction is a horrible idea

16:06 brehaut: joshua__: a surprising number of things work without being correct ;)

16:07 joshua__: hiredman: Can you explain why? I'm guessing that it has something to do with other transactions causing aborts or something like that.

16:07 brehaut: ;p like internet explorer

16:08 brehaut: ie works?

16:09 * brehaut is a bitter ex-corporate web drone

16:09 hiredman: joshua__: right, your transaction will never complete, and behave oddly when retried

16:09 Thread/sleep is a side effect and transactions should be side effect free

16:09 joshua__: hiredman: So I guess the thing to do would be to leave the recursive trying in another function outside the transaction.

16:11 hiredman: depends what the function does, I try not to read code beyond the point of diagnosing the given problem, so I don't really remember anything else about your code

16:13 joshua__: In general: It tries to rate limit the number of times a function can be called. It gives the option of trying the function again when doing so is within capacity or of dropping the call entirely.

16:16 hiredman: joshua__: I don't see why you would need stm for that

16:17 sounds like it should be implemented like memoize

16:17 joshua__: hiredman: I'm not sure how else to save state between function calls.

16:17 hiredman: with atom holding the last time the function was called

16:17 look at memoize in core

16:26 kotarak: joshua__: sounds like a kind of circuit breaker?

16:54 mvid_: is there a way i can use the key and the value in a function when i apply "map" to a hash-map?

16:55 brehaut: ,(map + {1 2 3 4})

16:55 clojurebot: java.lang.ClassCastException

16:55 brehaut: oh right

16:55 ,(map (fn [[k v] (+ k v)) { 1 2 3 4})

16:55 clojurebot: Unmatched delimiter: )

16:55 brehaut: ,(map (fn [[k v]] (+ k v)) { 1 2 3 4})

16:55 clojurebot: (3 7)

16:56 brehaut: mvid_: like that?

16:56 mvid_: cool

16:56 that's great

16:56 plus points for brehaut

16:59 chouser: (inc brehaut)

16:59 sexpbot: ⟹ 1

17:00 brehaut: hah awesome :)

17:10 whats the current state of textmate support for clojure?

17:11 Makoryu: brehaut: On a scale of 1 to 10: "Good luck"

17:11 brehaut: still? bah

17:12 Makoryu: I think there's third-party syntax highlighting support, if nothing else

17:12 brehaut: yeah ive got a really old syntax highlighting mode

17:12 Makoryu: But don't ever expect TextMate to understand Lisp-style indentation

17:14 lrenn: brehaut: https://github.com/swannodette/textmate-clojure

17:14 brehaut: lrenn: cheers

17:14 (inc lrenn)

17:14 sexpbot: ⟹ 1

17:16 arohner: is there a paredit command that will turn (foo a b (bar c d)) into (bar c d (foo a b))?

17:30 bhenry: how is it that merely adding a dependency can break one of my existing, otherwise working function calls?

17:31 raek: using use?

17:33 islon: how don't I fully qualify a name inside a macro?

17:33 joshua__: Alright, so I want to make a macro that will let me do something like (def var (rate-limited-function func rate)) as (defrl func rate) how do I do this?

17:33 raek: islon: that depends on what you want to do...

17:33 joshua__: (defrl var func rate) rather

17:33 mvid_: is there a way to pretty print a sequence or map of strings?

17:34 islon: raek: something like (defmethod [parameter] ...) inside the macro, parameter can't be qualified

17:34 mvid_: im tired of ljava.lang.String90327879438752

17:34 raek: you can write parameter# in that case

17:35 islon: but i want to know the name

17:35 because i will get the body from outside and it will use the parameter name

17:36 raek: then you can do the ~'foo trick

17:36 islon: exactly what i want! thanks

17:36 brehaut: joshua__: (defmacro defrlf [name func rate] `(def var ~name (rate-limited-function ~func ~rate))) i think ?

17:37 joshua__ note the back tick rather than quote on the macro and the unquote twiddles on the args to the macro

17:38 joshua__: you can test it with (macroexpand '(defrlf a b 10))

17:38 joshua__: kk =)

17:39 brehaut: joshua__: and read http://clojure.org/reader to brush up on the reader tricks those twiddles and stuff represent at http://clojure.org/reader under 'macro characters'

17:40 syntax-quote in particular

17:47 bhenry: i had a working function, and after adding incanter to my dependencies in project.clj (never changed any of the src files), one of my function calls in myproject.core no longer works.

17:48 brehaut: bhenry: this is a wild guess, perhaps incanter requires a different version of a dependancy that you use? i have no idea how lein/maven resolve that sort of thing

17:54 joshua__: yeay yeay yeay

17:54 working!

17:54 islon: does anyone knows why this macro only works for the last defmethod not the first? http://pastebin.com/8QRnjXYt

17:59 brehaut: islon preumably defmacro is like any other form with an implicit do; ie only the last form is ever returned

17:59 islon try switching to a cond and you should be fine

18:00 islon: brehaut, i'll try a cond

18:01 joshua__: How can I keep emacs from indenting my comments all the way across the page in cl the mojure mode?

18:01 *in clojure mode?

18:01 ; how do I stop this?

18:02 hiredman: use ;;

18:02 ;; is for blocks

18:02 (+ 1 2) ; is for comments on a line of code

18:02 clojurebot: 3

18:03 rasactive: clojurebot just evals any expression?

18:03 islon: brehaut, now only the first one works... =/

18:03 brehaut: how are you invoking gen-skill-methods ?

18:03 anything truthy will trigger the first form

18:04 islon: both are supposed to work at the same time

18:04 brehaut: ah right. i have no idea if thats possible sorry. you'll need someone with more macro fu than i have

18:04 islon: brehaut, thanks anyway

18:05 brehaut: ah actually

18:05 hiredman: rasactive: nope

18:06 brehaut: islon: (defmacro f [] `(do (def a 1)(def b 2))) gets you part of the way there

18:06 islon: hmmm... lets try

18:06 rasactive: hiredman, how do you make "him" eval something?

18:06 i'm assuming 3 came from your (+ 1 2)

18:07 islon: rasactive: ,(expressions) i think

18:07 ,(+ 3 3)

18:07 clojurebot: 6

18:07 rasactive: cool, thanks

18:09 brehaut: islon: (defmacro m [a b] (let [da (when a `(def my-a ~a)) db (when b `(def my-b ~b))] `(do ~da ~db)))

18:09 islon that might be considered horrible though

18:09 islon: till i get told otherwise i'd categorise that as a nasty hack

18:10 islon: i'll try do first

18:16 joshua__: ,(+ 1 2)

18:16 clojurebot: 3

18:35 bhenry: brehaut: you were correct. incanter has an older version of mongo-java-driver…jar and after deleting that my original code works again. question is now… since both libs that require mongo-java-driver are third party, how do i exclude that older jar automatically? perhaps that should be directed at technomancy or another lein pro?

18:36 technomancy: it's in the faq

18:36 brehaut: bhenry: lein pros

18:36 technomancy: wait... incanter has a mongo driver‽ o_O

18:37 bhenry: [incanter "1.2.3"] requires incanter/incanter-mongodb 1.2.3 which i assume is what's pulling that.

18:37 technomancy: maybe I have no idea what incanter actually is, but that sounds crazy to me.

18:37 brehaut: crazy statisticians

18:39 bmart: hi all, i'm trying to set up swank-clojure and slime and am running into some issues

18:39 specifically, i do slime-connect which succeeds with a warning

18:39 if i then evaluate a number, e.g., 3, it succeeds

18:39 but if I enter an expression like (+ 1 2), nothing happens

18:39 suggestions?

18:46 islon: brehaut, the "let" version worked =D

18:48 brehaut: islon: cool :) its a bit hacky though

18:50 islon: coulnd't find a better way

18:53 brehaut: islon maybe have a look at the extends-protocol macro? im sure there are some examples in core that might show you a better way

18:54 islon: i'll take a look

19:19 clizzin: i've got a case where i want to be able to specify what java class i want to use as an argument to a function. i'm trying something like (defn foo [subclass] (new subclass)), but that says it's unable to resolve instance-type as a classname. is there any way i can achieve my desired behaviour?

19:49 anyone know how to increase heap space for the jvm when using lein swank?

19:49 islon: clizzin, (defmacro foo [clazz] `(new ~clazz))

19:50 or better (defmacro foo [clazz & args] `(new ~clazz ~@args))

19:51 tomoj: clizzin: try JAVA_OPTS

19:51 clizzin: islon, tomoj: thanks!

19:52 tomoj: nothing i can set from lein swank? i don't want to allocate this much heap space every time, just for a few things i'm doing

19:53 tomoj: if JAVA_OPTS works, it works that way

19:54 JAVA_OPTS=-Xmx1000m lein swank

19:54 islon: brehaut, I think thats what I'm looking for https://github.com/clojure/clojure/blob/b578c69d7480f621841ebcafdfa98e33fcb765f6/src/clj/clojure/core.clj#L2309

20:04 vIkSiT: 'lo all

20:04 has anyone done any logfile tailing/stream processing?

20:04 clizzin: tomoj: wouldn't JAVA_OPTS=-Xmx1000m lein swank cause any java process to attempt to run lein swank?

20:09 hmmm the JAVA_OPTS attempt doesn't seem to have worked

20:11 brehaut: islon: cool thanks

20:11 islon: brehaut, worked as a charm =)

20:21 tomoj: clizzin: I meant run that command

20:22 don't set JAVA_OPTS to "-Xmx1000m lein swank", just type `JAVA_OPTS=-Xmx1000m lein swank` into the shell

20:25 clizzin: tomoj: i see. so forgive my ignorance, but lein swank seems to actually start two processes, and i'm not sure what each is for. the first has the JAVA_OPTS amount of heap space, but the second one is the actual jvm that my repl commands run on, and that one still has the default amount of heap space.

20:27 tomoj: weird

20:27 for me they both have my custom heap space

20:29 clizzin: hm that is odd indeed

20:30 tomoj: lein -v ?

20:31 clizzin: 1.3.1

20:31 full version string: Leiningen 1.3.1 on Java 1.6.0_22 Java HotSpot(TM) 64-Bit Server VM

20:31 swank clojure 1.2.1

20:32 oh wait, no, swank-clojure 1.3.0-snapshot. interesting, i wonder when someone on my team updated that.

20:35 technomancy: clizzin: you can set :jvm-opts in project.clj if you only want it applied to the project's JVM

20:36 tomoj: technomancy: but the project JVM should inherit JAVA_OPTS, right?

20:37 technomancy: tomoj: yeah, but lein's JVM doesn't need a gig

20:37 tomoj: right

20:37 technomancy: oh, I see; it's not propagating

20:37 that is strange

20:37 :jvm-opts is preferrable; does it work?

20:39 clizzin: technomancy: ah, thanks for the tip. just looked, and someone already set jvm-opts to a different heap size, hence the lack of propagation. so that solves that problem.

20:39 technomancy: dun dun dun!

20:39 clizzin: sorry tomoj and technomancy, still getting used to all the details of this stuff ;)

20:40 technomancy: thwarted by a so-called team-mate.

20:40 it happens; there's a lot to take it. I recommend a perusal of sample.project.clj.

20:40 islon: is there a way on cake to kill only the swank server?

20:41 joshua__: Question: How do you abort a command running on your emacs slime swank repl?

20:41 Like C-z in python?

20:42 tomoj: C-c C-c

20:43 joshua__: Didn't work =(

20:44 tomoj: are you waiting for a bunch of output?

20:44 joshua__: More like trying to prevent it.

20:44 technomancy: not all operations are cancellable in the JVM

20:44 tomoj: yeah

20:44 joshua__: =( awhh

20:44 so a loop that is spamming print can't be cancelled?

20:45 Guess I

20:45 Guess I will keep up my current dash to the exit button when things go south.

20:46 clizzin: yeah, i typically just restart the jvm in situations like that. =/

20:47 tomoj: I wonder if the unicode problems are slime's or swank-clojure's, or who..

20:47 pdk`: ctrl D

20:49 joshua__: I'm just really hoping that my rate limiting function worked right and that I was caught in a print loop like I think I was.... going to really suck if I just sent out a few thousand http requests =(

21:30 hiredman: I never actually done any profiling with type hints and without, seeing your runtime dominated by invokeMatchingMethod is disconcerting

21:30 I've

22:13 bortreb: why can't I call my record types as a function on their keys like I can with normal maps?

22:13 like ({:hi 1} :hi) == 1

22:14 but (defrecord whatev [hi]) ((whatev. 1) :hi) gives an error

22:16 arohner: bortreb: (whatev :hi) uses the IFn interface, i.e. clojure functions

22:16 (:hi whatev) uses the IPersistentMap inteface

22:16 defrecord implements IPersistentMap, but not IFn

22:17 bortreb: I'm wondering why it doesn't implement IFn?

22:17 arohner: bortreb: because (:hi whatev) has a different performance profile

22:17 on a defrecord, (:hi whatev) has the same speed as a java field lookup, i.e. whatev.hi in java

22:17 (whatev :hi) is a lot slower

22:18 bortreb: but treating it as a function is slower I guess?

22:18 arohner: right

22:18 bortreb: hmmmmm..... but you can't just plop your record into any code that worked with clojure maps and expect it to work then?

22:19 but that behaviour can be added, right

22:19 arohner: yeah, it's a problem. But I've started doing (:hi whaev) in all my other map code now

22:19 (:hi whatev) works on normal maps, and (get whatev :hi) works on both kinds as well

22:20 bortreb: can you define the record to implement IFn and give it a method that looks up on clojure keywords?

22:20 arohner: yes

22:20 bortreb: I just started learning about defrecord, how would you implement IFn?

22:23 tomoj: you need to implement the invoke functions of the appropriate arities

22:25 bortreb: https://gist.github.com/0e196e1b27ec25256d2e

22:26 bortreb: yay I got it

22:27 (defrecord whatev [hi] clojure.lang.IFn (invoke [this k] (get this k)))

22:27 that seems to work

22:27 but! am I missing something crucial here that makes this actually incorrect?

22:27 tomoj: you should probably also implement the 2 arity invoke

22:28 bortreb: why's that?

22:28 tomoj: (invoke [this key not-found] (get this key not-found))

22:28 ,({:foo 3} :bar 10)

22:28 clojurebot: 10

22:28 bortreb: ho!

22:28 thanks tomoj!

22:29 (defrecord whatev [hi] clojure.lang.IFn (invoke [this k] (get this k)) (invoke [this k not-found] (get this k not-found)))

22:30 so then, is that totally right, or am I still missing something?

22:33 tomoj: dunno

22:33 compare the interfaces that maps implement to the ones your records implement

22:34 if you have everything covered you should be good, I think

22:34 bortreb: indeed. thanks

22:35 tomoj: ,(require 'clojure.set)

22:35 clojurebot: nil

22:36 tomoj: err.. nevermind. can't defrecord

22:36 (clojure.set/difference (supers (class {})) (supers Foo)) -> #{clojure.lang.APersistentMap clojure.lang.AFn clojure.lang.IEditableCollection clojure.lang.MapEquivalence}

22:36 so you can't call transient on it

22:37 a transient record would be a strange thing

Logging service provided by n01se.net