#clojure log - May 08 2010

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

0:09 * slyphon tries to figure out what "you can implement a protocol on an interface" means

0:12 * slyphon calls it a night

0:55 cap11235: I'm trying to extend JPanel using gen-class, and I can't find a way to implement a constructor so I can add a KeyListener to it. From what I can tell, :init is only for setting up the :state reference for the class, and calling super's contructors. I tried having it have "this" as a parameter, but I get get an IllegalArgumentException. How can I add my KeyListener?

1:13 Drakeson: sometimes (maybe whenever a jar is actually downloaded) lein deps nags something like Exception in thread "main" java.lang.NoClassDefFoundError: clojure/lang/Agent

1:14 does that happen to you, too?

1:24 tomoj: never seen that before

1:24 Drakeson: ^

1:28 Drakeson: tomoj: thanks

1:48 technomancy: Drakeson: that's a known bug; shouldn't affect functionality

1:48 you can ctrl+c your way out of it

1:49 perils of living on the edge

1:49 Drakeson: it's not happening in a stable release, is it?

1:52 Drakeson: technomancy: no, but I cannot switch back to the stable. (I need :repositories, for instance).

1:53 technomancy: do you plan on integrating a `search' task?

1:53 technomancy: Drakeson: not in the next release, possibly in 1.3

1:55 Drakeson: how about a cache (as in apt-cache update), for instance in order to know which repository to find [the latest of] each artifact from

1:56 technomancy: Drakeson: it's a possibility; I haven't really thought it all the way through

1:56 web-based search works well enough that it's not the highest priority for the next release for me

1:58 Drakeson: well, that is not just for search, it is to speedup the process of finding the repository that has the latest version of an artifact. If I am not mistaken, it currently hits all the repositories everytime lein deps is issued.

1:59 technomancy: yes, but changing that behaviour would involve hacking maven itself

1:59 Drakeson: aah, I see.

1:59 technomancy: there are a lot of ways you could be smarter than mvn's current behaviour obviously, but I don't think any of them are really doable without at least doubling lein's LOC count

2:00 would love to be proven wrong though =)

2:00 Drakeson: Will seting up a local maven "proxy" help?

2:01 technomancy: yeah, definitely

2:01 I mean, probably

2:02 actually I wonder if the Agent classdef not found is a Clojure bug

2:03 replaca: late friday night in #clojure. hi, gang

2:03 technomancy: replaca: heyo

2:03 replaca: as a pprint kind of guy you might be interested in this: http://github.com/technomancy/serializable-fn

2:04 replaca: technomancy: saw it. very cute!

2:04 technomancy: we hacked it up at last night's seattle clojure meeting

2:04 replaca: I've thought about doing that a bunch of times, but never actually sat down to work it all the way out

2:05 technomancy: it was way easier than I thought it'd be now that you have access to &form and &env

2:05 I tried adapting clojure.core/fn to do it, but the weirdness of how that macro is defined stymied me

2:05 replaca: yeah, I was looking at that a week or so ago and there's a lot going on there

2:06 technomancy: the first hundred lines of core.clj have changed a lot since I last looked =)

2:06 it was pretty illuminating to go over it though, shows pretty well how &form and &env are done

2:07 replaca: core.clj is kind of like the bible, it has to be studied and you also have to take context into account (since it unfolds in order)

2:07 I've been messing around with declare to keep it from squashing metadata

2:07 technomancy: that analogy works surprisingly well

2:09 replaca: in the beginning, Rich said "Let there be #'list and there was #'list"

2:10 technomancy: "and Rich divided the fns from the macros..."

2:11 man, I think it's bad when I break things while hacking swank; I hate to think what it's like when you mix things up while redefining fn

2:12 replaca: yeah, but it breaks pretty quickly at least

2:15 it's hard to even have a conversation about git vs. perforce anymore. So much of what I do would be unimaginably annoying in perforce

4:33 fnuction: Does anyone know if ClojureCLR will work against .Net 4?

5:14 Borkdude: fnuction: no, I haven't got it working in my VS2008 whatsoever

5:14 I didn't mean no, it doesn't work on .NET 4, I meant: I don't know -- sorry ;)

5:16 fnuction: I had it working against 3.5 in VS 2010, then I broke it.

5:18 Post on the Google group explains why..

5:32 nurv: Hi.

5:38 Borkdude: fnuction: I didn't follow the GG much, I just tried what was said on the website but I kept getting errors

5:39 Something about references it couldn't find, although Intellisense could find it

5:48 fnuction: Borkdude: There are lots of potential problems with finding multiple version of the assemblies etc.

5:49 nurv: Hi.

5:50 Borkdude: yes, hello nurv

8:11 GeoffSK: can some suggest why http://pastebin.com/raw.php?i=hsqMPeru causes a java exception?

8:20 hoeck: GeoffSK: probably the #((echo name running))

8:20 try #(echo name running) instead

8:21 because the echo funktion returns nil and you dont want to call nil #(nil) <- throws NPE

8:24 GeoffSK: hoeck: thanks (again)

8:25 hoeck: GeoffSK: np :)

8:25 GeoffSK: btw, is this an acceptable way to tell a thread to exit?

9:27 tufflax: It's great that I can do (rest [1 2 3]) on vectors like that, but how can I use that as a vector again? The class of it is clojure.lang.PersistentVector$ChunkedSeq, so underneath somehow it is still a vector, so I should be able to "cast" it back or something, yes?

9:49 patrkris: tufflax: the answer may depend on what you're trying to do here

9:49 usually, if you're just looping through a vector to do something to each item, then it doesn't matter that you're not getting a vector back

9:50 but for cases where you need to get a subvector the aptly named subvec function may help you

10:07 rhickey: if you are there, could you help me understand a few things about obstruction freedom?

10:12 zakwilson: I'm finding several tutorials and libraries related to Google App Engine with Clojure. Is there one library that's generally preferred over others?

10:19 SynrG: hmm. something's wrong with my vimclojure ... doesn't look like localleader is doing its stuff ...

10:20 if i press \ then s, it just performs an 's'

10:20 :p

10:25 patrkris: SynrG: have you started the nailgun server?

10:29 SynrG: yes

10:30 patrkris: and does the nailgun server have the necessary .jar-files in its classpath?

10:30 you can check the classpath by invoking `ng ng-cp`

10:49 SynrG: patrkris: seems like a vim issue, not a nailgun issue

10:50 pressing \ and *any* other key doesn't do anything. it's as if i hadn't pressed the key at all :p

10:52 patrkris: SynrG: I had the same symptoms. It seems that vimclojure does not map keys for starting the REPL and performing evaluation unless it detects that the nailgun server is started. Even though you may have set the localleader to something, I don't think it comes into effect unless some key combination uses it.

10:53 SynrG: aha

10:53 patrkris: SynrG: but of course, it could also be a Vim issue. Did you get syntax highlighting working? Just to get an indication whether you installed vimclojure's vim scripts correctly into ~/.vim

10:54 SynrG: syntax highlighting works fine

10:54 patrkris: Ok. And you unzipped the vim-stuff as per the instructions?

10:55 SynrG: yes.

10:56 patrkris: Ok. Then I'm pretty sure it has something to do with your nailgun setup. Btw, are you using a *nix or Windows?

10:56 SynrG: when i ask vim what the filetype is when i'm editing a file it says 'clojure'

10:56 *nix

10:56 patrkris: ok, that's fine then

10:56 SynrG: debian, to be precise

10:56 patrkris: Ok. Do you have the nailgun client in your path?

10:56 SynrG: yes

10:57 patrkris: have you tried invoking ng ng-cp?

10:57 SynrG: yes. it gives reasonable results

10:57 it includes clojure.jar, clojure-contrib.jar, vimclojure.jar

10:57 patrkris: Ok... hmmm...

10:57 SynrG: and jline.jar

10:57 patrkris: ok

10:58 have you tried setting localleader to something else?

10:58 SynrG: yes

10:58 patrkris: sorry, it's called maplocalleader - but you probably know that

10:59 and you have the g:clj_want_gorilla option set to 1, I guess?

10:59 SynrG: yes. i tried changing it after loading a .clj file and earlier, in .vimrc

10:59 no. is that essential?

10:59 patrkris: yes :)

10:59 as far as I remember, I don't think it is enabled by default

11:00 try setting it in your vimrc and see if it works

11:00 let g:clj_want_gorilla = 1

11:00 Borkdude: What does this stuff from the core function + actually do? {:inline (fn [x y] `(. clojure.lang.Numbers (add ~x ~y)))

