#clojure log - Oct 28 2010

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

0:00 defn: ^double negative

0:00 shows how smart I am...

0:01 cemerick: have you had a chance to look at cljc?

0:01 replaca: back in the day, I knew a guy who picked which language to build his company around by going to conferences and seeing which group seemed smarter

0:01 defn: replaca: lol that's awesome

0:01 replaca: he picked RoR and has been quite happy with the choice

0:01 defn: what if you just get a bunch of arrogant jerks

0:01 cemerick: defn: Using double negatives is not a contraindicator of intelligence ;-)

0:02 replaca: well, it does depend on how good a judge of people you are

0:02 his strength was more there than tech, so it was a good call

0:02 cemerick: Arrogance is OK. Jerk is no good. :-)

0:02 replaca: getting back to normal yet?

0:02 replaca: but we're better w/o arrogance too

0:03 no, not really

0:03 defn: cemerick: :) i was wading into uncharted waters with the compiler talk on saturday. my brain is vapor on that subject. lisp in small pieces is slowly making me feel adequate.

0:03 replaca: reminded me of getting home from burning man

0:03 a long time to readjust

0:03 cemerick: replaca: I was wondering if that tweet was informed by experience. When were you at burning man?

0:03 defn: it's sort of like a religious experience

0:03 replaca: cemerick: how about you?

0:04 defn: like "i've seen clojure you can only hope to imagine."

0:04 cemerick: defn: I've not looked at cljc yet, no. It looks like a formidable piece of work.

0:04 replaca: I've been a whole bunch of times, but only once since kids

0:04 defn: cemerick: yeah i was quite surprised to see it just /pop up/

0:04 that's the sort of thing that sits around for awhile collecting opinion and design

0:05 cemerick: replaca: I almost got into a groove this afternoon. Working on the contrib build stuff has been a good catalyst for restarting things.

0:05 defn: or at least that was my impression of it

0:05 i suppose if someone has vision they ought to just go for it

0:05 dthomas: Hi, is there a way to tell if an object is an instance of an array? Like "x instanceof StackTraceElement[]" in Java?

0:05 defn: dthomas, of Wendy's fame?

0:05 dthomas: Yes. Have you seen our $1 menu? It's dynamite.

0:05 replaca: cemerick: I've been doing some clean up. It's been a big fire drill week at work, but I feel like Neo at the end of the Matrix

0:06 just looking at the bullets in a very bored way

0:06 dthomas: Also I have been dead for years. I should change my nick to zombiedthomas.

0:06 defn: or rob thomas

0:06 he's /basically/ dead

0:06 technomancy: I've never been one to turn down an offer for discount dynamite from the undead.

0:06 defn: (inc technomancy)

0:06 sexpbot: => 1

0:07 cemerick: -> (.isArray (class (make-array Object 0)))

0:07 sexpbot: java.lang.SecurityException: Code did not pass sandbox guidelines: ()

0:07 cemerick: uk

0:07 defn: d'oh

0:07 cemerick: dthomas: .isArray will work

0:07 defn: replaca: i did strangeloop and clojureconj in two successive weekends

0:07 my life is in a shambles

0:07 cemerick: yeah, that sounds tough

0:08 dthomas: technomancy: Heh, are you technomancy of swank-clojure fame? I'm actually hacking on that right now.

0:08 replaca: defn: I'm jealous!

0:08 defn: lots of dropped balls as a result

0:08 replaca: I bet

0:08 * defn shrugs

0:08 technomancy: dthomas: any such fame is undeserved; I only maintain it from a distance

0:08 love to get patches though

0:08 defn: they'll be back in the air in a few days -- can't go around working all the time, need some hammock time every once and again

0:09 dthomas: cemerick: Yeah, OK, that'll actually work here since it's either going to be an array or not, not varying types of arrays.

0:09 replaca: defn: :)

0:10 cemerick: dthomas: you can use instanceof? as well, if you prefer

0:11 bah, instance? I mean

0:11 dthomas: cemerick: What is the second argument? Array?

0:12 cemerick: dthomas: to instance?

0:12 -> (instance? (class (make-array Object 0)) (make-array String 0))

0:12 sexpbot: java.lang.SecurityException: Code did not pass sandbox guidelines: ()

0:13 cemerick: sandbox hell :-P

0:13 dthomas: cemerick: Yeah. I don't know how to spell the type.

0:13 cemerick: dthomas: The easiest way is (class (make-array base-type 0))

0:13 dthomas: cemerick: Oh, sorry, thought class was the second arg not the first.

0:14 cemerick: OK, that was the trouble I was running in to. I someone using Class/forName with the ugly "[Ljava.lang.StackTraceElement;" name too.

0:14 cemerick: Thanks!

0:14 cemerick: that should work, too *shrug*

0:15 dthomas: It does, but I can't decide what's worse: creating an instance just to get its class or using what looks like an implementation detail to look that class up by name.

0:16 cemerick: Class/forName is definitely not an impl detail :-)

0:16 dthomas: I'm liking (class (make-array base-type 0)) better.

0:16 cemerick: You can stick that in a var and reuse it, thereby avoiding the array creation cost.

0:17 dthomas: cemerick: Certainly not, but the class name of "[Ljava.lang.StackTraceElement;"? I was guessing that was at best how Java serializes the class name, and the serialization format is probably defined along with the language.

0:17 cemerick: That class name is for an array of StackTraceElement BTW.

0:17 cemerick: dthomas: yes, that's part of the java language spec

0:17 defn: cemerick: okay to PM you?

0:17 cemerick: defn: indeed, tho I'm off to bed in 5 min :-)

0:33 replaca: cemerick: you're not going to power through for another hour so I can say, "Chas, it's 1:30"? :)

0:36 cemerick: replaca: crap no :-D

0:37 I've almost got a normal schedule back down

0:37 5:30 – 5:30

0:37 It's all hugod's fault that I fell off the wagon tonight. ;-)

0:38 replaca: cemerick: yeah, you really did!

0:39 cemerick: I used to keep such absurd hours. 53 straight, once. Those were the days.

0:39 Not.

0:42 replaca: yeah, better to keep a sustainable rhythm

0:42 cemerick: loved the talk on pallet, btw. really learned a lot there

0:45 cemerick: replaca: Thanks. :-) I hope it was helpful.

0:46 I was pretty leery about following up such insightful material with a methods and tools talk.

0:46 but, that's my pay grade, as it were.

1:02 Raynes: I'm fixing that damned sandbox tomorrow if it kills me.

1:02 * Raynes runs off to bed.

1:21 tomoj: pinging solr clojure hackers

1:49 defn: anyone know if stuarthalloway's slides are online?

1:56 _rata_: hi

1:57 amalloy: morning _rata_

1:57 _rata_: hi amalloy

2:12 tomoj: I'm doing sums of a bunch of sparse high-dimensional signed integer vectors

2:12 mahout has fast sparse random access vectors, but they only store doubles or floats

2:13 would switching to integer math speed those sums up a whole lot?

2:16 amalloy: tomoj: i don't think so

2:17 tomoj: cool

2:18 amalloy: ->(dorun (map #(time (dotimes [_ 1e7] (+ % %))) [15 1.5]))

2:18 sexpbot: ⟹ "Elapsed time: 166.978 msecs" "Elapsed time: 301.631 msecs" nil

2:19 amalloy: tomoj: so it looks like integers are ~2x as fast

2:19 in this wholly unreliable microbenchmark

2:19 tomoj: when i just ran it, I got 3.41x

2:19 err

2:20 _rata_: hahahaaha... 2x is a lot though

2:20 amalloy: and on my computer, i get that doubles are 35% faster. like i said, not so reliable

2:20 tomoj: huh, yeah, ran it again and the doubles went faster

2:21 amalloy: tomoj: although type-hinting and/or using primitives may make a bigger difference; i'm hardly a performance expert

2:22 _rata_: is there a function like xor in clojure.core?

2:22 tomoj: well, the choice is, use the fast java stuff written by people way smarter than I (but under the assumption of floats), or write clojure stuff assuming ints

2:22 amalloy: ah

2:23 tomoj: I'll just use the java stuff :)

2:23 _rata_: tomoj, is it important for you the exactness of the result?

2:24 tomoj: no

2:24 _rata_: ok, then use the java stuff :)

2:24 or what's the idiomatic/simplest way to write a xor (if I can't think that by myself should be going to sleep)

2:25 s/or //

2:25 sexpbot: <_rata_> what's the idiomatic/simplest way to write a x(if I can't think that by myself should be going to sleep)

2:25 _rata_: really should be going to sleep

2:25 ok guys... see you tomorrow

2:39 zmyrgel: hi, how can I test if function arg is some record type?

2:40 so if I have defined (defrecord Node [label children]) I want to be able to tell if fn arg is of that type

2:52 amalloy: ->(doc instance?)

2:52 sexpbot: ⟹ "([c x]); Evaluates x and tests if it is an instance of the class c. Returns true or false"

2:52 amalloy: zmyrgel: ^^ records are java classes

2:54 zmyrgel: amalloy: ok, thank you

2:56 amalloy: clojuredocs seems to link to nonexistent github pages

3:01 specifically, i'm looking at c.contrib.duct-streams/copy, and the Source section links to http://bit.ly/czekSl (shortening mine)

3:02 dunno who owns clojuredocs, but i'm off to bed so i'm putting it out there. night, folks

3:27 TobiasRaeder: morning :)

5:43 notsonerdysunny: is file io in clojure basically same as that in java? is there a good place for me to just get started ..?

6:05 raek: notsonerdysunny: yes, with some helper functions

6:05 notsonerdysunny: http://clojure.github.com/clojure/clojure.java.io-api.html is very handy

6:07 lazy sequence of lines in a file (line-seq (io/reader "filename"))

6:08 c.j.io/reader works with URLs too

6:12 notsonerdysunny: raek: I am not used to java io .. ..

6:12 thanks for the pointers

