#clojure log - Jun 25 2010

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

0:58 vIkSiT: hi all

0:59 does anyone recommend a way to do a merge on 2 lists?

1:18 Raynes: vIkSiT: What do you mean by "merge"?

1:20 alexyk: how do you error out with a message?

1:22 vIkSiT: Raynes, ah, something like doing a merge sort, except you're taking the union of 2 lists

1:22 Raynes: (throw (Exception. "message"))

1:22 vIkSiT: Raynes, basically, the imperative model has you parallely iterating through the 2 lists, doing a compare, and then adding elements in order..

1:23 functionally, it looks like a combo of loop-recur and first/last would work.. but not sure if there's a known way to do it

1:32 alexyk: Raynes: was there an (error ...) or something?

1:48 Raynes: alexyk: Not that I know of. There is one in Haskell... It probably wouldn't be very hard to simulate it.

1:49 alexyk: Raynes: yeah. failwith in ocaml. I do all three at once... mixups

1:50 Raynes: alexyk: It might be as simple as throwing a (println "Omgerrors!") in there.

1:51 alexyk: I just do an assert for now after such

1:51 it's zomgerrors btw

1:51 Raynes: Indeed.

2:47 jeffhill: Hello! I'm hacking about with generating lazy sequences, and I wanted something like iterate but with something like recursive arguments... so I built a macro around lazy-seq. It seems to work fine, but I feel like I've done something non-idiomatic. Is there anything I'm missing here? Link to source: http://paste.lisp.org/display/111831

3:16 mmarczyk: technomancy: ping! about Lein -- responded to your comment on GitHub

3:17 gotta be off now, though...

3:56 AWizzArd: ,(vec (.getBytes (str (char 55366))))

3:56 clojurebot: [63]

3:56 AWizzArd: wtf

4:00 neotyk: ,(java.lang.Character/MAX_VALUE)

4:00 clojurebot: \ï¿¿

4:02 AWizzArd: That's 0xffff

4:03 neotyk: just noticed that is is a range

4:03 AWizzArd: The thing is: when I .getBytes on my string (be it latin1, utf-8, utf-32, etc) I get something different from (map int my-string)

4:04 I can't (String. (.getBytes my-string "UTF-8") "UTF-8") to get the same result

4:04 (= my-string (String. (.getBytes my-string "UTF-8") "UTF-8")) ==> false

4:04 neotyk: ,(str (char 55366))

4:04 clojurebot: "?"

4:04 cschreiner: is there a way to put @ inside a symbol-name?

4:04 neotyk: ,(str (char 63))

4:04 clojurebot: "?"

4:05 AWizzArd: It's fine that it is a questionmark, but I would prefer that it used the same number

4:05 cschreiner: this is relation to generation css; like the @font-face tag

4:05 I cannot do :@font-face