11:00 :inline-arities #{2}}


11:01 SynrG: patrkris: still doesn't help

11:01 things are suddenly much slower tho

11:01 patrkris: SynrG: strange

11:02 you might want to check back here when kotarak is online

11:02 or try the mailinglist

11:02 SynrG: k

11:03 patrkris: Borkdude: inlines calls to +...?

11:04 Borkdude: patrkris when does that happen? I mean, there is also a 'normal' definition for two parameters

11:04 patrkris: i.e. wherever you use +, a call to clojure.lang.Numbers/add is inserted instead during compilation

11:05 Borkdude: aha

11:05 patrkris: Borkdude: maybe the normal definition is used when you don't use + directly but instead refer to it through an indrection

11:05 but i'm just guessing :)

11:06 SynrG: patrkris: hm. something changed. i stopped ng-server, exited bash, started a fresh session to ensure my environment was properly set up, edited my file again ...

11:07 Borkdude: patrkris: maybe you're right, when it is compiled the function with 2 args gets inlined, I just wondered what this inlining stuff is about

11:07 SynrG: patrkris: now i get a lot of error spew and syntax highlighting is not turned on

11:07 patrkris: SynrG: then try :e<CR>

11:07 SynrG: hopefully you know that <CR> means the Enter key :)

11:08 Borkdude: i think it's for the sake of performance

11:08 SynrG: Couldn't execute Nail! java.io.FileNotFoundException: Could not locate book_list__init.class or b

11:08 ook_list.clj on classpath: at ...

11:08 hey, where'd my classpath go? looks empty

11:08 patrkris: SynrG: try editing an empty .clj file

11:09 e.g. :e myfile.clj

11:09 and then try starting a REPL via <localleader>sr e.g. \sr

11:10 SynrG: patrkris: nope. same symptom as before

11:11 :let maplocalleader

11:11 E121: Undefined variable: maplocalleader

11:11 zakwilson: Using Compojure and ring.adapter.jetty, changes I make at the REPL are not reflected when I reload a page. I'd RTFM, but there doesn't really seem to be one.

11:11 patrkris: ok, try :let maplocalleader=";"

11:11 SynrG: ^

11:12 SynrG: no effect

11:12 patrkris: SynrG: I like to use semicolon, but you can try any key you'd like

11:12 ok

11:13 SynrG: could you try and close vim, but keep the nailgun server running and then start vim on an emtpy clojure-file ... just to try it out

11:13 SynrG: and remember to put a let maplocalleader=";" in your .vimrc

11:15 SynrG: patrkris: still no joy :/

11:15 patrkris: SynrG: damn

11:16 SynrG: but it seems that the "gorilla" part of vimclojure has been activated in some sense