6:18 raek: crash course: {File "a path to a file", #{InputStream OutputStream} "byte-oriented stream (use these for binary data)", #{Reader Writer} "character-oriented stream (use these for text)"}

6:24 notsonerdysunny: thanks raek .. ..

6:26 what is this parent child thing in the documentation of io/file ?

6:27 ,(doc 'clojure.java.io)

6:27 clojurebot: java.lang.ClassCastException: clojure.lang.PersistentList cannot be cast to clojure.lang.Symbol

6:27 notsonerdysunny: ->(doc 'clojure.java.io)

6:27 sexpbot: java.lang.SecurityException: Code did not pass sandbox guidelines: (clojure.java.io)

6:27 notsonerdysunny: ~(doc 'clojure.java.io)

6:27 clojurebot: the doctor is out

6:29 raek: ,(clojure.java.io/file "foo" "bar")

6:29 clojurebot: #<File foo/bar>

6:29 raek: allows you to build paths in a platform independent manner

6:29 also:

6:31 http://download.oracle.com/javase/6/docs/api/java/io/package-summary.html <-- javadoc for the classes in java.io (if you have to call the methods directly, which you might need some times)

6:31 clojure's reader and writer returns BufferedReader (which has the readLine method) and BufferedWriter

6:33 notsonerdysunny: unfortunately, you cannot use doc to lookup docs on namespaces...

6:33 notsonerdysunny: raek: i just realized that .. :)

6:33 raek: also, it is a macro, so you don't quote the argument

6:36 notsonerdysunny: ->(clojure.java.io/file "hello" "world" "in" "clojure")

6:36 sexpbot: java.lang.SecurityException: Code did not pass sandbox guidelines: (#'clojure.java.io/file)

6:53 notsonerdysunny: what is clojure.core/read ? I it the one that understands all the clojure-datastructures and creates the data-structure for eval to evaluate?

6:53 *Is it

6:54 raek: yes

6:55 what kind of io are you doing?

6:55 notsonerdysunny: raek .. I am considering using a s-exp like file format .. I feel that would be very easy to read...

6:56 and load the data in

6:56 raek: if you use the Clojure reader, it's very easy

6:57 notsonerdysunny: suppose my file "inp.txt" has "(+ 1 2)" .. how would I use read to read it in?

6:58 raek: (require '[clojure.java.io :as io]) (import 'java.io.PushBackReader)

6:58 (with-open [r (PushBackReader. (io/reader "inp.txt"))] (read r))

7:02 the opposite of read is pr, btw

7:02 notsonerdysunny: raek .. I am getting java.io.PushBackReader class not found exception .. do i need to do anything special?

7:03 raek: oh, sorry for that... the B should be lowercase

7:03 java.io.PushbackReader

7:03 no, you shouldn't need anything special

7:04 notsonerdysunny: thanks raek .. it works so beautifully .. reading couldn't have been easier

7:28 Bootvis: hi I have this string: ". 17,00" (in my client I see a dot, it's a euro sign in some charset). What is the best way to parse this to a number?

7:34 raek: ,(when-let [[_ euros cents] (re-find #"\u20ac\s+(\d+)[,.](\d+)" "\u20ac 17,01")] (+ (Integer/parseInt euros) (/ (Integer/parseInt cents) 100)))

7:34 clojurebot: 1701/100

7:34 raek: dunno if this is the _best_ way...

7:36 ,(when-let [[_ euros cents] (re-find #"\u20ac\s+(\d+)[,.](\d+)" "\u20ac 17,01")] (+ (Integer/parseInt euros) (/ (Integer/parseInt cents) 100M)))

7:36 clojurebot: 17.01M

7:36 raek: (BigDecimal version)

7:37 Tordmor: Now again with propper locale support :)

7:37 raek: *sigh* :)

7:38 at least I made it parse both strings with commas and points...

7:39 Bootvis: thanks

7:42 ,"."

7:42 clojurebot: "."

7:46 Bootvis: thanks raek, your code works great outside of SLIME

7:47 raek: Bootvis: as far as I can tell, my IRC client receives that character as an ASCII full stop

7:48 Bootvis: note that slime's default encoding is latin1, which does not inlcude the uro character

7:48 *euro

7:48 you can configure slime and swank to use UTF-8. then you can use all unicode characters

7:50 Bootvis: ok, i'll google that

7:51 raek: I have this in my .emacs: (custom-set-variables '(slime-net-coding-system (quote utf-8-unix)))

7:53 and you can start swank this way: lein swank 4005 ':encoding' '"UTF-8"'

7:53 hrm, that doesn't seem to work anymore...

7:57 ah, found it...

7:57 lein swank 4005 localhost ':encoding' '"UTF-8"'

7:59 AWizzArd: Chousuke: ping

8:01 Bootvis: this works!

8:02 I also set the encoding following advice from leonel on http://stackoverflow.com/questions/3101279/how-do-i-use-unicode-utf-8-characters-in-clojure-regular-expressions

8:05 raek: ah, yes. when you save that, you will get what I wrote before in your .emacs file... anyway, you still need to tell swank to use that encoding too

8:08 to test that all encoding stuff works, you can try to eval (seq "日本語") at the repl. if everything works correctly, you should get a sequence of *three* characters: (\日 \本 \語)

8:08 Bootvis: yes I noticed, this should be documented somewhere...

8:09 raek: I could add some instructions too http://www.assembla.com/wiki/show/clojure/Getting_Started_with_Emacs

8:09 Bootvis: it needs further work then, I'm getting 6 chars back

8:09 but that could be an irssi thing

8:10 AWizzArd: ~seen Chousuke

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

8:10 AWizzArd: $seen Chousuke

8:10 sexpbot: Chousuke was last seen talking on #clojure 1 day, 1 hour ago.

8:11 raek: Bootvis: have you restarted the slime session (or emacs)?

8:12 also, note that lein repl uses JLine, which does not support UTF-8 at all (in case you were trying this there)

8:12 Bootvis: yes

8:13 restarted emacs

8:13 and lein swank ... from a shell

8:14 hiredman: JAVA_OPTS=-Dswank.encoding=utf8 -Dfile.encoding=utf8

8:14 then there are emacs settings which I don't recall off the top of my head

8:16 raek: ah, is that how you set java system properties?

8:17 Bootvis: do you happen to run emacs in a terminal? if so, you have to configure teh coding of the terminal as well.

8:21 Tordmor: ,(let [nf (java.text.NumberFormat/getInstance java.util.Locale/GERMANY)] (.parse nf "17,01"))

8:21 clojurebot: 17.01

8:21 Tordmor: ,(let [nf (java.text.NumberFormat/getCurrencyInstance java.util.Locale/GERMANY)] (.parse nf "17,01"))

8:21 clojurebot: java.text.ParseException: Unparseable number: "17,01"

8:21 Tordmor: :(

8:33 Bootvis: raek: no and it stil fails your 3-char test

8:33 I blame irssi

8:34 kumarshantanu: Tordmor: that's strange

8:34 because getInstance and getCurrencyInstance and supposed to behave the same

8:36 raek: Bootvis: what happens when you eval "\u65e5\u672c\uu8a9e" and (seq "\u65e5\u672c\uu8a9e") ?

8:36 sorry... \u65e5\u672c\u8a9e

8:37 Bootvis: it returns \.

8:38 with . a character

8:38 from japan i guess

8:39 the seq returns three chars

8:39 and the last matches the output of the first

8:43 Tordmor: kumarshantanu: yea, that's what I thought

8:46 kumarshantanu: Tordmor: can you try this on another JDK? maybe IBM?

8:47 Tordmor: can you try this on another JDK? maybe IBM?

8:47 raek: Bootvis: what settings were save to your .emacs?

8:47 Tordmor: kumarshantanu: getCurrencyInstance needs currency format to parse it with the currency symbol at the end

8:48 kumarshantanu: ah!

8:48 Tordmor: It's obvious when you think about it :)

8:48 Bootvis: (custom-set-variables '(slime-net-coding-system (quote utf-8-unix)))

8:49 kumarshantanu: Tordmor: but the Javadoc says both methods are the same

8:50 Tordmor: :/ k, that's a bug

8:51 kumarshantanu: yeah, even though the behaviour is logical, I would consider the Javadoc a spec

9:01 djpowell: did accounts get copied across from assembla then?

9:02 Bahman: Hi all!

9:02 bmh: does anyone have experience deploying clojure apps with Java Webstart?

9:03 djpowell: not tried it, but I'd think it'ld work. I've even deployed native code using webstart before

9:05 well - by deployed, I really mean: wrote an helloworld-ish demo

9:05 bmh: heh

9:08 djpowell: if you aot compile, then clojure applets work

9:10 hoeck: bmh: it works with aot-compiled code as it would do with java

9:10 bmh: to be able to load and eval *.clj files in an applet, you have to sign it and patch a line in the clojure sources

9:10 bmh: hm

9:12 hoeck: bmh: as an example, see http://www.turbojugend-cossebaude.de/demo.html, a small project of mine, it uses clj-pivot for its gui

9:12 quite large and takes ages to load, and doesn't work on my ubuntu box, only on windows :/

9:12 but the webstart works on both systems

9:16 jwr7: clojure.contrib.json is broken, I've reported the bug, and I have a fix (and a signed CA). How do I submit the fix?

9:18 bmh: hoeck: dies on my OSX box too

9:18 chouser: jwr7: you attached the patch to the ticket?

9:18 raek: jwr7: clojure.org/patches <-- the official procedure

9:20 jwr7: raek: Hmm. The ticket was opened by my colleague. I don't think I'm able to edit the ticket or attach anything — does someone need to add me as a contributor for this to happen?

9:21 btw, this is #98 in clojure contrib in assembla

9:21 hoeck: bmh: yeah, I gave up because I did not find a way to grab the java console :/

9:21 raek: jwr7: yes. when you're logged in, does it say watcher or member at the top right corner

9:21 hoeck: bmh: http://www.turbojugend-cossebaude.de/demo.jnlp <-- this is the webstart version, should work

9:22 jwr7: Well, I'm a watcher, then. Which is suboptimal.

9:22 hiredman: assembla is toast

9:23 chouser: jwr7: the initial friction on this kind of thing is too high, but it's getting changed.

9:23 jwr7: and the new way hasn't settled in yet, being ~1 day old

9:23 hiredman: http://groups.google.com/group/clojure/browse_thread/thread/b7090cff317a47db?hl=en

9:24 jwr7: chouser: ok :-) But I'm really interested in getting this fix in, as clojure.contrib.json is currently broken, and I need it because it is way faster than org.danlarkin.json. Any suggested next steps?

9:24 chouser: hopefully once it has settled in, the friction (especially for contrib) will be significantly lower.

9:24 jwr7: what's the aseembla ticket number?

9:24 jwr7: chouser: 98

9:26 bmh: hoeck: thanks. neat. I'm working on some roleplaying software and I'd like to deploy as a webstart app

9:26 jwr7: chouser: the fix is simple and I have it sitting right in front of me. Keys need to be properly escaped, (as-str) won't do.

9:26 tonyl: morning

9:28 chouser: oh, is contrib assembla not moved over to jira yet?

9:29 jwr7: chouser: it seems so. I think the process is halfway done (clojure has migrated, but clojure-contrib has not)

9:32 chouser: jwr7: well, drat, you might just have to be patient. I think the best you can do right now is to ask for your assembla account to get bumped

9:32 ...and use your own patched version for now.

9:33 stuartsierra: Would it be fair to say that Clojure was the first language to implement something like Protocols on a mainstream platform (JVM) ?

9:33 chouser: I can't change your assembla status, nor can I apply a patch unless it's been submitted through an "official channel" like assembla, for legal reasons.

9:34 stuartsierra: depends on how narrowly you mean "like protocols" I suppose.

9:34 jwr7: chouser: right... I'll send an E-mail to Rich, then (I'm assuming he's the one to change my status). I want to make sure this fix goes in as soon as possible, it's rather important for anyone who uses c.c.json.

9:34 chouser: scala had traits (or whatever their equiv is) first

9:34 stuartsierra: Don't traits use wrapper classes?

9:35 chouser: Hm, I don't know.

9:36 * chouser skims "Types in Object-Oriented Languages

9:36 chouser: The Expression Problem in Scala

9:36 "

9:42 ugh. more than five-minutes work to understand all that.

9:45 stuartsierra: If I recall, Scala Traits can't be applied to existing classes, e.g. String.

9:46 hiredman: they have implicit conversions

9:47 stuartsierra: Right, which does use wrappers.

9:47 hiredman: and there own string class

9:47 their

9:47 chouser: "I know, I'll use traits!" ...and now you have 3 problems

9:48 hiredman: it's not a "wrapper" it's take this thing and make it into another thing

9:48 stuartsierra: I'm writing about Protocols, want to make sure to describe how they're different from Traits.

9:50 chouser: I don't think I even understood traits well enough to help. sorry.

9:50 stuartsierra: no worries

9:51 chouser: s/even/ever/

9:52 bobo_: scala people like to compare traits to mixins in ruby atleast

9:52 or "interfaces with implementation"

9:53 fogus_: "I know, I'll use implicits!" ... the good part is that you have no idea when you have a problem.

9:53 hiredman: clojurebot: tell me about scala

9:53 clojurebot: the scala compiler | is | <reply> see: http://harrah.github.com/browse/samples/compiler/scala/tools/nsc/typechecker/ConstantFolder.scala.html#65760

9:55 stuartsierra: heh

9:55 glass houses...

9:57 spicycode: stuarsierra: ....?

10:00 stuartsierra: spicycode: I'm sure the Clojure compiler has ugly bits too.

10:00 spicycode: stuartsierra: roger that, we were digging through the asm bits last night

10:01 stuartsierra: compilers are like sausage grinders: if you saw the process, you wouldn't eat the result

10:02 fogus_: stuartsierra: WRT being first. I would consider that maybe ABCL was first.

10:06 hiredman: well the clojure compiler doesn't have incriminating comments

10:06 (or any)

10:07 fogus_: Seems to go against the virtues of static checking to defer your crashes until runtim!

10:07 runtime even

10:07 hiredman: sure

10:13 nDuff: Did the proposal to implement a *clojure-version* global ever happen?

10:14 technomancy: ,*clojure-version*

10:14 clojurebot: {:major 1, :minor 2, :incremental 0, :qualifier ""}

10:15 nDuff: oops -- I was trying to check **clojure-version**

10:16 stuartsierra: At what point does a Protocol function look up an implementation in its internal map?

10:18 notsonerdysunny: I am new to java/clojure io .. raek say I could read a s-exp file with (with-open [r (PushbackReader. (io/reader "project.clj"))] (read r)) .. and it worked very well .. now I would like to be able to write it .. and he mentioned that I use pr .. but can somebody help me with the complete expression?

10:22 ,(doc pr)

10:22 clojurebot: "([] [x] [x & more]); Prints the object(s) to the output stream that is the current value of *out*. Prints the object(s), separated by spaces if there is more than one. By default, pr and prn print i...

10:51 notsonerdysunny: how do I write the value contained in a symbol p to a file "out.txt"

10:52 replaca: (spit "out.txt" (println p))

10:53 chouser: I don't think so

10:53 replaca: oh wait

10:54 (spit (java.io.File. "out.txt") (println p))

10:54 chouser: better?

10:54 chouser: doubt it :-)

10:54 Tordmor: top hit on google for "clojure io": (binding [*out* (java.io.FileWriter. "some.dat")] (prn {:a :b :c :d}))

10:56 gary_poster: I don't understand something a bit fundamental. Given ``(defn f [x y z & args] (apply (fn [& a] a) x y z args))`` and ``(f 1 2 3 4 5)`` I'd expect the result ``(1 2 3 (4 5))``. Instead, you get ``(1 2 3 4 5)``. Many built in functions rely on this. Can somebody clarify what I'm missing?

10:56 chouser: (spit "/tmp/foo.txt" (prn-str p))

10:56 * gary_poster probably should reread early chapter of JoC :-P

10:57 fliebel: gary_poster: the latest arg of eval takes a seq.

10:57 *apply

10:57 replaca: chouser: why prn-str instead of println?

10:57 chouser: println prints to *out* and returns nil

10:57 replaca: unless you're looking for readability?

10:57 fliebel: Is there still any use for clojure.contrib.generic.arithmetic, or can this stuff be handled by extend-type?

10:57 replaca: oh, of course

10:58 gary_poster: fliebel: ah, got it, thanks

10:58 * replaca goes to finish the first morning cup of coffee bfore answering any more questions

10:58 fliebel: Or in other words, can I use extend-type to make + support other types of objects?

10:58 chouser: replaca: :-)

10:59 stuartsierra: fliebel: not at present

10:59 fliebel: stuartsierra: Why not? It's only for interfaces or something like that?

10:59 stuartsierra: 1) Protocols only support single-argument dispatch, although this can be extended to multiple arguments.

11:00 2) Clojure's arithmetic operations are not defined in terms of interfaces or Protocols

11:00 for efficiency, although the compiler may support it someday

11:00 but if you're doing serious math, you wouldn't want the performance hit of multimethods anyway

11:01 notsonerdysunny: thanks chouser and replaca .. it worked .. :)

11:01 fliebel: Cool, thanks! I think Overtone is using a good deal of multimethod magic for working with ugens. I thought I'd have a look at the extend-type thing.

11:04 stuartsierra: Ages ago, I posted an example of multiple-argument dispatch with protocols http://paste.lisp.org/display/93387

11:06 chouser: stuartsierra: all your old code feels differents to me now that I imagine you writing it with blue hair (though I reliaze your hair may not have been blue at the time)

11:06 stuartsierra: I tend to have blue hair in the Fall, so you can interpolate on that.

11:11 pdlogan: I love fall colors.

11:11 don't see a lot of blue in the PNW though

11:12 fliebel: pdlogan: Yea, you should make fall-chemed-rainbow parens for your editor.

11:12 *themed

11:27 jcromartie: Well this makes me that much more reluctant to go with CouchDB http://wiki.apache.org/couchdb/Installing_on_Windows

11:27 anyway

11:28 NoSQL is so tempting but choosing Clojure is enough of a risk I wonder what the value is

11:28 cemerick: jcromartie: No need to build it: http://www.couch.io/get#win

11:28 jcromartie: oh, I should check the date on those wiki pages

11:28 I get the feeling that Couch is more mature, but I know Mongo is popular with Clojure

11:29 cemerick: yeah, both are used a fair bit

11:30 I don't know if it makes sense to speculate on relative usage.

11:30 jcromartie: yeah I guess so

11:31 I am trying to weigh the tradeoffs... JavaDB/Derby is appealing too, since I could basically have a single Jarfile for small demo/testing deployments

11:31 cemerick: AFAIK, couch has been around for far longer, and the basis for it is pretty hard to argue with from a reliability standpoint (i.e. the legacy of notes, etc)

11:31 jcromartie: yeah, just being written in Erlang wins there

11:31 cemerick: A Clojure impl of couchdb would be interesting, actually.

11:32 jcromartie: we are looking at building a new version of our company's main product, and it seems like a good candidate for a document store

11:32 jcromartie_: our data is very self-contained and denormalized

11:32 each record is really kind of an island

11:33 a very large island

11:33 with an airport

11:33 anyway

11:33 hiredman: mongo is popular with clojure?

11:34 cemerick: people have said they use it, sure

11:35 jcromartie_: I thought it had a bit more traction and adapter projects

11:35 :)

11:35 I guess saying anything is "popular" within the clojure community is kind of relative

11:35 stuartsierra: Parentheses are popular within the Clojure comumnity.

11:36 technomancy: I heard mongo supports sharding

11:36 apgwoz: cemerick: A Clojure impl of _____ would be interesting, actually. (applies for most values of _____)

11:36 * nDuff hasn't seen much about Mongo's concurrency semantics

11:36 nDuff: whereas CouchDB uses MVCC

11:36 and of course everyone here loves MVCC :)

11:36 apgwoz: mongo has concurrency semantics?

11:36 nDuff: well, that's the question

11:36 apgwoz: it's event-driven

11:37 cemerick: apgwoz: eh, almost ;-)

11:37 (re: the adlib bit)

11:37 LOPP: what's the easiest way to make a servlet in clojure

11:37 apgwoz: cemerick: yeah, i got that :)

11:37 cemerick: Couch's semantics are simple enough that it's a reasonable small project though.

11:38 Reimplement mongo in Clojure? No thanks.

11:38 fliebel: LOPP: The ring servlet adapter.

11:38 There is FleetDB, which is written in Clojure :)

11:38 apgwoz: cemerick: this is all true.

11:39 cemerick: fliebel: in-memory stores aren't super useful for me :-)

11:40 apgwoz: cemerick: so, add write ahead logging :)

