#clojure log - May 18 2010

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

0:12 jColeChanged: How would I create a function which would return 1 the first time it was called, 2 the second time, 3 the third ect

0:14 rava: jcolchanged: just have the function increment a counter var

0:20 turbofail: jcolchanged: what you may really want is an infinite stream that counts upwards

0:21 but if it's not then do what rava said

0:22 jColeChanged: I'm actually confused as to how to persist assignment between function calls.

0:23 TheBusby: (def current-count (ref 0)) then, (defn inc-count [] (dosync (ref-set current-count (inc @current-count))))

0:24 jColeChanged: Thanks.

0:26 rava: or use alter

0:58 mmarczyk: on 1.2, (deftype Counter [^{:volatile-mutable true} cnt] clojure.lang.IFn (invoke [this] (set! cnt (inc cnt)))) is also a possibility

1:29 kanak: Hi, in Programming Clojure's chapter on refs, the following snippet is called "bad idea":


1:29 ; bad idea

1:29 (defn naive-add-message [msg]

1:29 (dosync (ref-set messages (cons msg @messages))))

1:29 is it a bad idea because accessing and updating are not a single step?

1:36 rava: Essentially, yes. or at least that's how I understand it. If there's no need to deref the var first, like in the example where you don't care about the contents..you're just appending, it doesn't make sense to have to deref and re-set the ref.

1:36 Chousuke: I suppose it's a bad idea because you could just use alter or commute (if order doesn't matter)

1:47 joshua-choi: clojure.contrib.seq/separate is ostensibly useful, but I find that in all cases that I want to use it, I should use (map #(if ...) s) instead. Also, it crawls twice.

1:54 G0SUB: Chousuke, ping

1:56 LauJensen: Morning all

1:56 mmarczyk: hi Lau

1:56 nice work on the site -- and the blog post :-)

1:56 G0SUB: LauJensen

1:56 LauJensen: Thanks a lot mmarczyk !

1:56 mmarczyk: (and btw, thanks for the corrected classpath-building script :-))

1:57 LauJensen: np - it went into my 'deploy' script which converts the old site, builds the new and rsyncs it to the server

1:57 mmarczyk: cool :-)

1:57 G0SUB: LauJensen, something is wrong with your feed URLs. they are going to the CSS file.

1:58 LauJensen: G0SUB: Im on that right now actually

1:58 The way I inject CSS matches <link rel="atom" as well - gimme a couple of minz :)

1:58 rdsr: joshua-choi: how is (split with #(...) s) different from separate?

1:58 G0SUB: LauJensen, sure. I was surprised because your posts are not appearing on Planet Clojure.

1:59 LauJensen: I appologize for the inconvinience

1:59 joshua-choi: rdsr: You mean, in traversing the sequence twice? I'm not quite sure. :|

1:59 G0SUB: LauJensen, no problem man :) take your time.

2:00 rdsr: joshua-choi: in terms of functionality, maybe I can't think of any good examples

2:00 a little thick headed today I guess :(

2:00 rava: greetings all

2:02 LauJensen: really dig the blog

2:02 LauJensen: rava: the blog as in content or the design?

2:02 rava: LauJensen: both :)

2:02 LauJensen: rava: great, cool, thanks :)

2:03 rava: LauJensen: http://www.bestinclass.dk/index.clj/blog.html that link goes to 404

2:03 rdsr: oh sorry, just realized my mistake

2:03 LauJensen: rava: true, there's no file there

2:04 rava: LauJensen: its all sorts of helpful to have some well written code + commentary to read through as i'm teaching myself clj. the hardest part for me learning clj is wrapping my head around the idioms of functional programming.

2:04 G0SUB: hmm... Apress vs. Manning vs. Packt

2:04 argh!

2:05 LauJensen: rava: yes that is a painful but worthwhile experience :)

2:07 alexyk: mmarczyk: so every?-based version is much slower than a loop one: http://paste.pocoo.org/show/215132/

2:07 sometimes FP is pretty but slow, even though it allows for pmap!

2:08 LauJensen: Could somebody do me a favor and try to and leave a comment on my site please

2:08 G0SUB: LauJensen, yeah

2:08 LauJensen: thanks

2:09 G0SUB: LauJensen, done.

2:09 LauJensen: thanks

2:12 G0SUB: Got it thanks

2:17 mmarczyk: alexyk: could you please use some line breaks in there... but anyway, as far as I can see (without the line breaks!), the loop-based version doesn't include pmap, while the every?-based version does

2:19 um, whoops, next time...

2:19 turbofail: ,(doc ->>)

2:19 clojurebot: "([x form] [x form & more]); Threads the expr through the forms. Inserts x as the last item in the first form, making a list of it if it is not a list already. If there are more forms, inserts the first form as the last item in second form, etc."

2:23 LauJensen: G0SUB: moderated

2:24 mmarczyk: if thats a performance enhanced loop, I'd expect to see some hinted ints and transients? :)

2:28 turbofail: hm... that difference in performance is a little surprising

2:35 mmarczyk: LauJensen: not my loop, I only provided a few ideas :-)

2:35 LauJensen: aha - so you're the mastermind :)

2:36 mmarczyk: well, hardly -- I haven't managed to effect a nested ifs -> cond switch ;-)

2:37 Chousuke: how many dreps are there?

2:39 turbofail: dunno... the guy left

2:39 mmarczyk: no idea, you'll need to ask alexyk next time

2:39 Chousuke: the pmap overhead might be killing it if the day seqs are short but there are many dreps :/

2:40 also laziness does add its own overhead even if it didn't use pmap, but it shouldn't be that bad.

2:46 (every? true (map >= s (cons (first s) s)))) wonder if this could be replaced with (apply <= s)

2:46 turbofail: probably can

2:47 mmarczyk: hah, right :-)

2:47 G0SUB: Chousuke, can I PM you? something OT to discuss.

2:48 Chousuke: sure.

2:48 G0SUB: thanks

2:50 rava: LauJensen: I can't seem to find your blog's feed url on your site

2:51 johnmn3: hello

2:51 G0SUB: chouser, ping

2:51 rava: greetings johnmn3

2:52 johnmn3: I'm toying around with a rudimentary clojure code editor. I'm thinking about putting some kind of inspector on the left side

2:53 what do you guys think the most useful inspector would look like?

2:53 I'm thinking something akin to Rich Hickey's inspect-tree

2:54 but where you can drill down into an object... perhaps do a macro expand? or maybe collapsed nodes showed a short string from it's docstring

2:55 I'm not really sure though.

2:58 I really like eclipse's class inspector.. where you can drill down, then you find an object in there you'd like to explore and open it in another window

2:58 and look at all the fields and methods.

3:01 anybody have any preferrences?

3:01 or any preferences?

3:18 G0SUB: what is the difference between dev-dependencies and dependencies in lein?

3:18 why does swank-clojure have clojure 1.2.x as a dev-dependency? does it affect projects using clojure 1.1.0 ?

3:20 rava: LauJensen: on your web scraper blog entry, what ns contains that get-page function?

3:20 lancepantz_: G0SUB: dev-dependencies are not transitive

3:21 G0SUB: in other words, if a project you depend on has a dev-dep, when you do deps it will not get pulled down

3:26 G0SUB: lancepantz_, OK. so swank-clojure 1.2.1 should work fine with clojure 1.1.0, right?

3:27 lancepantz_: i'm not sure

3:27 i think so though

3:37 G0SUB: ok

3:38 kris928: Is anyone here familiar with vimclojure?

3:40 rava: i used it for a spell, what's up?

3:42 kris928: rava: I'm not sure how to get a new repl from within vim. Non of the default keybindings appear to work for me although I don't know if I am getting my Localleader correct.

3:42 LauJensen: rava: sec

3:44 rava: kris928: i could never get the nailgun repl thing to work in vimclojure, and your local leader is usually defaulted to ','

3:44 i ended up using slime.vim before just going back to emacs+slime

3:44 LauJensen: rava: That post has been a headache to me, because the html and regexes escaped Wordpress and mangled the post

3:44 kris928: rava: I think that is what mine is too, but it never does anything when I type "sr" s always triggers edit mode.

3:45 LauJensen: rava: but the text says "if search results contains the raw html output", so get-page would nowadays be called clojure.contrib.io.slurp*

3:45 rava: kris928: yup, what i ran into aswell. never found a satisfactory answer to fixing it.

3:45 kris928: rava: thanks

3:45 rava: kris928: if you're set on using vim, check out slime.vim

3:46 very simple extension that just copies the marked region and outputs it to a screen session running the repl

3:46 kris928: rava: nice, I'll try that

3:47 rava: at the same time you'll keep vimclojure's documentation reflection

3:48 kris928: i found it most useful to run vim, open a terminal and start screen, create the project with lein, hop into the proj dir and run lein repl

3:48 kris928: <3 lein repl for handling all the classpath crud

3:48 LauJensen: cool beans, thanks

3:48 kris928: yeah I like lein, but I need clojure 1.2.0 right now and lein doesn't like that

3:49 rava: kris928: why do you need 1.2?

3:49 kris928: rava: I guess I just want it. Hit a few functions that are in 1.2.0 and not earlier

3:50 rava: kris928: ah. i'm still learning a ton and haven't done anything worth while so haven't looked at 1.2 beyond protocols

3:52 kris928: rava: thanks for help. night!

3:52 rava: kris928: np, rest easy

5:44 liwp: is swank-clojure supposed to load ~/.clojure/user.clj?

5:46 I can see in swank-clojure.el that all the jars in ~/.clojure are added to the classpath, but I can't see .clojure being added or user.clj being explicitly loaded into the repl

5:51 hiredman: liwp: user.clj is loaded from the classpath by clojure

5:51 liwp: hiredman: yeah, I know that, and that works fine for me

5:52 hiredman: I just see all these posts on the web implying that user.clj gets loaded automatically for them by slime/swank-clojure/lein-swank

5:52 hiredman: liwp: oh, right

5:52 liwp: e.g. here http://stackoverflow.com/questions/2854618/using-clojure-contrib-functions-in-slime-repl

5:52 sexpbot: "Using clojure.contrib functions in slime REPL - Stack Overflow"

5:53 hiredman: people making stuff up on the internet

5:53 liwp: and I can't make it work...

5:53 hiredman: yeah that's right :)

5:53 hiredman: make what work?

5:54 liwp: hiredman: ~/.clojure/user.clj doesn't get loaded when I run slime

5:54 hiredman: is ~/.clojure on the classpath?

5:56 liwp: hiredman: probably not. The point is that it seems that other people have ~/.clojure on their classpath automatically when using slime, but I don't. So I'm trying to figure out why not.

5:56 so I'm wondering whether it's something that should work automatically or whether I need to configure something differently

5:56 hiredman: you don't use slime, do you?

5:57 hiredman: I do

5:57 I've never used user.clj

5:57 liwp: fair enough

5:58 rava: the most use so far i've found from a user.clj file is to autoload clojure.contrib.repl-utils

5:58 liwp: I just realised that there's all these contrib goodies that are useful in the repl and I'm not using them since I can't be bothered to (use) them every time I run the repl

5:58 rava: yeah, that's what I'm looking for ;)

5:58 hiredman: *shrug*

5:59 rava: liwp: just add "~/.clojure" to your swank-clojure-extra-classpaths

6:00 liwp: one thing i've found useful is to add "." "./src" "./classes" "./jars" to that aswell

6:00 liwp: rava: ok. I'm just wondering whether all this should work out of the box or not

6:01 rava: liwp: If it is then I've been doing it wrong :) . Even in clojurebox (emacs+slime bundle for windows) i had to manually add ~/.clojure to my classpath

6:02 liwp: rava: ok, thanks

6:03 rava: all and all, its still the jvm, so classpath munging doesn't go away

6:03 and by default clojure/-main isn't going to add ~/.clojure to your class path

