#clojure log - Nov 20 2010

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

9:58 defn: let the +b's commence

10:03 krumholt: hi is there a way to create the primitive datatype byte in clojure? when i do (byte 1) i get a Byte not a byte

10:04 Chousuke: krumholt: it's a byte, but when you pass it to a function it gets boxed

10:04 krumholt: can i prevent that?

10:05 im reading image data and its really slow. i think boxing every byte is the problem

10:06 Chousuke: you need a primitive array or a vector I suppose

10:06 no way to do primitive function args in 1.2

10:07 krumholt: but i could use a native array?

10:07 Chousuke: remember to remove reflection first though.

10:07 that's usually the biggest slowdown

10:07 tonyl: what about (.byte

10:07 what about (.byteValue (byte 1))

10:08 Chousuke: tonyl: that's even slower :P

10:08 it gets boxed just to call the method on the Byte, and then it returns the byte

10:08 krumholt: Chousuke, uh thanks. i added #^java.lang.Byte and the speed increased by 1000%

10:08 tonyl: yeah true mmm...

10:08 Chousuke: krumholt: hehe

10:09 krumholt: it went from 14 seconds to 1,8 seconds

10:09 Bahman: Hi all!

10:23 Chousuke: krumholt: It's good to bind *warn-on-reflection* to true when developing :)

10:23 krumholt: Chousuke, i will do that thanks

10:24 Chousuke: in the repl you can actually use set! to set it to true, so you don't need binding

10:27 krumholt: Chousuke, thanks for answering my next question before i could ask it :)

10:28 cmiles74: Does anyone have a Clojure language handler for Google Code Prettify?

11:03 Lajla: raek, but if it works, then surely it must be just a reader thing, right?

11:03 And that means that rich LIES on his page.

11:03 Rich' Shadow deserves no worship then

11:08 Chousuke: wtf are you talking about? :P

11:10 LauJensen: Lajla: You should really try out scala and #scala - report back here in 18 months :)

11:12 Lajla: Chousuke, what constitutes a symbol on clojure.

11:12 The point is that the main page says that symbols can't contain spaces et cetera or . or what-not.

11:12 Buuut

11:12 My claim is that that is just reader praecidence.

11:13 Like (symbol "I worship his shadow") works.

11:13 And (symbol? that) answers true.

11:13 Also,

11:13 you can even use eval on that

11:14 Like (let [funnysymb (symbol "I worship his shadow")] (eval (list (symbol "defn") funnysymb [(symbol "x")] (symbol "x"))))

11:14 And then you can actually use (eval (list (symbol "I worship his shadow") 3)))

11:16 Chousuke: Lajla: that's because there is no validation of symbols

11:16 the symbols are illegal still

11:17 as in, you're not supposed to use them

11:17 because then things might break

11:35 Lajla: Chousuke, what things?

11:35 If some things might break then, some one should mail rich to tell him that his type safety sucks an instead he should learn finnish to talk with me and Chousuke about deer and shadows to worship

11:37 Chousuke: Lajla: it's not a type safety problem

11:37 Lajla: it's just there being no check against the user creating stupid symbols

11:39 Lajla: Chousuke, I'd say that's a type safety problem. symbol claims to output symbols from strings, if you give it input from which it cannot produce a symbol, it should produce a runtime error.

11:39 Instead of just going on with it and producing something which is apparently 'garbage'

11:39 Chousuke: Lajla: well, duh

11:39 Lajla: Which strangely eval also accepts.

11:39 A bit sloppy, some would say.

11:39 But I think

11:39 Chousuke: Lajla: the thing is, no-one has yet come up with a patch to implement such validation

11:40 tonyl: Lajla: are you joking around or is this for real?

11:40 Lajla: the best wat is to just let symbols contain any and all characters strings can contain.

11:40 Chousuke: and since it's not a big issue, there's no rush to implement one

11:40 Lajla: And just have no reader syntax for it.

11:40 tonyl, I am f0 real.

11:40 tonyl: ok

11:40 Lajla: I am very theoretical.

11:40 I like to know the finer things about programming langauges before I write a Hello World.

11:40 Like these things

11:40 tonyl: hehe that is interesting

11:41 Lajla: I am very interesting.

11:41 Nahh, I actually tried out in C if "string"+1 did what I expected it to do before I wrote a hello world.

11:41 Chousuke: Lajla: Allowing arbitrary characters has also been considered.

11:41 Lajla: Chousuke, what were the arguments against?

11:41 Chousuke: Lajla: but since it has so far been a non-issue, it's not implemented

11:41 Lajla: I think in most lisps they say that arbitrary chars can make symbols, but there is just no reader synta for it.

11:42 Chousuke: no arguments, just that no-one has had a need for the feature.

11:42 Lajla: Chousuke, well, it seems to work so far, do you have a place where it might screw you up?

11:42 Chousuke: Lajla: the "screw up" is that symbols with whitespace in them are not readable