11:40 cemerick: it does persist things eventually, no?

11:40 apgwoz: I assumed it was redis-esque (dataset cannot be larger than available memory)?

11:41 apgwoz: cemerick: i don't know. but it does have logging, so my statement before doesn't make sense

11:41 replaca: chouser: no that I've had my coffee, is there any difference between: (spit "out.txt" (prn-str p)) and (spit "out.txt" p)?

11:41 A quick experiment says no

11:41 stuartsierra: only if p is as tring

11:41 * a string

11:42 apgwoz: cemerick: i think you're write, the persistence is meant for restarts, but not for unbounded databases

11:42 replaca: well I get teh same result when I pass it a vector of numbers

11:42 apgwoz: cemerick: (based on my quick look of the documentation..)

11:43 stuartsierra: replaca: because pr-str and str of a vector of numbers happen to look the same

11:43 replaca: what are they different for?

11:44 (oh, in my example they differ by a trailing newline, too)

11:44 stuartsierra: "pr" and "pr-str" attempt to reformat their argument so it can be read back

11:44 "print" and "str" produce strings for human consumption

11:45 replaca: stuartsierra: ah, so readability, ok

11:45 stuartsierra: ,(str "foo")

11:45 clojurebot: "foo"

11:45 stuartsierra: ,(pr-str "foo")

11:45 clojurebot: "\"foo\""

11:45 replaca: yup, gotchya.

11:46 so, print is to str as pr is to pr-str?

11:46 no, but print-str exists too

11:46 stuartsierra: yes

11:47 print-str will insert spaces between its arguments the same way print does

11:47 ,(print-str 1 2 3)

11:47 clojurebot: "1 2 3"

11:47 stuartsierra: ,(str 1 2 3)

11:47 clojurebot: "123"

11:48 replaca: oh, right. I never thought very hard about all these subtle points until this morning

11:48 vibrant: <- reading 'the joy of clojure'

11:49 replaca: (plus I always use cl-format cause I know what it does :))

11:52 muhdik: closure looks weird

11:53 i mean does it look ugly?

11:55 replaca: muhdik: What you're not used to looks weird and ugly. Most of us that have used Clojure for a while think it's baeutiful compared to C/Java syntax

11:55 muhdik: but in the end, it's a matter of taste

11:56 technomancy: replaca: closure is a javascript library =P

11:56 so the correct answer is "yes"

11:57 replaca: technomancy: oh, good reading. I was conflating that Q with the "JoC" statement above.

11:57 I'm sure glad I'm not taking the SATs this morning!

11:58 vibrant: hehe

11:58 muhdik: oh ok

11:58 technomancy: I don't know if that's what he meant, but it's what he asked

11:58 muhdik: i mean doesnt it have too many ))))))

12:00 technomancy: sure, just like Mozart has "too many notes" http://www.youtube.com/watch?v=dCud8H7z7vU

12:01 quoll: it has no more than other languages (like Java), but the syntax often leads to closing parens all appearing together

12:01 * gary_poster thinks Mozart parallel is funny, if not entirely apt :-)

12:02 vibrant: death to java!

12:02 muhdik: why u say death to java?

12:02 nDuff: "meh" to java!

12:03 muhdik: i thought clojure came from java?

12:03 i hate java personally

12:03 jcromartie: Java is Clojure's C

12:03 don't knock it

12:03 muhdik: did all the cool java kids go to ruby and clojure?

12:04 cause i dont think java is cool anymore

12:04 since oracle took over

12:04 nDuff: there are too many things called "Java" to have that discussion without more clarity

12:05 quoll: it reads like muhdik is talking about Java-the-language

12:05 muhdik: i mean

12:05 java

12:05 nDuff: it's specifically Java-the-language I was referring to, and its issues as a language are quite separate from ownership concerns.

12:05 muhdik: j2ee

12:05 ejb

12:06 u know

12:06 nDuff: muhdik, ...so it's more the standard-library set than the language itself?

12:06 muhdik: i mean the whole java package

12:07 nDuff: well, that's the thing -- "the whole Java package" is too many things to talk about cogently; the components are worthy of their own opinions.

12:07 muhdik: i mean

12:07 * nDuff shrugs; has actual work to do.

12:07 muhdik: sun had this whole website devoted to java crap

12:07 that was the worst

12:07 and tried to make something like msdn for java

12:08 im talkin bout all the stuff in that

12:08 like i mean

12:08 now kids are doing ruby clojure and node.js

12:09 ubii: one does not necessarily need to be coffee drinker to partake of clojure, but one should at least appreciate the efforts of all of those bean pickers :)

12:09 muhdik: and java has been pretty much eclipsed

12:09 and about node.js

12:10 LOPP: java is just failing to evolve as a language

12:10 all they do is add some more libraries to JRE each version

12:11 chouser: and it's design goals never lined up very well with my desires. I was never Java's target audience. Hard to blame it for that.

12:11 muhdik: well whats the difference between clojure and scala then

12:11 LOPP: java isn't dying out any time soon, too much server side software is running on java

12:11 Scriptor: I've heard what clojure really needs to expand to non-jvm platforms is for it to be completely self-hosting, is that true?

12:12 muhdik: i mean

12:12 arent they both functional java?

12:12 jcromartie: Java and the JVM are just simple stable and fast, and very widespread and mature, and with a huge set of available libraries to do pretty much anything you want.

12:12 That's why I'm not that excited about CinC

12:12 chouser: Scriptor: that would be the route of least total work. But various versions of Clojure have already been ported to CLR, JavaScript, and I think flash.

12:12 jcromartie: because the interop with the platform is what makes Clojure so useful

12:12 for just getting stuff done

12:13 Scriptor: hmm, anything going on for the LLVM?

12:13 technomancy: jcromartie: cinc also means having a compiler that is comprehensible by more than just rich, even staying on the jvm

12:13 chouser: Scriptor: not yet, that I know of.

12:14 Scriptor: hmm, wish I knew C++ (or clojure for that matter)