6:06 liwp: rava: no, but I was hoping that either swank-clojure (it adds ~/.clojure/*.jar to your classpath automatically) or lein-swank would do it for me

6:06 rava: i've tried it with lein-repl/swank and swank-clojure. I've not had any of them do it. I could be missing something though :)

6:45 bsteuber: how can I check if something implements a certain interface? not isa?, I suppose

6:45 cemerick: instance?

6:45 bsteuber: thx

6:48 ,(instance? clojure.lang.ISeq (into-array [1 2 3]))

6:48 clojurebot: false

6:48 bsteuber: what's wring here?

6:48 cemerick: arrays aren't seqs

6:48 bsteuber: wrong

6:48 so what are they, then, to have first work on them?

6:48 cemerick: ,(instance? clojure.lang.ISeq (seq (into-array [1 2 3])))

6:48 clojurebot: true

6:48 cemerick: but you can just do...

6:49 ,(seq? (seq (into-array [1 2 3])))

6:49 clojurebot: true

6:49 cemerick: if you only care about ISeq

6:49 bsteuber: so how can I ask if seq works on something, then?

6:49 or is there no such general method?

6:49 cemerick: ,(doc seqable?)

6:49 clojurebot: "clojure.contrib.core/seqable?;[[x]]; Returns true if (seq x) will succeed, false otherwise."

6:49 bsteuber: (ah, nice

6:53 patrkris: this should be a simple question: which function do I use to append an element to the end of a sequence? I could use concat and wrap the element in a vector, but there's gotta be another way?

6:54 bsteuber: ,(doc cons)

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

6:54 bsteuber: ,(doc conj)

6:54 clojurebot: "([coll x] [coll x & xs]); conj[oin]. Returns a new collection with the xs 'added'. (conj nil item) returns (item). The 'addition' may happen at different 'places' depending on the concrete type."

6:55 patrkris: yes, but how to *always* add to the end of a seq? if conj is used on a seq besides a vector, the element gets inserted as the first element

6:56 cemerick: patrkris: ensure you're using vectors if you must add to the end of the collection

6:56 bsteuber: ah, sorry

6:57 cemerick: otherwise, *always* adding to the end of a sequence is likely to be inefficient

6:58 patrkris: cemerick: yes - but in this case, it doesn't matter much because the collection wont contain many elements. I was just looking for a shortcut for adding an element to any seq. In which case I could 'vectorize' my seq or use concat by wrapping the element in a collection.

6:59 cemerick: patrkris: the latter is more idiomatic and efficient

6:59 patrkris: (I meant *appending* to a seq - i.e. at the end.)

6:59 cemerick: ok, thanks

6:59 cemerick: Asking to be able to append to any sequence is sort of like asking for a sorted collection without the cost associated with sorting.

7:00 Chousuke: clojure doesn't provide functions for silly operations :)

7:00 patrkris: well, if you have the ability to use concat to concatenate two seqs, wouldn't it be easy (and efficient) to create a function to append an element on top of concat?

7:01 Chousuke: so appending to a sequence has to be done in a roundabout way

7:01 it would be easy, but it's silly, so it won't be provided for you

7:01 patrkris: heh alright :)

7:01 cemerick: hi Chousuke, how goes it?

7:02 Chousuke: I think the point of Clojure is to be the right tool for you, not a too :P

7:02 tool*

7:04 cemerick: (Silly English, what's the "it"? :P) Just fine I think. I'm going to get some food right now. :)

7:05 lpetit: Hello, what problem exactly does the recent commit "hotfix for classloading, force new loader in all cases" solve ?

7:06 I'm asking because we have a bug in ccw involving class files being "still held" by something and maybe (maybe) it was related.

7:06 rhickey: hello, ^^^

7:07 rhickey: lpetit: If you have a reproducible test case for your bug, please try it with the latest

7:08 lpetit: the fix solves a problem with :reload-all and its ilk, but in general it uses finer granularity classloaders

7:08 lpetit: rhickey: that's what I intend to do (hopefully) tonight.

7:08 rhickey: oh, so maybe not related. I'll check.

7:08 rhickey: lpetit: great! let me know how it works out

7:09 cemerick: lpetit: is there a mailing list or google group, etc. for CCW?

7:10 lpetit: cemerick: yes, listed in the homepage of ccw

7:10 ~ccw

7:10 clojurebot: ccw is http://github.com/laurentpetit/ccw

7:10 lpetit: sh***t

7:10 ~counterclockwise

7:10 clojurebot: Counterclockwise aka ccw at http://code.google.com/p/counterclockwise/

7:10 lpetit: so ccw for github, counterclockwise for google code, isn't that logic, heh ? :-)

7:11 cemerick: ah, I didn't put 2 & 2 together re: "Groups:"

7:11 lpetit: cemerick: in practice, I use both mls for annoucing new versions. But both are low traffic.

7:12 cemerick: why ?

7:13 cemerick: lpetit: no particular reason -- just want to keep on top of things. I think CCW has a good deal of potential. What's coming in e4 may be a great set of raw materials a clojure env could do a lot with.

7:14 lpetit: cemerick: it's possible you're more informed than me concerning e4. What particular feature(s) are you thinking about ?

7:15 cemerick: lpetit: I'm not particularly well-informed either :-) IIUC, the entire UI will be accessible through a DOM-like model, making it far easier to modify/generate UI elements at runtime. Components can be styled with CSS. Take those, mix in a clojure frontend for it, and it seems a lot of things become possible.

7:18 lpetit: cemerick:I was aware of the UI being created via EMF models. What I didn't catch is the "dynamic part" of it. Seems interesting, indeed.

7:19 I want clojure on my client side GWT application !

7:19 cemerick: heh

7:20 lpetit: I think we'll all be flogging chouser to resurrect clojurescript soon enough. :-)

7:21 lpetit: cemerick: I didn't check #clojure as "well" as usual. What are the current informal plans for say the next 2-3 months ?

7:22 cemerick: lpetit: you mean release-wise?

7:23 lpetit: cemerick: I know about 1.2, just wondering what were the current research, if the focus remains on working on things related to make cinc become a reality (aka in the following of protocols) or more "exploratory" stuff (aka cells) ?

7:26 cemerick: lpetit: I think only rhickey knows that for sure. My impression is that cells has been shelved for a bit. There's a number of open issues w.r.t. types and protocols that I'd think would be fairly high on the list, which would likely get us closer to cinc (definable factory fns for types, maybe multiprotocols, etc). I remember seeing rhickey talking about/tinkering with readers impl'd in clojure a few weeks ago. *shrug*

7:28 lpetit: any news on the "problem" spotted by cgrand concerning extending protocols on existing types and concurrency ?

7:28 cemerick: lpetit: you'll have to remind me about that -- link?

7:29 lpetit: rhickey: ^^^ (protocols & concurrency) ?

7:30 cemerick: http://groups.google.com/group/clojure-dev/browse_thread/thread/59d2f3a1703cc09

7:32 cemerick: lpetit: yeah, I've no info on that.

7:52 AWizzArd: rhickey: the DynamicClassLoader that Clojure uses... do you think you can make it one day inherit the rights of its parent ClassLoader?

7:53 This would be very nice for Applets and Web Start applications. Currently it is a complex thing to get Web Start running all Clojure code.

7:54 I managed to do so, and am thinking about writing a How-To for that. But the thing is: if the Clojure ClassLoader could inherit the rights of its parent, then the How-To could be greatly simplified.

7:58 rhickey: AWizzArd: what do you mean by inherit the rights?

7:58 AWizzArd: Trying to check what rights the parent has and then setting the own rights to those.

7:59 Currently the default situation is that the Web Start class loader has its own rights, which can mean "all-permissions", while the Clojure ClassLoader still runs in the sandbox with only very few rights.

7:59 I managed to give Clojure also full rights, so I can run anything now via Web Start (or in an applet) easily, but getting there was a long quest.

8:01 If Clojure would "copy" the rights of its parent, then everybody could get started with Web Start (or applets) within 1-2 hours, without Clojure-specific tutorials. With tutorial it is a thing of 10-30 minutes.

8:03 It is a quite intruiging idea to write web applications in 100% Clojure, and this is really possible :)

8:13 rhickey: lpetit: http://groups.google.com/group/clojure-dev/msg/4522fe2e4fa21f63

8:18 lpetit: rhickey: thank s!

8:18 zakwilson_: http://github.com/zakwilson/zutil-clj/blob/master/map.clj <-- request for optimization - can this be made faster?

8:19 rhickey: AWizzArd: how about suggesting a patch?

8:30 AWizzArd: rhickey: oki thanks, I will add an issue then

8:30 rhickey: AWizzArd: I don't want an issue without a patch, please

8:30 cemerick: rhickey: A couple of times last week I bumped into some odd behaviour at the REPL, where an instance of a defrecord Foo would no longer be (instance? Foo obj) after reloading the file that contained the defrecord delcaration. In those cases, (= Foo (class obj)) was no longer true. Is this expected?

8:31 (I can imagine the old class was being GC'd, but I'd hope the instance? check would still work as I'd intuitively expect.)

8:31 AWizzArd: rhickey: I could give you patch, but currently I have no CA. Do you accept them also via fax? :)

8:32 rhickey: cemerick: the classes may be new ones with the same name. If you are keeping an older Foo class instance around, it need not be the same

8:32 cemerick: I try to reuse the class if the definition hasn't changed, but that is an optimization, not a promise

8:35 cemerick: hrm, OK. That almost makes me want to put together a quickie defrecord-once. Very rarely am I reloading a file to change a record's slots, and I'd very much like to not have instance? checks fail in odd ways.

8:35 rhickey: cemerick: can you construct a reproducible test case?

8:36 cemerick: rhickey: I'll see what I can do.

8:37 rhickey: cemerick: the existing logic *should* handle the simple reload case, as obviously there is no change

8:41 cemerick: rhickey: The defrecord spec and the object were actually defined in two different namespaces (reloaded in that order). I wonder if Namespace.referenceClass was simply continuing to get the old Class?

8:43 rhickey: cemerick: but the caching should make new-class identical-to old-class

9:24 yonatan_: hello

9:25 i think i just ran into a bug in clojure's RegexReader

9:25 it seems to choke on #"\Q"\E"

9:25 #"\Q\"\E" works, but matches \" rather than "

9:26 (re-pattern "\\Q\"\\E") works as expected (matches ")

9:26 is this a bug or am i missing something?

9:27 hiredman: what string are you trying to match?

9:27 yonatan_: "

9:28 a double quote char. (re-find (re-pattern "\\Q\"\\E") "\"") works.

9:30 RegexReader interprets a double-quote inside a \Q...\E sequence as the end of the regexp.

9:30 is this the expected behaviour?

9:30 chouser: I think so. That's not really what \Q...\E means

9:30 #"\"" should work

9:31 hiredman: well, \ "quotes"

9:31 and so does \Q \E, yes?

9:31 chouser: \Q is about making chunks of strings act as strings instead of regex metachars

9:32 yonatan_: i thought \Q...\E is supposed to treat everything in between as a literal

9:32 chouser: so if you want . to mean a period instead of "any char", you can wrap it in \Q...\E

9:33 but if you want a literal " you need to use \"

9:34 yonatan_: but you can't do that inside a \Q...\E sequens?

9:34 chouser: , #"\Q\"\E"

9:34 clojurebot: #"\Q\"\E"

9:34 yonatan_: nope

9:34 it matches \" not "

9:35 chouser: ah

9:35 hm

9:35 yonatan_: i ran into it trying to port your patch to las3r

9:35 (the clojure in flash thingie)

9:36 i don't know if it's a clojure issue or a jdk issue

9:37 but since (re-find (re-pattern "\\Q\"\\E") "\"") works i'm thinking maybe it's a bug

9:37 wanted to make sure before i try to fix it

9:40 chouser: well, I guess it's a soft spot in the definition. How do we want it to behave?

9:41 why do you want #"\Q\"\E" to match " instead of \" ?

9:50 yonatan_: dunno, it seems like the right thing to do. i mean, \Q'\E matches ', \Q\\E matches \, \Q.\E matches . why should " be any different?

9:51 that's how it works in actionscript, and http://java.sun.com/j2se/1.4.2/docs/api/java/util/regex/Pattern.html says that's how it should work in java (although i didn't check if it really does).

9:51 sexpbot: "Pattern (Java 2 Platform SE v1.4.2)"

9:58 yonatan_: although Regular Expressions Cookbok says "If you omit the \E, all characters after the \Q until the end of the regex are treated as literals."

10:03 which implies that the regexp can end without an \E. so no need to fix anything i guess :)

10:07 patrkris: rhickey: what exactly from the Ennals paper convinced you that Clojure's STM should not be obstruction-free? I can't connect the ends.

10:27 _na_ka_na_: hi

10:27 when im doing (defrecord A [i j]) .. it gives a reflection warning ..Reflection warning, NO_SOURCE_PATH:4 - call to contains can't be resolved.

10:28 using the latest snapshot for 1.2

10:28 clojure-1.2.0-master-20100518.110252-71.jar

10:29 is this as expected? or am i doing something wrong?

10:32 helloooo anyone?

10:35 AWizzArd: ,(read-string "{:a 1, :b}")

10:35 clojurebot: 3

10:35 AWizzArd: :)

10:35 The Exception is a bit misleading.

10:37 _na_ka_na_: , (defrecord A [i j])

10:37 clojurebot: DENIED

10:37 _na_ka_na_: ,(defrecord A [i j])

10:37 clojurebot: DENIED

10:39 Borkdude: ,(letfn [foo #("umbrella")] (foo)

10:39 clojurebot: EOF while reading

10:39 _na_ka_na_: ,*clojure-version*

10:39 clojurebot: {:interim true, :major 1, :minor 2, :incremental 0, :qualifier "master"}

10:39 Borkdude: ,(letfn [foo #("umbrella")] (foo))

10:39 clojurebot: java.lang.RuntimeException: java.lang.RuntimeException: java.lang.IllegalArgumentException: Don't know how to create ISeq from: clojure.lang.Symbol

10:39 Borkdude: o yeh, never mind

10:48 hoeck: _na_ka_na_: I guess thats a bug, the values method in the defrecord expansion probably needs a typehint

10:50 _na_ka_na_: but the defrecord will work regardless of the reflection warning, it just uses reflection to compute .containsValues

10:50 _na_ka_na_: hmm .. even this gives the same warning (defrecord A [^int i ^int j]) .. never mind

10:50 Licenser: Hmm anyone around who used ring and sessions before?

10:51 hoeck: _na_ka_na_: its not related to hinting the records fields

10:51 _na_ka_na_: hoeck: got it .. thx

10:51 cemerick: rhickey: that defrecord/type class change issue is reproducible, but only sporadically, and does appear to be related to the namespace import mechanism. Gotta run for a bit, but I'll bear down on it later.

10:52 AWizzArd: How can I catch read-time exceptions?

10:52 ,(try (read-string "{[]}") (catch Exception e (println "Hi")))

10:52 clojurebot: AWizzArd: Pardon?

10:52 AWizzArd: On my system this throws an Exception and does not enter the catch block.

10:53 gfodor: are there any known issues with anonymous closures leaking? I have been load testing a service written in clojure and after taking a heap dump after a night of testing, there are thousands of what look to be anonymous function closures stuck in RAM

10:53 chouser: AWizzArd: your exception is coming during printing, not during reading.

10:53 it is read without error, which is a bit startling to be sure.

10:54 AWizzArd: ,{[]}

10:54 clojurebot: java.lang.RuntimeException: java.lang.ArrayIndexOutOfBoundsException: 1

10:54 chouser: ,(class {[]})

10:54 clojurebot: 1

10:54 AWizzArd: chouser: to what does this eval for you? (try {[]} (catch Exception e (println "Hi")))

10:54 chouser: ,(class (read-string "{[]}"))

10:54 clojurebot: clojure.lang.PersistentArrayMap

10:54 Licenser: might it be a lazyness problem?

10:55 hoeck: laziness

10:55 Chousuke: I thought that was a know issue?

10:55 chouser: no, it's just that the reader creates a map that can't print itself.

10:55 not about lazy seqs.

10:55 Chousuke: you get weird behaviour with illegal literals.

10:55 ,`{~@[1]}

10:55 clojurebot: 1

10:55 Chousuke: ,`{~@[1 2]}

10:55 clojurebot: 1

10:56 AWizzArd: ,(with-out-str (read-string "{[]}"))

10:56 clojurebot: ""

10:56 Chousuke: hm, the latter has worked for me before :P

10:57 Licenser: is the ring developper in the channel every now and then? Everyone an idea?

10:59 AWizzArd: So, currently, if I want to check if some expression is valid I will have to do (try (print (read-string s)) (catch Exception e "not valid"))

10:59 cemerick: Licenser: try #compojure?

10:59 Licenser: cemerick: thanks!

10:59 AWizzArd: putting read-string into try does not do the trick, I also have to print it

11:01 ah okay, this is it then: (try (with-out-str (print (read-string "{[]}"))) (catch ...))

11:02 Licenser: http://grab.by/4rce it worked!

11:05 tcrayford: chouser: ended up giving up on the whole compiler/analyze thing, it wasn't that useful in the end

11:07 Licenser: tcrayford: did you look in the analyzing methods the sandbox provides? they can be 'abused' for quite some funny things

11:08 tcrayford: Licenser: not yet

11:08 Licenser: *nods*

11:08 tcrayford: I found that repetition is almost better done without looking at just the variables in each specific function

11:08 and more looking at the length/layout of sexps

11:08 Licenser: *nods*

11:09 tcrayford: it points out things that should obviously be functions/macros pretty well now that I've made that change

11:11 the next thing to do: code generation for proxy (ala cmerick's article)

11:12 Licenser: is there a type in the docstring for add-reader-to-sandbox? I've never seen the word 'conuse' before

11:12 *typo

11:12 Licenser: tcrayford: I've never seen it before either :P

11:13 tcrayford: :)

11:20 AWizzArd: What is a meaningful Exception for wrong entries in a config file?

11:23 MrHus: Hi I came across The Clojure Library Coding Standards, and saw the following rule:

11:23 Unroll optional named arguments. Callers should not have to wrap optional named arguments in a map literal:

11:24 But how do you get the [& args] in a map

11:24 An example from the page: (release-sharks 2 :laser-beams true) ; good (release-sharks 2 {:laser-beams true}) ; bad

11:26 Licenser: question: I have this code:

11:26 (. clojure.lang.LockingTransaction (clojure.core/runInTransaction (clojure.core/fn [] (alte r y inc)))) (it is a dosync)

11:26 Chousuke: MrHus: on 1.1, (apply hash-map args)

11:26 Licenser: what is happening here? clojure.lang.LockingTransaction is a class, but there seems to be no function called o.O

11:26 hoeck: MrHus: (defn foo [n & {:keys [laser-beams, other-key]})

11:26 Chousuke: MrHus: and 1.2 has a new destructuring syntax, so you can do ... that.

11:26 Licenser: is it the same as new?

11:27 Chousuke: Licenser: note the . special form

11:27 AWizzArd: ,(Exception. "hi")

11:27 clojurebot: #<Exception java.lang.Exception: hi>

11:27 Chousuke: it

11:27 AWizzArd: ,(throw (Exception. "hi"))

11:27 Licenser: Chousuke: yap

11:27 clojurebot: java.lang.Exception: hi

11:28 AWizzArd: ,(throw (proxy [Throwable] [] (getMessage [] "hi")))

11:28 clojurebot: java.lang.IllegalStateException: Var null/null is unbound.

11:28 AWizzArd: hiredman: uh oh

11:28 Chousuke: it's calling the runInTransaction method of the LockingTransaction class.

11:28 Licenser: The question is the . special form takes a class a member and parameters right? but I don't see a member or parameters in this call

11:28 Chousuke: it works for static methods too.

11:28 Licenser: but why the () there?

11:29 Chousuke: the static method takes parameters :)

11:29 (. class (staticmethod args))

11:29 (. obj (instancemethod args))

11:29 Licenser: oh I thought it was like (. class method args)

11:29 darn it ^^

11:29 AWizzArd: Anyway: is there a name to give my proxied Throwable a custom name? Something different from #<Throwable$0 my.companies.ns.proxy$java.lang.Throwable$0>?

11:30 Licenser: Chousuke: thanks for the update :) I'll work this out!

11:30 Chousuke: AWizzArd: not the class.

11:30 AWizzArd: ,(proxy [Throwable] [])

11:30 clojurebot: java.lang.IllegalStateException: Var null/null is unbound.

11:30 AWizzArd: Chousuke: ok

11:32 Chousuke: Licenser: note that the syntax means that if you want to call a method on an instance of Class, you need to do eg. (. (identity String) newInstance) :)

11:32 Licenser: but this is usually not a problem

11:32 MrHus: Chousuke so you can't destructure the argument in a map in 1.1?

11:32 Chousuke: MrHus: correct. it's a new feature.

11:33 Licenser: Chousuke: it is for clj-sandbox to allow dosync ;)

11:33 Chousuke: Licenser: usually the difference is determined from the sugared form

11:33 joshua-choi: Question: when protocols were first introduced (http://www.assembla.com/wiki/show/clojure/Protocols), I got the impression that you named them "ASomething" by convention. Is this really true though?

11:33 sexpbot: "Show | Clojure | Assembla"

11:33 Chousuke: ie. (.foo bar) is always an instance method call

11:33 joshua-choi: nah.

11:34 joshua-choi: Eh.

11:34 Chousuke: joshua-choi: I think the convention is just to call them Something :P

11:34 joshua-choi: though that might change.

11:34 MrHus: Chousuke What's the syntax in 1.2?

11:34 Chousuke: joshua-choi: PSomething is not a bad choice either.

11:34 joshua-choi: Chousuke: Oh oh. Well, I'll get rid of my "A"s.

11:35 What's up with APersistentList, etc., though

11:35 Chousuke: MrHus: just map destructuring after the &, borrowing hoeck's example (defn foo [n & {:keys [laser-beams, other-key]})

11:36 joshua-choi: they're abstract base classes

11:36 joshua-choi: Ah

11:36 Better not conflate protocols with them then

11:36 Nomenclature-wise

11:36 Chousuke: yeah.

11:40 hamza: guys how can i access a filed in a proxy? such as extended class has a filed called someObject and i need to invoke a function on this object?

11:41 * field

11:42 Chousuke: 'this is bound to the proxy instance within its methods

11:44 hamza: Chousuke: (.someObject 'this) is this the correct usage?

11:44 Chousuke: no, that would be calling the method on the symbol :P

11:44 lose the quote :)

11:45 AWizzArd: Better test than (or (true? b) (false? b))

11:45 hamza: kk, thanks alot.

11:46 AWizzArd: ah (instance? Boolean b)

11:46 Chousuke: heh, that is indeed a confusing test :P

12:04 rsenior: lpetit: thanks for the blog comment, do you have some info on the -?> operator you mentioned? I couldn't find it in the docs...

12:06 lpetit: look in clojure.contrib.core

12:06 ,(doc -?>)

12:06 clojurebot: "clojure.contrib.core/-?>;[[x form] [x form & forms]]; Same as clojure.core/-> but returns nil as soon as the threaded value is nil itself (thus short-circuiting any pending computation). Examples : (-?> \"foo\" .toUpperCase (.substring 1)) returns \"OO\" (-?> nil .toUpperCase (.substring 1)) returns nil "

12:06 lpetit: rsenior: ^^^

12:07 rsenior: lpetit: ah, in contrib, thanks

12:08 lpetit: rsenior: I know the -?> operator quite well (wrote it, my only contribution AFAIK :) )

12:09 must leave, cu

12:09 rsenior: lpetit: does just what I need, I also didn't know that -> works on java methods, I thought it was just for clojure functions

12:10 lpetit: rsenior: np, clojure changes are not always well propagated, and the most stuff I know has been gathered on the ml and this channel

12:10 (I mean, once I had read the clojure.org site from a to z, of course)

12:20 arkahn: do the macros #^ and ^ have anything to do with each other, or is #^ still current and ^ just being deprecated and forgotten?

12:21 chouser: in git master, #^ and ^ mean the same

12:22 arkahn: chouser: is that 1.2/1.3?

12:23 chouser: 1.1 gives deprecation warnings on ^

12:25 hamza: is not permitted to access protected objects in a class? when i do (.someObject (proxyed-class)) gives field not found exception..

12:25 chouser: arkahn: right, in 1.1 ^foo expanded to (meta foo), with deprecation warning.

12:26 in 1.2 ^ will mean the same as #^

12:26 arkahn: chouser: thank you

12:27 and I think google needs to learn how to search on things like #^ ; )

13:10 LauJensen: http://dorophone.blogspot.com/2008/03/common-lisp-reader-macros-simple.html

13:10 sexpbot: "Dorophone: Common Lisp Reader Macros: A Simple Introduction"

13:10 LauJensen: :)~

13:13 KirinDave: Reader macros are beautiful

13:13 I miss them badly

13:16 etate: LauJensen: your new blog is awesome man... this is the best use of clojure on the web i've seen so far - very professional

13:16 LauJensen: congrats

13:16 LauJensen: etate: wow, thanks man :)

13:16 KirinDave: LauJensen: url plz?

13:16 LauJensen: btw, Ive been looking for you, where's that bright theme? :)

13:16 technomancy: I was wondering how long it would take before the ".php" in the URL would be too much for Lau to take. =)

13:16 LauJensen: KirinDave: http://www.bestinclass.dk/blog.html

13:16 sexpbot: "Best In Class - Software Innovator"

13:16 LauJensen: technomancy: yea, it was killing me :)

13:17 KirinDave: LauJensen: So this is in clojure?

13:17 LauJensen: yep

13:17 etate: LauJensen: :) Im in process of changing it i'll paste it a bit later for you

13:17 KirinDave: Fun

13:17 Is it on GAE?

13:17 LauJensen: Nope, just a Linux/NGINX combo

13:18 etate: great, and if Im not here feel very free to send me an email :)

13:18 etate: LauJensen: will do, I really love your new logo

13:18 LauJensen: etate: Im very glad - though its about to get tweaked a little

13:19 (I think)

13:19 Im not sure I can ever be happy with a website that doesn't have the Knight Rider scroller and theme song in flash

13:19 etate: LauJensen: yeah it could use some polish for some of the UI elements but the direction is great, I mean it looks great as it is - and its a good example of how clojure can compete in this domain

13:20 LauJensen: Yea, I hope you guys can verify that the site as a whole is much more responsive now, even in peak periods

13:21 etate: LauJensen: yeah, that was a noticeable difference

13:21 LauJensen: great; I gotta duck out. etate you got my email right?

13:21 Borkdude: etate: LauJensen: agreed about the competition. I just discussed functional programming today with a colleague, that we should promote it at our work, but he said, it's still just an academic thing (he is into Haskell). So I explained him that serious nice things happen these days in Clojure, people translate their blogs into it ;)

13:21 LauJensen: hehe

13:21 etate: LauJensen: Its on your site right? :) So cool that you included enlive tips in your post too :)

13:22 LauJensen: etate: yea it is. And more Enlive tips to come when I realise the code

13:22 Anyway - I gotta duck out

13:22 KirinDave: I went all the way down the rabbit hole of compiling enlive transforms on templates into actual functions before I realized it couldn't work.

13:22 I was pretty bummed out with that.

13:22 Borkdude: LauJensen: bye

13:23 etate: KirinDave: why couldn't it work?

13:23 KirinDave: etate: Because inserting new markup would require a rescan of the whole tree.

13:23 If you are a good boy and your selectors don't overlap in any way, it's MUCH faster.

13:23 Otherwise it reduces to the same thing

13:24 etate: KirinDave: can you not memoize or something? (naive suggestion warning)

13:24 KirinDave: etate: Imagine two xforms on a tree

13:25 One inserts a series of <article> tags.

13:25 The other decorates article tags.

13:25 If the information for generating those article tags is dynamic, it's very difficult to fold the two together.

13:27 etate: KirinDave: so what are you using as an alternative to this?

13:27 or what did you decide on doing in the end :)

13:32 cgrand: KirinDave: can't you decorate the articles as you insert them?

13:36 KirinDave: cgrand: I dunno what that'd be like

13:37 etate: cgrand: by the looks of it this was LauJensens approach in his blog, "baking" the post into html

13:37 KirinDave: cgrand: I just am bummed because I wrote a bunch of code without thinking about it. ;)

13:37 etate: KirinDave: check http://www.bestinclass.dk/index.clj/2010/05/refresh-your-cache--best-in-class-has-been-baked.html

13:37 sexpbot: "Best In Class: Refresh your cache - Best In Class has been baked"

13:38 KirinDave: cgrand: It's possible that for a limited class of selectors I could make it work

13:38 cgrand: But if people get exotic about the boundaries of things, it'd be difficult to get a correct result.

13:42 cgrand: I'm not sure to understand what you want: did you want a sort of pipeline (-> html-tree xform1 xform2 render)?

13:43 I see you are speaking about non-overlapping selectors, in enlive you can now specify sets of indepedent transforms, thus they are applied in one pass

13:43 KirinDave: cgrand: I tried to take the template and the xforms and precompile it into a function that just patches wholes in the template.

13:43 cgrand: Basically xform to a ` macro.

13:43 cgrand: I was trying to get enlive generated pages to exceed 2k r/s

13:44 And it works, but not if the selectors overlap.

13:44 At least not yet

13:45 cgrand: very interesting, are your experiments public?

13:45 KirinDave: cgrand: Sadly, no. It's a microsoft deal.

13:45 But I will recreate at home once I am out from under their cruel yolk

13:45 cgrand: Some common lisp systems do it this way tho.

13:45 technomancy: KirinDave: how much longer?

13:45 KirinDave: technomancy: Sept 1 unless I get a good offer.

13:46 technomancy: nice

13:46 KirinDave: technomancy: A mutual acquaintance of ours has expressed interest in pulling me away. I'm considering it strongly

13:46 * technomancy is sure he has no idea about that ... =)

14:18 ArkRost: Hi! I find a strange thing: ('a 1 2) return 2. Why does it happens?

14:19 chouser: ArkRost: symbols used as functions expect their first arg to be a map, and look themselves up in it.

14:19 ('a {'c 1, 'b 2, 'a 3})

14:19 ,('a {'c 1, 'b 2, 'a 3})

14:19 clojurebot: 3

14:20 chouser: they accept a second arg which is returned if the key is not found

14:20 ,('z {'c 1, 'b 2, 'a 3} :missing)

14:20 clojurebot: :missing

14:20 chouser: that second arg is also returned if the first arg isn't a map

14:20 ,('z 1 :missing)

14:20 clojurebot: :missing

14:20 chouser: ,('z 1 2)

14:20 clojurebot: 2

14:20 chouser: ,('a 1 2)

14:20 clojurebot: 2

14:22 ArkRost: ok. Another question: how can I shadow special forms(def, do and ect)?

14:22 technomancy: ArkRost: if you have to ask ... you should probably think twice before doing it. =)

14:23 there's probably a better way to do what you're thinking of

14:23 sorry to sound like a smartass

14:24 chouser: I actually think it may be impossible

14:24 ArkRost: oh no.. I don't want to use it in code. Just curious

14:24 chouser: ,(let [def 5] def)

14:24 clojurebot: DENIED

14:24 chouser: bah

14:24 ,(let [do 5] (do do))

14:24 clojurebot: 5

14:25 chouser: ,(let [do (fn [] 7)] (do))

14:25 clojurebot: nil

14:25 chouser: yeah, don't do it. Even if it's possible in some cases, such as above, I very much doubt it's supported and could quit working at any time.

14:26 ArkRost: ok. Thanks

14:27 Borkdude: ('fibnext 0 1)

14:27 ,('fibnext 0 1)

14:27 clojurebot: 1

14:27 Borkdude: damn it works! ;)

14:28 ('add 0 1)

14:28 ,('add 0 1)

14:28 clojurebot: 1

14:28 Borkdude: yup perfect.

14:30 what is so graceful about symbols accepting everything, instead of throwing actually?

14:31 lancepantz: Borkdude: i like the behavior, but the powers have be said not to rely on it and they may change it at any point in time

14:31 *that be

14:31 chouser: what? symbols as functions are fully supported, afaik.

14:31 just like keywords

14:31 lancepantz: i thought he was referring to the alphanumeric requirement

14:32 chouser: oh

14:32 lancepantz: i may have misunderstood

14:32 Borkdude: chouser: I mean, you gave the example of the MapKey throwing an exception instead of nil

14:32 why is returning nil better, errors may be hard to find

14:32 lancepantz: yep

14:33 Borkdude: and the same goes for ('foo 'dont-care-what-is-here 'i-just-return-this)

14:34 ,('foo 'dont-care-what-is-here 'i-just-return-this)

14:34 clojurebot: i-just-return-this

14:34 chouser: If any sort of reasonable default behavior can be provided, I genearlly prefer that over exceptions.

14:35 leads to cleaner simpler code, rather than try/catches and if's all over the place.

14:35 Borkdude: so exceptions aren't considered helpful in Clojure?

14:36 Chousuke: I'd say they're a last resort thing

14:36 chouser: I'm not setting clojure policy here, just voicing my agreement with some specific decisions.

14:36 Chousuke: when something is obviously wrong

14:36 technomancy: Chousuke: dare we say ... exceptional?

14:36 Chousuke: technomancy: perhaps.

14:37 technomancy: though what qualifies as exceptional is open to discussion

14:37 chouser: if there is a reasonable and/or obvious default, why not provide that instead of forcing the code to be explicit.

14:37 (meta nil) could throw, but I'm happy it just returns nil

14:37 Borkdude: I would say an empty map is ok, but when would it be good to give a non-map to a symbol?

14:37 Chousuke: Borkdude: maybe you have some generic lookup code

14:38 Borkdude: that could take any collection and just return nil if the item is not there

14:38 or if it's not a collection

14:38 so you can do stuff like (if ('something foo) (dostuff) (fail))

14:39 or just (dostuff ('something foo 'default))

14:40 chouser: hey look, you eliminated an 'if'! congrats!

14:40 Borkdude: I guess you can always check yourself if a map has been provided, if it's really important to you

14:41 Chousuke: if you want an exception you can always do the lookup as (foo 'something) :(

14:41 :) I mean :P

14:41 Borkdude: ,({:a "dude"} :b)

14:41 clojurebot: nil

14:41 Borkdude: ?

14:41 chouser: ,(nil :b)

14:41 clojurebot: java.lang.IllegalArgumentException: Can't call nil

14:42 chouser: ,(1 :b)

14:42 clojurebot: java.lang.ClassCastException: java.lang.Integer cannot be cast to clojure.lang.IFn

14:42 Borkdude: ah ok

14:43 I guess there are always ways to get what you want out of Clojure ;)

14:44 ,nil

14:44 clojurebot: DENIED

15:02 LauJensen: etate: progress? :)

15:02 arohner: is there any way to specify the startup arguments to the JVM using lein / maven?

15:02 or any other tool? I dislike writing my clojure startup script in bash, because that's the only way I know of right now

15:03 tcrayford: lein is just a bash script

15:03 so if you want to, you could copy the lein bash script to your project, then modify it

15:04 arohner: tcrayford: I would like to define my startup script in something lein-y, that would go in the project.clj

15:04 tcrayford: arohner: there's no decent way to do that now (as far as I know)

15:04 the jvm has to start before lein can process project.clj

15:05 arohner: hrm, looks like maven exec might do it

15:06 LauJensen: chouser: when do we get reader macros in clojure?

15:06 chouser: LauJensen: never

15:06 Raynes: Ever ever.

15:07 chouser: LauJensen: of course you can write your own reader and/or fork clojure, but don't expect many people to use your new language. :-)

15:08 LauJensen: chouser: Why not ?

15:08 arohner: LauJensen: reader macros don't compose

15:09 etate: LauJensen: almost there :)

15:10 LauJensen: etate: cool

15:10 arohner: But I just dont see us ever accomplishing the goal of being Lisp-Perl without them :(

15:10 arohner: that's a goal?

15:11 LauJensen: Im kidding of course

15:11 chouser: because you'll have to convince each potential clojure user to trust your judgement over rhickey's. tough.

15:11 kotarak: Isn't @#^foo perly enough?

15:12 LauJensen: chouser: so... no real arguments, its just a matter of taste?

15:12 chouser: what? how'd you get that?

15:13 LauJensen: chouser: I just didn't see a real argument. Reader macros doesn't imply a transfer of trust anymore than regular macros and they can be used in some restricted sense

15:13 kotarak: LauJensen: this was discussed several times, with lots of reasoning in all directions. Check the group archives.

15:14 chouser: I wasn't arguing about reader macros, it's just the challenge that any functionality-fork of clojure would face. You failed to convince rhickey or you wouldn't have forked.

15:14 LauJensen: oh, I wouldn't fork :)

15:14 chouser: ah

15:14 LauJensen: I was just thinking of implementing them in Clojure

15:14 But I'll take kotaraks advice and check the group

15:15 chouser: I think the composability of reader macros is actually a red herring. I mean it's part of the problem, but I actually proposed a feature that would address a subset of reasons people want reader macros that was fully namespaceable, and rhickey smiled politely and said "I don't like it".

15:16 LauJensen: Well, at least he was polite :)

15:16 chouser: they are very rarely necessary and carry a burden for anyone trying to parse or read a clojure file.

15:16 LauJensen: But ok, I guess in all honesty I do actually get along very well without them

15:17 chouser: right now, untrusted clojure can be read. with reader macros this would be impossible

15:17 untrusted clojure code

15:17 LauJensen: depending a little on how you implement them

15:17 chouser: that is a clojure reader doesn't need to be able to eval -- this has benefits for editors, syntax highlighter, code analyzers, etc.

15:18 reade macros by definition eliminate all that.

15:18 and to what benefit? I have a DSL here that needs to support x.y.z field-lookup syntax, with non-standard rules for the resolution of x.

15:18 LauJensen: strong point

15:19 chouser: wrap it in a (--> x.y.z) or something, and a regular macro does just fine.

15:19 etate: LauJensen: http://paste.lisp.org/display/99418

15:19 LauJensen: chouser: , the thing is, I really want 5**2 instead of (Math/pow 5 2) :)

15:19 etate: LauJensen: thats a rough draft of what i'm working on - trying to get rid of the purple

15:19 Chousuke: I think a reader library might be useful though

15:19 chouser: LauJensen: no you really don't.

15:19 * LauJensen is loading color-theme

15:19 etate: LauJensen: I have to head out so i'll send you an updated version some other time :)

15:19 chouser: though apparently Incanter provides that now.

15:20 Chousuke: so people can write their own readers when they need to :)

15:20 kotarak: LauJensen: (def ** #(Math/pow %1 %2))

15:20 LauJensen: cool, thanks etata

15:20 chouser: well, provides 5 ** 2

15:20 LauJensen: chouser: I dont ?

15:21 chouser: rhickey worked so hard to talk us out of including an infix example in the book, and then Leibke goes and puts one in his hugely popular library.

15:21 Borkdude: hehe

15:21 tcrayford: chouser: what did rhickey argue against infix stuff with?

15:21 Chousuke: well, in their defense it does more than just infix math

15:21 and it is a math library :P

15:22 chouser: tcrayford: he was afraid people would actually use it, which was never our point.

15:22 Chousuke: you can just think of it as a dsl for matrix/vector (oh, and scalar) manipulation

15:22 tcrayford: chouser: makes sense

15:23 chouser: our point was to show that clojure could do infix just fine -- the reason it doesn't is because it's undesriable (in clojure) not because it's impossible.

15:23 tcrayford: and demonstrating macros as well

15:24 chouser: I don't think it was a macro. Just a function.

15:24 tcrayford: nice then

15:24 Chousuke: I don't think most people will suffer incanter as a dependency just to get infix math

15:25 chouser: no, but lots of people use incanter. I'm sure I'll end up debugging somebody's infix math code at some point now.

15:25 Chousuke: and I think most math in clojure consists of (apply + ...) or somesuch

15:26 Borkdude: (import-static java.lang.Math pow pow), is this considered normal practice in Clojure?

15:26 Chousuke: Borkdude: you should just use Math/pow I think

15:26 kotarak: no, at least on on my side

15:26 Chousuke: it's not that much longer, is it? :P

15:31 cemerick: arohner: not sure if you've settled anywhere, but look @ clojure-maven-plugin

15:33 arohner: cemerick: interesting. The primary thing I'm looking for is setting JAVA_ARGS

15:35 cemerick: arohner: Sure. That's done via the clojureOptions in the plugin config. i.e. <clojureOptions>-Xmx512m -Djava.awt.headless=true -XX:MaxPermSize=256m</clojureOptions>

15:36 lancepantz: i don't know what to search for, so i'll just ask- how do i jump to the closing parent for one my cursor is in in emacs?

15:36 like % in vim

15:36 tcrayford: I've never found something that works well for that in vanilla emacs

15:36 arohner: lancepantz: C-M-f, if you're running paredit

15:36 lancepantz: s/parent/paren

15:36 arohner: cemerick: cool, thanks

15:36 lancepantz: that works, thanks arohner

15:37 tcrayford: lancepantz: note that works for going forwards

15:37 you need C-M-b for backwards

15:37 lancepantz: just realized that :)

15:37 thansk

15:45 joshua-choi: uestion. I used to do (isa? (type obj) t) whenever I was checking if an object was a certain type. With the advent of records, should I use (= (class obj) t) instead, if I'm *not* using a protocol?

15:46 Chousuke: you can use instance?

15:46 though I think checking for an interface is better.

15:46 the class can freely change then

15:47 joshua-choi: I'm not using a protocol or interface; there's only one type of record to check for. But I suppose that whenever I need to check a type, I should consider using a protocol instead...

15:48 Chousuke: perhaps.

15:48 joshua-choi: I totally didn't know about instance?, though

15:48 Chousuke: a protocol function should be interchangeable with a normal function in the best case.

15:48 Borkdude: chouser: does TjOC treat defrecord, protocol and the like somewhere?

15:49 chouser: Borkdude: ch8, not released yet

15:49 Chousuke: so if protocols don't work for you, you can replace it with a normal function with an instance check.

15:49 chouser: it was mostly done before defrecord was invented, so we need to revise...

15:49 joshua-choi: Chousuke: When would you want to do that?

15:49 Borkdude: chouser: ah good to know that will come up

15:50 Chousuke: joshua-choi: dunno. I suppose replacing a protocol function with a multimethod is more plausible

15:50 Borkdude: chouser: is middleware also a topic that belongs in there, or is that a compjore specific thing?

15:50 Chousuke: joshua-choi: but the point remains that they're all just functions

15:51 joshua-choi: Does anyone use (type ...) nowadays?

15:51 chouser: Borkdude: we won't be dealing with specific library features like that.

15:51 we're way over our target pagecount already

15:51 Borkdude: chouser: I just wondered if that term was a general thing in Clojure

15:52 chouser: Borkdude: it's not

15:52 kotarak: joshua-choi: yes, why not?

15:52 Borkdude: k

15:52 joshua-choi: kotarak: (type obj) is (or (:type (meta obj)) (class obj)). I'm wondering if using :type in metadata is still idiomatic at all

15:53 I myself use it, but I'm wondering if I should change it...

15:53 Same goes for isa? in the context of object type hierarchies

15:54 kotarak: btw, what do I use to test for a deftype? Is its type still ::SomeType? Or do I test for a class?

15:55 AWizzArd: kotarak: (type yourRecord) ==> ou

15:55 kotarak: (type yourRecord) ==> your.ns.recordName

15:55 kotarak: AWizzArd: so I test with (instance? your.ns.recordName x)?

15:55 AWizzArd: exactly

15:56 if you use Protocolls this test will be done automatically for you

15:56 kotarak: AWizzArd: Except when I don't use a protocol function and want to test for the type explicitely.

15:56 AWizzArd: positive

15:59 _na_ka_na_: hi , i want to create a doubly linked list .. a node looks like (defstruct node :data :next :prev) .. so first i cr8 a list of nodes and then try to link them up .. is there a way to do it w/o creating each node as an atom/ref .. i ask coz after i create the list i'm not going to mutate it ..

15:59 whats the most idiomatic clojure way to do this

15:59 chouser: _na_ka_na_: why do you want a doubly linked list?

16:00 Chousuke: I don't think there is a way to do that with immutable thigns

16:00 _na_ka_na_: i actually want to create a graph data structure .. where nodes are connected to other nodes via 2-3 different kinds of edges ...

16:01 i thot ask abt doubly linked list would be easier

16:01 Chousuke: maybe you should use a set or a map of edges then

16:01 _na_ka_na_: hmm ya thats an option ..

16:01 Chousuke: for doubly linked lists you'd need mutual references, which are impossible with persistent things.

16:02 _na_ka_na_: so i create a list of nodes + a map of sets (key=node, value=set of connected edges) ?

16:02 oh i meant set of connected nodes

16:03 Chousuke: something like that I guess.

16:03 chouser: a common solution is a map of ids to nodes, with each node refering to its neighbors by id

16:04 _na_ka_na_: hmm .. that looks good ..

16:05 but .. how do these two solutions compare .. i mean where i have nodes as atoms v/s persistent maps ..

16:05 the first one makes a more intuitive picture in my head ..

16:06 is the only concern perf?

16:06 alexyk: which predicate do you give to every? to check none of a seq's elements is nil?

16:07 _na_ka_na_: (comp not nil?)

16:07 alexyk: shorter!

16:07 chouser: (not (some nil? ...))

16:07 Borkdude: (complement nil?) ?

16:08 Chousuke: identity

16:08 chouser: (every? identity ...)

16:08 Chousuke: fails on false though.

16:08 chouser: is the seq produced by 'map' perchance?

16:08 alexyk: hmm... let's call it meaty?

16:08 every? meaty?

16:09 but it should be in core! not-nil?

16:09 not= is there

16:09 some useless when-not is there!

16:09 almost-useless

16:09 ninjudd: when-not isn't useless

16:09 lancepantz: ruh roh

16:09 alexyk: ninjudd: it was an overstatement :)

16:10 Borkdude: isn't there a macro that can define the complement each thing in core and append -not to it's name ;)

16:10 chouser: alexyk: you need to differentiate between nil and false?

16:10 alexyk: hope not, but am afraid

16:11 I'll defn ismeat? as not nil?

16:11 is? <-- cute

16:11 every? is?

16:11 _na_ka_na_: is what?

16:11 alexyk: exists?

16:11 Borkdude: nil exists

16:12 alexyk: it *is*

16:12 Borkdude: but things which are nil don't

16:12 _na_ka_na_: but how to ppl looking at your code understand *is* ..?

16:12 Borkdude: yes, they do, because they ARE nil

16:13 alexyk: does a key exist in a map if lookup is nil?

16:13 Borkdude: does the lookup return the key?

16:14 alexyk: does a value for the key exist?

16:14 Borkdude: it's a default value for non-mapped keys

16:14 tcrayford: ,({:a nil} :a)

16:14 clojurebot: nil

16:15 _na_ka_na_: better to use contains

16:15 ,(contains? {:a nil} :a)

16:15 clojurebot: true

16:15 Borkdude: I think not nil? is the best description you can get ;)

16:15 tcrayford: alexyk: you want "untruthy"

16:16 or perhaps not-truthy?

16:16 alexyk: Borkdude: alas

16:17 _na_ka_na_: i use not nil quite often so i've just put (defn not-nil? (comp not nil?)) at the top ..

16:17 remleduff: vici?

16:19 _na_ka_na_: hey guys how abt the graph ds .. how do the atoms v/s maps solution compare ..

16:21 chouser: _na_ka_na_: don't use atoms for this

16:22 _na_ka_na_: chouser but why? .. just want to understand ..

16:22 chouser: it's not about performance -- I'm not sure which would be faster, actually.

16:23 alexyk: how do you assert something is a number?

16:23 _na_ka_na_: why does your gut feeling say no to atoms? :)

16:23 chouser: rather it's sort of an abuse of an atom to have it sitting there able to change with a vague promise that you won't.

16:23 _na_ka_na_: hmm ya ..

16:24 chouser: if you can do something more like transients, where you can "lock it" when you're done building it, that would be something else.

16:24 Borkdude: ,(number? "foo")

16:24 clojurebot: false

16:24 Chousuke: _na_ka_na_: it would be just emulating traditional mutability, which is not maintainable :/

16:24 Borkdude: ,(assert (number? "foo"))

16:24 clojurebot: java.lang.AssertionError: Assert failed: (number? "foo")

16:25 Chousuke: you don't want your core data structure to have anything to do with state :P

16:25 alexyk: Borkdude: thx! that's my not-nil :)

16:25 _na_ka_na_: Chousuke: i think every one agrees on that .. thats why we are here :D ..

16:26 Borkdude: alexyk: =)

16:28 _na_ka_na_: but that is an issue only if someone *actually changes* the ds after building it .. if this graph of mine is a "private" ds which i don't expose in my API .. and i know that i'll never mutate it ..

16:28 tcrayford: well if you're never going to mutate it, why do you need an atom?

16:29 _na_ka_na_: its not like i favor the atoms .. i'm just trying to put arguments both ways

16:29 Chousuke: _na_ka_na_: in this case, there isn't much of a case to be made in favour of the atoms :)

16:30 people will think it's unidiomatic, ugly and stupid :P

16:30 _na_ka_na_: the graph data structure represented with atoms is more intuitive no? .. anyone who sees it will understand at the first glance?

16:30 Chousuke: even if it works.

16:30 chouser: is the graph a value or not? if it's a value in the way other complex nested map/vector things are, then you get all the same benefits: keep old version, build using 'reduce', etc.

16:30 _na_ka_na_: hehe ya thats one more point against :)

16:30 Chousuke: _na_ka_na_: no, a person used to clojure will go "what?"

16:30 chouser: but as soon as there's an atom in there, it's a stateful thing and you can have only the one.

16:31 gotta go

16:31 Chousuke: _na_ka_na_: while they might understand mutability, atoms are meant to address mutability in a very different way from what you're suggesting, so they would be confused.

16:32 _na_ka_na_: yes I agree with that point .. its not idiomatic Clojure at all ..

16:32 Chousuke: actually, s/mutability/state/g

16:34 doing things "the right way" might be difficult at first but this gets easier with experience.

16:34 and it's never too early to start experiencing :P

16:34 _na_ka_na_: now that seems like the best argument to me :P ..

16:35 Borkdude: atoms are there, but never use them!

16:35 heh ;)

16:35 _na_ka_na_: hehe ..

16:36 Chousuke: try the approach using maps of ids -> node where node = some stuff + set of edges which are pairs of [edge-type, node-id] (you had several kinds of edges, right?)

16:36 also, starting advice: don't be tempted to use struct maps

16:37 they're not real types, and you won't need them until you know you need them :P

16:37 _na_ka_na_: ya i have several kinds of edges ...

16:38 ya if im not using atoms .. then no need of structmap i guess ..

16:38 Chousuke: struct maps are just an optimisation of regular maps

16:38 Borkdude: What would be a good example of import-static?

16:38 _na_ka_na_: Math/PI ?

16:39 Chousuke: if you feel you need the memory benefit, it should be pretty easy to convert code using plain maps to struct maps

16:39 tcrayford: struct-maps are confusing when you're starting out. The first major thing I wrote in clojure used struct maps, and I look back on it now with annoyance

16:39 they look so like classes :/

16:39 technomancy: struct-maps are a tank trap

16:39 Chousuke: tcrayford: yeah, I think the first reaction from people new to clojure must be something like "ooh, structs, I know those"

16:40 _na_ka_na_: but I just treat them as regular maps ..? only its named and little more optimized

16:40 Chousuke: then they go and use struct maps. no real harm there, but it's often unnecessary ceremony.

16:40 tcrayford: technomancy: looking at the swank-clojure source, it says M-TAB to complete symbol, wheras slime says C-c TAB

16:40 AWizzArd: Isn’t completion on just <Tab> only?

16:40 technomancy: tcrayford: they both work, but in most WMs C-c TAB is easier to invoke.

16:40 tcrayford: s/source/README

16:40 technomancy: I'll change the readme; thanks.

16:41 Chousuke: _na_ka_na_: the optimisation won't matter unless you have many "instances" of the base map (in the order of several thousand)

16:41 tcrayford: AWizzArd: that's slime specific completion

16:41 AWizzArd: tcrayford: which one? With tab or C-c Tab?

16:41 tcrayford: C-c TAB

16:41 _na_ka_na_: Chousuke: I have around 100,000 nodes .. so isn't struct-map better

16:41 technomancy: AWizzArd: bare tab is usually bound to indentation

16:41 unless you're in the repl

16:41 AWizzArd: technomancy: yes, in the repl i mean

16:41 Chousuke: nathanmarz: will your node be a map?

16:41 tcrayford: or using smart-tab-mode or summat

16:41 Chousuke: oops

16:41 AWizzArd: indentation and completion

16:42 tcrayford: does bare tab work in the repl for completion?

16:42 Chousuke: _na_ka_na_: couldn't the node be just a pair?

16:42 nathanmarz: no keys, just [stuff, set-of-edges]

16:42 AWizzArd: M-Tab would not be so nice for Windows users - it switches out of Emacs to the next application.

16:42 tcrayford: same for osx :/

16:43 AWizzArd: I put fuzzy-completion on C-Tab

16:43 Borkdude: technomancy: maybe a dumb question, but why would I upgrade to swank-clojure 1.2?

16:43 technomancy: Borkdude: all the cool kids are doing it.

16:43 Chousuke: nathanmarz: I suppose a struct-map could be useful too

16:43 Borkdude: technomancy: I noticed, that's why I ask ;)

16:43 technomancy: Borkdude: here's the list of new features: http://github.com/technomancy/swank-clojure/blob/master/NEWS

16:43 AWizzArd: technomancy: btw, is the freshest swank-clojure + clojure-mode working with the freshest slime?

16:44 Borkdude: technomancy: tnx

16:44 technomancy: Borkdude: who-calls and swank-break are pretty awesome

16:44 Chousuke: nathanmarz: just don't think it's anything more than a regular map; that's a common mistake.

16:44 _na_ka_na_: Chousuke: yup .. it can be for the moment.. but later i'll need to introduce several kinds of attributes with the nodes (like {:id :data :attr1 :attr2 ..}) .. i could use several maps for this .. one for data, one for attr1 .. but isn't that overkill ?

16:44 technomancy: AWizzArd: swank-clojure.el or swank-clojure clojure server?

16:45 Chousuke: _na_ka_na_: well, the nodes will be just maps so you can just assoc the keys.

16:45 _na_ka_na_: in that regard it doesn't matter what you put in there.

16:45 Borkdude: technomancy: ok, sounds good. Now I have to find out how I do it using ELPA, can I just overwrite it or smth?

16:46 sorry, I'm still an Emacs n00b

16:46 AWizzArd: technomancy: I was not aware of those two so far. I still have a very old installation where I just do M-x Clojure to get a repl and Clojure-Mode. I typically did not start a swank server to which I then connected on port 4005 or something like that.

16:46 Chousuke: _na_ka_na_: so maybe using a map as a node is a good idea. try and experiment with a small prototype first

16:46 technomancy: Borkdude: the readme now shows a more foolproof method of using it. basically you don't need the elisp for swank-clojure anymore. on the Emacs side just get slime-repl and clojure-mode, and launch your swank server from the command-line

16:46 _na_ka_na_: Chousuke: yes, but the question is maps v/s struct-maps (v/s defrecord ?) .. coz I'm not going to dynamically add keys .. well maybe if my app runs for weeks along :D

16:47 tcrayford: _na_ka_na_: read steve yegge's article about systems that never stop

16:47 Chousuke: _na_ka_na_: well, a struct-map will be okay.

16:47 Borkdude: technomancy: and if I don't want to use the command line?

16:47 technomancy: AWizzArd: I'm using a relatively recent slime (two or three weeks old) with lein swank. I quit using M-x swank-clojure-project, but I think it still works

16:47 Chousuke: _na_ka_na_: though records are better.

16:47 technomancy: Borkdude: then it's more manual, but you can use this: http://p.hagelb.org/swank-launchers.html

16:47 sexpbot: "programming.el"

16:47 AWizzArd: technomancy: do you now always start a jvm with a swank-server listening and do slime-connect them from emacs?

16:48 technomancy: AWizzArd: that's what I do now, yes. it's much more foolproof; M-x swank-clojure-project had several nasty edge cases that confused a lot of people

16:48 Chousuke: _na_ka_na_: if you're using 1.2 and need the memory savings, you can use defrecord and then treat it as if it were a regular map I suppose :)

16:48 _na_ka_na_: tcrayford: link pls .. and ur is hard to see at first :) i wrote tracyford :P .. hope u dont mind

16:49 Chousuke: exactly what i was thinking after i learnt protocols, datatypes today itself!

16:49 tcrayford: technomancy/AWizzArd: though swank-clojure-project lets you customize the jvm startup better than you can with lein atm

16:49 _na_ka_na_: http://steve-yegge.blogspot.com/2007/01/pinocchio-problem.html

16:49 sexpbot: "Stevey's Blog Rants: The Pinocchio Problem"

16:50 tcrayford: warning: Steve Yegge post, ie really really long

16:50 Chousuke: _na_ka_na_: the important thing in the beginning is not to marry yourself to a certain approach. programming to generic interfaces (ie. thinking of your data as just maps of stuff) often helps.

16:50 especially if you have a background in OOP :/

16:51 Borkdude: technomancy: maybe it's more foolproof, it's not n00bproof

16:52 _na_ka_na_: Chousuke: thats right, my background is OOP .. but the more I did it the more I felt this is wrong, we are just writing variables too much .. then I came across Clojure :D

16:55 the sad thing now that I look back is we were thought not even one functional language in school, not even the topic of functional programming, immutability came across in so many "programming courses"

16:55 first Java then C then Perl, Python ..

16:56 Borkdude: _na_ka_na_: what school was that

16:56 _na_ka_na_: I mean, what kind

16:56 _na_ka_na_: not that it sounds ridiculous, just curious

16:58 LauJensen: etate: ping

16:59 _na_ka_na_: Borkdude: not giving away the names .. but it was the... institute of technology

16:59 Borkdude: _na_ka_na_: only a few options then

17:00 _na_ka_na_: Borkdude: lets not name the options :P

17:01 Borkdude: _na_ka_na_: I'm just asking because I work at a 'school' as well

17:01 _na_ka_na_: Borkdude: Hmm, you teach or just work?

17:02 Borkdude: I teach

17:02 _na_ka_na_: Oh wow thats nice to hear, what subject(s) if you don't mind?

17:02 Borkdude: _na_ka_na_: I just started since March 1

17:04 _na_ka_na_: as of now, I teach things like Google Web Toolkit, a project using that and Object Oriented Design, some course around Oracle JDeveloper

17:04 _na_ka_na_: Borkdude: I like teachers :), wish you a rewarding career!

17:04 Borkdude: I hope to sneak in some Clojure somewhere sometime ;)

17:05 _na_ka_na_: Hehe ;) not let them know

17:05 AWizzArd: technomancy: what is swank.core/break doing?

17:05 Borkdude: _na_ka_na_: tnx

17:06 technomancy: AWizzArd: http://hugoduncan.org/post/2010/swank_clojure_gets_a_break_with_the_local_environment.xhtml

17:06 sexpbot: "Hugo Duncan : Swank Clojure gets a Break with the Local Environment"

17:06 technomancy: spoiler alert: it's awesome

17:06 _na_ka_na_: Chousuke: thanks for discussion, I'm off to test some of the ideas discussed.

17:06 tcrayford: technomancy: I've never had break succesfully work for me

17:10 does it only work from the repl?

17:10 alexyk: ninjudd: you know what a cool sideeffect of jiraph format is?

17:10 tcrayford: technomancy: (ie won't work using C-x C-e)

17:10 ninjudd: alexyk: what?

17:11 technomancy: tcrayford: it should work that way, but I usually invoke it via tests

17:11 alexyk: ninjudd: it's language-independent! you can read it from Scala presumably, or even from Python or C++

17:11 whatever supports TC and protobuffers

17:12 joshua-choi: Question: In Clojure, in order to have two mutually recursive functions, must you use two vars? Is it impossible to create them in a let binding?

17:12 mmarczyk: joshua-choi: see letfn

17:12 ninjudd: alexyk: good point. didn't even think of that. i was just going for speed

17:12 joshua-choi: mmarczyk: Can letfn create mutually recursive functions?

17:12 mmarczyk: joshua-choi: that's its entire point :-)

17:13 alexyk: ninjudd: yeah, OTOH, compiling a proto is annoying, but you get portability too

17:13 ninjudd: alexyk: i'm working on lein tasks for compiling protobufs right now

17:13 alexyk: I'm sick of NPEs and will try Scala on a jiraph soon :)

17:13 joshua-choi: mmarczyk: Oh, I've been using it since it's cooler than (let [a (fn ...)] ...). That's cool. But only letfn can do that?

17:13 ninjudd: should make it easier

17:14 mmarczyk: joshua-choi: well you could conceivably use let with atoms (not sure why you'd want to, though)

17:14 alexyk: ninjudd: cool! as I understand, if you add a proto/ directory to classpath of a repl, you can keep compiling protos there without reloading repls, right?

17:14 mmarczyk: joshua-choi: anyway, letfn is there precisely for this purpose

17:15 * alexyk will form a support group for programmers traumatized by debugging NPEs

17:15 mmarczyk: ,(letfn [(ev? [n] (if (zero? n) true (od? (dec n)))) (od? [n] (if (zero? n) false (ev? (dec n))))] (ev? 10))

17:15 clojurebot: true

17:15 joshua-choi: mmarczyk: No, I don't want to use mutable structures. I have a problem with recursive nested functions that I've been using solving with vars, but now I've come up against a wall with them: namely, metadata.

17:15 alexyk: post-NPE-debugging stress disorder

17:16 joshua-choi: Oh dear, letfn seems to use a special form "letfn*".

17:16 ,`letfn*

17:16 clojurebot: letfn*

17:16 mmarczyk: joshua-choi: yeah, and let uses a special form "let*", loop uses "loop*" and fn uses "fn*"

17:16 don't worry about it

17:16 ninjudd: alexyk: no, you'll still have to do 'lein proto' to recompile your proto files

17:16 joshua-choi: mmarczyk: I was hoping that I could utilize letfn's source code for my own parser library

17:17 I am having to deal with recursive rules, and I don't want to use var-quoting anymore

17:17 alexyk: ninjudd: true, but I can do it from another dir and laod into a running repl by defining protobuffer there with just a class name

17:17 mmarczyk: joshua-choi: perhaps you can utilise letfn itself for your library? :-)

17:17 alexyk: clojurebot: take your NPE and shove it!

17:17 clojurebot: excusez-moi

17:17 mmarczyk: joshua-choi: note that there's no way around the lack of TCE for non-self-calls

17:19 joshua-choi: mmarczyk: Yes; I can unfortunately do little about that, I think; I can just hope that the stack stays small

17:19 mmarczyk: I guess so

17:19 joshua-choi: I thought that I could wrap all my rules in zero-argument functions, and that would fix it

17:19 mmarczyk: or maintain your own CPS stack, or use trampoline

17:19 joshua-choi: The mutual recursion reference problem I mean

17:19 mmarczyk: yup

17:20 joshua-choi: Yeah, no way I can use trampoline, I think; there's always many functions in between the mutually recursive functions

17:20 mmarczyk: that doesn't necessarily mean that you can't trampoline

17:21 as long as you can wrap up all info on how the computation is to continue in a thunk, you can

17:22 joshua-choi: Really? I'll have to think hard about that

17:22 Gee, it looks like I won't be done with FnParse 3 for a while again

17:22 mmarczyk: oh, this is about FnParse 3? cool :-)

17:22 joshua-choi: Yes. I'm trying to solve the problem of mutually recursive rules.

17:22 mmarczyk: do you have a public scratchpad somewhere...?

17:23 joshua-choi: Up to today it's been solved by var-quoting: #'

17:23 mmarczyk: just asking cause I'd be curious to have a look

17:23 joshua-choi: No, I don't

17:23 mmarczyk: oh well.

17:24 joshua-choi: Var-quoting isn't adequate, though: it introduces dependencies on mutable objects (the vars), it complicates validation (the vars can't be evaluated until...I don't even understand this part, actually), and it makes it impossible to use in a let form.

17:24 technomancy: clojurebot: swank-break is http://hugoduncan.org/post/2010/swank_clojure_gets_a_break_with_the_local_environment.xhtml

17:24 clojurebot: Ik begrijp

17:24 sexpbot: "Hugo Duncan : Swank Clojure gets a Break with the Local Environment"

17:25 joshua-choi: mmarczyk: What's a public scratchpad, by the way?

17:25 Like a wiki?

17:27 mmarczyk: joshua-choi: well, I'm not sure myself :-)

17:27 a wiki, a set of gists etc.

17:27 tcrayford: or just a TODO.txt on github

17:27 mmarczyk: you've got your 3.alpha.x tags on github

17:27 so I guess I'll have a look at what you've committed lately

17:27 joshua-choi: Those aren't updated often. It'd be better to pay attention to my commits

17:27 mmarczyk: right.

17:27 joshua-choi: Yes. I also update a news page on my wiki from time to time

17:28 I was waiting for Clojure 1.2 to release so Autodoc could work again, but I think I'll do one more revamp :)

17:28 mmarczyk: :-)

17:28 um, sorry, I need to be off for now; bbl

17:29 joshua-choi: Talk to you later.

17:33 Question. If a future JVM implements good tail-call optimization, would trampoline become obsolete?

17:45 neotyk: Hi *

17:46 can someone explain why if I: (set! *print-length* 1) and than do (str '(1 2 3)) I will get (1 ...) I just can't see where it is happening in str function

17:49 _na_ka_na_: neotyk: Don't think its in the str function, has to be the print function ..

17:49 Borkdude: neotyk: maybe it's not happening in the str function

17:50 neotyk: at REPL than?

17:50 but look: user> (str '(1 2 3))

17:50 "(1 ...)"

17:51 I get that one: user> '(1 2 3)

17:51 (1 ...)

17:53 Borkdude: neotyk: I see what you mean

17:55 neotyk: ~str

17:55 clojurebot: destructuring is http://clojure.org/special_forms#let

17:55 neotyk: source str

17:56 http://github.com/tomfaulhaber/clojure/blob/7b4b8e18c0d28e03e7c66f54bc441ef355ceb5ed/src/clj/clojure/core.clj#L401

17:56 where is this magic cut off happening ?

17:58 just checked that it is not just emacs, normal repl does the same

18:01 arohner: anyone have experience with clj-cont?

18:02 tcrayford: no, but I think I understand continuations

18:02 (if I was going to use continuations in clojure, I'd probably use the cont-m monad from c.c.monads)

18:02 arohner: I think I understand continuations, I'm wondering how reliable clj-cont is compared to say, scheme. Any weird gotchas?

18:03 _na_ka_na_: neotyk: maybe the .toString method?

18:03 tcrayford: no idea on that count then

18:04 neotyk: _na_ka_na_: but .toString is called on each element of list, not on a list

18:07 arkahn: neotyk: set! is often used for Java interop - I would think it's setting something in java.lang.String

18:09 neotyk: printf related? I'm probably grasping ...

18:11 neotyk: arkahn: I have no idea, str source doesn't indicate this kind of behavior at all

18:11 I'm trying to find usages of *print-length*

18:11 arkahn: neotyk: nvm, I was wrong. *print-length* is located in core_print.clj in the actual clojure source

18:12 LaPingvino: Hello hubert :)

18:12 Joop here

18:12 neotyk: LaPingvino: Hello

18:12 LaPingvino: how are you?

18:12 neotyk: goed, en jij

18:12 LaPingvino: I am playing a bit with the newest compojure... it did change enough to make me search a lot to get it all running :S

18:13 met mij ook :)

18:13 kotarak: (doc number?)

18:13 clojurebot: "([x]); Returns true if x is a Number"

18:13 arkahn: neotyk: (doc *print-length*) <- have you tried that? Hopefully I'm helping what you're asking.

18:13 LaPingvino: you know how to do a serve-file now?

18:13 I will put the question in #compojure as well :)

18:14 kotarak: ,(some number? [nil nil nil 5 nil nil])

18:14 clojurebot: true

18:15 kotarak: ,(some #(and (number? %) %) [nil nil nil 5 nil nil])

18:15 clojurebot: 5

18:15 neotyk: arkahn: yes, though didn't help :(

18:15 LaPingvino: neotyk: any idea?

18:15 neotyk: LaPingvino: no idea, I'm serving files via apache

18:16 LaPingvino: ah okay

18:17 arkahn: neotyk: the doc on *print-length* looks like it totally explains the behavior. Can you re-state what you're asking?

18:18 neotyk: why (str '(1 2 3)) gives "(1 ...)" if (set! *print-length* 1)

18:20 arkahn: to what I'm understanding, *print-length* set to 1 will only print the first item of a collection, with all remaining items represented by the ellipsis

18:20 ,(do (set! *print-length* 1) (str '(1 2 3)))

18:20 clojurebot: java.lang.IllegalStateException: Can't change/establish root binding of: *print-length* with set

18:21 _na_ka_na_: ,(let [s (str '(1 2 3)) s1 (binding [*print-length* 1] (str '(1 2 3))) s2 (binding [*print-length* 2] (str '(1 2 3)))] [s s1 s2])

18:21 clojurebot: ["(1 2 3)" "(1 ...)" "(1 2 ...)"]

18:21 alexyk: I get a StackOverflow, and printStackTrace shows a huge block of internal things, like clojure.lang.LazySeq.sval/seq/RT.seq, and none of my files' lines. How do I debug it?

18:21 arkahn: and then if you set *print-length* to logical false it'll print the whole collection

18:23 _na_ka_na_: and this will prove that its not just repl printing thats using *print-length* ..

18:23 ,(let [s (str '(1 2 3)) s1 (binding [*print-length* 1] (str '(1 2 3))) s2 (binding [*print-length* 2] (str '(1 2 3)))] [(count s) (count s1) (count s2)])

18:23 clojurebot: [7 7 9]

18:24 alexyk: can apply cause StackOverflow?

18:25 with a very long arg list?

18:25 tcrayford: I think clojure arg lists fail somewhere around 40

18:25 alexyk: looks like it

18:25 strangely no source line, apparently it overflown the said stack

18:26 tcrayford: ,(apply + (repeat 100 10))

18:26 clojurebot: 1000

18:26 arohner: clojure functions can take an infinite number of arguments

18:26 alexyk: so that's not it

18:26 tcrayford: nope

18:26 arohner: alexyk: my guess is the function being applied has a 'normal' stack overflow

18:27 alexyk: arohner: why would it? is apply nesting?

18:28 arohner: alexyk: no, I was saying that I doubt apply is causing a stack overflow. it's more likely either the function being applied, or the seq that is passed to apply

18:28 alexyk: ,(apply max (range 1000000))

18:28 clojurebot: 999999

18:29 arohner: alexyk: apply has been known to cause heap overflows. some kind of head-holding going on in some circumstances

18:29 _na_ka_na_: neotyk: found anything?

18:29 neotyk: _na_ka_na_: still nothing

18:30 I know that print-method multimethod does this limiting tirck

18:30 but can't find a link between str and print-method

18:31 s/tirck/trick/

18:31 sexpbot: but can't find a link between str and print-method

18:32 arohner: neotyk: the repl prints the return values of expressions

18:32 it's the P in Read Eval Print

18:32 neotyk: ,(binding [*print-length* 1] (str '(1 2)))

18:32 clojurebot: "(1 ...)"

18:33 _na_ka_na_: neotyk: yup i'm stuck thr too

18:33 neotyk: esp. see this ..

18:34 ,(let [s (str '(1 2 3)) s1 (binding [*print-length* 1] (str '(1 2 3))) s2 (binding [*print-length* 2] (str '(1 2 3)))] [(count s) (count s1) (count s2)])

18:34 clojurebot: [7 7 9]

18:34 arohner: neotyk: I don't understand what's wrong with that example

18:34 _na_ka_na_: arohner: can you see the above example?

18:34 neotyk: arohner: look at source of str

18:35 and please do tell why it prints "(1 ...)"

18:35 alexyk: is there a simple way to find a max of a list without (apply max that-list)?

18:35 neotyk: I think key here is '('

18:37 I don't see anything in str source that would make it print '('

18:37 arohner: neotyk: ok, now I understand what you mean

18:38 _na_ka_na_: alexyk: whats wrong with apply max?

18:38 neotyk: I should *not* be saying print, when we talk about str fn

18:38 alexyk: _na_ka_na_: I'm not sure what causes StackOverflow

18:38 _na_ka_na_: yup thats why i printed counts

18:39 ipostelnik: looks like clojure.lang.PersistentList#toString respect *print-length*

18:39 _na_ka_na_: ,(apply max (into [] (range 100000000)))

18:39 clojurebot: Execution Timed Out

18:39 alexyk: I am thinking of apply; I don't have any recursion, and trace shows LazySeq.sval=>seq=>RT.seq ad infinitum

18:40 neotyk: I think I got it: IPeristentList has it's own .toString that delegate to print-method

18:40 _na_ka_na_: but its a PersistentList right?

18:40 ,(class '(1 2 3))

18:40 clojurebot: clojure.lang.PersistentList

18:42 remleduff: ,(RT/printString '(1 2 3))

18:42 clojurebot: java.lang.Exception: No such namespace: RT

18:42 remleduff: ,(clojure.lang.RT/printString '(1 2 3))

18:42 clojurebot: "(1 2 3)"

18:43 arkahn: I wonder if all/most collection .toString's delegate to print-method

18:43 _na_ka_na_: it looks that way, but the question is how?

18:43 can you point out in the source?

18:43 remleduff: ASeq is the abstract base of most of the collections, its toString calls RT.printString which is where the magic happens

18:44 _na_ka_na_: ya ..

18:44 ,(binding [*print-length* 1] (clojure.lang.RT/printString '(1 2 3)))

18:44 clojurebot: "(1 ...)"

18:45 _na_ka_na_: remleduff: but can you point out in the source? i'm unable to see

18:45 remleduff: You mean point out the delegation or what does the cut-off?

18:45 neotyk: ASeq has toString that calls RT/printString

18:46 PersistentList extends ASeq

18:46 so in str it is arity 1 case

18:46 _na_ka_na_: yup it is ..

18:47 neotyk: though I would have though that is is last case

18:47 _na_ka_na_: remleduff: i mean point out where exactly the magic is happening in RT.printString

18:48 LaPingvino: neotyk: found it :)

18:48 neotyk: it must be calling print-method multimethod

18:48 arkahn: that's what I see, too (the print-method multimethod)

18:49 _na_ka_na_: but the question is how does it reach thr?

18:49 arkahn: what is RT ?

18:50 _na_ka_na_: its a class in the Clojure java source

18:51 alexyk: this fragment of a let causes stack overflow: http://paste.pocoo.org/show/215514/ -- why?

18:52 neotyk: RT.printString -> print -> printInnerSeq

18:52 and I'm still missing link to print-method

18:52 LaPingvino: so how do you serve-file?

18:52 alexyk: I've tried to stick a doall at random. Googling for StackOverflow shows notions of filters closing over locals as culprits; I do have locals in the map's fn. The list it works on is about 300,000 long

18:53 _na_ka_na_: i see it!

18:54 alexyk: _na_ka_na_: what is it you see?

18:54 _na_ka_na_: neotyk: if you are looking the source of clojure.lang.RT/printString .. see the lines ..PR_ON.invoke(x, w);

18:55 islon: defmethod body has an implicit do?

18:55 neotyk: oh yeah, it even has a comment on top saying "//call multimethod"

18:56 islon: thanks

18:56 _na_ka_na_: oh i just glossed all over that comment :(

18:57 its 2 light

18:57 neotyk: rest of this method is commented out

18:57 remleduff: All of the multimethod implementations that get called for the core datastructers are defined in clojure/lang/core_print.clj, specifically the one that looks like (defmethod print-method clojure.lang.ISeq ...)

18:57 neotyk: syntax highlighting borked

18:57 _na_ka_na_: nope its not commented out is it?

18:58 remleduff: I think everything except for the multimethod invocation is just there for bootstrapping/debugging

18:58 neotyk: islon: I did *not* answer your question

18:59 _na_ka_na_: atleast its not commented out in the main .. //* .. //*/

19:00 remleduff: can you explain how does in help in bootstrapping/debugging

19:00 neotyk: oh my so evil

19:00 it is not commented out

19:00 /* is not multiline comment in java

19:00 ///*

19:00 /

19:01 the one in the source

19:01 alexyk: hmm -- I traced the overflow to let: ustats (into {} ustats) where ustats is computed above now as a huge vector. Possible?

19:01 islon: neotyk, i tested in the repl

19:01 remleduff: I imagine it just lets rich debug stuff until the actual print-method multimethods get defined by clojure/core_print.clj. Once the pr-on var is defined in core.clj, none of that method gets called except for the very first multimethod invocation.

19:01 _na_ka_na_: neotyk: well we solved one mystery today .. but the point is that the str docs should say so!

19:03 neotyk: _na_ka_na_: did we? I still don't get why arity 1 is used

19:03 alexyk: actually, wrong -- a doall on the vector forces overflow

19:03 _na_ka_na_: remleduff: I see ..

19:03 neotyk: Oh thats easy

19:04 neotyk: do tell

19:04 _na_ka_na_: ,(str [1 2 3])

19:04 clojurebot: "[1 2 3]"

19:04 _na_ka_na_: [1 2 3] is one object ...

19:04 neotyk: ,(str '(1 2 3) [1 2 3])

19:04 _na_ka_na_: where as

19:04 clojurebot: "(1 2 3)[1 2 3]"

19:04 _na_ka_na_: ,(apply str [1 2 3])

19:04 clojurebot: "123"

19:04 _na_ka_na_: ,(str 1 2 3)

19:04 clojurebot: "123"

19:05 neotyk: got it

19:05 _na_ka_na_: are both same, multiple arity

19:05 neotyk: we did solve one mystery

19:05 _na_ka_na_: neotyk: I guess you should notify the developers involved

19:05 neotyk: _na_ka_na_: that it works?

19:06 _na_ka_na_: neotyk: that the doc of str should reflect the *print-length* thingy

19:06 remleduff: Here's a question for you, now that we think we know how the printing works, is ASeq.toString actually being called?

19:07 _na_ka_na_: thats how it reaches RT.printString right?

19:08 str -> ASeq.toString -> RT.printString -> print-method -> print-sequential

19:08 remleduff: I don't think so ;)

19:08 _na_ka_na_: then?

19:09 remleduff: clojure.main/repl evaluates your form then calls "print" on it, which by default is the method "prn"

19:09 prn uses the pr-on multimethod

19:10 Sorry, pr-on isn't a multimethod, but that calls the print-method multimethod

19:10 neotyk: remleduff: str fn

19:10 alexyk: can something like let ... stats (assoc :key val) in a nested fn of a long map cause overflow?

19:10 _na_ka_na_: remleduff: but i'm not even calling the print

19:10 remleduff: Oh, bah! :)

19:11 Yeah, you're right

19:11 neotyk: remleduff: arity 1 case

19:11 calles toString on PertistentList

19:11 ninjudd: alexyk: StackOverflow usually means infinite loop

19:11 neotyk: that takes impl from ASeq

19:11 alexyk: ninjudd: I don't get it on a shorter data

19:11 remleduff: Yeah, didn't realize you were calling str, thought you were just printing it at the repl

19:12 alexyk: I only get it if I add a doall to a map

19:12 ninjudd: hmm. let me look at your code fragment

19:12 _na_ka_na_: that's why the docs of str should reflect *print-length*

19:12 alexyk: the doall there causes overflow

19:12 _na_ka_na_: can anyone chk in 1.1 ?

19:12 alexyk: http://paste.pocoo.org/show/215514/

19:13 ninjudd: alexyk: is this inside a loop?

19:13 arkahn: _na_ka_na_: check for what ?

19:14 ninjudd: or are you using recursion?

19:14 remleduff: str docs just say it calls toString, and toString has always been super-loosely defined

19:14 alexyk: ninjudd: no, it's a piece of let which explicitly iterates over days. it fails on the very first one

19:14 arkahn: oh .. yeah

19:15 alexyk: ustats is a map with 300,000 structs

19:15 remleduff: Whenever you call toString in java, you should assume that eventually you're going to run across a programmer who was hungry and just decided to make his class print, "I like pie" ;0

19:16 _na_ka_na_: neotyk: i guess thats fine then .. but I'm sure there would have been / will be many fellows who'll just find the hard way

19:16 arkahn: having *print-length* affect str is bad - seems like it should be more than documented, it should be changed

19:17 it was fun trying to keep up with you guys, though ... I learned along the way ; )

19:17 remleduff: What do you expect str to do if you do (str (range)) ?

19:17 neotyk: arkahn: I'm fine with it doing so, or at least to have a variant that has this cut off behavior, but docs should reflect it

19:19 alexyk: ninjudd: in fact, forget it, it may be above it... am doalling it

19:20 I had an init-less reduce which suddenly barfed on count'ing its result

19:20 _na_ka_na_: ,((fn [n] (when (pos? n) (x (dec n)) (nil? nil))) 6280)

19:20 clojurebot: java.lang.Exception: Unable to resolve symbol: x in this context

19:20 _na_ka_na_: blah

19:20 remleduff: Oh, fortunately, LazySeq doesn't delegate

19:21 Maybe ASeq should bind *print-length* to nil before calling printString

19:21 ninjudd: alexyk: so you figured it out?

19:21 alexyk: or it's a nested remove... man, lazy bastartds are tricky!

19:21 ninjudd: not yet

19:22 my graphs are huge

19:22 ninjudd: hehe

19:22 _na_ka_na_: ,(letfn [(x [n] (when (pos? n) (x (dec n)) (nil? nil)))] (x 6280))

19:22 clojurebot: java.lang.StackOverflowError

19:22 alexyk: I got more Twitter user than you mormons :)

19:22 ninjudd: huh?

19:22 alexyk: ninjudd: in your genealogy :)

19:22 _na_ka_na_: wierd for me 6280 works and 6281 fails

19:23 ninjudd: oh, we do genealogy way better than the mormons

19:23 they're genealogy 1.0

19:23 plus we don't baptize our users

19:23 _na_ka_na_: How do I easily figure out at what point my stack will blow off?

19:23 alexyk: I may be dense today, but this seems the line du jour candidate for overflow: (reduce (fn [sums terms] (map + sums terms)) (remove nil? sum-terms)) ; why?

19:24 lancepantz: we do tell them they're going to hell if they quit using our site though

19:24 alexyk: doall'ing remove didn't save it

19:24 tomoj: _na_ka_na_: why not just stop blowing the stack?

19:24 alexyk: adding [0 0 0] init doesn't save it either. Each element of sum-terms is a tuple of 3 numbers

19:25 _na_ka_na_: tomoj: well thats ideal :) but say just for fun / knowing it

19:25 alexyk: I simply compute all 3 sums in one pass, for each position

19:25 ninjudd: lancepantz: isn't that standard practice with all internet companies?

19:25 tomoj: ah, I dunno

19:25 I think it probably depends on how big the stack frames are

19:25 alexyk: or, will nested (map + sums terms) lazily sit there??

19:26 ninjudd: alexyk: can you update the code snippet with the reduce?

19:26 lancepantz: that's why facebook doesn't let users quit, just trying to protect them from going to hell

19:26 tomoj: e.g. if the functions close over more variables, you'll run out sooner, I'd think?

19:26 _na_ka_na_: hmm that sounds an idea, i'll quickly test it

19:27 yup you're right

19:27 so is there a way to how the size of stack frames?

19:27 know* the size

19:28 alexyk: yes! that nested (map + sums terms) had to be doall'ed into submission, like 3 mormonic wives who don't use geni.com! :)

19:28 remleduff: alexyk: Every map returns a LazySeq, so you end up with (+ LazySeq (+ LazySeq (+ LazySeq...)))) in pseudo-stack notation

19:28 alexyk: map is lazy and dangerous -- my new motto

19:28 remleduff: nm, you got it

19:29 alexyk: remleduff: thx, too! this was evil and took long on a huge graph to locate

19:29 neotyk: thanks _na_ka_na_ remleduff for helping in figuring str out

19:30 remleduff: I run into laziness problems with map all the time still

19:30 alexyk: new Clojure T-shirt: doall

19:30 remleduff: I mean self-imposed laziness problems

19:30 alexyk: did you doall your nested map today?

19:31 for every lazy map, there's a doall

19:35 islon: does this works: (defn foo [{bar :bar :as stuff}] bar)?

19:36 tcrayford: ,(let [{bar :bar :as stuff} {:bar 1 :foo 2} ] stuff)

19:36 clojurebot: {:bar 1, :foo 2}

19:37 remleduff: stuff is extraneous there, but yeah

19:37 tcrayford: yeah, but shows that the destructuring works like that

19:37 remleduff: Could also use (defn [{:keys [bar]}] bar)

19:38 Too many bars

19:38 islon: i was just asking if :as worked with maps, thanks =)

19:41 alexyk: "just doall it" <-- my final slogan for today

19:42 tcrayford: I need to get a t-shirt with "unqualified lisp chainsaw operator" at some point

19:44 remleduff: (let [{:keys [a] :syms [b] :strs [c] :as foo} {:a 1 'b 2 "c" 3}] [a b c foo])

19:45 (-> it doall)

19:45 mario-goulart: Hi. I'm trying to execute a clojure script from java. The clojure script access java methods. I'm getting some errors.

19:45 Here's what I'm trying: http://paste.lisp.org/display/99436

19:47 remleduff: Why do you think (. bar baz a b) should work? What are bar and baz?

19:48 mario-goulart: remleduff: that's my interpretation from I read at http://clojure.org/java_interop

19:48 I'm new to clojure, BTW.

19:48 remleduff: You need to add a "bar" parameter to your function in clojure, and then pass "this" when you call the function

19:50 Or, since your Bar class is static, you could actually do (. Bar baz 1 2), but note that this is kind of old style and it's bad because your Bar is in the default package, so I don't think it is doing what you think it's doing.

19:51 mario-goulart: remleduff: thanks. What'd be the proper way for doing that?

19:51 remleduff: Alternatively, (Bar/baz 1 2) is the way to do it nowadays. But Bar should really be in a package

19:51 Then it would be (import package.Bar) (Bar/baz 1 2)

19:52 MadWombat: stupid question, what is a simple method of removing last character from a string?

19:52 mario-goulart: remleduff: thanks for the tips. I'm gonna try that.

19:54 MadWombat: chop seems to work, anyone using enlive? is there a way to avoid constructs like (chop (chop (first (:content (first (select item *store-name-selector*))))))

19:54 remleduff: Or make baz not a static method, and pass an object to invoke named "object" ... (defn foo [object a b] (.baz object a b)). In that case, you'd use the this pointer from java

19:54 tcrayford: ,(reduce str (drop-last "foo"))

19:54 clojurebot: "fo"

19:54 remleduff: MadWombat: (apply str (drop-last "Hello"))

19:54 mario-goulart: remleduff: one more thing: is it a problem is the package Bar loads the clojure script and the script imports Bar? Should I make the Bar package something isolated from the script loader?

19:55 problem if*

19:55 MadWombat: remleduff: yes, chop from str-utils2 seems to work as well

19:55 remleduff: Wonder if there's a reason to prefer reduce or apply

19:55 tcrayford: reduce is often faster

19:55 especially with + (iirc)

19:57 remleduff: mario-goulart: I don't think so, just don't think that they get any special access to each other because of that

19:57 mario-goulart: remleduff: right. Thanks.

20:00 Raynes: Just a bit of an announcement: I've put out a new version of http://www.try-clojure.org/. Thanks to some work by Licenser, def has been allowed. There is an also short, totally incomplete first-cut of a tutorial that I threw up in about an hour. More serious work on that will start tomorrow.

20:00 sexpbot: "TryClojure"

20:00 Raynes: Good night, friends. <3

20:01 tcrayford: Raynes:

20:01 unless you've gone

20:02 you've misplaced a "they're" on that page, should be "their"

20:05 ninjudd: Raynes: nice! how about an iphone version of the site?

20:05 Raynes: tcrayford: I'll fix that in a moment. I've not gone yet. Feeding my snake.

20:05 remleduff: Raynes: Is it intentionaly that I can't copy or paste?

20:05 Raynes: ninjudd: I don't have an iphone to test that on.

20:06 tcrayford: neat then

20:06 Raynes: remleduff: It uses jquery-console. There doesn't seem to be a way to allow copypasta.

20:06 tcrayford: I added a github issue in case you had gone

20:07 Raynes: tcrayford: Thanks for the catch.

20:07 remleduff: Note that none of the trylanguage sites allow copypasta.

20:07 It's helpful for learning, but not so much for practicality.

20:07 ninjudd: Raynes: oh, the source is on github. sweet!

20:08 Raynes: Indeed.

20:08 ninjudd: i guess jQuery console is where the work would need to be done to get it working on iphone

20:11 * tcrayford managed to do very silly things with macros, so that the prototypical rails 15 minute blog app reduces into http://gist.github.com/405746

20:13 Raynes: tcrayford: Fixed.

20:14 tcrayford: Raynes: good to hear

20:14 night all

20:15 Raynes: Night here as well. <3

20:21 Actually, ninjudd: I was just thinking, and it would be possible to somewhere down the line support a more HTML-based REPL or something. Kind of like what I had originally. I can just add another interface over it and call it m.try-clojure.org. :p

20:22 tomoj: what, like page reload per form eval'd?

20:22 s/re//

20:22 sexpbot: what, like page load per form eval'd?

20:22 mario-goulart: Hmmm. Still no luck: http://paste.lisp.org/display/99436#1

20:22 Raynes: tomoj: If necessary.

20:22 tomoj: Whatever it takes.

20:23 tcrayford: Raynes: for an iphone app you wouldn't need that

20:24 Raynes: Anyway, I'll point out that try-clojure has an API in there too. http://www.try-clojure.org/magics?code=urlencodedcode, so anybody could write their own interface around that for whatever they want.

20:24 ninjudd: Raynes: that would be nice

20:24 * tcrayford laughed a lecturer who wrote a 'php repl' this term using reload-page

20:24 tcrayford: /s/a/at a

20:24 Raynes: I'd be tickled if someone wrote an IPhone app using try-clojure.

20:25 Anyway, I'm off to sleep. For real this time. ;)

20:25 tcrayford: heh

20:25 I should go as well

20:25 tomoj: typing clojure on the iphone sounds painful

20:25 ninjudd: Raynes: hmm, can't get the API to load

20:25 tomoj: unless the app has some tricked out editing interface

20:25 ninjudd: Raynes: java.lang.Exception: Unable to resolve symbol: urlencodedcode in this context

20:26 tomoj: what would paredit be in multitouch? :D

20:26 Raynes: ninjudd: It tried to execute that code. Try it with actual code, silly.

20:26 * Raynes goes to sleep.

20:26 ninjudd: tomoj: wouldn't be as bad with gestures for parens, brackets etc

20:26 tomoj: and completion

20:26 ninjudd: Raynes: heh

20:30 Plouj: does anyone knelse have problems with readLine in slime/swank/eclipse?

20:31 s/eclipse/emacs/

20:31 sexpbot: does anyone knelse have problems with readLine in slime/swank/emacs?

20:33 Plouj: :)

20:33 s/knelse/else/

20:33 sexpbot: :)

20:35 Plouj: once readLine is called, i can't get back to the prompt in *slime-repl clojure*

20:38 lancepantz: :)

20:38 s/)/(/

20:38 sexpbot: Incorrectly formatted regular expression: )

20:38 ninjudd: foo bar

20:38 s/foo/bar/

20:38 sexpbot: bar bar

20:38 lancepantz: s/\)/\(/

20:38 sexpbot: s/foo/bar/

20:38 ninjudd: s/bar/baz/

20:38 sexpbot: s/\)/\(/

20:38 lancepantz: :)

20:39 s/\)/\(/

20:39 sexpbot: :(

20:39 ninjudd: foo bar

20:39 s/foo/bar/

20:39 sexpbot: bar bar

20:39 ninjudd: s/bar/baz/

20:39 sexpbot: s/foo/baz/

20:39 lancepantz: that's awesome

20:43 remleduff: mario-goulart: I think your problem is that class Bar isn't in directory "bar" which java expects for packages. Also, you need to change your main class to "bar.Bar" on your java invocation line.

20:43 tomoj: s.awesome.annoying.

20:43 cool, it doesn't pick up on other delimeters :)

20:45 remleduff: mario-goulart: Also, your foo.clj lost its namespace

20:46 mario-goulart: remleduff: you mean the (ns user) declaration?

20:46 remleduff: mario-goulart: Yeah, in the paste at least. That will make RT.var("user", "foo") not find anything

20:48 mario-goulart: remleduff: Thanks a lot. The directory structure and (ns user) make it work. I can get 6 as output. :-)

20:49 remleduff: Cool, good luck :)

20:49 mario-goulart: Thank you. :-)

20:55 MadWombat: hmm... seems like enlive encodes non-breaking space into some sort of strange character... wonder how to remove it

21:11 SynrG: win 18

21:11 bluh

21:20 maxhodak: is it possible to destructure a list into a list-of-lists?

21:20 i.e.,

21:21 ("foo" for 1 at 3214 where "bar")

21:21 into something like

21:21 [myvar [[key value]]] ?

21:21 ([for 1] [at 3214] [where "bar"])

21:22 tomoj: I don't think that's possible, but maybe something like this?

21:23 dnolen: ,(partition 2 (for 1 at 3214 where "bar"))

21:23 clojurebot: java.lang.RuntimeException: java.lang.IllegalArgumentException: Wrong number of args passed to: core$for

21:23 tomoj: ,(for [[k v] (partition 2 '(for 1 at 3214 where "bar"))] [k v])

21:23 clojurebot: java.lang.RuntimeException: java.lang.RuntimeException: java.lang.IllegalArgumentException: Wrong number of args passed to: core$for

21:23 tomoj: whoops

21:23 dnolen: ,(partition 2 '(for 1 at 3214 where "bar"))

21:23 clojurebot: java.lang.RuntimeException: java.lang.IllegalArgumentException: Wrong number of args passed to: core$for

21:23 tomoj: ,3

21:23 clojurebot: 3

21:23 tomoj: weird

21:24 $(for [[k v] (partition 2 '(for 1 at 3214 where "bar"))] [k v])

21:24 sexpbot: Wrong number of args passed to: core$for

21:24 dnolen: ,(partition 2 '(for-blah 1 at 3214 where "bar"))

21:24 clojurebot: ((for-blah 1) (at 3214) (where "bar"))

21:24 tomoj: I'm confused

21:25 maxhodak: hmm

21:26 tomoj: why are sexpbot and clojurebot both broken?

21:26 $(partition 2 '(for 1 at 3214 where "bar"))

21:26 sexpbot: Wrong number of args passed to: core$for

21:27 tomoj: or maybe they're using a different version of partition?

21:27 ,(doc partition)

21:27 clojurebot: "([n coll] [n step coll] [n step pad coll]); Returns a lazy sequence of lists of n items each, at offsets step apart. If step is not supplied, defaults to n, i.e. the partitions do not overlap. If a pad collection is supplied, use its elements as necessary to complete last partition upto n items. In case there are not enough padding elements, return a partition with less than n items."

21:27 tomoj: looks ok to me, very strange

21:27 Licenser_: ping

21:27 maxhodak: it works for me in repl so

22:55 johnmn3_: test

22:56 johnmn3: how do you do the opposite of (str .. ?

22:56 like, return the contents of "(pr \"hi\")"

22:56 though I don't want them evaluated by the reader.

22:56 which read-string seems to be doing

22:57 print, maybe

23:00 no, read-string should work

23:00 ,(let [s (read-string "2")] (pr (str "1 " s)))

23:00 clojurebot: "1 2"

23:01 johnmn3: ,(let [s (read-string "2")] (pr (+ 1 s)))

23:01 clojurebot: 3

23:01 johnmn3: rather

23:12 I'm getting a java.lang.Exception: EOF while reading

23:12 dakrone: johnmn3: did you close all your parens?

23:12 johnmn3: last call was clojure.lang.LispReader.read

23:13 while doing a read-string

23:13 yea, I did. strangely, it's like read-string is sending the data into a reader

23:14 dakrone: what string are you reading?

23:15 johnmn3: and I'm getting an EOF on the data I'm sending into read-string to send a treemodel the datastructure to be displayed.

23:17 I mean, read-string is un-stringifying strings pulled from a gui component and feeding them to a clojure.inspector/tree-model, which is in turn sent to a JTree.

23:17 dakrone: do you know the actual text of the string being passed to read-string?

23:18 johnmn3: I guess I should verify

23:18 should be whatever it scrapes from the textarea, like "(println \"hi")"

23:18 should be whatever it scrapes from the textarea, like "(println \"hi\")"

23:24 meh, theres got to be a missing parens in my code somewhere

23:24 dakrone: anyone know why I'm having problems with variable-arity protocols? http://gist.github.com/405912

23:40 brweber2: If I have a seq and I want to get the items (but not in a seq) what function should I use? ie I want to go from ((+ 2 3) \a) to (+ 2 3) \a

23:40 tomoj: functions can't return multiple values

23:41 ,(let [[a b] [(+ 2 3) \a]] [a b])

23:41 clojurebot: [5 \a]

23:42 tomoj: ,(let [s [(+ 2 3) \a]] [(first s) (second s)])

23:42 clojurebot: [5 \a]

23:42 brweber2: I just want to "unroll" a sequence. tomoj so de-structuring won't work if I don't know the size of the seq will it?

23:42 tomoj: correct

23:42 unrolling a sequence of an unknown size doesn't really make any sense

23:43 assuming you're not willing to drop some off the end

23:43 maybe just explain what you're actually trying to do

23:44 is it a string you want in the end? like (your-fn [(+ 2 3) \a]) == "5 \a" ?

23:45 brweber2: tomoj no, more like I want to do (list fun-name ... ) in a macro

23:46 but the ... is a lazy seq

23:46 and I just want the values of the seq

23:46 tomoj: ,`(list ~@[(+ 1 2) \a])

23:46 clojurebot: (clojure.core/list 3 \a)

23:47 tomoj: ,`(list ~@`[(+ 1 2) \a])

23:47 clojurebot: (clojure.core/list (clojure.core/+ 1 2) \a)

23:48 johnmn3: ,(map read-string '("1" ""))

23:48 clojurebot: java.lang.RuntimeException: java.lang.Exception: EOF while reading

23:49 johnmn3: that's my problem right there

23:49 brweber2: tomoj thanks!

23:49 johnmn3: ,(map read-string '("1" "2" "hi"))

23:49 clojurebot: (1 2 hi)

23:50 johnmn3: ,(map read-string '("1" "2" "hi" ""))

23:50 clojurebot: java.lang.RuntimeException: java.lang.Exception: EOF while reading

23:50 tomoj: ,(read-string "")

23:50 clojurebot: java.lang.RuntimeException: java.lang.Exception: EOF while reading

23:50 johnmn3: hmm, it's the empty quotes

23:50 so filter ""

23:53 ,(map read-string (remove #(= "" %) '("1" "" "hi")))

23:53 clojurebot: (1 hi)

23:54 tomoj: ,(map read-string (remove #{""} '("1" "" "hi")))

23:54 clojurebot: (1 hi)

Logging service provided by n01se.net