11:42 Lajla: Ahh

11:42 you mean writing and then reading?

11:43 Chousuke: ie, you can't do (read-str (pr-str weird-symbol))

11:43 Lajla: &(write (symbol "I worship your shadow"))

11:43 sexpbot: java.lang.Exception: Unable to resolve symbol: write in this context

11:43 Chousuke: and get weird-symbol

11:43 Lajla: Yeah.

11:43 Chousuke: ,(print (symbol "foo bar"))

11:43 clojurebot: foo bar

11:43 Lajla: Ahhh, print.

11:43 Chousuke: see the problem? :)

11:43 Lajla: Clojure makes no difference between write and print, like cl does?

11:43 Chousuke: I'm not sure what the difference is in CL

11:43 Lajla: Well, does clojure make the claim that reading back always gives the same as what you print?

11:44 Chousuke: no

11:44 there's pr

11:44 ,(pr "foo")

11:44 clojurebot: "foo"

11:44 Chousuke: ,(print "foo")

11:44 clojurebot: foo

11:44 Lajla: Well, basically write gives out the 'external repraesentation' and print accepts only strings and chars I think.

11:44 Ahh

11:44 then pr is write

11:44 But like

11:44 &(pr (fn [I-worship-your-shadow] (+ 3 I-worship-your-shadow)))

11:44 sexpbot: ⟹ #<sandbox6621$eval8180$fn__8181 sandbox6621$eval8180$fn__8181@110710>nil

11:45 Lajla: If I read that back in

11:45 do I ge the same function back?

11:45 Does it guarantee that in each case, you get the same thing back?

11:45 Chousuke: no

11:46 some things are not readable.

11:46 (#<foo>)

11:46 #< throws an error if you try to read it

11:46 Lajla: But does it guarantee it for symbols?

11:46 Chousuke: for legal symbols yes

11:47 Lajla: Hmm

11:48 And does the symbol function guarantee that ...

11:48 who am I kidding man

11:48 I'm talkinga bout a language which has no formal specs.

11:48 But a 'reference implemtnation'

11:48 There are no guarantees, carry on, carry on, every bug is a feature.

11:48 Chousuke: You need to be less theoretical :P

11:50 Lajla: That comes as no surprise from someone who believes in conceptual programming. =)

11:50 But hey, your Finnish is very good.

11:51 I just like to know these things before I start, I don't like to hack and slash around before I know exactly what mechanically is supposed to happen with my code.

11:51 And since Cloj has no specs, I'm just reverse-engineering it by using the bot.

11:51 Chousuke: My Finnish is good because I am Finnish :P

11:51 though on second thought, that is no guarantee

11:55 trybeingarun: hey guys

11:56 Do monads and continuations have any practical value or are they simply theory stuff?

11:56 I am having a headache trying to understand them.

11:59 anybody there?

11:59 Chousuke: sure they have applications

11:59 you can think of monads as an API

12:00 for composition

12:00 of operations

12:00 Lajla: Chousuke, do you have good finnish for a fin though?

12:00 High literary standard?

12:00 Chousuke: yes

12:00 Lajla: Hmm

12:00 clojure has monads and continuations?

12:00 How can continuations work if there is no TCO?

12:01 trybeingarun: Why do i need an API for compositions when i can write small wrapper code and use them for compositions

12:01 Lajla: Wouldn't that keep on infinitizing the stack frame.?

12:02 trybeingarun: Dudes, before u guys go into depths of these can anybody point me to any useful tutorial (beginner friendly) which won't punch a hole though my brain??

12:03 raek: trybeingarun: this is a Clojure + monads tutorial I know of: http://onclojure.com/2009/03/05/a-monad-tutorial-for-clojure-programmers-part-1/

12:04 I have never used monads in clojure so far myself, though

12:04 trybeingarun: hm

12:04 raek: oh wait... you wern't looking for a tutorial... sorry

12:05 trybeingarun: thanks raek. I will see how much I understand those concepts

12:05 no. in fact I was looking for a tutorial

12:05 raek: as for continuations, clojure does not have a call/cc

12:06 but the ring web framework uses a control technique that I think is a bit similar to CPS

12:06 trybeingarun: okay.

12:09 raek: a handler is a function that takes a request map and returns a response map. a middleware fn takes a handler function and returns a new function

12:09 the reurned function will most often proxy the request to the given handler, but might also do something else (like render an error message)

12:10 (defn some-middleware [handler] (fn [request] (if (valid-request request) (handler request) (render-some-error))))

12:10 trybeingarun: okay

12:10 notsonerdysunny: the swank-clojure I am using, which is 1.3.0-snapshot, to try out the 1.3.0-alpha3 seems to be having problems .. Is anybody else facing similar problems?

12:19 _ulises: afternoon gents

12:27 Lajla: raek, but how does that work without TCO?