12:14 jcromartie: technomancy: I see :)

12:16 ubii: just curious, how much interest and effort is currently being put towards CinC?

12:16 chouser: most of it

12:16 cemerick: heh

12:17 jcromartie: where "it" is the interest and effort of clojure core?

12:17 cemerick: chouser: how much (if at all) have you looked at cljc?

12:18 chouser: cemerick: only saw it was there. do we know who jarpiain is?

12:18 I do intend to read through the code.

12:22 cemerick: No idea. I've only perused it for a few minutes myself. At the very least, it seems like we should give him a holler.

12:23 chouser: yeah. I've got a small but growing list of people who may actually be willing to chip in on the compiler work.

12:24 LOPP: do you screen these people?

12:24 chouser: we can't use his code at all without a CA of course

12:25 I screen nobody

12:25 LOPP: ok

12:25 ubii: chouser: CA?

12:26 chouser: ubii: http://clojure.org/contributing Contributor Agreement

12:26 ubii: chouser: ah, thx

12:26 cemerick: LOPP: we're working on a Clojure Contributor Certification Exam.

12:27 chouser: sheesh

12:27 cemerick: lol

12:27 LOPP: sorry, had to do it ;-)

12:27 Raynes: :o

12:27 chouser: if your code makes rhickey show the Sign of the Cross to ward you away, then ... you're in the same boat as the rest of us.

12:28 cemerick: chouser: c'mon, those Cisco certification exam books are *huge* money! :-P

12:29 ubii: tell me about it, I have too many of them sitting on my shelves

12:29 chouser: cemerick: ruby drama link?

12:32 cemerick: chouser: oy. http://oppugn.us/posts/1282122987.html

12:33 apgwoz: cemerick: you're forgetting that there's drama whenever you *mention* the name Zed Shaw

12:33 * apgwoz actually likes Zed

12:34 cemerick: I've no idea who the jets and the sharks are in that world.

12:34 ubii: Zed is the man, I met him at RubyFringe in Toronto, super nice guy in person

12:34 technomancy: he's just trying to be bad and nationwide

12:35 * cemerick goes off to meditate or something

12:36 hsuh: is a jetty+ring+compojure app single-threaded?

12:38 cemerick: hsuh: no, jetty manages the concurrency in that realm. Each *request* is single-threaded, though.

12:39 jwr7: …which reminds me I need to find out how to change the threading model that jetty uses. I think there are several.

12:40 hsuh: where can i read more about that? like "the life of a request" or something

12:40 cemerick: hsuh: There are slight variations from container to container, but any search for "servlet lifecycle" will probably lead you to the right spot.

12:41 hsuh: tks

12:41 and from that to clojure code is just a function call, no thread involved

12:44 cemerick: right

12:52 quoll: does anyone know how I can make a binding work down in "map"?

12:53 or, more precisely, how a (binding....) can be recognized by the function being supplied to (map .....)

12:54 fliebel: quoll: Oh, I can't remember… Someone recently blogged about this.

12:54 quoll: Hmmm, OK. I'll search then

12:54 chouser: quoll: simplest solution is to wrap (doall ...) around your (map ...)

12:54 quoll: but it's worth understanding what's going on there.

12:54 quoll: well, I'm guessing that map is creating a new thread

12:54 amalloy: chouser: dorun works too, doesn't it? if so it's more useful

12:55 quoll: if I replace map with my own implementation, then it works as expected

12:55 chouser: dorun returns nil

12:55 fliebel: chouser: Is laziness killing it because the closure doesn't pick up the binding? Or what?

12:55 quoll: for instance: (defn mymap [f s] (if (nil? (first s)) s (cons (f (first s)) (mymap f (rest s)))))

12:55 that keeps the binding just fine

12:56 chouser: quoll: right, because that's not lazy

12:56 quoll: yup

12:56 chouser: remember, 'binding' is dynamic scope, not lexical

12:56 quoll: let me try it lazily

12:56 chouser: the fact that your map call is lexically inside 'binding' doesn't really matter at all

12:57 quoll: unfortunately, I don't really understand the distinction

12:57 chouser: any elements of your lazy seq that are realized outside the dynamic scope of the binding will the vars values from outside the binding

12:57 will see

12:58 quoll: I'm pretty sure I understand that

12:59 fliebel: Oh, I'm going to work out some evil things...

12:59 quoll: but I also know that I don't quite get it, since I don't see how lazy ends up being different

12:59 LOPP: lexical binding = where in code your stuff is

12:59 pdlogan: quoll: another way to visualize "dynamic binding" is that it does not look at the text of your code for a binding. It looks "up the call stack" for a binding.

12:59 LOPP: dynamical binding = where in call stack your stuff is

12:59 pdlogan: jinx

13:01 quoll: pdlogan: that was what I thought was happening. I couldn't figure out a way to avoid that though (while staying lazy)

13:03 so to be sure I have it..... by the time I'm trying to access the lazy-seq, I'm out of scope of the binding, so I get whatever binding is currently in place at that point

13:03 is that it?

13:03 pdlogan: quoll: not sure that you can - it's not like a lexical closure which has captured an environment

13:03 chouser: quoll: if you want to stay lazy, look at bound-fn

13:04 quoll: well, in this case I don't HAVE to stay lazy. I just like to whenever possible :-)

13:04 pdlogan: it's generally better not to be dynamic than not to be lazy

13:04 quoll: my point is.... is the lazy sequence picking up the binding of the value when I access the sequence, as opposed to when the sequence was created?

13:06 chouser: btw, bound-fn looks to be useful. Thanks.

13:06 pdlogan: quoll: generalizing laziness --- consider any function that references a dynamic value will get that value as of it's nearest binding in the call stack.

13:06 quoll: I'll go with non-lazy this time. I just wanted to understand what was happening

13:07 pdlogan: do you mean the "current call stack"? As in, when the lazy value is accessed

13:07 as opposed to when the lazy structure was created

13:07 pdlogan: yes - "dynamic" --> "runtime call stack for the current thread"

13:07 JamesIry: A dynamically bound symbol (logically) searches back through the call stack at the moment of evaluation to find its meaning.

13:08 Although in practice that's now how they're typically implemented

13:08 quoll: OK, I get it then. Thanks for the elucidation

13:10 fliebel: ,(def s (repeat 1))

13:10 clojurebot: DENIED

13:11 fliebel: Guess what this returns: (take 2 (binding [s (repeat 2)] (cons (first s) (lazy-seq s))))

13:12 raek: (2 1)?

13:12 fliebel: yea :)

13:13 chaslemley: Hey folks, I just put up a templating engine for clojure on github http://github.com/chaslemley/slim.clj check it out if you need to render html, xml from compojure or any other framework

13:13 fliebel: First time I managed to write some sort of obfuscated Clojure :)

13:13 raek: is it true that rich is rethinking binding?

13:14 AWizzArd: raek: it is already happening

13:14 raek: nice. good.

13:14 AWizzArd: just download Clojure 1.3 α2

13:15 fliebel: Anyone knows what's up with the mysterious "improved stacktraces"?

13:15 chouser: mysterious? (pst)

13:16 fliebel: chouser: Yea, in the message he mentioned them, but I can;t find what's improved. disclaimer: I havn't tested any of the alphas.

13:17 AWizzArd: Anyone here from Finland?

13:18 Chousuke: o/

13:18 AWizzArd: aah, wb

13:18 Chousuke: please look into your private

13:19 pyrtsa: o/

13:34 rhickey: chouser: it was just an X

13:37 chouser: rhickey: ha! oh, ok.

13:37 rhickey: you're not vampires, are you?

13:38 chouser: sucking your life's work dry of it's simplicity?

13:38 its

13:38 * rhickey gets his wooden stake

13:39 chouser: rhickey: have you seen http://github.com/jarpiain/cljc ?

13:41 the author has clearly put a *lot* of effort into it, including reimplementing bytecode generation to avoid depending on ASM

13:42 rhickey: never saw it

13:42 bytecode gen w/o ASM seems needless wheel reinventing

13:43 * spicycode doesn't see anyone glittering in the sun

13:46 AWizzArd: Will (char 65) return on all JVMs on all OSes always \A ?

13:47 cemerick: unless there's one that's using ebcdic…

13:47 AWizzArd: where is the encoding set which determins what char returns?

13:47 cemerick: AWizzArd: it's all UTF-16. That was a joke. :-)

13:48 AWizzArd: Strings always use char[] internally as their value.

13:49 jarpiain: heh, actually I wrote the class file parser/assembler first and then kind of figured a compiler would be a good way to generate test input :)

13:50 and also a more interesting project

13:50 AWizzArd: cemerick: so, on all official JVMs (char n) for n between 0 and 65535 will return the identical char.

13:52 cemerick: AWizzArd: I believe so, yes. (char n) is the equivalent of (char)n in Java.

13:52 chouser: jarpiain: so what are your plans/goals for the thing?

13:53 AWizzArd: good

13:55 jarpiain: in short term to implement the remaining few special forms, then I guess wait to see if there's any interest to take it further

13:55 I'm going to send the CA in any case

13:56 amalloy: hey, speaking of CA, should i expect some kind of notification when mine gets in? put it in the mail last monday

13:56 Raynes: amalloy: No notification.

13:56 amalloy: Just keep an eye on the contributor list.

13:56 $whatis CA

13:56 sexpbot: CA = The Clojure contributors agreement: http://clojure.org/contributing

13:57 amalloy: ah cool

13:57 drewr: $whatis CYA

13:57 sexpbot: CYA does not exist in my database.

13:57 drewr: lame

13:57 Raynes: amalloy: Also, I think (I'm pretty sure) I've fixed clj-sandbox, and should be able to use a blacklisting scheme rather than a whitelisting scheme in sexpbot. Theoretically, this will make sexpbot's evaluation equivalent to clojurebot's when I'm finished.

13:58 danlarkin: $whatis raynes

13:58 sexpbot: raynes does not exist in my database.

13:58 danlarkin: bam!

13:58 pjstadig: CLABANGO!

13:58 hiredman: ~suddenly

13:58 clojurebot: CLABANGO!

13:58 nickik: I don't know mutch about compiler (jet) but what does it mean to not depend on ASM?

13:59 chouser: nickik: ASM is a Java library the current Clojure compiler uses to generate JVM bytecode.

13:59 Nafai: technomancy: Around? I'm having some problems with slime from your git repo, perhaps you have a moment to help me debug?

14:00 _rata_: hi

14:00 kotarak: Wah! CLABANGO!

14:01 pjstadig: is ASM needless wheel reinvention? what about cross compiling from .NET to Java or something?

14:02 chouser: wow

14:03 abrooks: Heh, "Grand Theft Wumpus: The most violent programming example ever put into a textbook." http://nostarch.com/lisp.htm (third page sample)

14:04 mabes: can you tell leiningen to ignore certain sub-dependencies in the project.clj?

14:04 abrooks: That's from Conrad Barski's "The Land of LISP" book which looks hysterical.

14:04 cemerick: pjstadig: I think it's assumed that every potential host has suitable bytecode/executable generation facilities.

14:04 Bootvis: abrooks: it is

14:04 cemerick: I don't think anyone would be happy with cross compilation as a long-term solution in any case.

14:04 pjstadig: sure

14:05 it's a use case

14:05 _rata_: has anybody seen jkkramer?

14:05 pjstadig: maybe not eminently useful, but a use case

14:06 lrenn: mabes: there is an :exclusions key

14:06 nickik: http://landoflisp.com/ follow the arrow to the comic its really funny

14:07 lrenn: mabes: see http://github.com/technomancy/leiningen/blob/master/sample.project.clj for an example

14:08 mabes: lrenn: great, thanks!

14:16 hiredman: Towards Performance Measurements for the Java Virtual Machine’s invokedynamic: http://www.cs.iastate.edu/~design/vmil/2010/papers/p06-kaewkasi.pdf

14:16 Raynes: ,clojure.lang.RT

14:16 clojurebot: clojure.lang.RT

14:17 Borkdude: Can someone give me guidance to how I can create a GWT Project in Eclipse and use Clojure for the server side?

14:22 fogus_: Borkdude: GWT can talk any number of protocols to your server.

14:29 Raynes: ,(Thread/sleep 10000)

14:29 clojurebot: Execution Timed Out

14:30 kotarak: Is there someone windows script kiddie hanging around, who would help poor vim users on Windows with some cmd magic?

14:37 technomancy: "script kiddie" is kind of a derogatory term actually.

14:37 might not be a good thing to say if you are looking for volunteers. =)