11:17 SynrG: btw which version of vimclojure are you using - the bleeding edge version or the last release?

11:17 SynrG: ,, which is the localleader for vimoutliner seems to work

11:17 clojurebot: java.lang.Exception: Unable to resolve symbol: which in this context

11:18 SynrG: shush, clojurebot

11:18 patrkris: :)

11:18 SynrG: sec ...

11:18 2.1.2

11:18 patrkris: yeah, i think it's the one I'm using

11:19 well ... I don't have any other suggestions right now

11:19 SynrG: yup. thanks for trying :)

11:29 patrkris: hm. rebuilt and reinstalled the jars. seems to be cooperating now

11:29 dunno what i did :/

11:29 i still get error spew at the beginning

11:30 patrkris: SynrG: can you start a REPL now?

11:31 SynrG: apparently

11:31 but ;ef gives:

11:31 Couldn't execute Nail! java.lang.ClassNotFoundException: de.kotka.vimclojure.nails.Repl at java.n

11:31 et.URLClassLoader$1.run(URLClassLoader.java:217) at java.security.AccessController.doPrivileged(N

11:31 ative Method) at java.net.URLClassLoader.findClass(URLClassLoader.java:205)

11:31 test.clj contains:

11:31 (+ 2 2)

11:31 clojurebot: 4

11:32 SynrG: thanks, clojurebot :p

11:32 when did clojurebot stop requiring a prefix?

11:33 patrkris: dunno - I never actually used it :)

11:33 do you know where to find instructions on using clojurebot? :)

11:33 * SynrG shrugs

11:33 patrkris: strange that upon invoking ;ef it says the Repl class is missing

11:34 but are you able to enter and evaluate text inside the REPL?

11:35 SynrG: restarted ng-server again. restarted editing again

11:35 looks fine now

11:35 * SynrG shrugs

11:35 SynrG: mystifying

11:36 i try random things and things work ...

11:36 i hate it when that happens :p

11:36 tufflax: don't we all

11:37 SynrG: so, my HOWTO:

11:37 obtain wall

11:37 beat head against wall

11:37 repeat until unconscious, or things work

11:38 patrkris: :)

11:42 tufflax: patrkris: Thanks by the way, for answering my question earlier. I wasn't trying to do anything specific, I was just curious.

11:47 SynrG: patrkris: things are *not* working flawlessly, however

11:48 it seems very temperamental

11:51 patrkris: SynrG: you could take a look at the leiningen nailgun plugin, if you use leiningen

11:51 SynrG: it sets up the classpath for you

11:52 SynrG: hm. always restart ng-server each time you start vim again

11:52 seems to be part of my problem

11:54 the other is that sometimes my ; seems to be 'eaten' by whatever i did previously, and i don't know why

11:54 ah, it's timing

11:55 because these sequences are unfamiliar, if i wait too long while i try to think of what the sequence is ...

11:55 it forgets i typed localleader

11:58 patrkris: SynrG: that's right - also had that problem :)

12:00 SynrG: I hope you get it to work - see you later

12:08 Drakeson: how can I extend an existing interface?

12:10 is gen-interface the only option?

12:13 hoeck: Drakeson: deftype, proxy or genclass

12:14 oh, sorry, that implements an existing iface

12:20 Borkdude: What's with rfirst? I see it on the Clojure cheatsheet, but it doesn't work in my repl

12:23 Drakeson: Borkdude: nfirst

12:25 there was a rest --> next transition. rfirst and rrest probable got renamed to nfirst and nnext

12:26 How does one put an "Integer []" or "I[" type hint on an argument?

12:26 #^ints apparetnly does not do it

12:28 tcrayford: have you tried #^Integer[] ?

12:28 Drakeson: yes

12:28 fails

12:29 DuneMan: or #^{:tag Integer[]}

12:29 ?

12:31 *wonders*