12:27 I mean, obviousy loop/recur is a limit example of continuations, all languages have them, but when people say 'continuations', they generally mean 'fully general continuations'

12:27 limited

12:35 raek: Lajla: you can only have limited levels of nesting, due to the lack of TCO

12:36 Lajla: raek, but continuations are abstracted as ordinary functions, right?

12:36 CPS would fill the stack pretty fast.

12:37 I am a theorete and feel no shame!

12:40 raek: yes

12:43 Lajla: &(+ 1 "string")

12:43 sexpbot: java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Number

12:43 Lajla: Hmm

12:43 no "tring" like in C

12:43 &(+ "string" "string")

12:43 sexpbot: java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Number

12:43 Lajla: hmm

12:43 &(+ \a \b)

12:43 sexpbot: java.lang.ClassCastException: java.lang.Character cannot be cast to java.lang.Number

13:21 Lajla: Chousuke, can you cite me the part where it makes that reader / pr guarantee for legal symbols?

13:31 Chousuke, totele minua, sinä orjani.

13:32 mattmitchell: is there a library that will take a url/string and parse it out into fields like, host, path, query etc.?

13:33 technomancy: ,(bean (java.net.URL. "http://technomancy.us:80"))

13:33 clojurebot: java.lang.reflect.InvocationTargetException

13:33 technomancy: ಠ_ಠ

13:33 Raynes: (bean (java.net.URL. "http://technomancy.us:80"))

13:33 &(bean (java.net.URL. "http://technomancy.us:80"))