14:39 kotarak: technomancy: I know the term. It was not intended as an offense, though. Rather a (slightly too) bold call.

14:42 Raynes: ,(println "blah")

14:42 clojurebot: blah

14:45 Raynes: sexpbot's evaluation should be much less sucky now.

15:00 rhickey: hiredman: thanks for the link

15:02 alpheus: Using deftrace, there's a nice tree printed when the function is called. Should dotrace print the tree for functions defined with defn?

15:05 jcromartie: trace!? what have I been missing

15:06 alpheus: clojure.contrib.trace/trace

15:08 jcromartie: awesomesauce bolognese!

15:09 TeXnomancy: dotrace is really great

15:10 alpheus: I must be using it wrong

15:11 TeXnomancy: alpheus: dotrace works on vars IIUC. fn literals can't be affected by it

15:13 rickmode: Using clojure.contrib.def/name-with-attributes is a bit awkward when not all macro arguments beyond name are variadic. Am I missing something? Example: http://gist.github.com/652096

15:22 alpheus: deftrace doesn't understand docstrings

15:22 jcromartie: does anybody else think that the metadata system adds a burden to library authors?

15:23 chouser: what kind of burden?

15:23 jcromartie: because there's a whole class of operations that can destroy metadata on objects, right?

15:24 and if you want to maintain metadata you have to be careful of the way you approach things

15:24 chouser: hm

15:24 jcromartie: I mean it could be that everything in clojure's core libraries maintains metadata

15:25 ,(meta (seq (with-meta [] {:foo :bar})))

15:25 clojurebot: nil

15:26 jcromartie: but I guess not

15:26 chouser: but ... seq doesn't return the same object

15:26 not even the same type

15:26 jcromartie: no

15:26 that's true I guess

15:26 I suppose metadata is something you'd be using very mindfully anyway

15:26 I've never found a big use for it

15:26 chouser: most of your normal collection ops maintain metadata: conj, assoc, dissoc, disj, etc.

15:27 kotarak: ,(meta (pop (with-meta [:a] {:foo :bar})))

15:27 clojurebot: {:foo :bar}

15:27 kotarak: I think the burden is on type implementors.

15:27 chouser: kotarak: yeah, I think that's fair

15:27 jcromartie: yeah I guess "destroy" is the wrong word

15:27 since there's no contract about what should or shouldn't return an object with metadata

15:28 cemerick: kotarak: which is an unfortunate thing, insofar as so few people use metadata, and aren't generally aware of the small details involved.

15:28 chouser: not many people implement types

15:29 kotarak: cemerick: I personally have no idea what to use metadata for besides talking to clojure and taint checks. But when I implemented my list with fast random lookup, the metadata was kind of annoying.

15:30 chouser: I haven't added metadata support yet to finger-trees. We'll see how annoying it is there. :-)

15:30 it's brilliant for passing extra data along with code

15:30 TeXnomancy: Robert Hooke and Radagast rely heavily on metadata; those would have been awful to implemnet without it.

15:31 when did (name "stringy") start to work? was it around the time 1.2 was released?

15:31 kotarak: chouser: I probably should investigate factory functions. ;)

15:31 chouser: TeXnomancy: does work in 1.2

15:33 jcromartie: of course it would be simple enough to have something that maintains the metadata for a value at both ends of some operations

15:34 hiredman: technomancy: you are being recalled

15:35 kotarak: jcromartie: the is a question where a new copy of the type is created. Then the operations don't really matter.

15:45 rickmode: Has anyone else hit awkwardness using name-with-attributes?

15:47 chouser: rickmode: never used it

15:48 arkh: technomancy: I filed an issue with leiningen on github yesterday - should I be able to see it when I go to "Issues"?

15:49 kotarak: rickmode: what awkwardness?

15:49 * KirinDave mutters.

15:49 KirinDave: I think I hate gen-class and static methods.

15:49 There are all these weird little issues when scala is trying to call my gen-class forms

15:49 chouser: KirinDave: hate of gen-class is a natural consuequence of using it

15:50 rickmode: kotarak: it works but I had to cons together my none name macro args, e.g. (cons a (cons b rest)) with [name a b & rest], then pull the back apart after the name-with-attributes call. http://gist.github.com/652096

15:50 KirinDave: chouser: Even the docs are poor.

15:50 It's like a layer cake of hate. A layer-hate, if you will.

15:50 chouser: KirinDave: but I don't understand why static methods are still causing you problems

15:50 KirinDave: chouser: Neither do I.

15:50 chouser: Some vars it just insists are unbound.

15:50 chouser: My last problem was it choked on (declare ...)

15:50 chouser: So I changed all my (declares ) in my macro to (def sym identity)

15:51 chouser: But now even some *functions* are coming back unbound.

15:51 hiredman: oh wait, your macros are failing you?

15:51 chouser: there's got to be something wrong with your setup

15:51 KirinDave: hiredman: No.

15:51 hiredman: should have gone with conduit

15:51 KirinDave: chouser: It's not just my setu

15:52 hiredman: Maybe, just maybe, you should take your shoe and swallow it. It's not the macros, unless the clojure compiler itself is freaking otu that them

15:52 kotarak: rickmode: ehm, well, then don't name the arguments in the arg list. Just use [& macrotail], do the destructuring afterwards.

15:53 KirinDave: hiredman: And I may still go with conduit. Because of my macros, I actually get to change that as I go.

15:53 All I did was encode the logic of the graph, rather than how it's actually executed.

15:53 raek: KirinDave: have you made a simple working example, and then gradually added stuff until it breaks?

15:53 KirinDave: raek: No, because I keep running into new problems.

15:54 I can reliably break (declares ...) under (do ...)

15:54 I have a deadline I am trying to hit before I start submitting bugs.

15:54 So I stopped doing that.

15:54 But this problem is unrelated to any macro-ness

15:54 It's just saying a var in my clothesline.util module is unbound, when it's called from scala or java.

15:54 But it doesn't happen in Clojure.

15:55 rickmode: kotarak: I thought of that, but it makes the code less obvious visually and using (doc ...)

15:56 kotarak: no worries - I was mainly curious if I missed something

15:56 kotarak: rickmode: the doc part is broken anyway, because it should read [docstring? metamap? your stuff here ...]

15:57 chouser: KirinDave: I don't mean to be stubborn or anything, but I can assure you I generate a Java class with static methods using gen-class, and use the results from both Clojure and Java code, in unit tests and integration tests on a regular basis, and have done so for many months.

15:57 KirinDave: so it *can* work. clearly there's some difference between the code here and the code there

15:57 KirinDave: chouser: I believe you.

15:57 I am stressing something, somehow.

15:57 chouser: that difference is probably not in clojure itself

15:58 kotarak: rickmode: you can use a metamap like this: http://paste.pocoo.org/show/282847/

15:58 KirinDave: Well this only happens when called from scala.

15:58 I mean, it's saying an fn is unbound.

15:58 But it doesn't fail from the clojure repl.

15:58 chouser: what's the exact exception message for that?

15:58 KirinDave: chouser: https://gist.github.com/6486c21ed45dfc776321

15:59 Some variation of that.

15:59 rickmode: kotarak: I see.. override the arglists the compiler would build. Good suggestion.

15:59 KirinDave: Or, if we use "use" instead of "use ... :only"

15:59 https://gist.github.com/3a1d9830452f3c155c56

16:01 cemerick: KirinDave: "Maybe, just maybe, you should take your shoe and swallow it"? :-(

16:01 * cemerick is on aggression patrol today, don't mind me

16:02 KirinDave: cemerick: I'm a little tired of hiredman telling me macros are bad 600 oblique ways.

16:03 cemerick: KirinDave: Whatever. As incredibly civil as the community has been in aggregate, we can all be moreso.

16:04 chouser: "does not exist" is not quite the same as "is unbound"

16:04 KirinDave: chouser: Are there any sorts of issues in my setup that might be worth investigating?

16:04 chouser: Right

16:05 chouser: It depends on how we use (:use )

16:05 If I say (:use clothesline.util) it does the dne, if I change it to :only it says unbound.

16:06 hard to debug this, tho... since it's a thing involving what happens when a clojure function is called from scala...

16:07 tlockney: KirinDave: actually, other way around. with :only we're getting DNE

16:07 KirinDave: tlockney: Ah

16:07 chouser: interesting, that makes more sense

16:08 tlockney: the DNE is coming from the defn for refer in core.clj, fwiw

16:08 chouser: sounds like the namespace is getting loaded by :use -- with :only [], you'd expect the var to not be referred, and thus "does not exist"

16:08 tlockney: which makes sense, since that one blows up trying to create an instance of the class

16:09 chouser: but without :only [], all the names will be referred, and if the var has no root binding, you'd expect "is unbound"

16:10 you might trying printing out the value of map-keys at the end of clothesline/util.clj and verify that the namespace is indeed getting loaded before you try to use it, and that the value is what you expect.

16:11 but that's just general debugging advice: verify what you think you know

16:11 hard to be more specific without all the code, build env, etc.

16:11 tlockney: chouser: I'm confused by the first part of your statement. the var we put in :only is the one that's getting the "does not exist"

16:11 so, it is getting referred

16:11 or, should be anyway

16:11 chouser: the only use of :only anyone has mentioned to me is :only [] which refers nothing

16:12 KirinDave: Ah, well of course we put a symbol in the [] dude. :)

16:12 tlockney: I think that was a miscommunication

16:12 it's :only [map-keys]

16:13 technomancy: :only [] is actually a pretty reasonable thing to do

16:13 chouser: KirinDave: well, I actually recommend the use of :only [] with an empty vector.

16:13 but anyway...

16:13 technomancy: but only through historical accident

16:13 chouser: heh, right.

16:14 KirinDave, tlockney: but my debugging advice still stands

16:16 KirinDave: chouser: we'll keep at it. Thanks for your time.

16:18 arkh: Having a lein issue with dashes in namespaces (unrelated to my last IRC post)

16:18 in project.clj, I have '(defproject ... :main syslog-relay.core)'. My directory structure is ./src/syslog_relay/core.clj, my namespace in that file is '(ns syslog-relay.core ...)', and when I do a lein jar it throws a 'Exception in thread "main" java.lang.NoClassDefFoundError: syslog_relay/core'

16:19 ugh ... I'm sorry, when I do a 'java -jar syslog-relay-0.0.5-SNAPSHOT.jar' it throws the above error. lein jar is fine

16:20 raek: does 'lein jar' imply 'lein compile'?

16:21 arkh: I would think so (?) - I have generated .class files

16:22 my MANIFEST.MF says 'Main-Class: syslog_relay.core', fwiw

16:22 raek: I browsed through the source, and it looks like it does

16:22 arkh: oh - I guess I should have done that too! ; )

16:23 raek: arkh: do you have a :gen-class thingy in the ns form?

16:23 arkh: I do not

16:23 KirinDave: arkh: Ah. Yes. Well. There, as they say, is your problem. :)

16:24 arkh: oh .. I need a :gen-class just for lein jar?

16:24 raek: looks like a (:gen-class) is sufficient

16:24 then the "-main" function will be the main method of the main class

16:26 arkh: you need :gen-class in order to generate a class that has a main method

16:26 the namespace foo.bar will become the class foo/bar__init.class

16:26 arkh: I'm wondering how I missed that - where should I have read that before?

16:27 raek: http://clojure.org/compilation is where I found out about this

16:27 arkh: is creating a jar the same thing as "aot compile"?

16:28 raek: ...but you can control what method that class gets. so you use :gen-class to generate another class which can have the methods you like

16:28 *but you can't

16:28 technomancy: arkh: I think the lein tutorial covers it

16:30 arkh: sorry for asking a question that's in the documentation - raek, KirinDave, technomancy, thank you for your help

16:31 raek: np

16:31 Nafai: technomancy: Question about slime from your github repo; when I execute something in the repl that causes an error (but not all errors), like trying to use a non-existant namespace, Emacs becomes unhappy and starts spitting out this:

16:31 error in process filter: Wrong type argument: characterp, nil

16:31 error in process filter: define-key: Wrong type argument: characterp, nil

16:31 I have to kill emacs because I can't even do anything after this

16:31 Any hints on how to debug this?

16:33 technomancy: Nafai: maybe make sure you've got the latest swank-clojure 1.3.0-SNAPSHOT

16:33 AWizzArd: Is that available as a .jar too?

16:34 technomancy: it's on clojars

16:34 * Nafai double checks

16:34 raek: is it safe to use that one for clojure 1.2?

16:35 meh. I could as well upgrade everything to 1.3.0-alpha2

16:35 technomancy: sure; it's "lein multi test"ed against 1.1, 1.2, and 1.3-snapshot

16:35 not that the test suite is any good

16:36 Nafai: technomancy: Yeah, running the latest swank-clojure snapshot

16:42 technomancy: sorry, not sure what's going on there

16:43 Nafai: ok

17:01 duncanm: dum de dum

17:01 finally fixed a bug that has been haunting me for 3 days

17:01 turns out it was just because I couldn't read the order of the arguments to the AffineTransform constructor correctly

17:02 AWizzArd: 3 days?

17:02 Those are the pitfalls of dynamically typed langs.

17:02 ohpauleez: Does anyone in here use paredit.vim?

17:03 duncanm: yeah, m00 m10 m01 m11 m02 m12 vs. m00 m01 m02 m10 m11 m12

17:03 rows first, or columns first

17:04 i paid attention to the multimethod that took in a vector, and got that right, but forgot to check how i destructure the incanter.matrix

17:04 anyhoo

17:04 i have this code to do some other destructuring, and it's a bit long, i was hoping to see if someone could figure out a better, more concise way

17:04 it goes "From a map of {key, {:entries {s [sx sy] ...} ...}} and 's', return a map of {key, [sx sy]}"

17:05 i put mine here: http://gist.github.com/652322

17:16 _seanc_: Is there a simple way in Clojure, without using Java, to replace one character in a string with another. Say, replace spaces with a dash

17:17 Raynes: Why do you not want to use Java here?

17:17 &(.replace "foo bar baz" " " "-")

17:17 sexpbot: ⟹ "foo-bar-baz"

17:17 _seanc_: I'm a Java dev, I want to try and learn Clojure without Java

17:18 raek: if we define "without using Java" as "by only calling clojure functions", clojure.string/replace seems to be a match

17:18 http://clojuredocs.org/clojure_core/clojure.string/replace

17:18 Raynes: Clojure embraces Java quite a bit. Where Java isn't broke, Clojure doesn't really aspire to fix it.

17:18 raek: ,(require '[clojure.string :as str])

17:18 clojurebot: nil

17:18 _seanc_: whoa, ClojureDocs, how the hell hasn't Google shown me this before?!

17:18 Raynes: There is the replace function in clojure.string and raek just pointed out, but it uses .replace under the hood. Hell, I think it even takes the arguments in the same order.

17:19 raek: ,(str/replace "foot" \o \e)

17:19 clojurebot: "feet"

17:20 raek: yeah, clojure.string is a very thin wrapper

17:20 _seanc_: I appreciate the help. I'm learning more and more :)

17:22 @raek where you put (require '[clojure.string :as str]), does that have no negative impact on clojure.core's str?

17:22 scottj: _seanc_: I think clojuredocs.org is fairly new, maybe not a high pagerank bc few links to it

17:24 raek: _seanc_: no, the "src" it introduces is a namespace prefix, which are always distinct from var names from context

17:28 _seanc_: raek: So since require creates a new str in a new namespace. Does that mean when you use str, without specifying the namespace that clojure has to figure out which is the correct one to use?

17:29 raek: require does two things in this case: 1) makes sure that the namespace gets loaded 2) adds a namespace alias in the current namespace

17:30 so writing str instead of clojure.string (which you can still use) only works in the namespace you made the require

17:30 no

17:30 now

17:30 namespaces does not have var entries in other namespaces

17:31 _seanc_: I think I may have misunderstood something. I'll do some more reading. I appreciate the help

17:32 duncanm: la la la

17:32 technomancy: is there any way to add a method to a defmulti for which you only have the var at runtime?

17:32 other than eval

17:32 raek: when clojure evaluates the symbol str, it will first resolve it to fully qualified form: str -> clojure.core/str

17:33 if the symbol already has a namespace part, then that part will be looked up in the alias table and replaced with the full form, of there is any

17:33 Raynes: &(resolve 'str)

17:33 sexpbot: ⟹ #'clojure.core/str

17:34 raek: so namespaces only go before the slash, and var names only after the slash

17:35 (on exception is when you use quoted symbols to refer to namespaces, like when calling 'require' or 'use')

17:35 but since they are quoted, normal rules don't apply

17:35 _seanc_: quoted being ' ?

17:36 raek: yes

17:36 _seanc_: You know, I don't want to bother you guys all day. Do any of you know of some good resources for clojure? I can honestly say none of the things I've read really cover much

17:37 nickik: how do i get a normal map from a record?

17:37 (because i want to use the data as a function)

17:37 raek: _seanc_: I haven

17:38 technomancy: ~peepcode

17:38 raek: 't read this, but it seems to cover many things: http://en.wikibooks.org/wiki/Learning_Clojure

17:38 I learned very much about clojure from the pages of clojure.org, but then I had programmed in Lisp before...

17:39 _seanc_: raek, you're the (wo)man!

17:40 (I have no idea if you're a dude or dudette, no offense intended)

17:40 raek: how politically correct of you... :) but I'm just a male geek as you would expect

17:41 nickik: is there a better way then this (apply hash-map (interleave (keys <The Record>) (vals <The Record>)))

17:41 _seanc_: Hah, I know a few female devs so you can never be sure

17:41 amalloy|brb: nickik: (into {} <The Record>)?

17:41 raek: nickik: (into {} the-record)

17:42 nickik: ah of course why did i not think of that

17:42 amalloy|brb: if you want to be verbose, you can use (apply zipmap ((juxt keys vals) the-record))

17:43 raek: amalloy's brain and mine seems to be in lockstep... or should I say "juxed"? :-)

17:44 hey, you managed to sneak in a juxt there too... :)

17:44 nickik: sais something about the clojure api too

17:45 raek: nickik: another way would be #(get the-record %)

17:45 if you don't want to build a new data structure

17:45 a_strange_guy: Hello Clojurians

17:46 nickik: oh my good a strange guy

17:46 hallo :)

17:46 a_strange_guy: is anyone else building clojure and contrib himself

17:46 ?

17:46 raek: not since lein was released... :-)

17:48 if you're just going to use them (and not fix bugs or something) there is little benefit of compiling them yourself

17:48 Raynes: Most people just use cake or lein these days.

17:48 nickik: i never did :)

17:49 a_strange_guy: i just like playing with the bleeding-edge versions

17:49 ohpauleez: a_strange_guy: you can pull the daily snapshots with lein

17:49 or cake

17:49 Raynes: The bleeding edge versions are on in a maven repository, I believe.

17:49 Like he said.

17:50 a_strange_guy: are those the same as the ones at build.clojure.org?

17:50 raek: yes

17:50 ohpauleez: a_strange_guy: you want to use alpha2 as your 1.3.0 artifact, that's the last major step. If you want snapshots, you can use snapshots, but the alpha cuts are better (imo)

17:51 raek: there's both http://build.clojure.org/releases/ and http://build.clojure.org/snapshots/

17:51 a_strange_guy: a lot seems to have changed since I last used clojure xD

17:52 ohpauleez: a_strange_guy: http://gist.github.com/652400

17:52 and example where I use alpha2 in my project.clj

17:52 raek: well, Leiningen (pretty much the first useful Clojure build system) was released in november last year, IIRC

17:53 ohpauleez: There's also commented lines how how to get snapshots

17:53 raek: a_strange_guy: yes, indeed.

17:54 I remember the times before lein...

17:54 a_strange_guy: I stopped programming last spring for a while, and now so much had changed ^^

17:55 i remember the times before 1.0 ...

17:55 ohpauleez: yes, I too remember those days

17:56 joegallo: When we had to walk uphill, both ways, to read a sexp.

17:56 And we liked it!

17:56 ohpauleez: It's going to be funny when we say things like, "Remember when all we had were transients and type hints"

17:57 technomancy: remember the tarbomb releases?

17:57 joegallo: You kids today! I once wrote a lexer/parser using nothing but closing parens!

17:57 technomancy: that was my first bug reports

17:57 *report

17:58 a_strange_guy: "Did you know that once apon a tome, clojure was written in a strange language called 'Java'?"

17:58 ^^

17:59 i just asked if someone builds clojure from scratch, because I cant get contrib to build against my clojure.jar

17:59 the -Dclojure.jar option doesnt seem to work

18:00 it still downloads a clojure.jar via maven

18:00 and the resulting satandalone.jar ist binary incompatible

18:01 ohpauleez: Is it possible to destructure in an anon func?

18:01 amalloy: yes

18:01 ,((fn [[a b]] [b a]) [1 2])

18:02 &((fn [[a b]] [b a]) [1 2])

18:02 sexpbot: ⟹ [2 1]

18:02 amalloy: i'll get over this comma habit yet!

18:02 ohpauleez: I'm mapping something across a map, and I want the key and value

18:02 amalloy: ohpauleez: ^^

18:02 ohpauleez: ahh, cool, thanks amalloy

18:02 I knew I had done it before, I don't know what I'm doing wrong right now haha

18:02 amalloy: *laugh* what does your broken attempt look like?

18:03 ohpauleez: it's sitting on a repl right now, let me poke it a little more, and if I can't fix it, I'll gist it

18:04 apgwoz: what's the proper way to add metadata in the `ns` macro? i've seen (ns #^{..} ..) and i've seen (ns x.core {:blah blah}...) ?

18:04 or, are they equivalent?

18:05 ... though, i've also seen (ns ^{..}...) too..

18:05 ohpauleez: amalloy: solved. I was being foolish

18:05 amalloy: apgwoz: i don't know about the ns form, but i think #^ is deprecated in favor of ^ these days

18:05 MayDaniel: apgwoz: (ns ^{:doc "..."} user)

18:06 apgwoz: amalloy, MayDaniel: ah, sweet.

18:07 ohpauleez: apgwoz: I do (ns some-name ^{:author Me} (:require ...))

18:07 technomancy: you don't need that syntax for just :doc; just put a string after the ns name

18:07 MayDaniel: Just an example..

18:07 apgwoz: technomancy: right, but, for :author as well

18:08 ohpauleez: does that actually attach the metadata to the namespace?

18:08 technomancy: I fail to understand why that belongs in code rather than version history, but if you wanted to do it, that's how you would.

18:08 apgwoz: i thought the metadata shortcut only worked for the preceeding element.

18:09 ohpauleez: I don't know actually, let me try on the repl real quick. It's just what I've seen done

18:10 apgwoz: technomancy: while i'd normally agree with you, some companies have rules regarding these things where everything has to be documented, who wrote it, etc. that metadata seems like an appropriate place.

18:10 hiredman: ,(symbole "\o")

18:10 ,(symbol "\o")

18:10 amalloy: apgwoz: comments with version-control tags?

18:11 apgwoz: amalloy: that works too, but by not meta data with version-control tags?

18:11 :)

18:11 technomancy: apgwoz: true; better than comments

18:11 ohpauleez: apgwoz: both forms don't actually attach meta data for me

18:12 technomancy: actually it needs to be before the namespace name

18:13 ohpauleez: technomancy: does it?

18:13 MayDaniel: Yes.

18:15 ohpauleez: MayDaniel: http://gist.github.com/652449

18:15 apgwoz: yeah, looks like it.

18:15 ohpauleez: Ohhhh

18:15 nvm

18:15 It's attaching to the require, not the ns

18:15 I understand now

18:17 scottj: what's the oldform param in if-let for?

18:18 apgwoz: yeah, it seems the reader effectively does: 1. if find a ^form, push it on a stack 2. read next form 3. if stack not empty, add meta data to result of 2.

18:19 scottj: oh nm, guess old version must not have used binding vector so it's to show an error