4:06 AWizzArd: ,(let [s (apply str (repeatedly 5000 #(char (rand-int 65000))))] [(count s) (count (.getBytes s "LATIN1"))])

4:06 clojurebot: [5000 5000]

4:06 AWizzArd: ,(let [s (apply str (repeatedly 5000 #(char (rand-int 65000))))] [(count s) (count (.getBytes s "LATIN1"))])

4:06 clojurebot: [5000 4999]

4:06 cschreiner: (symbol ":@font-face") works though

4:08 nevermind, it's okay

4:09 neotyk: AWizzArd: sorry I wan't be able to help

4:10 AWizzArd: I was just surprised to see such behaviour.

4:11 neotyk: ~str

4:11 clojurebot: duck-streams is now clojure.contrib.io

4:11 neotyk: ,(source str)

4:11 clojurebot: java.lang.Exception: Unable to resolve symbol: source in this context

4:13 neotyk: it calls .toString on result of (char ...) and that most likely does reencoding

4:15 AWizzArd: Over there in #Java they had a tip, I will study it now.

4:39 dsop: hmm what is a good tool to generate documentation like the ones on clojure.org ?

4:52 tomoj: autodoc

4:54 dsop: tomoj: thanks

4:57 cschreiner: Looking for a more reasonable way to do:

4:57 ,(let [items (list 1 2 3 4)] (zipmap items items))

4:57 clojurebot: {4 4, 3 3, 2 2, 1 1}

4:58 cschreiner: or is this sound clojure?

5:06 sergey_miryanov: hi all!

5:07 i have a question about into for transient data - how to use it? if i use (into (transient []) (range 10)) i got an exception...

5:10 AWizzArd: sergey_miryanov: yeah, transients could need a bit more work. For example 'find' does also not work on transient maps.

5:12 sergey_miryanov: AWizzArd: clear

5:15 Licenser: aloa

5:22 tomoj: cschreiner: that seems fine to me

5:22 not sure why you'd want to do it..

5:30 cschreiner: tomoj: I just want to create a map from a list where the keys are eq to the vals

5:31 tomoj: right, but why?

5:32 cschreiner: that's another story, not really important here

5:32 tomoj: going to replace some of the values?

5:32 cschreiner: Iit's just for personal testing

5:33 if I would go for (into {} ...) I could'nt quite figure out how

5:34 tomoj: ,(let [s (range 10)] (into {} (map vector s s)))

5:34 clojurebot: {0 0, 1 1, 2 2, 3 3, 4 4, 5 5, 6 6, 7 7, 8 8, 9 9}

5:34 tomoj: your way is fine

5:34 cschreiner: guess so ;)

6:28 AWizzArd: Anyone here with a SSD?

6:31 I would like to see what the performance difference is.

6:32 Please start a Server JVM and (import '(java.io FileOutputStream BufferedOutputStream DataOutputStream)) and define a string of one million random chars (def s (apply str (repeatedly 1000000 #(char (rand-int 55000)))))

6:33 And then simply (with-open [dos (DataOutputStream. (BufferedOutputStream. (FileOutputStream. "/data" false)))] (time (dotimes [i 100] (.write #^DataOutputStream dos (.getBytes #^String s "UTF-8") 0 1000000)))) ; writing the string a hundred times to disk

6:54 bartj: Any Russian's here? I want to ask them a slightly off-topic question (:

6:55 regarding phone-numbers in Russia (:

6:57 AWizzArd: bartj: maybe #C++ ?

6:59 bartj: AWizzArd: why so ?

6:59 AWizzArd: ja nje ponimaju po russki

7:01 sergey_miryanov: i'm a russian

7:06 bartj: AWizzArd: can you please tell me why phone numbers on this page are 12 digits? - http://www.77rosfirm.ru/catalog/card/77.1188629

7:09 silveen: Happy midsummer everyone

8:02 AWizzArd: ,"\ud80e\udc80"

8:02 clojurebot: "𓢀"

8:17 mmarczyk: AWizzArd: ouch... exposing my Emacs's failure to display unicode characters properly :-(

8:19 AWizzArd: mmarczyk: yes sure :)

8:20 ,(.codePointAt "\ud80e\udc80" 0)

8:20 clojurebot: 80000

8:20 AWizzArd: This is a string of just one character, with Unicode code point 80000

8:20 ,(count "\ud80e\udc80") ;-)

8:20 clojurebot: 2

8:20 mmarczyk: is there such a code point?

8:20 AWizzArd: yes

8:21 mmarczyk: oh, look, a bug! :-)

8:21 AWizzArd: no, not a bug

8:21 this is correct behaviour

8:21 mmarczyk: huh?

8:21 AWizzArd: internally 2 chars are used, to produce one real character

8:21 * mmarczyk needs to teach himself better encoding-fu :-(

8:21 AWizzArd: this char does not fit into 2 bytes

8:22 code points exist up to 0x10FFFF = 1114111

8:22 mmarczyk: I'd still kinda sorta expect "logical" characters to be counted

8:23 ,(.length "\u80e\udc80")

8:23 clojurebot: Invalid character length: 3, should be: 4

8:23 mmarczyk: ,(.length "\ud80e\udc80")

8:23 clojurebot: 2

8:23 mmarczyk: ...not going to argue with the host though

8:24 AWizzArd: yes, two 2-byte-chars are used, and they represent one unicode char

8:24 Was a Java design descision and makes mostly sense.

8:24 mmarczyk: was it before the rise of utf-8?

8:24 just out of historical curiosity

8:25 AWizzArd: Otherwise they would have to encode each char with 4 bytes under the hood, which is quite wasteful, as 99,99999% of all texts don't contain such very specific chars

8:25 First Unicode was designed to eat 65k chars

8:25 Java incorporated this

8:26 chouser: it may not be an implementation bug, but it might well be a design bug

8:26 mmarczyk: I suppose a variable-length encoding would be terrible for indexing into strings etc.

8:26 AWizzArd: Then, later, the unicode consortium discovered this is not enough.

8:26 They now wanted to support over a million characters.

8:26 mmarczyk: "nobody should ever need more than 65k chars" -- sounds familiar somehow ;-)

8:27 AWizzArd: It could be a design bug, but it probably isn't one

8:29 mmarczyk: actually, how does one replace a "narrow" character with a "wide" character in an array of characters? copy the whole thing while adding an extra char in the middle...?

8:29 AWizzArd: The real problem is that the api doesn't deal with malformed strings.

8:29 When you want to traverse a(ny) string correctly, you can not traverse its (seq)

8:30 You need to look at the .codePointAt i

8:30 and if that value is > than (int Character/MAX_VALUE), then you need to an extra increase of i in the loop

8:30 +do

8:30 mmarczyk: oh, you mean it's a clojure.lang.StringSeq problem...?

8:30 AWizzArd: no

8:30 there is no problem

8:31 The default behaviour is to traverse a string with charAt

8:31 This works in nearly 100% of all cases.

8:31 mmarczyk: not quite though?

8:31 AWizzArd: It's good.

8:32 Though, it is not really a correct approach.

8:32 mmarczyk: ok, so an alternative would be a "CodePointSeq" on a string

8:32 AWizzArd: yes, for example

8:32 mmarczyk: which couldn't have characters as members, I guess

8:32 interesting!

8:32 AWizzArd: In principle such a CodePointSeq could be half the (count of-the-string).

8:33 (<= (/ (count s) 2) (count CodePointSeq) (count s))

8:34 mmarczyk: wondering I might be tripped up by this: do Chinese characters fit into the lower 65k part of Unicode then?

8:34 AWizzArd: I think all or most of all fit in there

8:34 mmarczyk: ok

8:34 chouser: I don't see how this could possibly be ideal

8:34 There should be two things -- bytes and codepoints a.k.a. chars

8:35 AWizzArd: It really is not ideal. We need a good bit of inside knowledge if we wanted to write correct code.

8:35 chouser: having a string be made up of something that is neither isn't useful, is it?

8:35 AWizzArd: Not the best thing, I agree. But this allowed all Java programs to continue to run. Also it means that Strings are not even more hungry than they already are.

8:35 mmarczyk: is a big-C Character capable of holding a wide char?

8:35 AWizzArd: An empty string eats 30+ bytes or so

8:36 chouser: utf8 is teh bomb

8:36 AWizzArd: no, native char and the wrapper Character both internally use 2 bytes to represent a character.

8:36 mmarczyk: utf-8... would need to store an extra array of indices indicating where, say, every 32nd char starts

8:36 for constant-time .charAt

8:38 AWizzArd: All this would be okay.. people who studied this topic can write correct code.. but there still remains one problem, and that is: malformed strings.

8:38 chouser: maybe constant-time .charAt isn't worthwhile

8:38 AWizzArd: Unfortunately those don't throw an exception.

8:39 mmarczyk: chouser: isn't that what enables StringSeq...? though maybe we could do without it

8:39 AWizzArd: While "\ud80e\udc80" is a perfect 2-char / 4-byte / 1-unicode-char string this one is nonsense: "\udc80\ud80e" (just reversed)

8:39 ,(vec (.getBytes "\ud80e\udc80" "UTF-8"))

8:39 clojurebot: [-16 -109 -94 -128]

8:39 mmarczyk: though constant time indexing also enables substring

8:39 AWizzArd: ,(vec (.getBytes "\udc80\ud80e" "UTF-8"))

8:39 clojurebot: [63 63]

8:39 mmarczyk: I'm not letting anyone take away my substring :-P

8:40 AWizzArd: ,[(map int "\ud80e\udc80") (map int "\udc80\ud80e")]

8:40 clojurebot: [(55310 56448) (56448 55310)]

8:40 chouser: mmarczyk: in it's current implementation, sure. If String's charAt weren't constant-time, you'd want other adjustments to its API

8:41 AWizzArd: Those designers of the spec decided that there have to be low surrogate chars and high surrogate chars, which expect something to their left or right

8:41 mmarczyk: chouser: I suppose, not sure what those would be though; .substring is more important anyway

8:43 AWizzArd: well, substring won't work on such strings

8:43 mmarczyk: AWizzArd: with utf-8 strings supported by array of indexes into the underlying byte array it would

8:43 AWizzArd: It works correctly when looking at the single chars, as in 2-byte-values.

8:43 mmarczyk: I think?

8:44 AWizzArd: Strings are internally represented by a char array.

8:45 If you know for sure that your string contains no surrogate char at all, then subs and .substring work correctly and as expected.

8:45 If you want to do a substring as a human would expect it, by visible characters, then you will have to do it manually :)

8:46 Before each use of subs you can check if it is okay to use it: (re-find #"[\uD800-\uDFFF]" s)

8:46 mmarczyk: yeah, I understand

8:46 but you could theoretically implement strings differently

8:47 AWizzArd: if those 2048 chars are not included in the string (and this should be true for nearly 100% of all strings), then using subs is fine

8:47 mmarczyk: the above was referring to such hypothetical implementation

8:47 AWizzArd: mmarczyk: yes, and in such a case that would work

8:47 Or they could make char being 3 or 4 bytes wide.

8:48 mmarczyk: I think I'll make figuring out the performance/memory hit into a little project :-)

8:48 AWizzArd: well sure, that could be interesting

8:50 mmarczyk: thanks for the conversation, this is interesting stuff

8:50 AWizzArd: The very easy solution is to use 3 bytes per char. That allows you to represent up to 16 mio different chars, while the current unicode standard supports just 1,114,112 characters

8:50 But interesting would be a compressed string, so that "aaaaaaaaaa" would just eat around 10 bytes, not 30

8:51 chouser: seriously. UTF8 is awesome

8:51 mmarczyk: presumably different things are possible on big proper boxen than in the embedded realm

8:52 AWizzArd: I am still pissed, because I am now writing a very fast serialization lib for Clojure and can't rely perfectly on .getBytes, which will produce wrong results for random strings.

8:52 chouser: I mean, it was nice when strings could have fixed-sized chars, but that era has passed.

8:52 mmarczyk: extra byte per char in J2ME -> "surely you are in jest?"

8:53 chouser: yup, and currently we live in the era where strings cannot / must not have fixed-sized chars, yet they still do ;-)

8:53 somebody make the next one hurry up

8:57 alright, I need to be off for now... see you later

9:16 jcromartie: I wish every programmer realized how evil mutable state is

9:16 then I would have apps that set session variables and trigger a chain of event handlers that results in reading the session variable, in the same HTTP request

9:17 wouldn't

9:25 lpetit: hello there.

9:28 Regarding the recent "resurgence" of newbie questions such as "why does contains? has the semantics it has ..." et al., I've been thinking about some ways to make it both easy for the newbie to get the answer by himself, and easy to the newbie to contribute back where he found the info

9:30 Something directly usable from the REPL. e.g. some 'rationale' namespace. rationale functions would work on the same set of symbols (doc) and (find-doc) work on. rational content for vars/specialchars could be contained somewhere in the cloud (would need the network available).

9:30 (rationale contains?) may return a string with an indexed list of texts.

9:31 e.g. "(0) http://some.googlegroup.thread\n(1) Rich Hickey once said on #clojure ..."

9:31 (rate contains? 0) would mean : me as a user found rationale 0 to be useful

9:32 (unrate contains? 0) would mean: me as a user found rationale 0 particularly useless

9:32 the 2 last functions would go to the cloud and and a "vote" for the given rationale

9:33 finally, (add-rationale contains? "some free text") would contribute a new rationale

9:34 Just thinking about it. Thoughts ?

9:37 jcromartie: i don't see the benefit of it over just sending them here or to the mailing list

9:41 lpetit: jcromatie: I was thinking about this as an easy way to accumulate knowledge (especially concerning the rationale of things: why is contains? the way it is ?), and, via the rate/unrate functions, to automatically sort good knowledge. In the end: time saver for both the newbie and the non-newbie. So more time for the non newbie to help the newbie on more interesting questions. But maybe I'm...

9:41 ...just dreaming up ?

9:41 jcromatie: I thought that the immediate access of those functions via the "always open" REPL could help leverage these functionalities

9:42 jcromatie: of course, a little help from clojure-bot could also help add knowledge directly from irc, just after having answered for the nth time to the same question

9:43 I know the answer generally is in the ml archive and / or in the #clojure logs and / or somewhere on the wikis / blog posts, but it's kind of steganographied knowledge ...

9:45 eevar2: lpetit: imo the best way to learn the essentials is "programming clojure" + "the joy of clojure"

9:46 chouser: it would be nice to have something better. right now we have official docs that are mostly up-to-date, but pretty dense and minimal. And we have "live help" on irc and ggroup which is up-to-date and as verbose as needed.

9:46 stuarthalloway: has anyone ever written/seen a Clojure (into-bean bean map)

9:46 chouser: if you want something more verbose but less live, I think the main difficulty to overcome is keeping it up-to-date. All the books, and both wikis have this problem.

9:47 stuarthalloway: like clojure into but reflective to get stuff into random java beans?

9:47 chouser: stuarthalloway: I've seen unbean somewhere I think.

9:47 stuarthalloway: chouser: thx, works as a search term

9:48 chouser: into-bean's a better name

9:49 stuarthalloway: and implies the right semantics (starting with an existing bean)

9:49 chouser: 'bean' may be misnamed as suggested in the ggroup thread. you found that?

9:49 stuarthalloway: yes

9:50 I am going to put into-bean into contrib somewhere

9:57 lpetit: chouser: I thought about somtheing totally "open to the community", just as a wiki with read/write access to anybody, but not a wiki, just 3 functions from the REPL to consult (rationale), add content (add-rationale), remove content (remove-rationale) (and/or rate/unrate). A simple "wikipedia" indexed by var

9:58 chouser: but more an aggregator of links (per var) than containing the real content. But maybe it would just be yet another out of date source of info :-(

9:59 chouser: lpetit: well, it is a social problem not a techincal one. if lots of people use it and it's easy to update, it's likely to stay up to date.

10:00 perhaps having it in-repl would be enough to solve that.

10:00 lpetit: chouser: yes. And it's it does not cost too much to introduce the feature, ...

10:00 chouser: yes, I bet that having it in repl could greatly help make the dream come reality

10:02 chouser: I guess a minimalist approach could leverage the most useful part of the features very quickly

10:03 there is no http client in contrib, right ?

10:05 hugod: lpetit: a repl based tool would probably reduce the amount of spam too.

10:05 I have the start of a repl/command line feedback tool that uses google appengine

10:06 lpetit: clojure.contrib.http.agent

10:06 lpetit: hugod: yay !

10:08 hugod: I was testing the idea. I don't intend to work on this *for real* in the next few weeks. If you like the idea, feel free to go ahead !

10:08 hugod: I've been put off by appengine startup times though, 10s to 20s. I assume it gets better with volume, but...

10:09 lpetit: hugod: oh yes, this would be a breaker for using app engine, I guess

10:10 hugod: the evil will be in the detail (as for what differenciates an iphone to an ordinary mobile phone). If it ain't fast (as in "instantaneous"), it won't be used.

10:11 hugod: lpetit: asynch requests help to keep it feeling fast

10:25 lpetit: hugod: can you tell us more 'bout your "repl/command line feedback tool that uses google appengine" ? Especially, I don't understand why it is tied to appengine. Just using GET/POST HTTP functions should suffice, no ?

10:26 hugod: lpetit: well, the data has to go somewhere, but it would be easy to move to some other storage

10:27 it would be trivial to change it to couchdb or similar

10:28 lpetit: hugod: ok, but can't you make the client/server protocol independent of the server's underlying storage techno ?

10:29 hugod: lpetit: of course the the protocol is independent of the storage

10:29 lpetit: hugod: sorry then

10:30 hugod: lpetit: I'm probably not explaining it well :)

10:31 lpetit: at the moment it uses hash tags to identitfy individual comments, and allows replies on particular tags

10:32 lpetit: but adding recoginition of clojure function names would be simple

10:32 lpetit: hugod: let us know when you've implemented it ! :)

10:32 hugod: lpetit: each user is identified by an opaque handle

10:33 lpetit; which the user can attach to aomething less anonymous

10:33 lpetit: hugod: I don't think we need to identify people. I'm thinking about a "no-config" "no-brainer" system for the "rationale" feature

10:34 hugod: lpetit: ranking would be per item then?

10:34 lpetit: hugod: well, yes

10:34 hugod: lpetit: I think allowing people to identify their comments would be an incentive for some

10:36 lpetit: hugod: I was more thinking about keeping it as simple as possible. You find something useful, you push it, done.

10:37 hugod: or maybe a "loose" identification, not via an id of any sort, but just an optional argument to the function : (add-rationale "my text" "lpetit")

10:37 hugod: lpetit: I'm all for the simpler the better, at least initially

10:37 lpetit: ,(System/getProperty "user")

10:37 clojurebot: nil

10:37 lpetit: ,(System/getProperties)

10:37 clojurebot: #<Properties {java.runtime.name=Diablo Java(TM) SE Runtime Environment, sun.boot.library.path=/usr/local/diablo-jdk1.6.0/jre/lib/i386, java.vm.version=10.0-b23, java.vm.vendor=The FreeBSD Foundation, java.vendor.url=http://www.freebsd.org/java/, path.separator=:, java.vm.name=Diablo Java HotSpot(TM) Client VM, file.encoding.pkg=sun.io, sun.java.launcher=SUN_STANDARD, user.country=US, sun.os.patch.level=unknown, java.vm.spe

10:38 lpetit: ,(System/getProperty "user.home")

10:38 clojurebot: "/home/hiredman"

10:38 lpetit: ,(-> (System/getProperties) bean)

10:38 clojurebot: {:empty false, :class java.util.Properties}

10:38 lpetit: argh

10:39 hugod: was thinking about maybe using the System env context, but I fear complaints for violation of privacy ....

10:40 hugod: lpetit: that's why I am using an opt-in scheme for identification

10:43 lpetit: I was aiming for a repl based version of something like uservoice

10:44 lpetit: hugod: what is uservoice ?

10:44 hugod: lpetit: uservoice.com

10:45 lpetit: hugod: ok

10:45 hugod: lpetit: but using #tags similar to thedeadline

10:45 lpetit: hugod: I must leave, keep up the good work, cu later !

10:46 hugod: lpetit: :)

10:46 jimduey: Hi folks. Anyone have a favorite webhost company to serve a site of static pages.

10:46 ?

10:48 * rhickey is stunned google has let this infinite redirect in ggroups go for so long

10:49 bhenry: jimduey: nearlyfreespeech.net unless your volume will be big

10:49 jimduey: Thanks, I'll check it out. Minimal volume

10:59 arohner: before I start writing, are there any lein plugins that start a daemon process?

11:14 chouser: stuarthalloway: have you tried making the laprepl example in enclojure recently?

11:22 AWizzArd: ,(instance? Long/TYPE (long 10))

11:22 $(instance? Long/TYPE (long 10))

11:22 sexpbot: => false

11:22 AWizzArd: Why is that?

11:23 $[Long/TYPE Long (class? Long/TYPE) (class? Long)]

11:23 sexpbot: Command not found. No entiendo lo que estás diciendo.

11:23 AWizzArd: $(vector Long/TYPE Long (class? Long/TYPE) (class? Long))

11:23 sexpbot: java.lang.SecurityException: Code did not pass sandbox guidelines: (#'clojure.core/class? #'clojure.core/class?)

11:24 cemerick: what happened to clojurebot?

11:24 stuarthalloway: AWizzard: long doesn't promise it will return a Long/TYPE

11:24 AWizzArd: anyway, (identical? Long Long/TYPE) ==> false

11:24 stuarthalloway: and the assumption that such things hold is making rhickey crazy as he fixes overspecified tests in the various num branches

11:25 cemerick: In any case, the (long 10) is going to get boxed going into instance?

11:25 stuarthalloway: cemerick: I don't think the doc promises that either

11:26 if you call (long x) on the way into a Java interop form, you don

11:26 't want boxing

11:27 cemerick: Right, but if instance is a clojure fn, then everything is boxed -- modulo prim

11:33 arkh: What's a good way to loop over something x times or until (testfunc) returns false

11:34 hiredman: ~ping

11:34 clojurebot: PONG!

11:36 chouser: ,(for [i (range 10) :while (even? i)] i)

11:36 clojurebot: (0)

11:37 arkh: chouser: thank you

11:37 chouser: arkh: note that's a lazy seq, not a loop in the imperative sense

11:38 arkh: chouser: so wrap with (doall) ?

11:38 chouser: ... assuming I wanted the whole thing realized

11:38 chouser: you want side effects?

11:39 you could try doseq instead of for

11:39 ,(doseq [i (range 10) :while (even? i)] (println "Mutate the universe:" i))

11:39 clojurebot: Mutate the universe: 0

11:41 arkh: chouser: doseq looks good; side effects are involved

11:46 cemerick: clojurebot: nice to have you back :-)

11:47 clojurebot: excusez-moi

11:47 cemerick: exactly

11:48 bhenry: chouser: i can't figure out why those code snippets don't display 0 2 4 6 8.

11:49 ah nevermind

11:50 chouser: bhenry: right, for that you'd use :when instead of :while

12:02 bhenry: chouser: does :while withhold laziness so that (range 10) never sees the 1?

12:06 chouser: no, :while has to realize 1 in order to see that it's not even. But it won't realize any more than that.

12:07 ,(for [i (iterate inc 0) :while (even? i)] i)

12:07 clojurebot: (0)

12:15 arohner: technomancy: did you get my github email last night?

12:16 technomancy: arohner: yeah, still working through a slight backlog on pull requests. hope to get to it this weekend.

12:17 arohner: technomancy: no problem. I had another thought, which is a plugin that hooks lein deps would work if src/ was on the lein classpath

12:17 technomancy: nm. something else must have been broken

12:30 defn: lancepantz: sorry if you already answered this, but did you get your JRuby + Rails + Clojure project up for viewing?

13:18 Kjellski: Hi there, I'm trying to build a function that blocks a seq like this: [1 2 3 1 4 5 1 6 7] into these: [[1 2 3] [1 4 5] [1 6 7]] with a signature like this (defn block-by [pred coll] ...) is there already something that does this?

13:19 AWizzArd: $(map vector (partition 3 [1 2 3 1 4 5 1 6 7]))

13:19 sexpbot: => ([(1 2 3)] [(1 4 5)] [(1 6 7)])

13:20 mmarczyk: s/vector/vec/

13:20 chouser: Kjellski: http://clojure-log.n01se.net/date/2010-06-23.html#12:40

13:20 bhenry: kjellski do you want to make a new group whenever you get to something lower than the previous number or do you want to actually do it by 3's?

13:21 AWizzArd: or do you want to start a new group whenever you hit a 1?

13:21 bhenry: that too

13:21 AWizzArd: mmarczyk: identity would also be an option

13:22 chouser: he asked this a couple days ago

13:22 mmarczyk: AWizzArd: better not use map at all then

13:22 AWizzArd: chouser: how do you know this? You don't remember everything you read in here, do you? ;)

13:22 Kjellski: I want it to split the vector by 1, whatever pred is should split...

13:22 mmarczyk: $(doc split-with)

13:22 sexpbot: => ------------------------- clojure.core/split-with ([pred coll]) Returns a vector of [(take-while pred coll) (drop-while pred coll)] nil

13:22 AWizzArd: mmarczyk: yesss *lol*

13:22 Kjellski: AWizzArd: exactly!

13:23 mmarczyk: AWizzArd: :-)

13:23 chouser: Kjellski: I posted a couple answers for you on Wednesday, after you left. :-P

13:23 AWizzArd: Kjellski: you can not answer an or-question with yes/no/exactly

13:23 Kjellski: mmarczyk: but split with looses the relation between the elements and groups them into one

13:23 mmarczyk: well, that's what the questions above are about...

13:24 chouser: ,(map #(apply concat %) (partition 2 (partition-by #{1} [1 2 2 1 3 3 1 4 4])))

13:24 clojurebot: ((1 2 2) (1 3 3) (1 4 4))

13:24 mmarczyk: there'll be different solutions depending on what you want to apply the predicate to

13:24 Kjellski: chouser: Oh sorry mate... but thanks for that, I think this would be useful as a standard funtion...

13:24 AWizzArd: mmarczyk: I was thinking of matrix transposition, such as (map list [1 2 3] [4 5 6] [7 8 9]) and started out with map, doh!

13:25 chouser: Kjellski: what would you name it?

13:25 mmarczyk: AWizzArd: ah, then prefixing your snippet with apply would work

13:26 Kjellski: chouser: something like "block-by" or "block-by-pred" ...? I would use this for parsing, but maybe the name would be good for other viewpoints?

13:27 ,(map #(apply concat %) (partition 2 (partition-by #{1} [1 2 3 4 1 5 6 7 1 8 1 9])))

13:27 clojurebot: ((1 2 3 4) (1 5 6 7) (1 8) (1 9))

13:28 Kjellski: chouser: what a dream... I'm always thinking way to complex to get to such solutions...

13:28 chouser: Kjellski: well, me too, pretty often. did you scroll up from that link and see my first solution?

13:28 mmarczyk: oh, something like Haskell's groupBy then?

13:28 groupBy (\x y -> if y == 1 then False else True) [1,2,3,1,4,4,1,5,5]

13:29 [[1,2,3],[1,4,4],[1,5,5]]

13:29 chouser: (doc group-by)

13:29 clojurebot: "([f coll]); Returns a map of the elements of coll keyed by the result of f on each element. The value at each key will be a vector of the corresponding elements, in the order they appeared in coll."

13:29 Kjellski: chouser: yes

13:29 mmarczyk: good function, to be sure, but we've already got a group-by which does something completely different

13:29 ah, right.

13:29 so not sure what to call it now...

13:30 chouser: it's closes to partition-by

13:30 closest

13:30 perhaps partition-starting-when :-)

13:30 Kjellski: mmarczyk: I thought of "block-by" but that could be confusing too...

13:30 mmarczyk: chouser: yeah

13:31 shall we hold a naming contest? ;-)

13:31 Kjellski: chouser: what about "collect-blocks"

13:31 mmarczyk: or maybe call it partition-with and laugh diabolically each time somebody confuses it with partition-by :-P

13:31 Kjellski: mmarczyk: ^^

13:32 chouser: hm, I thought we already had a partition-with, but I guess not

13:33 Kjellski: ,(map #(apply concat %) (partition 2 (partition-by #{1} [1 2 3 4 1 5 6 7 1 8 1 9 1 1 1 2 1])))

13:33 clojurebot: ((1 2 3 4) (1 5 6 7) (1 8) (1 9) (1 1 1 2))

13:33 Kjellski: chouser: see the end?

13:33 chouser: ooo, you broke it!

13:34 ,((fn [p s] (->> [nil s] (iterate (fn [[_ [_ & xs]]] (split-with (complement p) xs))) (partition 2 1) (map (fn [[[_ [i]] [r]]] (cons i r))) (take-while first))) #{1} [1 2 3 4 1 5 6 7 1 8 1 9 1 1 1 2 1])

13:34 clojurebot: ((1 2 3 4) (1 5 6 7) (1 8) (1 9) (1) (1) (1 2) (1))

13:35 Kjellski: chouser: actually, that rocks

13:36 chouser: thanks

13:36 chouser: a bit of a mess, but you're welcome.

13:36 Kjellski: chouser: *thinking*: I´ll try to understand it the next two weeks ^^

13:37 chouser: I deny allegations of destructuring abuse

13:39 Kjellski: chouser: could you do me favour? I would love to see it indented the best, so I could try to figure out what it does...

13:39 chouser: yeah, sure.

13:40 rhickey: updated docs for equiv branch, ready for people to check it out: https://www.assembla.com/wiki/show/b4-TTcvBSr3RAZeJe5aVNr/Enhanced_Primitive_Support

13:41 chouser: Kjellski: http://gist.github.com/453174

13:42 Kjellski: chouser: thanks a lot!

13:47 chouser: Kjellski: just updated the gist to a simpler version

13:48 Kjellski: chouser: I´ll have a look...

13:52 chouser: this function comes in really handy *happy*

13:52 eivindgl: q

13:53 Kjellski: chouser: how nice to split logs with it... ^^

13:53 chouser: Kjellski: :-) great.

13:54 cemerick: I played with stack traces some yesterday, basing a lot on clojure.stacktrace

13:55 cemerick: chouser: any breakthroughs?

13:56 chouser: no, but I segmented the code differently -- have a fn that returns a seq of stack-trace lines, so that you can then filter, map, etc. to get what you want

13:56 then another fn that prints them once you've filtered

13:57 I'll keep playing with it, but I wanted to mention that your code was a nice starting place.

13:57 cemerick: my code?

13:57 chouser: didn't you write clojure.stacktrace?

13:58 cemerick: No -- I think SS did?

13:58 I would never produce something so useful.

13:58 chouser: oh. sure enough named right there at the top. I wonder how I got confused.

13:59 sorry.

13:59 cemerick: no worries

13:59 Kjellski: there is no way to step through clojure code right? ^^ like good old debugging?

13:59 cemerick: People often think I'm responsible for awesome stuff. I just make sure I'm next to people that do real work, or I think out loud and often someone will do something I can take credit for. ;-)

13:59 chouser: anyway, I've got shorter stack by throwing away RestFn patterns that show up on every apply, and non-core .clj lines highlighted

13:59 cemerick: like, shell highlighted, or otherwise?

14:00 chouser: yeah, shell. ANSI color codes. I live in the 70s

14:00 or was that 80s

14:01 cemerick: Nah, I'm jealous of good shell highlighting, etc.

14:01 Not jealous enough to actually use a shell for real work, of course.

14:01 chouser: I want to throw away multi-line patterns that show up on seq-walking. probably collapse compiler lines since I normally don't care.

14:01 cemerick: Sounds awesome.

14:02 Is it reasonable to screen out clojure.* frames by default in general?

14:02 (however much that might irritate rhickey? ;-)

14:02 chouser: dunno. I'll keep playing with it.

14:03 the seq thing is pretty key though -- allows modular filtering.

14:03 I want to play with reversing the causes and/or lines within each cause.

14:03 maybe the root cause and it's line should be immediately above the prompt

14:04 walking up the screen would be walking back in time

14:05 cemerick: are you working on a patch to be grabbed somewhere?

14:05 chouser: hrm. no. dumb.

14:06 cemerick: chouser: oh, #322 is done AFAIK. Not sure if you remember, but we were poking at some solutions a few months ago. http://www.assembla.com/spaces/clojure/tickets/322

14:07 chouser: cool. I've been watching the conversation, but haven't looked at the code.

14:07 cemerick: It was pretty simple, once I had a clue as to what was going on.

14:08 chouser: http://gist.github.com/453211 stack-trace-playground.clj

14:09 so the idea is people can write up different filters, colorizers, etc. then mix and match as desired.

14:10 technomancy: chouser: have you tried http://github.com/mmcgrana/clj-stacktrace ?

14:10 chouser: technomancy: once long ago

14:10 technomancy: we just started using it, and it makes me very glad.

14:10 chouser: hm... ok!

14:10 technomancy: I would love to see it in clojure 1.3

14:10 cemerick: "\033[31m" == red?

14:10 * cemerick facepalms

14:10 technomancy: it's pretty easy to hack into clojure.test

14:11 (with some monkeypatching)

14:12 http://p.hagelb.org/clj-stacktrace-monkeypatch.html

14:12 chouser: nice. mmcgrana writes good code.

14:14 oh, man. I clearly need to start with clj-stacktrace and work from there.

14:15 alpha-punc-subs, trim-redundant, color-codes, all good stuff I would have ended up doing roughly the same way, but he's already done it better.

14:16 but I do want to do filtering which I don't see a way to plug in very cleanly.

14:39 arkh: being unable, at this point in my clojure education, to comprehend the source for 'for', does anyone know if 'for' realizes all seq-exprs on each iteration, regardless of modifiers, or will it short circuit evaluation of a seq-expr if a :while is false on an earlier listed seq?

14:39 e.g., does for behave like and ?

14:42 chouser: ,(for [x [1 2 3], y [4 5 6] :while (< y 6)] [x y])

14:43 clojurebot: ([1 4] [1 5] [2 4] [2 5] [3 4] [3 5])

14:43 chouser: I guess I'm not quite sure what you're asking.

14:43 arkh: you know ... I might not either ...

14:44 chouser: I have a vague recollection of :while not short-circuiting in quite the way one might expect, but I'm having trouble remembering the details

14:44 ,(for [x [1 2 3], y [4 5 6] :while (odd? x)] [x y])

14:45 clojurebot: ([1 4] [1 5] [1 6] [3 4] [3 5] [3 6])

14:46 arkh: ,(for [x [1 2 3], y [4 5 6] :when (odd? x)] [x y])

14:46 clojurebot: ([1 4] [1 5] [1 6] [3 4] [3 5] [3 6])

14:47 mmarczyk: ,(for [x [1 2 3] :while (odd? x) y [4 5 6]] [x y])

14:47 clojurebot: ([1 4] [1 5] [1 6])

14:47 chouser: so, :while only will skip the rest of the seq it's applied to

14:47 mmarczyk: clj-stacktrace looks awesome.

14:48 arkh: chouser: thank you again

14:48 briancarper: mmarczyk: Cool, I didn't know `for` worked that way.

14:49 I never tried sticking a :while in the middle.

14:49 mmarczyk: aye... still, nowhere near as funky as PLT Scheme/Racket's list comprehensions :-)

14:50 arkh: mmarczyk: I meant to thank you also! Thanks.

14:50 mmarczyk: arkh: np :-)

15:08 dnolen: heh "equiv the revenge of num"

15:16 jcromartie: Why would a Common Lisp user say that Clojure can be "incredibly slow?"

15:16 Is that just the "Java is slow" myth extended?

15:17 Raynes: Probably.

15:17 jcromartie: SBCL ranks pretty far behind Scala on the benchmarks game

15:17 but SBCL is JVM too

15:17 weird

15:17 qbg: No...

15:18 SBCL is native

15:18 Raynes: Common Lispers can be "incredibly elitist".

15:19 qbg: Well, CL does lay waste to many other languages...

15:19 jcromartie: oh wait, I see, it was comparing it to Java... I got it confused with ABCL

15:20 technomancy: CL'ers might be looking for excuses to stick with CL and not try new stuff

15:20 since that strategy has worked for them since the mid-80s

15:21 jcromartie: he says it's because it's all because they "have to make refs"

15:21 to interop with Java

15:23 and that Kawa (a JVM Scheme) is "over 1000 times faster than optimized Clojure"

15:23 "All because it doesn't have to make refs"

15:24 technomancy: he's clearly not interested in having a discussion; he just wants to Be Right.

15:24 qbg: Wow...

15:24 dnolen: just another troll looking for a good time it sounds like

15:53 yacin: i've got a project in emacs

15:53 and i moved some functions to a separate file

15:53 now, i'm obviously going to run into namespace/functionname clashes

15:53 how can i remove the defined functions from the old file?

15:53 without having to restart my swank session?

15:54 bhenry: yacin: i am also curious about this. i don't think you can.

15:54 i always just restart

15:55 yacin: restarting isn't a big deal, but it'd be nice to not lose my current state

15:55 mmarczyk: ns-unmap

15:56 bhenry: ,(doc ns-unmap)

15:56 clojurebot: "([ns sym]); Removes the mappings for the symbol from the namespace."

15:56 bhenry: mmarczyk nice.

15:56 mmarczyk: I use this for convenience: (defmacro undef [& syms] `(doseq [s# '~syms] (ns-unmap *ns* s#)))

15:57 (undef foo bar baz) / (clojure.contrib.with-ns/with-ns my.old.ns (undef foo bar baz))

15:58 got it in my init scripts (user.clj on the classpath)

15:59 yacin: mmarczyk: thanks!

16:00 mmarczyk: (doseq [old-name (keys (ns-interns 'my.old.ns)) :when (contains? (ns-interns 'my.new.ns) old-name)] (with-ns my.old.ns (undef old-name)))

16:00 for some generalised cleanup

16:00 (wrote it here, so sorry for any typos etc. missed)

16:01 ah, the name 'old-name' for the local doesn't make any sense, should be 'sym' or sth

16:08 yacin: mmarczyk: for setting up a user.clj, do i need any (ns ...) declaration? or just a bunch of functions?

16:08 mmarczyk: yacin: no (ns ...) form, no

16:08 yacin: kk

16:08 that's what i figured

16:08 thanks

16:09 mmarczyk: whatever you put in there will be loaded into the user namespace on startup

16:09 I've got a bunch of requires... [clojure [set :as set] [walk :as walk]] etc.

16:09 ^requires in there...

16:10 polypus: ~ping

16:10 clojurebot: PONG!

16:10 yacin: gotcha

16:10 mmarczyk: the script goes into any directory present directly on the classpath; clojure.jar has "Class-Path "."" in its MANIFEST, so if you put user.clj alongside it, it should work fine

16:12 ...at least I think that's why my setup for experimental repls involving ~/.clojure/{clojure.jar,clojure-contrib.jar,swank-clojure.jar,user.clj} works :-)

16:13 yacin: yeah, i just dumped it in ~/.clojure

16:13 polypus: if i define a seq using cycle or repeat and hold on to the head while bang on it for a while, is the seq caching aware of the cyclic nature of the seq, i.e. does it cache all the values, or just the period of the cycle? if that makes any sense

16:15 i.e. (def s (repeat 4)) (take 1000000 s) are 1000000 values cached or just 1 because it's a repeat

16:16 mmarczyk: it's aware of its cycling value

16:17 if I understand you correctly

16:17 (def t (cycle [(promise)])) (deliver (first t) :foo) @(second t)

16:17 gets back :foo

16:18 (meant to say "cyclic nature" above)

16:19 ah, wait, I guess I did misunderstand...

16:19 polypus: mmarczyk: what i mean is will the seq cache consume 1000000 int's worth of memory or just 1

16:20 because i've held on to the head

16:20 mmarczyk: yeah

16:20 polypus: yeah 1000000

16:20 ?

16:20 mmarczyk: (let [foo (cycle [:foo])] [(first foo) (first (drop 100000000 foo))]) ; => see if memory runs out :-)

16:24 having looked at the code I'd still say it knows it's cyclic

16:26 however that's not to say the generated lazy seq cannot get bigger... I guess it will, due to bookkeeping (multiple pointers to the same seq bundled with instructions to go on cycling when the end is reached)

16:26 that's as far as I can tell, anyway.

16:27 polypus: mmarczyk: ok ty, the code you just posted did not run out of memory but i'll mess around a bit more. would be good to know for sure though, cuz you don't seem %100 convinced

16:28 mmarczyk: well the seq cycle returns will doesn't make copies of the cycled seq as it goes

16:29 it sorts of "chains together" multiple pointers to the same seq

16:29 and at the end there's a "terminator" which, if you hit it when traversing the cycled seq, will produce extra elements

16:29 so whatever was in the cycled seq will not be replicated (as the promise/deliver example demonstrates)

16:30 but there will be a growing lazy seq scaffolding

16:30 polypus: mmarczyk: thanks again

16:30 mmarczyk: np

16:30 I am, say, 99% convinced ;-)

16:30 polypus: :)

16:31 Kjellski: is it deprecated to use (defstruct ...) ?

16:31 polypus: Kjellski: yeah, use defrecord or deftype

16:31 Kjellski: polypus: thanks =)

16:32 polypus: np

16:33 Kjellski: polypus: ... they´re not in the cheatsheet at clojure.org/cheatsheet =(

16:35 mmarczyk: Kjellski: actually they haven't been released... 1.2 stuff

16:35 polypus: Kjellski: http://clojure.org/datatypes

16:36 mmarczyk: Kjellski: so, if you're on 1.1, you won't be able to use them, but transitioning from structs to records should be entirely painless

16:37 Kjellski: thanks to both of you, but in that case I could use (defstruct ...) nevertheless?

16:38 polypus: Kjellski: yeah, like mmarczyk says, it'll be easy to upgrade later

16:38 and np :)

16:38 Kjellski: polypus: alrightyyyy thennnn ^^

16:38 mmarczyk: :-)

16:47 dnolen: rhickey: equiv isn't quite as zippy for me as the latest equal. but perhaps the more important issues are addressed.

16:53 arohner: stupid question: in paredit mode, how do you split strings? i.e. "foo bar" -> "foo" "bar"

16:53 polypus: arohner: option shift s

16:53 mmarczyk: M-S

16:54 arohner: polypus mmarczyk: thank you

17:00 polypus: best performing clojure datastructure for a stack?

17:01 i assume it's a list

17:05 mmarczyk: core functions seem to encourage vector usage -- peek/pop

17:07 polypus: mmarczyk: did you see that in commented code?

17:07 mmarczyk: I just mean that the mere existence of functions called peek/pop suggests that whatever they work on should be a good fit for a stack

17:08 polypus: but they're defined on lists too

17:08 mmarczyk: or a queue, I guess; and indeed, they also work with clojure.lang.PersistentQueue

17:08 hey... never noticed that :-D

17:08 thanks! :-)

17:08 polypus: np :)

17:09 mmarczyk: I thought a transient vector could do well in a single-threaded context, but there is no peek!, only pop!

17:09 and peek doesn't work

17:09 so probably a list after all, though definitely use conj over cons

17:10 riddochc: p WhyteShadow=Well, there's a few particular "parameters" you can tweak to adjust the perception of height in a figure...

17:10 mmarczyk: hm, really no peek! ...? checking again... nope

17:10 riddochc: Ack! Sorry.

17:10 Wrong window.

17:13 polypus: mmarczyk: i am in a single threaded context and don't need peek so maybe it'll do. ty

17:14 mmarczyk: polypus: you don't need to know what's on top of the stack?

17:17 ataggart: since peek doesn't modify anything, why would there need to be a transient version of it?

17:17 mmarczyk: because the regular version works with IPersistentStack instances

17:17 nothing transient is IPersistent*

17:18 polypus: mmarczyk: oops forgot pop returns the rest not the popped

17:18 mmarczyk: polypus: right

17:18 ataggart: ah, good point

17:18 mmarczyk: polypus: actually, why not use java.util.Stack?

17:19 ataggart: hopefully all things that will become nonissues when cic is done

17:19 mmarczyk: ataggart: agreed

17:19 polypus: mmarczyk: that's an idea

17:20 mmarczyk: ataggart: though in this case, I don't see a reason not to provide a transient counterpart to IPersistentStack *or* to use a persistence-agnostic interface

17:20 that's far from saying there isn't one -- just wondering :-)

17:21 ataggart: mmarczyk: agreed. As Rich says: "patches welcome" :)

17:21 mmarczyk: polypus: it's likely to have been beaten to death and back with optimisation sticks

17:21 ataggart: I might oblige when my CA gets processed :-)

17:22 appears to be stuck in the queue

17:25 is there any way to see pull requests one has sent off on GitHub? my memory is failing me and I'd like to check one...

17:36 SirNick: How can I use apply with an arbitrary symbol?

17:36 polypus: SirNick: elaborate

17:37 mmarczyk: trying out java's stack now. ty 4 tip

17:37 SirNick: polypus: Given I have a variable holding a symbol, how can I call apply with that symbol, for example (apply the-variable [])

17:37 mmarczyk: polypus: cool, np :-)

17:37 qbg: (apply (resolve the-variable) ...)

17:38 SirNick: qbg: Resolve is exaclty what I was looking for, thank you

17:38 replaca: does anyone know why the IntrenalReduce version of reduce is commented out currently?

17:38 in core.clj: #_(defn reduce... )

17:39 mmarczyk: replaca: which branch?

17:39 qbg: It isn't for me

17:40 replaca: mmarczyk: master

17:41 mmarczyk: hm, so it is

17:41 no idea

17:41 a08eac88766fa5eca96d: disable direct binding (and internal reduce with it, for now)

17:41 replaca: oh well. It breaks the doc string, but that's not the end of the world as long as it's temporary

17:41 mmarczyk: no rationale

17:42 but if it's somehow connected to direct binding, pre-:static stuff maybe...?

17:42 replaca: mmarczyk: yeah, that would make sense

17:43 mmarczyk: oh? personally, I can't make heads or tails of it ;-)

17:43 planning on a mystery-hunting trip to find out why there's any relation :-)

17:48 while of course I jest, I notice that equal has reinstated internal-reduce (with no mention of :static in core.protocols... oh well)

17:49 Kjellski: gn8 all =)

17:49 thanks for the help

17:49 ;)

18:01 SirNick: Say I have a function defined in namespace A and I call the function from namespace B, resolve then resolves from namespace B but how can I make it resolve from the place it was defined, namespace A?

18:03 AWizzArd: ns-resolve maybe

18:03 qbg: Or you could namespace-qualify the variable

18:03 SirNick: yea I was thinking ns-resolve, but is there anyway I can get around writing out the namespace name explicitly? Something like ns but that doesn't change perhaps?

18:04 rhickey: dnolen: go a git of something that's slower?

18:05 SirNick: I meant to say ns (with astericks) not bold ns

18:05 dnolen: rhickey: ahh, all this different operators because of your research, was using something that got slower (unchecked-multiply), replacing with unchecked-multiply-long fixed it. no equiv is light speed like equal.

18:05 SirNick: Well it did it again even with added spaces... that's annoying

18:06 ataggart: Am I the only one who never seems to pass around symbols? Is this a CL thing?

18:07 AWizzArd: SirNick: would it work that your function in A becomes a closure, capturing its own ns at compile time and using that then with ns-resolve?

18:07 mmarczyk: SirNick: functions can have metadata attached currently, so you can put the ns name there

18:07 in fact

18:08 $(meta #'reduce)

18:08 sexpbot: => {:ns #<Namespace clojure.core>, :name reduce, :file "clojure/core.clj", :line 773}

18:08 SirNick: AWizzArd: Hmm that might work, but I am not sure how to accomplish such a thing in clojure

18:08 mmarczyk: here you go

18:08 (meta #'your-var)

18:08 SirNick: mmarczyk: Oh interesting idea... I'll look into that as well, thanks

18:09 mmarczyk: ah, no, actually that presupposes an ability to resolve the Var

18:09 SirNick: mmaryczyk: would there be a way to get the metadata of the function you're currently in perhaps?

18:09 mmarczyk: I guess so

18:09 qbg: SirNick: Any reason why you can't namespace-qualify the symbol in the variable?

18:10 SirNick: qbg: well the function takes one argument and that argument is converted to a string for one purpose and is also used to call other functions in the same namespace

18:10 mmarczyk: $(^{:foo :foo} (fn foo [] (meta foo)))

18:10 sexpbot: => nil

18:11 mmarczyk: :-(

18:11 but it works for me at the repl :-/

18:12 $(^{:foo true} (fn foo [] (meta foo)))

18:12 sexpbot: => nil

18:12 mmarczyk: an equal-branch repl, but I don't see how that would be relevant

18:13 qbg: ,(name 'clojure.core/+)

18:13 clojurebot: "+"

18:13 SirNick: Hmm interesting, I thought name would include the namespace

18:14 well then I suppose that would work... makes things a bit more bulky to call the function though since I would have to write the function twice

18:14 Sorry, I mean the namespace twice

18:14 qbg: `+

18:14 ,`+

18:14 clojurebot: clojure.core/+

18:14 mmarczyk: ,(.namespace 'clojure.core/+)

18:14 clojurebot: java.lang.IllegalArgumentException: No matching field found: namespace for class clojure.lang.Symbol

18:15 mmarczyk: ,(.getNamespace 'clojure.core/+)

18:15 clojurebot: "clojure.core"

18:15 qbg: ,(namespace `+)

18:15 clojurebot: "clojure.core"

18:16 mmarczyk: oh, missed the wrapper

18:16 qbg: find-doc is useful

18:16 SirNick: see what I'm trying to avoid is having to call it like this (feeds/fetch-cached feeds/feed-name)

18:16 mmarczyk: right :-)

18:17 well, if you're just going to evaluate something in a different namespace

18:17 have a look at clojure.contrib.with-ns/with-ns maybe

18:17 (with-ns feeds (fetch-cached feed-name))

18:18 SirNick: hmm that might work

18:18 mmarczyk: not a good idea if this should cause side effects in the current namespace, of course

18:18 but for a pure function it works fine

18:20 rhickey: hrm, clj: http://github.com/liebke/clj, but the shell script to run clojure is likely to be called clj...

18:21 mmarczyk: SirNick: going funky (probably nonsensical, too) now: (clojure.walk/prewalk-replace #(if-let [v (and (symbol? %) (get (ns-publics 'feeds) %))] v %) '(fetch-cached feed-name)) ...use in a macro

18:22 SirNick: heh, wow, haven't been using clojure long enough to follow exactly what's going on there

18:22 mmarczyk: rhickey: indeed it is... plus, is this significantly different from lein + plugins?

18:23 technomancy: mmarczyk: it's remarkably similar to what I had in mind for lein 1.3 but haven't gotten around to implementing yet. =)

18:24 mmarczyk: technomancy: I see... so now not only do we not use the well-established JVM-land build tools (because mvn is icky), but also have two build tools of our own? hm :-P

18:25 um, not really build tools, more like "dev environment setup tools"

18:26 Raynes: technomancy: Speaking of leiningen, put out a new version already. You're slow, and I'm impatient. You've only got like 75 projects to work on, it isn't like you have time. ;)

18:26 mmarczyk: ah, scratch that... doesn't if lein doesn't need to duplicate that functionality

18:27 technomancy: Raynes: RC2 this weekend, dude

18:27 * technomancy plays a Malmsteen riff on an air guitar

18:28 Raynes: I don't do release candidates, because I'll bork something. I just can't wait to do "lein upgrade". :D

18:33 technomancy: it's actually pretty easy to use a from-source lein now; the bootstrap process is way simplified.

18:33 course you can always wait too

18:35 SirNick: mmarczyk: This seems to work, but is it a good idea to do this way? http://gist.github.com/453545

18:37 mmarczyk: SirNick: ah, that would be AWizzArd's suggestion

18:37 sure, if it makes life easier for you somehow

18:37 SirNick: Ah, so that's what he was meaning... well good then, thanks to both of you

18:38 riddochc: Hm. It looks to me like liebke's clj project overlaps slightly with leiningen or maven? This is interesting.

18:39 Or not, I suppose. Looks like it's not doing build-systemy things.

18:40 dnolen: riddochc: it's much more like gems it seems to me. simpler though less flexible then lein. but perhaps easier for people new to clojure

18:43 mmarczyk: its name clashes with my Python launcher for Clojure though -- grrr :-P

18:43 dnolen: also simplifies writing a decent bundle for an editor like TextMate it seems.

18:44 * dnolen wonders how many people haven't tried Clojure because they can't use TextMate ... probably a lot

18:45 riddochc: Its name clashes with my use of hashdot, too, but I suppose if clj becomes an "official" launcher, I wouldn't complain much.

18:45 technomancy: riddochc: you're using hashdot? sweet.

18:46 riddochc: Alternatively, we could look for a word for some mineral or rock that has the letters 'cl' in it somewhere.

18:46 Yeah, hashdot helps me keep my classpath sane.

18:48 technomancy: riddochc: does it have a sane build yet? I wanted to fix it, but the madness of makefiles plus .deb creation scared me off.

18:49 riddochc: One thing I haven't done yet is figure out good way to develop a hashdot-based script with slime/swank...

18:50 Sane build? I don't know, it's not the simplest system possible, that's for sure, but it solves the problem for clojure, jruby, and sisc all at once.

18:50 mmarczyk: riddochc: clinohumite :-P

18:50 technomancy: when I was using it you had to manually edit the makefile to point to your java home... this was basically right after it came out though.

18:51 I used to work with its author.

18:51 riddochc: For most things I build from scratch, like hashdot, I do something like ./configure --prefix=/usr/local/stow and then use Gnu stow to manage a ton of symlinks from /usr/local/bin/x etc. to /usr/local/stow/package/bin/x etc.

18:51 technomancy: cool

18:51 mmarczyk: whoa.

18:52 riddochc: I don't recall having to tell it to point to my java home, but it was a while ago I did it. Not sure.

18:53 Yeah, someone pointed me to gnu stow a few years ago, and it's become a seriously indespensible tool for me.

18:53 I use it and a shell script to switch between a zillion versions of ruby, for example.

18:54 mmarczyk: what OS?

18:55 riddochc: Linux, mainly. But I don't see why it wouldn't work on mac.

18:56 So, for example, I have /usr/local/stow/clojure-07f05862c2362f6b51e7c92ccd9476c45c9dff6e/lib/clojure.jar which is pointed to by a symlink, /usr/local/lib/clojure.jar To switch to a different version of clojure, I use stow like a package manager.

18:56 mmarczyk: I'm a penguin too ;-)

18:57 riddochc: Cool, mmarczyk. A lot of my fellow linux friends RL switched to apple systems over the years, I feel like a holdout.

18:58 mmarczyk: yeah... a friend of mine who as good as introduced me to Linux has bitten the devilish apple too... now he calls my notifications service "growl" :-(

18:59 riddochc: Anyway, that's my system. Usually, my hashdot scripts reference jarfiles in /usr/local/lib/ so they follow the updates as I build new versions of things. When I need to refer to a specific version, I refer to files within /usr/local/stow/...

19:00 Though now that I think of it, maybe I should have /usr/local/jar instead. I suppose jarfiles don't *really* belong in a lib directory.

19:04 * Lajla goes sitting in mmarczyk's lap

19:04 lpetit: thinking about the fact that currently, in counterclockwise (and I guess in enclojure as well ?), we always AOT compile namespaces, "to be certain" that the relevant bits that must absolutely be AOT compiled "by essence" (generating java classes/interfaces/protocol interfaces/type classes for java interop) are AOT compiled

19:04 Raynes: That's horrifying.

19:06 lpetit: wouldn't it make sense to have a mode where only those parts I qualified as "relevant" are AOT compiled ? that is only compile in memory everything, but genclasses, geninterfaces, protocol interfaces, definterfaces, type classes (close world of type of things which *need* to be AOT compiled for java interop)

19:06 ?

19:06 mmarczyk: lpetit: could you possibly delegate some of the work to a build manager? say, use lein as a library?

19:07 or maybe clojure-maven-plugin if that's required to play nice with the ide

19:07 lpetit: mmarczyk: I don't see how lein could help. I want something totally automatic.

19:07 riddochc: I still seem to be tripping over issues related to AOT compiled stuff and version stuff.

19:07 mmarczyk: well, you could just allow the user to specify what needs to be aot'd

19:08 lpetit: I don't want my users to have to specify the list of namespaces to be AOT compiled. I even don't want "namespaces" to be AOT compiled. Only the relevant parts. If a namespace defines 3 regular functions and 2 protocols, I just want the interfaces related to the protocols

19:08 mmarczyk: ah, that's actually what you suggest

19:08 hmmm

19:08 oh, so it isn't.

19:08 lpetit: mmarczyk: that's exactly what I want to avoid :-)

19:08 mmarczyk: lpetit: got that now :-)

19:09 I wonder if (binding [*compile-files* true] (eval '(definterface ...))) would do that...?

19:10 lpetit: things that must be AOT compiled for java interop will always (in java) be things that can only be loaded once per JVM, I guess. I just want to minimize the disk I/O work while recompiling the whole project. And also minimize the number of files in the disk after a day full of work !

19:10 riddochc: Well, have fun clojuring. Gotta run.

19:11 lpetit: (because everytime a ns is recompiled, new function names appear in the classes/ folder ...)

19:11 mmarrczyk: maybe. but, again, code cluttering ....

19:11 mmarczyk: lpetit: ah, so you want a new, really fine-grained compile function

19:12 lpetit: mmarczyk: yes, balancing the potential virtues of that

19:12 s/balancing/contemplating/

19:12 sexpbot: mmarczyk: yes, contemplating the potential virtues of that

19:13 mmarczyk: that would be cool, especially since I guess interfaces don't really depend on Clojure, so they could be AOT'd and not break cross-clojure.jar compatibility

19:13 right?

19:15 lpetit: right for interfaces.

19:16 for types, I guess not right. for gen-classes, which generate stubs, I guess not right. :-(

19:20 time to go to bed, let's continue this discussion later :)

19:23 mmarczyk: good night :-)

19:23 ataggart: Other than nil punning is there a rationale for using next vs rest? I tend to use next, but much of the code I see online is using rest.

19:25 mmarczyk: rest is lazier

19:26 next evaluates the head of its return value, whereas rest doesn't

19:26 defn: http://www.youtube.com/watch?v=KrfpnbGXL70

19:27 lol.

19:27 rfg: defn: Yeah, it's great :)

19:27 ataggart: mmarczyk: that was my thinking as well.

19:29 defn: They enable us to send XML messages through SOAP. Through SOAP!"

19:31 mmarczyk: defn: that... is... AMAZING!!! :-DDD

19:31 defn: mmarczyk: :)

19:31 I wish they would have mentioned Clojure in there

19:31 they only have Scala Johannson

19:32 technomancy: clojurebot: soap is <reply>"They enable us to send XML messages through SOAP. Through SOAP!!!" (http://www.youtube.com/watch?v=KrfpnbGXL70)

19:32 clojurebot: c'est bon!

19:32 defn: hahaha, well done technomancy

19:35 lol I missed how his dad actually dies

19:36 His dad rips his shirt and finds the Java tattoo with a heart around it, bahahaha

19:36 ah man -- brilliant

19:37 ataggart: the shutdown chime when the guest gags at the kids announcement: priceless.

19:37 mmarczyk: then he has "Where do you want to go today?" on his gravestone

19:37 just watched again, still can't believe this :-D

19:49 ataggart: technomancy: do you foresee any reason to avoid augmenting lein to optionally process/emit dependencies a la ivy? There are a few cases I'm running into where maven's all-or-nothing approach is causing problems.

19:53 technomancy: ataggart: I evaluated Maven, Ivy, and maven-ant-tasks before starting Leiningen, and the latter was the only one I could get working at all. I think it would be doable with Ivy, but it would be a lot of work, and I don't know what the benefits would be.

19:53 that said, it would be easy to write a plugin that could emit an ivy.xml file which you could use for certain ivy-specific operations.

19:53 ataggart: ivy's dependency system is far more flexible than maven's

19:54 basically ivy is a superset of maven w/r/t dependency management

19:54 technomancy: sure, but maven's is a lot more flexible than leiningen's, and I've never found myself needing more flexibility than that. =)

19:54 ataggart: heh I do

19:55 maven's dependency stuff is pretty limiting for us

19:55 technomancy: I guess I would need to see some use cases.

19:57 ataggart: one hypothetical example would be c.c.logging emitting multiple configurations depending on what implementation you wanted to use

19:57 so I could depend on a particular configuration of the logging lib, and only those transitive deps for that configuration would be pulled in

19:57 not every single possibly needed transitive dependency

19:58 technomancy: hmm... I still haven't figured out why you'd want to use c.c.logging against anything other than log4j, but maybe I'm missing something.

19:58 it's not like you can have a medium-to-large-sized clojure project without already pulling in log4j. =)

19:58 ataggart: it was an example of the filtering of transitive dependencies

20:00 for a more real world example, we have a rest framework that supports representing resources as xml, json, etc. each of those are underpinned by a transitive lib. if one doesn't care about the json stuff, then one could depend on the rest framwork's "runtime" and "xml" configurations

20:00 and only get those dependencies

20:01 it's not a big deal when one has a shallow dependency tree, but for more complex systems without that kind of specification someone could end up pulling in many dozens of unneeded jars

20:02 technomancy: it seems like you could get close to the same effect by just splitting it into multiple artifacts

20:03 I don't know... I'm unlikely to implement it myself. if you would like to experiment with it and try to determine if it'd be possible without doubling the complexity of the deps task, I might be convinced if it's clear people would use it.

20:03 ataggart: yes you could move the cost into the project organization, and break things up as needed, but sometimes that's not very useful when it's one new local class that needs some lib that in turn needs a dozen other libs

20:03 it's already possible since I made it work

20:03 I'm just trying to guage the pushback

20:05 technomancy: why don't you ask on the mailing list to see if that problem is affecting many other users?

20:06 ataggart: k

20:11 yacin: are there already jars set up for clojure 1.2 for lein?

20:12 technomancy: yacin: [org.clojure/clojure "1.2.0-master-SNAPSHOT"] should do the trick

20:23 (def foo (constantly (bar))) ;; <= bar is only evaluated at compile-time, right?

20:38 hiredman: technomancy: eh, functions are called at runtime

20:39 technomancy: hiredman: I mean bar isn't called for every call of foo.

20:40 ,(let [a (atom 0) foo (constantly (do (swap! a inc) :hi))] (foo) (foo) (foo) @a)

20:40 clojurebot: 1

20:42 tomoj: constantly is a function, so

20:42 technomancy: (pardon the gratuitous do)

20:42 yes, that. =)

21:28 polypus: anybody know why peek is not supported on a transient vector?

21:58 ataggart: polypus: no one cared enough to submit a patch?

21:59 but since you know it's a vector: (let [t (transient [1 2 3])] (get t (dec (count t))))

22:06 polypus: ataggart: ok, ty

22:09 ataggart: btw why do you need peek if you're the one modifying the transient?

22:11 polypus: ataggart: cuz i'm using it as a stack and it get recursed over

22:12 ataggart: k

22:13 polypus: s/get/sets

22:13 s/sets/gets :)

22:26 Raynes: Is there a way to run uncompiled clojure code inside of a jar? I think we need to get rid of jars and start using special cljars. :D

22:26 tanob: Raynes: I would name "clars" :)

22:27 Raynes: >_>

22:28 lancepantz: Raynes: you're actually not supposed to compile clojure inside of jars

22:28 wars you have to

22:29 Raynes: Huh?

22:29 I'm not sure I caught that right.

22:29 lancepantz: i think i may be misunderstanding

22:29 but you shouldn't put class files generated from cljs inside of jars

22:30 tomoj: uncompiled clojure code in a jar works fine

22:30 lancepantz: the idea being that your jars are not dependent on a specific version of clojure

22:30 Raynes: Oh, I don't want to.

22:30 tomoj: Not if you're trying to *run* the code.

22:30 polypus: Raynes: if you do 'lein jars' and unzip the jar you'll see just plain uncompiled clojure files

22:31 tomoj: oh, I see

22:31 no main class?

22:31 hiredman: lancepantz: pretty sure you don't really need to in wars either

22:31 Raynes: I don't want to compile the code.

22:31 I'm just saying. There is no way to package up a Clojure application without compiling the code, as far as I know.

22:31 hiredman: you just need a compiled servlet class and it can load and compile clojure at runtime

22:32 polypus: Raynes: just try lein jars. no compilation involved

22:32 Raynes: That doesn't help.

22:32 tomoj: certainly need compilation

22:32 of _something_ anyway

22:32 lancepantz: hiredman: that may be true

22:32 hiredman: Raynes: https://www.assembla.com/spaces/clojure/tickets/315-add-support-for-running--main-namespace-from-clojure-main-without-aot

22:34 tomoj: that wouldn't help for a runnable jar, would it?

22:34 Raynes: Yeah, it would.

22:34 tomoj: run some wrapper instead?

22:35 Raynes: It's not hard to work around, but it sucks to have to work around it.

22:35 It will be really cool to be able to make use of jars without AOT.

22:35 For applications, I mean.

23:18 Is there a way to stop Clojure from printing the already refers to warnings?

23:35 ,(clojure.contrib.string/ltrim " blah")

23:35 clojurebot: "blah"

23:58 defn: Anyone here meditate?

Logging service provided by n01se.net