13:33 sexpbot: ⟹ {:path "", :protocol "http", :authority "technomancy.us:80", :host "technomancy.us", :ref nil, :content #<HttpInputStream sun.net.www.protocol.http.HttpURLConnection$HttpInputStream@9d4b24>, :class java.net.URL, :defaultPort 80, :port 80, :query nil, :file "", :userInfo nil}

13:33 technomancy: aha

13:34 Raynes: That's pretty cool.

13:34 Derander: I wish map but for hash-map values was in core

13:35 mattmitchell: wow awesome thanks!

13:35 technomancy: clojurebot: clearly you need to lighten up a bit.

13:35 clojurebot: 1

13:36 rata_: hi

13:36 which fns can give me a PersistentList when I give it a LazySeq?

13:37 Chousuke: Lajla: there is no such guarantee.

13:37 Lajla: except that if you don't use illegal symbols, you won't get any illegal symbols from pr/read either.

13:37 Lajla: the only way you can create an illegal symbol is manually by calling "symbol", so it's a non-issue

13:38 Raynes: &(type (into '() (lazy-seq [1 2 3])))

13:38 sexpbot: ⟹ clojure.lang.PersistentList

13:38 Raynes: That doesn't quite work like you might expect.

13:38 &(into '() (lazy-seq [1 2 3]))

13:38 sexpbot: ⟹ (3 2 1)

13:38 technomancy: rata_: you don't want just doall?

13:39 you shouldn't care about the class, just whether its contents have bene realized

13:39 *been

13:40 chouser: a PersistentList though is different than a seq. Knows its count, for instance.

13:40 & (apply list [1 2 3])

13:40 sexpbot: ⟹ (1 2 3)

13:40 technomancy: true

13:41 rata_: technomancy: the bottleneck of my program was a the function rand-nth, then I change to use it vectors for fast random-access, but now the bottleneck is vec :(

13:42 thearthur: where can I find out more about the new contrib modular structure (google is failing me)?

13:43 when i build from github i get a modules directory and am not sure what to add to classpath where in order ot use it

13:43 raek: rata_: if you are using lazy seqs, nothing will get computed until it is needed

13:43 Lajla: Chousuke, but where is that written?

13:44 raek: rata_: rand-nth or vec might be the first functions that need the values, and in the calls to them, the seq will be forced

13:44 Lajla: Missä se on kirjoitettu? =(

13:44 raek: rata_: you could try to add (doall ...) around each thing that returns a lazy-seq to see where the bottleneck really is

13:45 rata_: raek: I think it's easier to use visualvm to detect the bottleneck... it doesn't fail in saying that most of the time the program was computing vec or rand-nth

13:46 Chousuke: Lajla: nowhere, it's obvious

13:46 Lajla: the reader is not stupid, nor is pr :P

13:47 Lajla: though if you can find a way to get the reader to produce an illegal symbol, report that as a bug

13:49 Lajla: Chousuke, then where does it say that such symbols are illegal?

13:50 I mean, whence can you deduce that because the reader can't read them they are illegal.

13:50 rata_: Raynes: I'm not using (into '() ...)

13:50 Lajla: a lot of lisps explicitly state that various data do not have a reader syntax, but are still valid data.

13:50 rata_: do you know of any other fn that can return a PersistentList from a LazySeq?

13:51 Chousuke: Lajla: that's the definition of illegal :P

13:52 rather, the docs state what is legal

13:52 and everything else, even if it happens to work when you call symbol, is illegal.

13:52 raek: rata_: what would be the benefit of making a PersistentList from a LazySeq? constant time count?

13:52 Lajla: Chousuke, maybe the docs conflict

13:53 For instance, what do the docs say about the symbol? procedure

13:53 Chousuke: (doc symbol?)

13:53 clojurebot: "([x]); Return true if x is a Symbol"

13:53 Lajla: If the docs say at one hand that symbols cannot contain spaces, but at the other hand THAT THERE ABOVE

13:53 THen obviously the docs contradict itself.

13:53 rata_: raek: no... I don't want it to be converted... but somewhere in my code a fn is converting it

13:53 Chousuke: Symbol, not a symbol

13:53 Lajla: Ahh

13:53 Hmm

13:53 Chousuke: that means it returns true if it's an instance of the class.

13:53 Lajla: Ahhh

13:53 So Symbol and symbol are destinct?

13:53 chouser: raek: Did you see that (apply list a-seq) returns a PersistentList?

13:54 Lajla: So, symbol in fact returns a Symbol?

13:54 Chousuke: yes

13:54 Lajla: Ahhh

13:54 Chousuke: Lajla: in a way, because you can have instances of Symbol that represent illegal symbols

13:54 Lajla: I can live with that.

13:54 Chousuke: because there's no validation (yet)

13:54 Lajla: Fuck symbols

13:54 I like Symbols more.

13:54 chouser: rata_: sorry, that was for you not raek

13:54 Lajla: They can do more.

13:55 rata_: chouser: yes, but I'm not doing that either

13:55 chouser: rata_: how do you know you're getting a

13:55 PersistentList?

13:55 rata_: there's a function in my code that's converting my LazySeqs to PersistentLists

13:55 with class

13:56 raek: chouser: btw, is your extend-multimethod macro that you mentioned in your strange loop talk availabe somwhere?

13:56 chouser: raek: I'll look.

13:57 hm, is there a way to grep all versions of all files in a git repo?

13:59 rata_: I'm just using map, keep, conj and remove over my LazySeq afaik, yet I get a PersistentList

14:00 raek: conj will preserve the type, the other will produce lazy-seqs, IIRC

14:00 chouser: conj on a lazy-seq returns a Cons

14:01 rata_: yes, but Cons is not PersistentList

14:01 this conversion thing is so weird

14:04 raek: chouser: don't worry if you don't find it. i just thought it was an interesting idea, and I think it would be pretty easy to write myself

14:04 Chousuke: chouser: git has a grep command I think.

14:04 chouser: maybe you can use that?

14:06 Lajla: &(pr (symbol "I worship His Shadow"))

14:06 sexpbot: ⟹ I worship His Shadownil

14:06 Lajla: nil

14:06 ?

14:06 Ohhhh

14:06 return value.

14:06 You sort of would want like nil on failure or something.

14:06 Or like

14:06 nil on success, and some error message on failure.

14:06 Yeah, that'd work too.

14:12 &nil

14:12 sexpbot: ⟹ nil

14:12 Lajla: (symbol? 'nil)

14:13 &(read-str (pr-str (symbol "nil")))

14:13 sexpbot: java.lang.Exception: Unable to resolve symbol: read-str in this context

14:13 Lajla: Hmm...

14:13 Chousuke, what'sthe name?

14:15 raek: read-string

14:15 hrm. that's a bit asymmetric

14:22 Lajla: &(read-string (pr-str (symbol "nil")))

14:22 sexpbot: ⟹ nil

14:22 Lajla: &(symbol? (read-string (pr-str (symbol "nil"))))

14:22 sexpbot: ⟹ false

14:23 Lajla: raek, =(

14:23 It is true

14:23 raek, let's talk about our love.

14:25 tonyl: pr-str returns a string not a Symbol

14:25 wait scratch that

14:26 nil is not a Symbol :P it's a value

14:27 Chousuke: nil is null

14:27 tonyl: yeah

14:27 Chousuke: it's not a symbol at all

14:27 'nil is nil too

14:27 still not a symbol :)

14:28 jackdempsey: chouser: making my way through the joy of clojure. great stuff!

14:29 Chousuke: When was the dead-tree version supposed to be ready?

14:29 Raynes: I still haven't finished that book.

14:30 jackdempsey: yea, it's been a nice progression from programming clojure to practical clojure, and now some joy

14:31 i need to stop reading and code something tho :-)

14:31 anyone around SF and going to the meetup in a few weeks?

14:31 Lajla: tonyl, that was the point

14:31 But (symbol "nil") is a symbol

14:31 &(symbol? (symbol "nil"))

14:31 sexpbot: ⟹ true

14:31 Lajla: Well, evaluates to

14:31 technically it's a list

14:34 Chousuke, what is the environment that eval uses though?

14:34 Just the top level?

14:34 &(eval '(and 1 2 3 4))

14:34 sexpbot: java.lang.SecurityException: You tripped the alarm! eval is bad!1

14:34 Lajla: Hmm

14:35 Interestng

14:36 chouser: jackdempsey: thanks!

14:36 today I'm updating the lazy qsort code -- cgrand improved it.

14:37 Chousuke: Lajla: yeah

14:37 Lajla: Chousuke, does it also expand macros?

14:37 And can you give it an environment argument?

14:37 chouser: Chousuke: Hopefully January or before for the book

14:37 Chousuke: Lajla: yes?

14:37 Lajla: no env arg

14:38 chouser: ok

14:38 Lajla: =(

14:38 I want you as my environment baby

14:38 If you get what I mean

14:38 Chousuke: :P

14:39 Lajla: Chousuke, I wasn't talking to you

14:39 I was talking to myself.

14:39 Narc

14:39 You're so full of yourself.

14:39 tonyl: (symbol "nil") is a Symbol but once you pass it to pr-str it becomes a string "nil" which read-string evaluates to nil

14:40 jackdempsey: chouser: is there a site setup to report typos and such?

14:40 chouser: jackdempsey: yes, the Manning forums. But if I were you don't know that I'd bother right now.

14:41 jackdempsey: chouser: ok...? :-)

14:41 chouser: The version you can get is a bit out of date regarding typo fixes and stuff -- that's mainly what we're doing right now

14:41 jackdempsey: given they're probably all....yea

14:41 k

14:41 chouser: the opportunity to contribute in that way has essentially passed

14:42 jackdempsey: cool

14:42 chouser: when then "final" version is out in a couple months here, we can start collecting errata for subsequent versions. :-P

14:42 apgwoz2: does clojars not allow you to change your password/key?

14:42 jackdempsey: thx btw for writing something beyond a beginning/primer. its hard to get deeper into newer languages at times, so the pace and depth of getting into things has been great

14:42 cool

14:42 chouser: but hopefully anything you're finding now has already been fixed

14:43 jackdempsey: yea i'd imagine so

14:43 Chousuke: damn ustream. Causes Flash to gobble gigabytes of memory :/

14:43 chouser: jackdempsey: thanks, glad you're enjoying it.

14:43 Chousuke: I just closed firefox and Freed 2GB :P

14:43 apgwoz2: i should rephrase my question, is clojars currently broken when it comes to editing password/public key?

14:55 dnolen: apgwoz2: it seemed to be working last time I had to do that.

14:56 apgwoz2: dnolen: hmmm. i'm getting an error for both email address and password not being set... but even when they're not.

14:56 oh well

14:56 in lieu of just publishing to clojars, what's the best way to depend on another library with leiningen?

14:56 dnolen: apgwoz2: lein install

14:57 apgwoz2: just get a checkout of the library source, and run lein install from it's dir

14:58 apgwoz2: ah, ok. and then just add it as a dependency?

14:58 dnolen: apgwoz2: yup

14:58 apgwoz2: easy enough

14:58 thanks

14:59 shafiahmedbd: Hi

15:02 Do you know of any clojure web scraper?

15:02 apgwoz2: shafiahmedbd: checkout tag soup

15:03 shafiahmedbd: Thanks

15:03 apgwoz2: there's also https://github.com/brool/beaujiful-soup, which is a more clojure like lib for using tag soup

15:05 bobo_: shafiahmedbd: enlive can be used for scraping aswell

15:07 Lajla: tonyl, sure, but were were testing that.

15:07 Maybe a reader syntax like |nil| would be nice.

15:07 Tell Rich to add it.

15:07 I will hug you all day long.

15:13 raek: shafiahmedbd: enlive even uses tagsoup under the hood

15:14 dnolen: shafiahmedbd: enlive is probably best for easiest scraping, you can pull out elements with CSS3 syntax.

15:15 Lajla: &(eval 3)

15:15 sexpbot: java.lang.SecurityException: You tripped the alarm! eval is bad!1

15:15 dnolen: CSS3-like, with some interesting additions

15:15 Lajla: How can I get eval to work?

15:15 raek: Lajla: java -jar clojure.jar on your own computer

15:16 Lajla: =(

15:16 But I wamnt to steal your cycles.

15:16 I don't have the JVM installed right now.

15:27 mattmitchell: in ruby, you can do something like: my_hash[:key] ||= [] -- which sets :key to a new array if :key is nil, is there something like this in clojure?

15:30 Lajla: mattmitchell, if there isn't, you can write a macro I guess.

15:31 But I guess it will more be like

15:31 raek: mattmitchell: (assoc m (get m key []))

15:31 Lajla: returning nil if it's not nil, and already exists.

15:31 And return the updated, if it didn't already exist.

15:32 raek: (assoc m key (get m key []))

15:32 some had a neat example using update-in and fnil

15:33 mattmitchell: excellent thanks

15:34 would someone mind taking a stab at this? https://gist.github.com/708130

15:34 i'm messing with reduce now, just trying to learn how it works. i think reduce is the right way?

15:35 raek: I guess you could use merge-with in this case

15:36 ,(merge-with concat {:id 1, :f ["a"]} {:id 1, :f ["b"]})

15:36 clojurebot: java.lang.IllegalArgumentException: Don't know how to create ISeq from: java.lang.Integer

15:36 raek: oh, sorry

15:37 hrm

15:37 mattmitchell: don't be, merge-with is something i'm looking into now

15:38 raek: it would work if you had the data on the form {1 ["a"]} {1 ["b"]}

15:39 mattmitchell: raek: i see

15:40 dnolen: ,(merge-with concat {1 "a"} {1 "b"} {2 "c"})

15:40 clojurebot: {2 "c", 1 (\a \b)}

15:41 dnolen: ,(let [f (fn [a b] (if (vector? a) (conj a b) (conj [a] b)))] (merge-with f {1 "a"} {1 "b"} {2 "c"}))

15:41 clojurebot: {2 "c", 1 ["a" "b"]}

15:44 mattmitchell: dnolen: thanks, i'll have a play with that

15:44 raek: ,(reduce (fn [m [id f]] (assoc m id (conj (get m id []) f))) {} [[1 "a"] [1 "b"] [2 "c"]])

15:44 clojurebot: {2 ["c"], 1 ["a" "b"]}

15:45 raek: ,(reduce (fn [m {:keys [id f]}] (assoc m id (conj (get m id []) f))) {} [{:id 1, :f"a"} {:id 1, :f "b"} {:id 2, :f"c"}])

15:45 clojurebot: {2 ["c"], 1 ["a" "b"]}

15:47 raek: ,(map (fn [[id fs]] {:id id, :f (vec fs)}) (reduce (fn [m {:keys [id f]}] (assoc m id (conj (get m id []) f))) {} [{:id 1, :f"a"} {:id 1, :f "b"} {:id 2, :f"c"}]))

15:47 clojurebot: ({:id 2, :f ["c"]} {:id 1, :f ["a" "b"]})

15:47 raek: there. :)

15:47 dnolen: nice

15:48 raek: I would prefer using for here, but it gets messy do edit code of this length in one line...

15:48 mattmitchell: nice! that's a full days study lesson for me.

15:48 raek: (for [[id fs] result-of-reduce] {:id id, :f (vec fs)})

16:08 hrm, the order doesn't matter, you could replace the (assoc m id (conj (get m id []) f)) part, with (update-in m [id] conj f), since nil (the default value for get) work as () with conj

16:09 mattmitchell: raek: ok i'll try that. now what if I had hash-maps that had lots of keys, but I only wanted to append the :f key into a vector, but keep the rest?

16:09 raek: for a little background... this is a sql result set, using joins

16:13 raek: mattmitchell: how should {:id 1, :f "a", :x "y"} and {:id 1, :f "b", :x "z"} be merged?

16:13 mattmitchell: raek: oh they will always be the same values

16:13 raek: mattmitchell: also, have you checked out the new version of ClojureQL?

16:13 mattmitchell: raek: no, only using the clojure.contrib.sql

16:14 raek: i'll check out ClojureQL

16:14 raek: http://bestinclass.dk/index.clj/2010/11/clojureql--1.0.0-now-in-beta.html

16:15 mattmitchell: that's looking good :)

16:23 Lajla: raek,

16:23 if I paid you handsomely

16:23 would you write a formal spec of clojure?

16:23 That answers all my problems

17:31 Chousuke, why aren't you in casual?

17:31 We miss you.

17:31 We're talking about you're high literary standard now.

17:45 Chousuke: Lajla: your :P

17:45 Lajla: Chousuke, that is because mine is bad. =(

17:45 hippiehunter: Can someone point me in the right direction? I'm trying to define and throw an exception, but clojure complains that it cant find the class. I'm using lein and I've tried setting the exception classes to be aot compiled but without any luck.

17:51 raek: hippiehunter: has the .class file appeared in the classes/ directory?

17:52 hippiehunter: yes

17:52 raek: have you imported it in the clojure code?

17:53 hippiehunter: i have (:use [bla.bla myexception])

17:53 in my ns

17:53 raek: (although, that shouldn't be needed, if you use the fully qualified name)

17:53 ah, since it's a java class and not a var in a namespace, you have to :import it

17:53 (:import bla.bla.myexception)

17:54 (assuming "myexception" is the name of the generated class)

17:54 i.e. you should have a classes/bla/bla/myexception.class file

17:54 hippiehunter: now it just complains at the :import instead of where i try to instance it

17:54 hiredman: hippiehunter: the problem is the clojure code that throws the exception is being compiled before the code that generates the exception

17:55 you can use clojure.lang.Reflect (Relector?) to get around it

17:55 hippiehunter: in my project.clj I put the exception classes first in the aot list

17:55 an based on the output to the console its making them first

17:55 and*

17:55 Raynes: Reflector is right

17:59 hippiehunter: when i do an import do i have to replace the -'s with _'s?

18:00 looks like yes

18:01 that is mildly unpleasant

18:05 hiredman: you can't have - in a java class name

18:07 hippiehunter: it seems inconsistant that i can define things with - in clojure but depending on how i use them it might not work

18:08 hiredman: if you define something for java interop (a java class) you have to follow java rules

18:10 hippiehunter: I would agree with you but then it should be throwing an error at definition time when i do the :gen-class

18:11 or possibly when I do (:import [bla.bla my-exception-with-dashes])

18:12 well i suppose it is throwing an error on the import its just not a very helpfull one, anyway thanks for the assistance

18:24 harishtella: anyone know why I can't use "." as the function in map? (map . (repeat 2 javaclass) '(javafn javafn))

18:25 Raynes: Because '.' is a special form.

18:25 Special forms and macros cannot be used in places where functions can, like as the argument to map.

18:25 harishtella: any other way to collect results from calling function on a java obj

18:25 different functions

18:28 raek: instead of (map .method sequence-of-objects) you have to write (map #(.method %) sequence-of-objects)

18:28 i.e. create an anonymous function that does the interop call

18:30 harishtella: oh got it, thanks

18:46 hiredman: . is not a function, thats why you can't use it as one

18:47 harishtella: anyway a can eval a set of symbols without applying the first symbol as function rule (foo bar) ; where foo and bar are strings

18:47 I want a seq of strings

18:49 raek: if you want to evaluate an expression that is given in string form, you could do something like (eval (read-stirng the-string))

18:50 but if you are writing a code-evaluating bot or something, you should use a sandbox lib (like clojail)

18:51 harishtella: could you give an example of what your input look like, and what you want to get called?

18:55 harishtella: I should just ask my real question I trying to figure out;

18:56 (def foo "Green") (map #(. foo %) '(toUpperCase toLowerCase))

18:56 and say I want a list back like ("GREEN" "green")

20:07 ossareh: is anyone able to explain why my meta data :foo exists sometimes and not others? https://gist.github.com/708322

20:08 clj 1.2 fwiw

20:10 raek: to attach metadata, either do (defn ^{...} foo "docs" ...) or (defn foo "docs" {...} ...)

20:10 not the lack of ^ in the latter case

20:10 strange behaviour, though...

20:10 technomancy: does anyone use the lein interactive task?

20:12 well, if you do, try the latest git master; it's a lot nicer.

20:13 ossareh: so I guess in the case where I have no "docs" (the fn is super simple and the name describes it accurately) I have to do the ^{} version ?

20:13 technomancy: I'll take a look - I'm not sure if I'm ready for a major upgrade though

20:14 last time I did that I lost a fair amount of time :/ (1.1 -> 1.2)

20:14 technomancy: ossareh: you can keep 1.3.1 around for regular use; it's easy to just experiment with both in parallel

20:14 ossareh: I'm on 1.2

20:14 technomancy: right; you don't need to replace what you have is what I mean

20:14 ossareh: ... partly because that is what lein gives me ;)

20:15 technomancy: oh, clojure 1.2?

20:15 yeah, you can use lein with any clojure version, no upheval required

20:16 ossareh: yup, am aware of that - I'll give 1.3 a shot in the morning - right now I can just leave my meta data angle out

20:17 raek: same flakiness https://gist.github.com/708322

20:52 talios: 'lo

20:53 ossareh: what is the recommended way to get clojure mode into emacs these days? I last used elpa

21:17 devinus: will clojure begin to implement more basic core functions for e.g. parsing integers and such as part of it's transition to clojure in clojure ?

21:19 Lajla: devinus, that is your burning issue with a langauge that does not yet support TCO?

21:19 I'm so going to tell chousuke, and then he'll eat you. n.n

21:19 And I will win

21:20 Chousuke: devinus: probably not until there's a real need for it.

21:21 Lajla: and you need to stop being so annoying :P

21:23 devinus: Chousuke: there was a blog post i read, i think it was coder who says py, on his thoughts on clojure i've gotta agree with. i don't care at all that it uses the jvm, i just hate how much it seems you use the jdk

21:23 need a cdk :P

21:24 Lajla: java digit ... konvention?

21:24 What does the k stand for?

21:24 devinus, you wil answer this quaestion, which since the dawn of times has been etched upon my mind.

21:24 For long I searched the answers which I need, so that I may give purpose to my own existence.

21:25 I journeyed long across the stars, bore witness to the rise and fall of many a civilization, beheld the birth of negative suns.

21:25 Chousuke: You're being stupid on purpose.

21:25 please just stop.

21:25 Lajla: I just want ot know what jdk stands for. =(

21:26 Chousuke: google it :P

21:26 devinus: Writing wrappers for the jdk is not very productive.

21:26 hiredman: Chousuke: you can put him on ignore, I have, and I have clojurebot ignoring him, it's great

21:27 Chousuke: devinus: but if there's a real need for such a library I'm sure it'll get written :)

21:27 devinus: Chousuke: sure, it'd feel pretty tedious

21:27 Chousuke: But now I need to get some sleep :P

21:27 devinus: gnight

21:28 Chousuke: Also, I wish the ustream flash player wasn't so horrible.

21:28 it gobbled up 2.5GB of memory and now my system feels like it's going through tar while everything is fetched from swap into memory again

21:29 It must be doing something idiotic like caching the whole stream in memory or something

21:29 because it never stops growing.

21:29 anyway, good night :P

21:46 krumholt: at what time will calls to java static methods evaluated?

21:46 +be

21:55 where can i find the source code for the dot macro?

21:55 hiredman: not a macro

21:56 Raynes: krumholt: It's a special-form, of which you cannot find the source. The implementation would be in Java.

21:56 krumholt: Raynes, and can i find the java code somewhere?

21:57 Raynes: Sure, but I have no clue where. :\

21:57 hiredman: it's a special form so it is implemented in the compiler

21:57 Raynes: Right, the compiler.

21:58 krumholt: ok thanks

21:59 Raynes: krumholt: All of the Java stuff is here: https://github.com/clojure/clojure/tree/master/src/jvm/

22:01 paulrosania: https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/Compiler.java

22:01 L692

22:01 Good luck :)

22:05 Raynes: My eyes!

22:06 paulrosania: there's a lot of commented-out code in there

22:22 ossareh: zz... 1.3.0-alpha3 returns nil on (meta some-fn-with-md)

22:22 previously it would at least return :doc , :file, etc.

22:34 OK, fixed - I was not prefixing my fn with #' - i.e. (meta #'some-fn-with-md)

22:49 krumholt: ok i found my problem

22:49 macroexpand will create static fields?

22:50 so if a class has static fields they will be created at macroexpansion time?

22:50 hiredman: nope

22:52 joeyd81: hi, in which clojure channel should beginners go?

22:53 krumholt: ok import creates static fields?

22:53 hiredman: no

22:54 krumholt: hiredman, i wrote a simple testclass http://pastebin.com/t9QLtfQp

22:54 technomancy: joeyd81: here is fine

22:54 hiredman: krumholt: good for you

22:54 krumholt: evaluating (ns myns (:import Test)) will print output to the repl

22:55 the string "output"

22:55 or "Test"

22:56 hiredman: that is not "creating" the static field, that is initializing, I suggest you google "static field initialization"

22:56 krumholt: ok so import initializes the static fields?

22:57 hiredman: no

22:57 which is why I suggested you google and read

22:57 technomancy: ah static; a perfect "you keep using that word; I do not think it means what you think it means" example.

23:04 krumholt: ok, so evaluation (ns myns (:import blub.Test)) will create the static fields of Test?

23:04 i was not expecting that

23:04 hiredman: it does not

23:04 krumholt: i just tried

23:05 hiredman: that is not "creating" the static field, that is initializing

23:05 krumholt: ok it initizlises them. still not what i expected

23:06 hiredman: well, then you don't know anything about the jvm

23:07 krumholt: if i import something in java that will not initialise the static fields. the first creation of an object will

23:09 or a static method call

23:13 joeyd81: Hi, I am a beginner trying to learn clojure by writing simple programs, for example all permutations of a collection. Can somebody tell me where I am going wrong in function "permute" on http://pastebin.com/LCSR3nwM

23:14 technomancy: joeyd81: first thought: each defn should be independent at the top-level, not nested

23:15 joeyd81: the formatting of the code makes it hard to follow

23:16 inside my-fun you should use destructuring instead of let-binding first and rest explicitly

23:17 flat1 and my-fun would be easier to test if they were top-level defuns as well; perhaps private ones

23:17 you probably want apply concat instead of just concat on line 33

23:17 is that enough? =))

23:18 joeyd81: thanks for the feedback, I will study it, can you just clarify what you mean by " should use destructuring instead of let-binding..."

23:19 technomancy: sure. (let [[f & rst] param] ...) is the same as (let [f (first param), rst (rest param)] ...)

23:20 joeyd81: ok, cool thanks, I will be back here to seek help if I can't make progress by noon tomorrow, good night folks

23:20 technomancy: joeyd81: it will be easier to debug if you write and test the smaller functions first

23:21 and then compase them into larger pieces once you know they work

23:21 *compose

23:21 joeyd81: I usually do that in the repl

23:21 technomancy: sure; I just mean make sure the little pieces work before bothering to stitch them together

23:28 tramzee: exit

23:28 exit

23:28 quit

23:33 krumholt: ok i found my problem. The RT looks up classes in the classForName method with Class.forName(name, true, baseLoader()) which will initialise the class. is there a reason this is done for import expressions?

Logging service provided by n01se.net