19:02 duncanm: is there a shortcut syntax for writing {:x x :y y} ?

19:03 MayDaniel: No

19:03 duncanm: that's too bad

19:03 Raynes: What would the shortcut look like?

19:04 duncanm: i don't really know

19:04 there is something like it in destructuring, with :keys, which is why i asked

19:04 bhenry: what might be the opposite of not-any?

19:04 Raynes: I'm just not sure what your shortcutting. :p

19:05 MayDaniel: some is similar to the opposite.

19:05 Raynes: -> (doc every?)

19:05 sexpbot: ⟹ "([pred coll]); Returns true if (pred x) is logical true for every x in coll, else false."

19:05 bhenry: ,(doc some)

19:05 tomoj: do you also have a (let [x ... y ...]) around it?

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

19:05 MayDaniel: Oops.

19:07 tomoj: duncanm: https://gist.github.com/2f060dde83ac1bfbe551

19:07 if so

19:07 but you could change it from into to just macroexpanding to a literal map

19:07 since the let ensures evaluation order

19:07 MayDaniel: duncanm: Do you mean {x :x y :y} as in how you'd use it in destructuring?

19:08 tomoj: if you had a macroexpand to {:x x :y y}.. be careful

19:08 s/macro/macro /

19:08 sexpbot: <tomoj> if you had a macro expand to {:x x :y y}.. be careful

19:10 duncanm: tomoj: that's very cute

19:11 (let [min-x ..., min-y ..., max-x ..., max-y ...] {:min-x min-x :min-y min-y :max-x max-x :max-y max-y})

19:11 that's what i have

19:11 tomoj: so your macro would make it nicer

19:11 but i don't think i'll use that macro for just this instance

19:11 tomoj: that's exactly the pattern I had

19:11 duncanm: tomoj: it'd be cool if it were part of clojure.core ;-)

19:12 tomoj: I was also independently doing macros that generated big maps which caused all my code to execute in scrambled order

19:12 duncanm: then, i'd definitely use it

19:12 i don't even bind the dummy thing, i think that's quite nice

19:12 s/bind/mind/

19:12 sexpbot: <duncanm> i don't even mind the dummy thing, i think that's quite nice

19:13 duncanm: i posted a bit of destructuring code earlier, it'd be cool if someone can show me some better way to write it: http://gist.github.com/652322

19:13 my version works, but it seems kinda too verbose

19:14 maybe if i use for instead of map and then let, it'll be more concise

19:14 scottj: a couple weeks ago someone posted a macro where you could do (with-keys a b c) I think and get {:a a :b b :c c). Anyone remember the name of it?

19:15 tomoj: duncanm: that was the first thing I noticed

19:16 duncanm: tomoj: oh?

19:16 tomoj: I don't understand the rest of it

19:17 duncanm: tomoj: i posted a version with for, it looks a little better?

19:17 (first (get (:entries trail) section)) still seems too busy

19:17 tomoj: cool

19:18 well

19:18 hmm

19:18 mattrepl: technomancy: I'm trying to use a hook in leiningen to set the classpath in used by the lein-swank plugin. I can't see how to do it without modifying lein-swank to accept a handler which it could pass to eval-in-project. Am I doing it wrong or should I find a workaround (dynamic var of handlers in eval-in-project) and submit a patch to lein?

19:18 raek: duncanm: I would write (for [[id trail] trails] :let [entries (get (:entries trail) section)] [id (->vpoint (first entries))])

19:18 duncanm: tomoj: i'm also using maps when i could be using vectors, i guess?

19:18 yeah, i don't know what to do about that

19:18 raek: I personally prefer 'for' over 'map' + 'fn'

19:18 mattrepl: s/in used/used

19:18 raek: also, you can do lets with it

19:19 duncanm: raek: yeah, i'm slowly warming up to the list comprehension syntax

19:19 hsuh: clojure macros expand at compile time, right ?

19:19 duncanm: hsuh: macros expand at compile time

19:19 tomoj: (-> trail entries section first ->vpoint) ?

19:19 duncanm: tomoj: hehe

19:20 tomoj: I dunno

19:20 duncanm: tomoj: that wouldn't work when 'section' is a number, it'd work if it were a keyword

19:20 Raynes: Macros expand at macroexpansion time.

19:20 tomoj: funny how not knowing what the heck its doing makes it so much harder to read

19:20 duncanm: tomoj: is the comment not clear?

19:20 i guess the ...s are a bit too abstract

19:20 tomoj: I just am too dump to try to understand right now

19:21 I guess knowing what the code is doing gives you shortcuts for reading chunks of it

19:21 duncanm: tomoj: well, this function is *just* destructuring