12:31 Drakeson: ,(defn foo [#^{:tag Integer[]} x] x) (foo 1)

12:31 clojurebot: DENIED

12:31 Drakeson: ,(defn foo [#^{:tag Integer[]} x] x)

12:31 clojurebot: DENIED

12:31 Drakeson: lazy bot

12:32 DuneMan: anyway, doesn't work

12:36 DuneMan: http://groups.google.com/group/clojure/browse_thread/thread/9a276a1709a88eeb

12:39 Drakeson: thanks, "ints" works for some other places, but apparently non in definterface.

12:40 DuneMan: well, "ints" is int[], no?

12:45 cap11235: looks like :init to me

12:45 Drakeson: DuneMan: it seems it should be

12:46 DuneMan: Drakeson: So that wouldn't be Integer[]

12:46 so it shouldn't work.

12:47 Drakeson: I don't get it. why wouldn't (defn foo [#^ints xs] xs) work?

12:47 DuneMan: If you're giving it Integer[], int[] != Integer[]

12:48 but you could use #^objects foo, and then give a typehint to integer for all of the accesses.

12:48 Drakeson: I am not giving it anything yet. it fails even before that. (definterface foo-iface (#^ints bar [this]))

12:48 DuneMan: oh, weird.

12:48 I see

12:49 Drakeson: is definterface being depreciated?

12:52 DuneMan: (gen-interface :name "Foo" :methods ....)

12:52 dur

12:52 yeah

12:55 I mean... I'm pretty new to clojure... but definterface isn't in the docs... so maybe it was a 1.0 thing?

13:06 dakrone: what's the easiest way to convert (:a 1 :b 2 :c 3) into a map? I was using (apply hash-map ...), but it throws errors on duplicate keys

13:08 Drakeson: ,(into {} (vec '(:a 1 :b 2 :c 3)))

13:08 clojurebot: java.lang.IllegalArgumentException: Don't know how to create ISeq from: clojure.lang.Keyword

13:08 Drakeson: ,(into {} (map vec (partition 2 '(:a 1 :b 2 :c 3))))

13:08 clojurebot: {:a 1, :b 2, :c 3}

13:09 dakrone: Drakeson: that's it, thank you much

13:27 tufflax: If I want to save clojure objects/datastructures to files, should I use java's stuff? Do clojure datastrctures implement serializeable?

13:27 Borkdude: good question

13:28 rhudson: They implement Serializable in 1.2

13:30 tufflax: ok, thanks

13:31 zakwilson__: With compojure.html, (html (vector [:h3 "foo"] [:p "bar"] [:div "baz"])) is returning "<><p>bar</p><div>baz</div></>". Is this a bug, or user-error?

13:32 (expected was "<h3>foo</h3><p>bar</p><div>baz</div>")

13:52 _brian2_: noob question> regarding reading in a serialized java object, in java you use type casting to the object to identify it, how does that work in clojure -> http://clojure.pastebin.com/ZUmyyxYx

13:55 candeller: hi - having a list of strings, i.e '("foo" "bar" ...) Id like to get a list of the characters '(\f \o \o \b \a \r ...) what would be the most idiomatic way?

13:56 rhudson: _brian2_: The object you read in already has the right class. Clojure is dynamically typed.

13:56 _brian2_: i get type cast exception

13:57 rhudson: What's the expression?

13:57 rhickey: ,(apply concat ["abc" "def"])

13:57 clojurebot: (\a \b \c \d \e \f)

13:58 candeller: thanks, wouldnt have guessed that concat can return separate chars :o

13:58 rhickey: ,(seq "abc")

13:58 clojurebot: (\a \b \c)

13:59 candeller: oh, why i havent thought about it, thanks

14:01 _brian2_: rhudson: just a sec

14:04 dakrone: how do you refer to protocol methods outside of the namespace they're declared in? http://gist.github.com/394685

14:05 _brian2_: rhudson: (def classifier2 ( .readObject objIn )) , (def compiledClassifier ( AbstractExternalizable/compile classifier2))

14:10 rhudson : the problem , I think, is that this object needs to be cast into another type to be accepted by the function I'm passing it ot

14:11 this object is a subclass of the object I need to cast it into

14:13 rhudson: Sorry _brian2_, was away. So it's com.aliasi.util.AbstractExternalizable ?

14:13 _brian2_: yes

14:14 lingpipe library

14:15 rhudson: And classifier2 implments Compilable?

14:16 _brian2_: just a sec

14:18 rhudson : no, however ..

14:20 arkahn: is the ants.clj program Rich Hickey wrote two or three years ago still a canonical example in the use of clojure concurrency or is there something newer/updated that's a better example?

14:20 _brian2_: rhudson : I'm putting the authors notes up

14:21 arkahn: ... sometimes I feel clojure suffers from Perl's TMTOWTDI - I just want one good way ; )

14:22 a la Python

14:23 _brian2_: rhudson : -> http://clojure.pastebin.com/nh1aDCgY

14:26 he starts with DynamicLMClassifier , trains it, writes it out as that type, then appears to cast it into LMClassifer , which does not, I think, implement Compilable

14:26 when he reads it in

14:29 rhudson: When the object gets serialized, the serialization includes the name (or some indicator) of the class of the object. When you read it back it, you're reconstituting the same class of object.

14:30 In Java, a statically typed language, you have to say what the types of your variables are.

14:30 So when you cast to LMClassifier, you're saying "through this variable I will only perform LMClassifier calls".

14:31 But the object itself is unchanged.

14:31 _brian2_: But appears I cant cast it in clojure

14:35 rhudson: You shouldn't need to cast it in Clojure. There's only one "compile" method in AbstractExternalizable, which takes a Compilable, so the implementation should be looking at the object, seeing whether it implements Compilable, and making the call if so.

14:35 So I don't understand why you're getting a class cast exception.

14:37 You could try putting in a type hint -- (.../compile #^Compilable classifier2)

14:37 _brian2_: ok

14:39 rhudson: or, when you've read in the object, make sure you have the right one: e.g. (assert (instance? Compilable classifier2))

14:41 _brian2_: ok, this #^Compilable didnt do anything

14:41 rhudson: yeah, I didn't really expect it to

14:54 _brian2_, another troubleshooting thing to try is printing out the class of the object after you've read it in: (println (class classifier2)).

14:54 And you're using the same version of the library to write and read?

14:55 _brian2_: ok

14:55 yes

14:56 nurv: Hi.

14:57 _brian2_: (println (class classifier2)) , com.aliasi.classify.LMClassifier

14:59 rhudson: which is not a Compilable

14:59 _brian2_: hmm

15:00 ok, its my stupidity

15:01 thanks!

15:01 rhudson: you're welcome

15:06 Borkdude: What's the difference with # and #^ ?

15:06 no sorry ^ and #^

15:13 cschreiner: #^ is oldschool

15:22 Borkdude: Is there any more idiomatic way of getting a sequence from \a to \z? (map char (range (int \a) (inc (int \z))))

15:25 rhudson: ,(seq "abcdefghijklmnopqrstuvwxyz")

15:25 clojurebot: (\a \b \c \d \e \f \g \h \i \j \k \l \m \n \o \p \q \r \s \t \u \v \w \x \y \z)

15:25 ataggart: lol

15:26 LauJensen: naah, idiomatic would be more like

15:26 $(-> (map char (take 25 (drop-while (partial < 121) (iterate dec 10e6)))) reverse)

15:26 rhudson: It's actually fewer characters...

15:26 sexpbot: result: (\a \b \c \d \e \f \g \h \i \j \k \l \m \n \o \p \q \r \s \t \u \v \w \x \y)

15:26 rhudson: Zebra's won't like that...

15:27 Borkdude: LauJensen: I thought reverse was not so idiomatic, but more for people who come from CL ;)

15:28 LauJensen: of ofc you're right, try making it work with apply interleave instead :)

15:32 Borkdude: yes, much better than using inc, counting down is much more spacy

15:33 nurv: $(map char (range 97 123))

15:33 sexpbot: result: clojure.lang.LazySeq@726b766e

15:35 LauJensen: $(doall (map char (range 97 123)))

15:35 sexpbot: result: clojure.lang.LazySeq@726b766e

15:35 ataggart: btw, there are more than 26 letters

15:35 LauJensen: hrmf

15:35 Borkdude: hmm, I turned on clojure-mode in my ERC buffer, that didn't work out ;)

15:36 $(take-while true (map char (range 97 123)))

15:36 sexpbot: java.lang.Boolean cannot be cast to clojure.lang.IFn

15:36 Borkdude: ah damn ;)

15:37 $(take-while (constantly true) (map char (range 97 123)))

15:37 sexpbot: result: clojure.lang.LazySeq@726b766e

15:37 Borkdude: nopr

15:38 What happens if you use seq on it?

15:39 $(seq (map char (range 97 123)))

15:39 sexpbot: result: (\a \b \c \d \e \f \g \h \i \j \k \l \m \n \o \p \q \r \s \t \u \v \w \x \y \z)

15:40 nurv: mmmm...

15:41 $```````,(+ 2 2)

15:41 sexpbot: Command not found. No entiendo lo que estás diciendo.

15:41 hiredman: that is just sexpbot's broken result printin

15:41 nurv: Somehow it's a stack overflow here.

15:41 hiredman: ,(take-while (constantly true) (map char (range 97 123)))

15:41 clojurebot: (\a \b \c \d \e \f \g \h \i \j \k \l \m \n \o \p \q \r \s \t \u \v \w \x \y \z)

15:58 hiredman: ,(squote '(A B C# (unsquote-splice [(squote A) 2 3]) C#))

15:58 clojurebot: (list (quote sandbox/A) (quote sandbox/B) (quote C__15055) (quote sandbox/A) 2 3 (quote C__15055))

16:02 rhudson: ,#'squote

16:02 clojurebot: #'sandbox/squote

16:03 hiredman: I really need to break the (defmulti foo type) habit and start writting protocols

16:11 vIkSiT: hmm, I'm trying to write some code that takes in a sentence like - This 'is' a test _sentence_ (quoted word and underscored word), and then performs an operation on it.

16:12 now imperatively, I'd have an array/string, run through each word in that sentence in a loop, do an "if quoted() or if underscored()" on the word, and then perform the relevant operation, and append the changes into the string

16:13 but given immutable data structures - whats a good functional way to do it without resorting to atoms and derefs?

16:14 rhudson: Basically you want to produce a new sentence that's the appropriate transform of the old sentence

16:15 vIkSiT: exactly

16:16 rhudson: so roughly (for [w words] (if (changeit? w) (changeit w) w))

16:17 vIkSiT: hmm yes. I'd have two if conditions though

16:17 or n, for the purposes of this question..

16:17 rhudson: then cond

16:17 vIkSiT: I assume that the (changeit w) returns the changed value, but i'd have to operate on this _changed_ value in the next form..

16:18 let me paste what i have right now..

16:18 whats a good clojure pastebin btw?

16:18 lisppaste?

16:18 clojurebot: lisppaste8: url

16:19 rhudson: dunno; haven't done it myself yet

16:20 Lotsa folks seem to use gist.github.org

16:20 vIkSiT: thats true

16:20 http://paste.lisp.org/display/98969

16:21 so I have 2 issues here : a) how do i specify a "default" value to cond, and b) how do i take the return value from (myfun w) and pass it to the next statement?

16:21 rhudson: (a) :else w

16:22 (b) using 'for usually works out well

16:22 (a) -- any "true" value serves, but :else is conventional

16:23 vIkSiT: rhudson, ah, how dyou mean (b) there?

16:24 hiredman: a,b,a ?

16:24 rhudson: something like (let [words (for [w words] (cond ....))] (use-rebound-words ...)

16:24 hiredman: shoudl be ba

16:24 rhudson: hiredman: re his "so I have two issues here"

16:25 hiredman: oh, I assumed you had a binary alphabet

16:25 vIkSiT: hehe

16:25 rhudson: 01101010000101

16:25 hiredman: why use for in this case over map?

16:25 abbababaaaabab

16:25 rhudson: I just like for better

16:26 vIkSiT: hmm, I was thinking about map as well (i use it for everything in python) - but I'm still not sure in either case how the return value of (myfun w) is going to be reused?

16:26 rhudson: 'for reads better than 'map when the function is long

16:26 vIkSiT: lets say I have a vector ["a" "b" "c"]

16:27 and a function, (defn myfn [x])

16:27 hiredman: just say F

16:27 vIkSiT: sure

16:27 rhudson: F

16:28 hiredman: you want to transform the elements of V with F

16:28 vIkSiT: now after (for [w words] (cond (F? x) (F x)

16:28 (F x) returns the transformed value of x

16:28 hiredman: (transform <=> map)

16:28 vIkSiT: ah. so map will do an in-place transform?

16:29 Borkdude: ,(doc update-in)

16:29 clojurebot: "([m [k & ks] f & args]); 'Updates' a value in a nested associative structure, where ks is a sequence of keys and f is a function that will take the old value and any supplied args and return the new value, and returns a new nested structure. If any levels do not exist, hash-maps will be created."

16:29 hiredman: vIkSiT: how could it?

16:29 immutable

16:29 rhudson: No, the point is you get a new vector , and apply the next operation to that new vector

16:29 vIkSiT: yes exactly.

16:29 hiredman: no

16:29 you get a new seq

16:30 vIkSiT: I got that. My confusion is - how do I pass that new seq to the next (F? x)

16:30 hiredman: just call the next fn on it

16:30 rhudson: one way is, say ( -> ["a" "b" "c"] transform1 transform2 )

16:30 Borkdude: this sounds more like a map thing

16:30 hiredman: ,(apply str (map char (map inc (range 90 100))))

16:30 clojurebot: "[\\]^_`abcd"

16:31 vIkSiT: hmmm yes that does seem better

16:31 let me try

16:31 hiredman: ,(-> (range 90 100) (map inc) (map char) (apply str))

16:31 clojurebot: java.lang.ClassCastException: clojure.lang.LazySeq cannot be cast to clojure.lang.IFn

16:31 Borkdude: (map #(if this or that then ret this or that) your-seq)

16:31 hiredman: ,(->> (range 90 100) (map inc) (map char) (apply str))

16:31 clojurebot: "[\\]^_`abcd"

16:31 Drakeson: is there a way to transform the name of a class when you import it?

16:31 (or rename)

16:32 hiredman: try using for with -> or ->>

16:32 gets funky fast

16:33 ,(->> x (for [y (range 10) :let [x (* y y)]]))

16:33 clojurebot: (0 1 4 9 16 25 36 49 64 81)

16:33 vIkSiT: ah

16:33 what IS ->>?

16:34 hiredman: ->> is ->, but differnt

16:34 rhudson: ,(doc ->>)

16:34 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."

16:34 rhudson: ,(doc ->)

16:34 clojurebot: "([x] [x form] [x form & more]); Threads the expr through the forms. Inserts x as the second 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 second item in second form, etc."

16:35 vIkSiT: ha

16:35 never used either

16:35 rhudson: They are really useful

16:35 Plouj: ,(+ 1 2 3)

16:35 clojurebot: 6

16:36 Borkdude: it's just a rewrite of what you would otherwise nest

16:36 vIkSiT: right

16:37 rhudson: Anyway, my point was not so much syntactic, as that functionally what you do is produce a new sentence (not alter the old one), and feed that to the next operation

16:38 vIkSiT: sure

16:41 rhudson: The arrows are a convenient way to do that if the operations are short forms (like names), and has the advantage of reading the right way. (-> a f1 f2 f3) vs (f3 (f2 (f1 a)))

17:12 springify: Good evening. Has anybody here ever tried cuke4duke with lein-cuke and made it work?

17:20 LauJensen: Is there something in contrib which makes (mkdir "x/y/z.clj") create both x, y and z.clj provided they dont exist?

17:21 Drakeson: LauJensen: Don't know, but (.mkdirs (java.io.File. "x/y")) should create x/y/

17:22 LauJensen: Good enough, thanks

17:22 mmarczyk: Karmic -> Lucid: yet another painless upgrade :-)

17:23 nickpad: hi - wondering if anyone's come across this problem trying to run the labrepl project: http://paste.lisp.org/display/98972

17:23 LauJensen: mmarczyk: Go get that lottery ticket

17:23 mmarczyk: LauJensen: yup, on my way already :-)

17:24 apparently there's a Clojure package in universe, but it's 1.0... got to find out who maintains it and maybe bump it to 1.1

17:29 Plouj: hi

17:30 so, I still can't figure out why swank/slime only works right after I install it in emacs with elpa, but fails with "Lisp connection closed unexpectedly: connection broken by remote peer" on subsequent emacs restarts.

17:49 actually, sometimes it works (connects to addr=,port=0,localport=53077) once every 5 times I try to restart and do M-x slime

17:55 Borkdude: mfex: here?

17:58 Plouj: what would you guys recommend as a rest for learning clojure for someone who isn't new to LISP and programming in general

18:00 Borkdude: as a rest?

18:02 Plouj: erm

18:02 I don't know what I meant to type :)

18:02 I guess as a "good book"

18:03 I'm looking for a book/tutorial to learn clojure

18:03 I'm not sure if reading the clojure version of sicp is that helpful for practicing concurrent programming

18:03 rhudson: Stuart Halloway's book Programming Clojure is good

18:04 dnolen: Plouj: sounds like Joy of Clojure is going to be pretty good. Programming Clojure is good too, though a lot of 1.2 stuff is missing from it.

18:05 Plouj: is joy of clojure more up to date, dnolen?

18:06 dnolen: Plouj: seems like it

18:06 rhudson: Joy of Clojure looks good so far -- 7 chapters are out in early access.

18:08 vIkSiT: does anyone cover protocols (outside of the video?)

18:08 rhudson: Neither book has exercise material. projecteuler.net and rosettacode.org are good places to find some interesting problems.

18:08 vIkSiT: There's also codingkata.org

18:09 rhudson: Haven't seen that one; I'll take a look

18:09 vIkSiT: (PE is most mathematical et al; I've found ck has some interesting stuff to get used to a language)

18:09 mostly*

18:09 Plouj: project euler is hard :)

18:10 vIkSiT: Plouj, depends :) some of the "hardness" comes from not being familiar with certain concepts for instance.

18:11 ,(doc ->)

18:11 clojurebot: "([x] [x form] [x form & more]); Threads the expr through the forms. Inserts x as the second 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 second item in second form, etc."

18:11 vIkSiT: rhudson, what are the -> and ->> operators called?

18:12 rhudson: Not sure they have an official name; I think of them as the arrow operators

18:12 Plouj: vIkSiT: yeah, it requires more concentrated thinking than I can afford while learning a language at the same time

18:12 The-Kenny: vIkSiT: Some people call -> "thread".

18:13 (I forgot the name for the ->>)

18:13 vIkSiT: Plouj, agreed. I'd say PE/SPOJ/TC et al are to finetune language skills rather than learn; codingkata et al help do the latter pretty well

18:13 (spoj - sphere online judge, tc - topcoder)

18:13 they're also more algorithmic in nature

18:13 The-Kenny, ah thanks

18:14 The-Kenny: ,(doc ->>)

18:14 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."

18:14 rhudson: Rosettacode is a mixed bag. One advantage is that you see the same problem solved in a lot of different languages

18:14 vIkSiT: I was trying to find some example uses of -> and ->>

18:14 but obviously google is horrendous in finding some

18:14 technomancy: vIkSiT: "thrush" is one name that I think encompasses -> and ->>

18:14 The-Kenny: ,(-> 1 (+ 5) (- 10))

18:14 clojurebot: -4

18:14 technomancy: someone mentioned "stitch", which I think is much better than "thread"

18:15 The-Kenny: (- (+ 1 5) 10)

18:15 ataggart: -> "nest" since that's what it does

18:15 technomancy: hiredman: have you thought about changing the code invocation prefix for clojurebot? I get confused since clojurebot treats , like clojure treats ~

18:15 vIkSiT: technomancy, ah thanks. ironically a google of "clojure thrush" brings me to #clojure logs from 09 with the _exact_ same question being answered :)

18:16 technomancy: vIkSiT: http://debasishg.blogspot.com/2010/04/thrush-in-clojure.html <= a nice explanation

18:16 sexpbot: "Ruminations of a Programmer: Thrush in Clojure"

18:16 vIkSiT: ah. so -> takes 1, adds it as the second item in (+ 5 1), then -> takes the result of that and puts it as the second eleemnt in (- 10)

18:17 technomancy, ah thanks. let me check

18:17 The-Kenny: vIkSiT: yes, and second element means after the function

18:18 rhudson: ,(-> 7 (- 3))

18:18 clojurebot: 4

18:18 rhudson: ,(->> 7 (- 3))

18:18 clojurebot: -4

18:18 vIkSiT: hmm, after the function, as in?

18:18 ah. -> implies (- 7 3), and ->> (- 3 7)

18:18 rhudson: right

18:19 vIkSiT: gotcha

18:20 rhudson: -> is especially useful in Java interop, since the standard Clojure form for a method call is (.method object args)

18:20 ataggart: -> is useful for nested operations on a value. ->> id useful for nested operations on a collection of values.

18:25 rhudson: I recently wanted to get a line sequence from a URL, so first I got an InputStream (with-open [istream (-> drafts-url URL. .openStream)]

18:25 then

18:25 (let [lnseq (-> istream InputStreamReader. BufferedReader. line-seq)]

18:37 DuneMan: I find -> so hard to read.

18:40 probably would get used to it if I used it.

18:40 *switches some code to use it

18:45 ataggart: its a nice replacement for deeply nested stuff which can be harder to read, e.g., (foo (bar (baz x) y) z) (-> x baz (bar y) (foo z))

18:45 but if you don't like it, don't use it

18:46 tmtowtdi

19:03 vIkSiT: hmm is <- an operator too?

19:03 http://nathanmarz.com/blog/cascalog-news-feed/ uses it all over the place;

19:03 sexpbot: "News Feed in 38 lines of code using Cascalog — thoughts from the red planet"

19:04 rhudson: ,(doc <-)

19:04 clojurebot: "clojure.contrib.datalog.rules/<-;[[hd & body]]; Build a datalog rule. Like this: (<- (:head :x ?x :y ?y) (:body-1 :x ?x :y ?y) (:body-2 :z ?z) (not! :body-3 :x ?x) (if > ?y ?z))"

19:04 vIkSiT: weird. why didnt that work for me?

19:05 aah. c.c.datalog

19:05 damn. the doc function should allow queries for ALL modules

19:05 not just those used or required in the current namespace

19:05 rhudson: Yeah, clojurebot already has all the contrib libs

19:06 vIkSiT: is there a way to force doc to do that btw?

19:06 useful if no web connection/IRc open!

19:06 rhudson: not to my knowledge

19:06 vIkSiT: oh well :)

19:25 somnium: ,(apply assoc {} :a :b [1])

19:25 clojurebot: {1 nil, :a :b}

19:25 somnium: Im guessing its doing [[x y] [1]] to get the nil, would it make sense to throw there? (just took me a little bit to track down)

19:32 hrm, adapting it to conj instead of assoc makes it throw

20:04 dnolen: ,(assoc {} :a :b 1)

20:04 clojurebot: {1 nil, :a :b}

20:07 somnium: ,(assoc {} 1)

20:07 clojurebot: java.lang.IllegalArgumentException: Wrong number of args passed to: core$assoc

20:08 somnium: my POLS has been violated :/

20:25 tomoj: wat

20:25 assoc should error with an even number of args, no?

20:26 hiredman: just look at the implementation of assoc

20:26 it should be least surprising that it works that way

20:26 tomoj: is it RT.assoc?

20:26 hiredman: I dunno

20:26 I haven't look at it

20:26 but I can imagine how it goes

20:26 tomoj: hmm

20:27 I think I might see what you mean

20:27 hiredman: (defn assoc ([a b c] ...) ([a & keyvals] blahblah blah reduce or loop))

20:28 tomoj: just an arity thing then?

20:28 hiredman: (let [keyvals '(1)] (assoc {} (first keyvals) (second keyvals)))

20:29 ,(let [keyvals '(1)] (assoc {} (first keyvals) (second keyvals)))

20:29 clojurebot: {1 nil}

20:29 hiredman: it's an artifact of being a little sloppy with seq processing

20:30 somnium: so 'sloppy artifacts' should be unsurprising?

20:32 anyway, being aware of it its not a problem, just was the first time I recall encountering it

20:33 hiredman: no, but if you look at the function, and say "how would I implement this" and the way you would implement it could easily yield certain sloppy behaviour, why would you be surprised to see that behaviour?

20:35 somnium: hmm, ease of deduction = probability of existence :P

21:00 vIkSiT: hmm. bit stuck on doing this in idiomatic clojure - i have a string to which i want to make a transformation. "this _is_a *good* string". I'd like to replace everything within ** with the match of that word in another dictionary

21:00 (there can be multiple words with ** - I can do single words with re-gsub, for instance)

21:00 not sure how best to do it. Ideas?

21:07 somnium: vIkSiT: are all ** whitespace delimited?

21:07 hiredman: fnparse

21:07 vIkSiT: somnium, yes

21:08 hiredman, seems too complex for a toy program really :)

21:08 fnparse, that s..

21:10 somnium: vIkSiT: for easy you could tokenize it and then (map (fn [s] (if-let [s* (dict s)] s* s)) tokens)

21:10 vIkSiT: hmm, what is s* here?

21:11 somnium: s* is a non-nil result from (dict "string")

21:22 ,(require '[clojure.contrib.string :as s])

21:22 clojurebot: java.io.FileNotFoundException: Could not locate clojure/contrib/string__init.class or clojure/contrib/string.clj on classpath:

21:25 somnium: ,(require '[clojure.contrib.str-utils2 :as s])

21:25 clojurebot: nil

21:57 vIkSiT: btw, using a clojure string, how do i get it without the first and last characters?

21:57 I can do nth but it only returns the first char itself

21:57 nth i mean

21:59 cp2: ,(drop-last (rest "foo bar baz"))

21:59 clojurebot: (\o \o \space \b \a \r \space \b \a)

21:59 cp2: er

21:59 ,(apply str (drop-last (rest "foo bar baz")))

21:59 clojurebot: "oo bar ba"

22:00 vIkSiT: hmmm

22:00 a bit complex, for something that could be done using a[0] and a[-1] in other languages?

22:00 cp2: sure, but there are many ways to achieve something

22:00 vIkSiT: true

22:00 cp2: and all it really boils down to is how you use it in your code

22:01 vIkSiT: well, what i'm trying to do is - got a list of tokens. if any of them have **s as first and last, i want to strip * and call a function using it..

22:01 i guess i could use regexps.

22:02 cp2: so, if a string is like *foo*, call foo?

22:02 vIkSiT: more like: if string is like *foo*, call (f foo)

22:02 cp2: oh yeah, i missed that the first time around

22:03 vIkSiT: ,(second (re-find #"\$(\S+)\$" "$test$")

22:03 clojurebot: EOF while reading

22:03 vIkSiT: ,(second (re-find #"\$(\S+)\$" "$test$"))

22:03 clojurebot: "test"

22:03 vIkSiT: or something like that.. (for $ or *s)

22:03 somnium: vIkSiT: you may prefer the java String methods .contains, .startsWith, .endsWith etc

22:03 vIkSiT: oh good point.

22:04 cp2: mhm

22:04 honestly, your solution will be clunky just because of the way you need to deal with these tokens

22:04 i dont think its that big of a deal though

22:05 vIkSiT: sigh yeah

22:17 bbl

22:17 * cp2 wishes he had $800 to to blow...

22:17 cp2: http://tinyurl.com/2dyt9z8

22:17 sexpbot: "Vintage Symbolics 3650 36xx LISP Machine As-Is - eBay (item 260597652691 end time Jun-04-10 09:34:15 PDT)"

22:18 hiredman: huh, very tempting

22:18 but I think the jvm will have to do as a lisp machine for now

22:19 cp2: unfortunately :(

22:21 i would still love to get my hands on one of those symbolics keyboards, though

22:21 that is a lot more affordable, at least =P

22:37 cemerick: ~max

22:37 clojurebot: maxine is http://research.sun.com/projects/maxine/

22:37 cemerick: wha?

22:37 ~max

22:37 clojurebot: maxine is http://research.sun.com/projects/maxine/

22:37 cemerick: guess he's not tracking channel population anymore

22:37 clojurebot: what do you know?

22:37 clojurebot: Pardon?

22:37 cemerick: ~brain

22:37 hiredman: clojurebot: max users?

22:37 clojurebot: max people is 283

22:37 brain dump is http://clj.thelastcitadel.com/clojurebot

22:38 hiredman: the brain dump is busted

22:38 cemerick: ah, bummer

22:38 maxine is pretty interesting, tho :-)

22:38 hiredman: right

22:38 cemerick: There was a good interview with one of the researchers a while back.

22:39 se radio, perhaps

23:11 _brian2_: noob question> regarding exception handling, I 'm using a clojure library to scrape web pages, but how do I handle error 400 http exceptions, (try ( fetch ... doesn't seem to work

23:43 sids: _brian2_: the HTTP 400 errors are not the same as Java exceptions (unless the lib does the mapping)

23:43 _brian2_: which library are you using?

23:59 _brian2_: sids : I'm using enlive

Logging service provided by n01se.net