19:23 i have a map of {key, T} and each T is a map of {:entries { section-id [[x1 y1] [x2 y2]...] }

19:24 for some section-id, i want {key, [x1 y1]}

19:25 either way

19:34 i used to think that polymorphic sequence operators are the "missing things" in Scheme

19:35 but now that i've used them in Clojure, while I do like them generally, I can see that they could get confusing sometimes

19:35 maybe it's just me not being experienced enough with them

19:35 i find it 'annoying' that (map #(..) some-map) returns a seq of MapEntrys

19:35 same with filter

19:36 amalloy: duncanm: destructuring is the answer again :P

19:36 duncanm: maybe all i need is to write my own map-map and filter-map

19:36 amalloy: how so?

19:36 amalloy: &(map (fn [[k v]] [k (+ 1 v)]) {:k 10, :t 5})

19:36 sexpbot: ⟹ ([:t 6] [:k 11])

19:37 amalloy: if you want it as a map again, just use into

19:37 duncanm: but i want {:t 6 :k 11} instead of ([:t 6] [:k 11])

19:37 amalloy: &(into {} (map (fn [[k v]] [k (+ 1 v)]) {:k 10, :t 5}))

19:37 sexpbot: ⟹ {:t 6, :k 11}

19:37 duncanm: amalloy: yeah, that's the bit that bothers me

19:37 maybe i'll learn to accept it

19:37 amalloy: i agree we could use an into {} function

19:37 but it's convenient for map to always return a seq

19:38 rather than try to guess what to return based on the class it's passed

19:38 duncanm: amalloy: yeah, but most of the time, you *do* want it to be the class that you put in

19:38 Raynes: & (def into-map (partial into {}))

19:38 sexpbot: ⟹ #'net.licenser.sandbox.box9126/into-map

19:38 amalloy: Raynes: sure, of course it's not hard to write one

19:39 Raynes: &(into-map (map (fn [[k v]] [k (+ 1 v)]) {:k 10, :t 5}))

19:39 sexpbot: ⟹ {:t 6, :k 11}

19:39 MayDaniel: There's clojure.contrib.generic.functor/fmap

19:39 amalloy: &(def def inc)

19:39 sexpbot: ⟹ #'net.licenser.sandbox.box9126/def

19:39 amalloy: &(def def inc)

19:39 sexpbot: ⟹ #'net.licenser.sandbox.box9126/def

19:39 duncanm: i wrote a update-val in my code

19:39 (defn update-vals [m update] (into {} (for [[k v] m] [k (update v)])))

19:39 amalloy: Raynes: neat. we get a sandbox per user?

19:39 Raynes: &(def 3)

19:39 sexpbot: java.lang.Exception: First argument to def must be a Symbol

19:39 amalloy: or no

19:40 &def

19:40 sexpbot: ⟹ #<core$inc clojure.core$inc@f334db>

19:40 amalloy: ???

19:40 duncanm: having select-keys for maps different from filter is also one of the things i had to learn the hard way

19:40 amalloy: &(identity def)

19:40 sexpbot: ⟹ #<core$inc clojure.core$inc@f334db>

19:40 amalloy: &((identity def) 1)

19:40 sexpbot: ⟹ 2

19:40 amalloy: &(def 1)

19:40 sexpbot: java.lang.Exception: First argument to def must be a Symbol

19:40 duncanm: and i guess the other pair is dissoc/remove

19:41 Raynes: amalloy: There is a reason that bots shouldn't allow def and defn.

19:41 amalloy: Raynes: what is it doing under the hood here?

19:41 yeah, i agree

19:41 Raynes: I think I allowed it ages ago for playing with it in another channel and just never disallowed it.

19:41 amalloy: which is why i'm surprised it knows def is inc ever. but i don't understand what it's doing that makes it def sometimes, and inc other times

19:43 duncanm: i always prefered the Smalltalk's names for sequence operators over Lisp's: collect: instead of map, select: instead of filter, and inject:into: instead of reduce/fold

19:43 Raynes: amalloy: def is a special form.

19:43 amalloy: oh

19:43 Raynes: amalloy: It behaves the same way in an REPL.

19:44 amalloy: duncanm: so use them. nobody's stopping you from (def collect map)

19:44 duncanm: amalloy: i know i know

19:44 amalloy: well, it's probably bad form for others having to read the code

19:46 amalloy: yeah, i agree. but (a bit tongue in cheek here, no offense) i'd prefer that your code reflect your dislike, rather than your chat in #clojure do it

19:47 ie, rich isn't going to rename them anytime soon

19:48 Raynes: I strongly disagree.

19:48 Except for fold. I'd take fold over reduce, I guess.

19:48 amalloy: Raynes: disagree with whom?

19:48 Raynes: Both of you.

19:48 amalloy: heh

19:48 duncanm: heh

19:48 Raynes: :p

19:48 amalloy: well, yes. if i were giving selfless advice, it would be to complain in #clojure but write standards-conforming code

19:49 Raynes: I was implying that I disagree with your agreement. Not the rest of the message.

19:50 amalloy: oh

19:50 no, i agree that it's bad form to re-def in his code

19:50 i like map/reduce/filter, myself

19:50 Raynes: Oh. Then I agree with you and disagree with him. I think. :|

19:51 amalloy: if we ever get unfold and/or foldl/foldr then i'll support a name-change for reduce, but until then i prefer reduce

19:51 Raynes: I'm neutral as far as reduce vs fold.

19:51 Either one would work for me.

19:53 duncanm: i just found out that Select in .NET/LINQ is the equivalent of #collect: in the Smalltalk naming scheme, how confusing!

19:54 amalloy: duncanm: best to stick with map and filter then, eh?

19:54 duncanm: amalloy: yeah, i suppose ;-D

19:55 Raynes: Haskell uses map and filter as well.

19:55 $he map + [1..10]

19:55 sexpbot: => Couldn't match expected type `(a -> b) -> [a] -> [b]' against inferred type `[a1]'

19:56 Raynes: Man, I haven't used Haskell in so long.

19:56 $he map (+) [1..10]

19:56 sexpbot: => Overlapping instances for GHC.Show.Show (a -> a) arising from a use of `M1800505397.show_M1800505397' at <interactive>:(2,0)-(4,33)Matching instances: instance (Data.Typeable.Typeable a, Data.Typeable.Typeable b) => GHC.Show.Show (a -> b) -- Defined in show-0.3.4:ShowFun instance (Test.SmallCheck.Serial a, GHC.Show.Show a, GHC.Show.Show b) => GHC.Show.Show (a -> b) -- Defined in smallc

19:56 Raynes: Screw it.

19:56 duncanm: wow, there's a haskell REPL here too? what else can i write?

19:56 Raynes: Thats about it. It needs to truncate text though.

19:56 I'm surprised I overlooked that.

20:03 There.

20:08 bhenry: Raynes: is ruby learning down or is it my workplace's horrible network that seems to give me trouble with it every time.

20:08 the latter is my speculation based on your answer to the former

20:08 Raynes: It's down.

20:08 $ping rubylearning.org

20:08 sexpbot: Raynes: FAILURE!

20:11 guandao: suppose i figured out how to capture *out*, would it be thread-safe?

20:11 and what i mean is ... would i get the stream of a single thread in it, without mixing the other threads output in the stream...

20:13 i guess with-out-writer does that

20:20 tlockney: anyone got a pointer on how I can create a Clojure function from Java?

20:21 and, please, before anyone asks why I would want to do such a thing, just... well, don't

20:21 Raynes: Why would yo... damn. ._>

20:22 tlockney: I'm guessing the easiest thing to do is going to be to have the clojure side somehow wrap it, but wondering if there's a more direct way

20:44 notsonerdysunny: can somebody tell me when to use #^ and ^ for providing type(or meta info) information?

20:44 or are they both equivalent?

20:45 MayDaniel: I think #^ is deprecated from version 1.2.0

20:46 Raynes: What he said.

20:46 notsonerdysunny: thanks MayDaniel and Raynes

20:47 Raynes: I wish everybody thanked me for repeating other people's answers.

20:47 notsonerdysunny: :) confirmations adds weight to the answer ..

20:48 amalloy: Raynes: don't forget MayDaniel and i both said that an hour or two ago too, when apgwoz asked

20:51 hey, i just managed to ping/highlight/alert three different people in one message, none of whom actually care what i said

20:52 Derander: amalloy: cool

21:03 duncanm: is there no page on clojure.org on futures/promises?

21:04 i have a task to take an image and transform it and then write it to disk, i'd like to do that in parallel, so that i can use all my cores to run the transformation, should i just use pmap and fire off (future (render %)) inside the pmap?

21:40 chaslemley: ,(+ 5 5)

21:40 clojurebot: 10

21:51 technomancy: mattrepl: pong

21:51 mattrepl: technomancy: hola

21:52 technomancy: so did you try adding a hook to leiningen.classpath/get-classpath?

21:53 (add-hook #'leiningen.classpath/get-classpath (fn [f & args] (conj (apply f args) "/my/new/classpath/entry.jar")))

21:53 mattrepl: oh, I feel silly. I had it in my head that I needed to hook a plugin for some reason.. yes, that works perfect

21:54 thanks, that should do it

21:54 technomancy: schweet

21:55 mattrepl: what an awesome setup, robert.hooke may find it's way into crane... =)

21:57 technomancy: robert hooke has real ultimate power

21:59 maravillas: i never knew his last name was hooke

22:01 Plouj: hey guys

22:02 did anyone here see job openings at Akamai for Clojure development?

22:02 hiredman: they had a table at the conj

22:02 arscott: pretty sure they had a sign out saying they were hiring

22:02 Plouj: there's no way I'm moving to that area (Cambridge, MA), but maybe you guys would be interested

22:02 oh, I see

22:03 sounds like a posistive point for Clojure as a whole

22:04 positive*

22:08 technomancy: nothing like a little corporate backing

22:15 amalloy: can someone help me out with defmulti? i can't figure out the syntax and clojuredocs has no examples. i want to define a multifn that dispatches on the class of its first argument

22:16 (defmulti do-thing (comp class first)) doesn't seem to work

22:16 duncanm: (defmulti distance #(class %1)) ;; this ought to work

22:19 amalloy: duncanm: hm, thanks. i think the issue is actually that my defmulti is stale. if i (defmulti name func) and then later in the same repl session (defmulti name other), it still dispatches based on func instead of other

22:21 &(#(class %1) "1" 2)

22:21 sexpbot: java.lang.IllegalArgumentException: Wrong number of args (2) passed to: box12631$eval12833$fn

22:22 amalloy: that doesn't actually work duncanm, but it gets me to understand the syntax

22:25 duncanm: amalloy: oh right, the implicit % works kinda funky

22:25 amalloy: duncanm: (comp class first list) works as a dispatch fn

22:25 duncanm: (fn [a _] (class a))

22:25 or (fn [a & ignored] (class a))

22:25 amalloy: yeah

22:25 duncanm: is there no page on clojure.org on futures/promises?

22:26 technomancy: underscore is preferred to "ignored"

22:26 duncanm: technomancy: does _ bind varargs?

22:26 technomancy: duncanm: I mean with a &

22:26 duncanm: oh oh

22:26 (fn [a & _] (class a))

22:27 i'm trying to figure out how to use futures

22:31 technomancy: creating a future is like spawning a pooled thread, but you get a value back when it's done

22:32 promises are just simple reference types; no code executes inside them. they're just placeholders into which a value can be placed asynchronously (only once)

22:33 kind of like atoms, but they don't need swap concurrency semantics since they can only be set once

22:34 somnium: any adventurous clojure hackers interested in kicking the tires on a javascript compiler?

22:35 duncanm: technomancy: can you take a quick look at this? http://gist.github.com/652780

22:35 technomancy: render! is my CPU and IO intensive task

22:36 amalloy: &(macroexpand '(-> 1 #(inc)))

22:36 sexpbot: ⟹ (fn* 1 [] (inc))

22:36 amalloy: what's an idiomatic form using -> that will result in (fn [] (inc 1))?

22:37 _rata_: ,(macroexpand '(-> 1 inc))

22:37 clojurebot: (inc 1)

22:37 sexpbot: => 1

22:37 amalloy: _rata_: yes, but i need a function, not a result

22:37 _rata_: oh ok

22:37 hiredman: ,((-> inc (partial 1)))

22:38 clojurebot: 2

22:38 duncanm: hey hiredman

22:38 hiredman: hello

22:39 amalloy: &(-> inc (partial 1))

22:39 sexpbot: ⟹ #<core$partial$fn__3678 clojure.core$partial$fn__3678@909348>

22:39 amalloy: &(macroexpand '(-> inc (partial 1)))

22:39 sexpbot: ⟹ (partial inc 1)

22:39 duncanm: i've used future before like this (def f (future (do-some-io-work)))

22:39 hiredman: I wouldn't use future in a def

22:41 duncanm: hiredman: i do that so i can query the status of the work

22:41 hiredman: that thread will start running anytime that def is loaded

22:42 duncanm: hiredman: oh, i only do that in the REPL

22:45 hiredman: is that not a good thing to do?

22:45 oh, maybe i should do send-off instead of send

22:45 hmm, nope

22:58 dum de dum

23:02 amalloy: &\newline

23:02 sexpbot: ⟹ \newline

23:02 amalloy: &\nonsense

23:02 sexpbot: java.lang.Exception: Unsupported character: \nonsense

23:09 duncanm: how do i tell a future to start running?

23:09 ohpauleez: duncanm: A future will start running right away

23:09 "right away"

23:10 you get back the value from it, by deref'ing it

23:10 duncanm: ohpauleez: so what am i doing wrong here? http://gist.github.com/652780

23:13 ohpauleez: I'm not sure you want a future there, that's already being run in an agent, which will be in a different thread

23:14 otherwise, there's nothing super obvious. You might want to look at if you want to be using send vs send-off

23:14 duncanm: ohpauleez: right

23:14 ohpauleez: and if you're calling this on the repl, you'll want to call (shutdown-agents)

23:14 if it's hanging

23:19 duncanm: ohpauleez: is there a upper-bound to the number of futures i have running? or will they use a threadpool?

23:20 ohpauleez: they will use the threadpool. What symptom are you seeing?

23:20 duncanm: nothing's running ;-P

23:20 ohpauleez: As in, when you deref, you get nothing back?

23:20 duncanm: ohpauleez: should i use agent/send-off or future?

23:20 ohpauleez: right

23:21 i think i know how to do it with just future

23:21 ohpauleez: I would personally just use futures, and map deref across them

23:22 You might also just want to use a ref and pmap, chunked appropriately

23:23 duncanm: ohpauleez: i was chunking manually

23:23 ohpauleez: so by now i'm a little lost in how to put it all together

23:23 ohpauleez: oh, the ref holds the list of futures?

23:24 ohpauleez: right, you want to be chunking your data 2+ number of cores, and run pmap on that

23:24 duncanm: ohpauleez: and i just (map deref futures) to get all of them started

23:24 ohpauleez: right, that's one approach

23:24 duncanm: ohpauleez: how do i put the futures into the ref?

23:24 hiredman: deref doesn't start futures

23:24 ohpauleez: the other one is just to use pmap and no futures

23:24 hiredman: futures start right away

23:25 ohpauleez: hiredman: right, I think he knows that

23:25 duncanm: (future-done? (future-call (fn [])))

23:25 ohpauleez: ohhh, nvm, I didn't read his last line

23:25 duncanm: i tried doing that

23:25 and it always says false

23:25 ohpauleez: duncanm: futures start right away, jump on the repl and play around with them a little bit

23:25 duncanm: i'm still a bit lost

23:25 ohpauleez: let me make a gist for you, hang on

23:26 duncanm: ohpauleez: thanks so much

23:26 this is kinda silly, i have counted this - if i do this sequentially, it'll only take like 2 hrs

23:26 and i've spent close to 2 hrs trying to learn how to do it in parallel

23:26 i'm trying to render 1200 images

23:29 _seanc_: Hey guys, so I know two asterisks are use to denote *globals*, but what exactly are two pluses for in say: +db-path+ ?

23:30 _rata_: _seanc_, in common lisp that's used for constants... not sure in clojure

23:31 amalloy: in clojure it's frowned on, mostly. there are a few people who use it for constants

23:31 technomancy: _rata_: they're used by common lispres writing clojure

23:31 _seanc_: Oh ok, but I am right about the * * for constants?

23:31 technomancy: _seanc_: not globals but values which are intended for rebinding

23:31 duncanm: _seanc_: i think the java convention of UPPER_CASE is ok too

23:32 _rata_: hahahaha ok, I didn't know that

23:32 technomancy: all non-privates are globals

23:32 itistoday: shit... how do i switch channels in erc (emacs)?

23:32 duncanm: itistoday: by switching buffers?

23:32 dakrone: itistoday: channels are buffers

23:32 itistoday: i've auto-logged in to both #emacs and #clojure

23:32 oh

23:32 C-x b

23:32 dakrone: thanks!

23:32 _seanc_: I guess I don't really understand the concept of binding and rebinding yet. It's not as simple as assigning a new value is it?

23:33 duncanm: ohpauleez: i'm trying something like this now: http://gist.github.com/652780

23:34 _rata_: _seanc_, no, it's like "stacking" a new value on it and then you get back to the original value (when you live the "binding" form)

23:34 duncanm: oh wait, i forgot about the dorun

23:34 _rata_: + it's thread-safe

23:35 _seanc_: thread safe aside, when would you need to stack a value?

23:35 technomancy: _seanc_: if you're pretty-printing, you would bind the current indentation level, for example

23:36 _rata_: for example when you want to redirect standard output in some function calls

23:36 duncanm: i feel kinda stupid today

23:36 ohpauleez: duncanm: http://gist.github.com/652858

23:37 _seanc_: Interesting. So it keeps the new value for the duration of that execution then changes back?

23:37 _rata_: yes

23:37 you bind it, call some functions and inside that functions standard output will be redirected

23:37 _seanc_: Fascinating

23:37 duncanm: whoa

23:37 does *1 work?

23:37 _seanc_: So it's like a dependency injection on a per function basis almost

23:37 ohpauleez: yes

23:37 duncanm: oh sweet

23:37 i didn't know that

23:37 ohpauleez: *1 *2 and *3

23:37 technomancy: ,*e

23:37 clojurebot: java.lang.IllegalStateException: Var clojure.core/*e is unbound.

23:38 technomancy: ,botsmack

23:38 clojurebot: java.lang.Exception: Unable to resolve symbol: botsmack in this context

23:38 ohpauleez: also, I left out one line, where I (def num-of-cores 2)

23:38 technomancy: ~botsmack

23:38 clojurebot: Owww!

23:38 defn: evening folks

23:38 clojurebot: hey

23:38 clojurebot: hey is for horses

23:38 defn: clojurebot: horses?

23:38 clojurebot: Cool story bro.

23:38 ohpauleez: haha

23:38 defn: lol

23:49 ohpauleez: duncanm: How are things working out?

23:49 duncanm: ohpauleez: i got it running now

23:50 ohpauleez: perfect!

23:50 duncanm: i just have map and future

23:50 ohpauleez: and i chunk into 4 futures

23:50 inside each, i have a doseq

23:50 ohpauleez: sweet

23:50 duncanm: i dunno if that's optimal use of my hardware, though

23:50 i have a 2 yo Mac Pro at work, i have 8 cores here

23:50 ohpauleez: chunk it into 10 pieces

23:51 duncanm: ohpauleez: so this is silly, but the total number isn't divisible by 10, so partition doesn't work....

23:51 ohpauleez: partition-all

23:51 is what you want

23:52 duncanm: oh wow

23:52 ohpauleez: which will have 9 full pieces, and one slightly smaller part

Logging service provided by n01se.net