#clojure log - Apr 01 2010

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

0:00 hiredman: tela: delay is the same, but synchronous

0:02 tela: I'm trying to evaluate a tree structure where each node is a stochastic function of the children. The children might be shared sometimes, though, and I want to only run the shared children once even if two evaluation paths simultaneously request it. The tree gets evaluated over and over though so delay is worrisome. I'll have to try it out though.

0:02 hiredman: I don't think you understand delay

0:03 ,(let [a (delay (println :foo) 1)] [@a @a])

0:03 clojurebot: [1 1]

0:03 :foo

0:05 tela: yes, but I want to be able to call @a later and have it redo the computation. I'm thinking I'll just have to keep a step counter and generate a new delay if the step isn't in uptodate.

0:07 hiredman, but yes, I think those are the semantics I was looking for. Thanks :)

0:36 Crowb4r: heh, youtube aprilfools jokes you never get old

0:37 shadowspar: I only wish this was real; I wouldn't have to make 4 trips for coffee every morning =) http://bit.ly/Plenta

0:37 cp2: heh

0:39 alexyk: how do you efficiently supply the f to merge-with here instead of conj:

0:39 , (merge-with conj {:a 1 :b 2} {:a 2 :c 3})

0:39 clojurebot: java.lang.ClassCastException: java.lang.Integer cannot be cast to clojure.lang.IPersistentCollection

0:40 alexyk: to achieve {:a [1 2] :b [2] :c [3]}

0:44 tela: alexyk, best I can do would be #(if (seq? %1) (conj %1 %2) (list %1 %2))

0:44 alexyk: yeah, seems like we'll have to check type always

0:45 noidi: ,(seq? [])

0:45 clojurebot: false

0:46 noidi: so you might want to use coll? instead

0:46 alexyk: I want a vector anyways

0:46 noidi: I have this in my util.clj

0:46 (defn ensure-coll [x] (cond (coll? x) x (nil? x) [] :default [x]))

0:48 cheezey: so uhh.. im new to this. does clojure have pattern matching of some sort? O_o

0:48 tela: noidi, yeah, that's a good one to keep around

0:48 noidi: cheezey, not built-in, but there are libraries for that

0:51 tela: cheezey, well, there's some built in on sequences

0:51 alexyk: noidi: thx

0:51 tomoj: hmm

0:51 we can do this more efficiently I think

0:51 alexyk: tomoj: how?

0:51 defn: how do I do a println but suppress nil?

0:52 tela: ,(let [[x [a & os]] (list 10 (range 3))] (* x (+ a (apply / os))))

0:52 clojurebot: 5

0:52 tomoj: fmap over the Maybe monad?

0:52 defn: ^ ;)

0:52 defn: heh

0:53 for some reason i remember there being a println which suppressed newline

0:53 i can always just write my own i guess

0:53 err not suppressed newline, but didn't return nil

0:54 maybe im thinking of something i read in stuart's book...

0:54 hiredman: ,(doto :x prn)

0:54 clojurebot: :x

0:54 :x

0:56 noidi: defn, what do you want to return, if not nil

0:56 defn: nothing, i just want it to be blank

0:56 so i get a println, but no nil at the end

0:56 is that possible?

0:56 noidi: nil is the blank return value :)

0:56 you only see it in the REPL because it prints all return values

0:56 defn: yeah nvm, im reading the source and yes that makes sense

0:57 thanks noidi && hiredman

0:58 tela: alexyk, if you know the keys how about

0:58 ,(merge-with conj {:a () :b () :c ()} {:a 1 :b 2} {:a 3 :c 1} {:a 5 :b 3})

0:58 clojurebot: {:a (5 3 1), :b (3 2), :c (1)}

0:58 noidi: but you are right, it would make sense for the REPL to not print nil return values

0:58 or nil's at all

0:58 defn: im just building this thing: http://github.com/defn/walton

0:58 noidi: that's what Python's REPL does, and I don't remember it ever causing any trouble

0:58 defn: and id like to print an example without the trailing nil, it just looks better

0:59 tomoj: tela: genius!

0:59 noidi: maybe you could write your own read-eval-print loop?

1:00 tomoj: oh, but you have to know the keys

1:00 hrmm

1:00 maybe you could make an Associative that always gave ()

1:00 tela: tomoj, I'm trying to find a way to have (constantly nil) fit the associative interface

1:00 tomoj: and use that as a starting point

1:00 with deftype I was thinking

1:01 tela: hm, deftype I have not touched

1:01 alexyk: tomoj: simple, we prepend a map like the first with []'s

1:01 tomoj: but the first might not have all the keys

1:01 alexyk: yeah... argh

1:05 tomoj: noidi: well, my try was (defn ensure-coll [x] (case (empty x) (()) x [x])) but this turns out over twice as slow

1:07 also doesn't work with sets

1:08 tela: ,(merge-with conj {:a #{} :b #{} :c #{}} {:a 1 :b 2} {:a 3 :c 1} {:a 5 :b 3})

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

1:08 tela: haha

1:09 tomoj: so what you need is a generator for constant assocatives

1:09 tela: or just bakedin defaulting, a la Ruby (iirc)

1:11 tomoj: https://www.assembla.com/spaces/clojure/tickets/231-deftype-cons-doesn-t-support-maps-

1:11 tela: tomoj, wait, no. A generator wouldn't work because it would still have to know the names of all the keys that will be visited to prime the pump. Really just need a conj that wraps atoms if it's called on one.

1:12 tomoj: no, that's what I'm saying

1:12 the generator will give you something that acts like an Associative but returns the constant no matter what you give it

1:12 e.g. (get (the-generator []) x) will always return [] no matter what x is

1:13 but it looks like that bug prevents you from doing this with a deftype

1:13 tela: yeah, but the way merge-with works it'll think the generator is empty and not start off the reduction with the empty sequences. You still need to know all the keys upfront.

1:13 tomoj: it was set to "Approval" like yesterday

1:13 no, you don't

1:14 hmm

1:14 there is a problem, though

1:14 tela: ,(merge-with conj {:a ()} {:a 1 :b 2})

1:14 clojurebot: {:b 2, :a (1)}

1:15 tomoj: right

1:15 but it won't be {:a ()}

1:15 tela: exactly

1:15 tomoj: it'll be a deftype which always returns ()

1:15 so when it's asked what it's value for the key :b is, it'll return ()

1:15 tela: what does (keys <generator>) return though?

1:15 tomoj: some bogus value

1:16 the problem is that when conj does support deftypes, it probably won't mysteriously change the deftype into a hashmap

1:18 actually, why can't we just implement cons in IPersistentCollection and have it return a hash-map?

1:18 tela: tomoj, no, no, I don't think so. Even given a generator that behaves the way we're thinking, unless the generator can provide a decent respose to (first <generator>) it won't work. That's the problem I see. You can't reduce over this generator.

1:19 tomoj: you don't need to reduce over it

1:19 you only need to reduce over the maps you pass to merge, the first of which being the generator

1:19 merge only calls conj on the generator

1:20 tela: tomoj, ugh, I read it backwards. You're right.

1:21 tomoj: hmm, wait, I don't have my head on straight

1:21 (partial merge) is not (partial merge-with conj)

1:24 miltondsilva: any ideias how to condense this? [(.nextFloat s) (.nextFloat s) (.nextFloat s)]

1:24 tela: ,(merge-with conj {:a ()} {:a 1 :b 2})

1:24 clojurebot: {:b 2, :a (1)}

1:24 tela: tomoj, that's the clincher: the first hash doesn't "know about" b so it doesn't get wrapped.

1:25 tomoj: miltondsilva: (take 3 (repeatedly #(.nextFloat s)))

1:25 tela: you're not being liberal enough

1:25 this is a deftype

1:25 it can do whatever the hell it wants

1:25 it can say it contains every key

1:27 miltondsilva: tomoj: thanks.. I was using repeat.. (of course it wasn't working)

1:29 tela: tomoj, okay, yeah, it only needs to define [contains? (constantly true) get (constantly nil)]]. I need to not do this so late at night.

1:30 cp2: alexyk: not sure if this is still relevant, but

1:30 ,(reduce (fn [m [k v]] (assoc m k (conj (m k []) v))) {} [[:a 1] [:a 2] [:b 1] [:b 7]])

1:30 clojurebot: {:b [1 7], :a [1 2]}

1:30 cp2: might be of use to you

1:31 im sure i ripped that off of chouser or someone =P

1:34 tomoj: hmm, I've never been around when Peer reset my connection before

1:35 alexyk: cp2: interesting

1:36 tomoj: tela: you were right

1:36 there's a problem

1:37 (merge-with conj (ConstantAss []) {:a 1 :b 2} {:c 4 :d 3})

1:37 {:d 3, :c 4, :b 2, :a [1]}

1:38 oh, and if there's a duplicate key, it just explodes

1:38 haha, check this out

1:38 ,(merge-with conj {:a [] :a 3})

1:38 clojurebot: {:a [], :a 3}

1:39 tomoj: ,(merge-with conj nil {:a [] :a 3})

1:39 clojurebot: {:a [3]}

1:39 cp2: hehe

1:39 tomoj: ,(merge-with + {:x 1} {:y 1 :y 2 :y 3})

1:39 clojurebot: {:y 6, :x 1}

1:40 cp2: alexyk: i have a gift for you :D

1:40 hiredman: ,(doc merge-with)

1:40 clojurebot: "([f & maps]); Returns a map that consists of the rest of the maps conj-ed onto the first. If a key occurs in more than one map, the mapping(s) from the latter (left-to-right) will be combined with the mapping in the result by calling (f val-in-result val-in-latter)."

1:41 cp2: alexyk: http://gist.github.com/351421

1:41 forgive me, it's pretty nasty

1:41 =P

1:42 alexyk: oy

1:42 hiredman: what are you implying?

1:43 tomoj: to get this generator to work, it needs to stay around until the end

1:43 so you'd need to also have a function to convert back to normal

1:44 otherwise you will still have its weird behavior at the end

1:44 but it can build up an internal hash-map which it always checks and returns the constant if the internal map doesn't contain a key

1:45 then the function just pulls that internal hash-map out

1:46 hmm.. I have a 'scratch' project for miscellaneous stuff, so this namespace is scratch.constant-ass

1:46 hiredman: the behavior of map literals with duplicate keys is undefined, so what you are seeing is that undefined behavior contaminate everything it passes through

1:47 tomoj: yeah

1:47 I'm fine with that since it's only literals..

1:47 just funny

1:47 hiredman: so don't use map literals with duplicate keys

1:47 it's annoying

1:47 arraymap should really throw an exception

1:48 tomoj: yeah, and that would be fine since it's never going to happen after you've verified the program works

1:48 unless you're dynamically evaling some code which contains a bad literal map

1:49 but it would be like a compiler error

1:54 oh shit

1:55 I just realized that NEAT historical markings can just go into metadata in clojure

1:55 maybe they're not meta enough

2:12 miltondsilva: will clojure in clojure help with the cryptic java msgs?

2:19 defn: Anyone have any suggestions for an arg parsing library?

2:19 tomoj: hmm

2:19 Raynes: defn: Make it parse arguments. ;P

2:19 tomoj: if you find something, let me know

2:19 defn: I mean it's not totally needed

2:19 but something more robust would be nice

2:19 tomoj: how hard is arg parsing, anyway?

2:20 defn: not very...

2:20 but there are some fancier things i think one could do to make things a bit more clean and sane

2:20 tomoj: I gots an idea

2:22 defn: staying up late?

2:23 defn: tomoj: ill be here for oh, another... 6-7 hours

2:23 tomoj: what's your idea?

2:24 tomoj: it's actually sortof an idea I've had for a while now

2:24 but your mention of option parsing made something click in my head

2:24 defn: do tell! :)

2:24 you can PM me if youd like

2:24 tomoj: hmm

2:25 the original idea was just to automatically generate developer tools from clojure code

2:25 defn: "generate"?

2:26 like what sort of tools

2:26 tomoj: just write plain clojure functions, or maybe use some macros, and you get a tool

2:26 the original idea was irb like consoles

2:26 in which, of course, you'd have access to a full clojure repl

2:27 but option parsing makes me think of generating command line tools

2:28 if you look at the example from http://docs.python.org/library/optparse.html

2:28 omakase: how do i cast a string to an int/long?

2:28 tomoj: who really gives a fuck which letter is picked for the option

2:28 we can just use the argument names to the function

2:29 only need a way to provide defaults and documentation, perhaps with a special syntax in the docstring

2:29 or metadata maybe? dunno

2:29 Raynes: defn: Licenser is making me make a Walton plugin, which in turn means I had to look at Walton. Cool stuff, bro. :D

2:29 Walton plugin for my bot, even.

2:29 tomoj: walton?

2:30 googling seems futile

2:30 TheBusby: Omakase: Integer.parseInt I think

2:30 Raynes: http://github.com/defn/walton

2:30 defn: http://github.com/defn/walton

2:30 oops

2:30 tomoj: ah

2:30 defn: Raynes: Yeah I'm excited to get it into a bot

2:30 the latest version should be a lot closer to "working"

2:30 although it is still a bit shaky at times

2:30 Raynes: ,(Integer/parseInt "3")

2:30 clojurebot: 3

2:30 Raynes: omakase:

2:30 tomoj: that is a great idea

2:31 defn: Licenser has done a ton to help me get it working how I wanted it to. It's slowly getting there I guess.

2:31 Raynes: omakase: Also, there is read-string, but it reads /anything/.

2:31 ,(read-string "3")

2:31 clojurebot: 3

2:31 TheBusby: would be great if that got added to core somewhere. Kind of strange to have to go out to java just to transform an a string into an int value

2:31 Raynes: ,(read-string "{:a 3}")

2:31 clojurebot: {:a 3}

2:32 Raynes: TheBusby: No, it's not strange. Direct interop with Java is idiomatic.

2:32 defn: Raynes: I was thinking about a couple things for bot integration... 1.) Have the bot point to examples which exist on the website I'd like to generate using the current data. 2.) Have the bot intelligently give examples in a PM, since sometimes they can be very bad examples, even though they work in the sandbox.

2:33 Raynes: defn: I need to take off, but I'll read that in a few hours.

2:33 tomoj: Raynes: what bot are you using?

2:33 defn: Raynes: Licenser had a great idea wherein the bot would actually parse new sexps as they come in, reducing all of the extra up front processing.

2:34 tomoj: well, you still have to do up front processing to get at the history, don't you?

2:34 just the running bot doesn't have to go fetch logs?

2:35 TheBusby: Raynes: java interop isn't necessarily appreciated for such simple operations though. It implies you can't use clojure without knowing java first.

2:37 defn: tomoj: what happens is that the sexps which run in the sandbox are tagged as :good, and the ones that dont are tagged as :bad in a ref

2:38 tomoj: there's a cool addition today to walton where you can (background-init-walton), which parses and runs the sexps in the background, so you can search almost immediately

2:39 tomoj: it would be ideal if the bot could just continue to add to the ref as the channel moves on

2:39 perhaps serialize a daily snapshot or something?

2:40 btw, does anyone have good #clojure irc logs? I'm missing some days, from 03-09 to 03-16

2:41 tomoj: defn: ah, I see

2:41 defn: im sure chouser does, but id like to setup a crontask to update a tar.bz2 on my server to have a constant daily update of logging, a snapshot, if you

2:41 will

2:41 tomoj: I was probably here but I don't stay around all the time

2:41 defn: nod

2:41 tomoj: er, and my logging setup actually sucks

2:42 defn: I need to really have two sessions in here, one at this location, and one at the other, to make sure I don't miss anything

2:42 and then diff

2:42 i also need to quit jabbering in here so much so I don't flood my app with a bunch of useless data. :)

2:44 Another fun idea, if anyone is interested -- I have had some emails back and forth with someone who has been discussing indexing stackoverflow's clojure questions, the mailing list, irc, disclojure, planet.clojure.in, etc. -- and make a full syntax search engine for clojure syntax

2:45 tomoj: also, @optparse, i still guess i do not see exactly what you mean, i think being able to make handy command line tools for clojure would be really nice -- i was thinking about something similar where you'd just have a sort of modular repository which is added to your PATH, and you could just drop .clj files into it and have them be executable

2:46 tomoj: that would be nice, but doesn't handle option parsing, does it?

2:46 defn: perhaps some sort of dynamic way of updating the project.clj, running lein deps automatically, etc.

2:47 tomoj: not really :X :)

2:47 tomoj: how could you possibly update project.clj?

2:47 I mean, how could you determine which deps need to be added?

2:48 defn: tomoj: well it is just data, I was thinking you just parse the (ns) macro in the clj file which is added, and if it doesn't exist in the project.clj, you add it, you also add the file to the :namespaces

2:48 something like that

2:48 tomoj: but 'lein deps' is only for external maven deps

2:48 and you don't know where to find those based on just the ns, do you?

2:49 defn: i guess not. maybe the best thing to do would be to have a little map in the file which tells us which deps it needs?

2:49 tomoj: yeah, that doesn't sound bad

2:49 one of my initial ideas was that it should be doable without changing the source you're using to generate the tool

2:50 but realistically, this will probably not work very well anyway unless the author wants it to

2:50 and being able to easily wrap an external library and take care of the problems with a little bit of code like you suggest would be nice

2:50 defn: *nod* -- however... I can see simple .clj files which do not rely on external libraries working just fine

2:51 tomoj: maybe you just need an installer

2:51 defn: if the map doesn't exist we just assume all it needs are clojure.*

2:51 yeah that could work

2:51 tomoj: well, what about this

2:52 er, well, I was thinking you could just deploy to clojars and then "installing" this little bundle of tools is just adding it as a maven dep

2:52 but that loses the simplicity of just writing a single .clj file

2:52 defn: yeah and i dont really want to deploy everything i want to use to clojars.org

2:52 that would make clojars.org very messy

2:52 tomoj: well, you could also just lein install locally, but, yeah

2:53 the kinds of tools I was thinking of were pretty large suites

2:53 defn: i still haven't learn how to build lein modules

2:53 :\

2:53 tomoj: like a suite for managing cloud clusters

2:53 defn: err add lein tasks

2:53 tomoj: ah

2:53 tomoj: apparently you can define tasks in project.clj

2:53 but I don't know how

2:53 defn: yeah -- no one does! :)

2:53 tomoj: there's just that one commit that says "it's possible now"

2:54 defn: heh

2:54 tomoj: with an obscure change

2:55 defn: tomoj: let's make a repo!

2:56 tomoj: heh -- i can't guarantee ill work on it tbh, but i would like to make a handy little "make this .clj a command line tool" sort of thing

2:56 that's something id work on

2:57 tomoj: my boss apparently thinks the company owns this idea

2:58 but I am sure he would allow me to open source any work I do on the general framework, if not the cluster management tool

2:58 defn: tomoj: ive been meaning to ask someone more familiar with that...

2:58 tomoj: also, I'm pretty sure I've got the legal upper ground

2:59 in fact, they've only ever paid me a one-time bonus check, and I've signed nothing, so :P

2:59 defn: if i open source something before being allowed to do so

2:59 as in, i just throw an epl on it

2:59 is that binding?

2:59 tomoj: if they really have a legal claim to it, I'd think not

2:59 just like you can't take someone's GPL and slap a copyleft on it

2:59 defn: nod

3:00 tomoj: but I don't know what it takes for a company to acquire the copyright

3:00 defn: it makes me sort of worried about some of the things ive been working on at work

3:00 tomoj: I do all my work at home, so it's even more worrisome

3:00 defn: ive just been hacking around on clojure building little things for fun here and there

3:00 i get a couple hours per night to do that -- just messing around, but someone started using one of the tools, and i hope they do not try to claim it as their own

3:00 tomoj: (more worrisome that it would be if I had a clear separation I mean)

3:01 defn: nod

3:01 tomoj: "many software engineers can be independent contractors. Without a written agreement, they may own the software they created.."

3:03 I would like to read about how to determine whether some side project you made belongs to you or not, but don't know how to google it

3:03 defn: i am not primarily employed to write code

3:03 i wonder if that factors into any of this

3:03 aja: tomoj: Most jurisdictions have the concept of "work-for-hire". If you were paid to generate something, it may default to ownership by the payer, even if there is no explicit transfer.

3:04 * defn shudders

3:04 * defn stops coding at work entirely

3:05 defn: at the very least i need to do it on a laptop that is not company owned -- all my tools and snippets are on this machine

3:05 aja: tomoj: Also, if you used company resources (time, bandwidth, pencils, etc.) in development, that may be sufficient, even if you weren't explicitly hired to develop the product.

3:06 defn: aja: what if i printed a book on a company printer to learn a language? is all of that knowledge then owned by the company i work for?

3:07 tomoj: damn, this connection sucks

3:08 but what if the employer never told me to make it?

3:08 aja: defn: No, because knowledge does not constitue property (cannot be owned), and consequently wouldn't be the subject of a contract.

3:08 defn: aja: ah, okay

3:08 aja: tomoj: Again, if you used resources owned by the company (including time they paid you for), they may have a claim on the product.

3:09 defn: *may* is the operative word

3:09 they would need a good reason to want it in the first place -- which in my case, given how scared they are of using clojure, is a non-issue

3:09 aja: defn: Note that things like non-compete clauses may restrict what you can *do* with your knowledge, but those are often unenforceable.

3:09 tomoj: the problem is, of course, to distinguish between time they paid me for and time they didn't

3:09 is my whole life now being funded by the company?

3:09 defn: tomoj: if you do time tracking you have records

3:09 aja: defn: Of course, "may" is operative. But in cases like that, the issue is often won by whoever has more money for lawyers ...

3:09 tomoj: if I arrange my breakfast cereal in a neat pattern and try to sell it as modern art, are they going to sue me?

3:10 aja: tomoj: It's not black-and-white. It's a gradient. THere's stuff that is clearly your IP, stuff that is clearly the company's, and a huge freaking swath of arguable in between.

3:11 tomoj: yeah :(

3:11 * Apage43 is hourly, anything i do at home is mine.

3:12 aja: tomoj: In general, if developing stuff for yourself, do not do it at work, do not do it using company resources, and do not do it during work hours. Or, of course, make an explicit agreement with your employer, which is often best.

3:12 tomoj: yeah, makes sense

3:12 and in my current case I am sure open-sourcing will be feasible, which is all I'd want to do at this point anyway

3:13 open-sourcing stuff seems to be very popular for cool web shops

3:13 nvoorhies: if you're not an employee then it's not work for hire unless you explicitly say so in writing, btw

3:13 tomoj: hah

3:14 I can't go sell all their trade secrets to a competitor, though, can I?

3:14 nvoorhies: Not that that matters if it's the choice between paying a few thousand $ for a lawyer over something you don't care that much about

3:14 aja: nvoorhies: Depends on the jurisdiction and case law.

3:14 tomoj: (not that I would... this is an awesome job)

3:14 s/is an/will be/

3:14 nvoorhies: I'm just going by federal law tho

3:16 spariev: defn: hello, re: search engine for clojure code - it would be very cool and useful project, do you know about it's current status ?

3:19 defn: doing smthg with clojure examples seems to be a trend - I wrote http://github.com/spariev/find-example last weekend, only to realize in Monday that it's basically a copy of your cljex :)

3:20 tomoj: hmm, I wonder if I can round-trip clojure code in a source file -> emacs -> pass through a clojure fn -> back to emacs -> pretty print with proper indentation and replace in source file

3:20 so you can program your editor in clojure

3:21 Raynes: TheBusby: I don't believe it implies that you need to know Java. It implies you need to be able to google "parse int from string java", maybe. :p

3:22 TheBusby: RTFM works great when it's mentioned in teh documentation

3:22 the fact that it doesn't appear in clojure books though...

3:22 tomoj: some day in the future, we will want to move all this stuff into clojure, no?

3:23 otherwise code will be more incompatible across various implementations

3:23 TheBusby: it would be great if we just had an alias for it in core

3:23 tomoj: I think rhickey had mentioned some kind of implementation-independent numbers classes before

3:23 those would presumably come with handy fns

3:23 TheBusby: you'd think this kind of thing would drive the CLR guys nuts

3:24 tomoj: yeah

3:24 my boss sent me a link about using memory-mapped files for IPC in .NET 4.0 and mentioned this would have interesting implications for clojure

3:25 TheBusby: I haven't had any luck with mmap and java/clojure yet, still using C unfortunately

3:27 tomoj: I don't yet understand what the benefit is

3:27 defn: spariev: my cljex is not so good, so feel free :)

3:27 TheBusby: beyond offering blinding IO speed, two processes can mmap the same file to essentially share memory in some cases

3:28 defn: spariev: i have not worked on a search engine for clojure code (yet)

3:28 TheBusby: I just use threads if I need to share memory, but I could see where you could pull off some interesting tricks using mmap for IPC

3:28 defn: spariev: i am not a search guru, so I'm not sure how to approach such an operation

3:29 spariev: also check out my walton project

3:29 spariev: defn: I'm thinking about piggybanking on walton for find-example - running through irc logs and carefully handpicking the best examples, benefiting from your hard work :)

3:29 defn: hehe, that's what i planned on doing

3:29 cljex has sort of been abandoned, and one of my TODOs for walton is to generate a website of examples :)

3:30 spariev: consider maybe forking walton and adding something like that?

3:30 spariev: either way feel free -- it's great to see people working on the same types of stuff

3:32 spariev: it would be nice if we could, on the website, vote on the quality of an example

3:32 add a new example, etc.

3:32 spariev: defn: yep, that's something I'm thinking about

3:34 defn: would be nice to have a) some handpicked examples, b) indexed irc logs and blog posts from planet clojure, wikibooks and stuff in one place, with web-interface and some means to access it from repl

3:34 i wish i had 48 hours in a day :)

3:35 tomoj: TheBusby: ooh, I get it

3:35 defn: haha -- well perhaps some modularity would be nice

3:35 tomoj: I was thinking that IPC meant multiple threads

3:35 even though I knew what it stands for

3:35 defn: and the protocol?

3:35 or just combine them in clojure?

3:36 defn: tomoj: havent decided on that yet...any thoughts?

3:36 tomoj: dunno, I don't have a good understanding of what would be required for your project

3:36 I kinda like json, though :)

3:38 defn: spariev: i do own getclojure.org btw, that's a good place for something like this IMO, but there are plenty of other catchy names :)

3:39 tomoj: i really have no preference -- json would likely work just fine

3:39 spariev: defn: I've got clj-examples.appspot.com already :)

3:40 anyway, I should code somthing first, then talk on site names )

3:44 defn: spariev: hehe -- well, if you'd like to not duplicate work, consider forking walton -- im very open to changes

3:47 Raynes: defn: I don't know about the up front parsing, at least not initially, but I suppose the website pointing stuff would be simple.

3:47 When will there be such a website?

3:48 spariev: defn: yep, definitely, I'm thinking of merging find-example functionality into walton, or something like this

4:07 defn: Raynes: within a week hopefully

4:08 my goal is to have the whole basic functionality of web front end + irc bot by that point

4:08 it likely wont be pretty, but should be close...

4:09 spariev: any interest in using enlive and moustache?

4:11 spariev: defn: I've used only compojure so far, but enlive/moustache will do

4:12 defn: spariev: compojure is fine also -- it's been around longer so it has that going for it

4:35 tomoj: I am also thinking of switching to moustache

4:40 Raynes: defn: Yeah, I was going to point out that somebody might want to develop a bot specifically for the purpose of walton, because my bot does all sorts of stuff, and likely wouldn't be welcomed in here since clojurebot runs the house. ;)

4:40 However, I'll still work walton into my bot just for awesomeness.

4:45 bsteuber: raynes: I don't think anyone would mind another bot around - if it gets us sth. new

4:46 Raynes: Just saying. Some channels are picky when it comes to bots. Of course, mine doesn't do anything disrupting unless you make it.

4:46 ;P

4:46 LauJensen: Morning team

4:47 Raynes: Morning.

4:47 LauJensen: Raynes: What does your bot do, that clojurebot doesnt ?

4:47 Raynes: LauJensen: Google Translate and quote-like stuff. :p

4:47 LauJensen: Oh

4:47 Raynes: Naw, I'm not really sure. I don't keep track of what it can do.

4:48 LauJensen: Then ehm. I'm sure he'll have fun in #casual

4:48 Raynes: It does lots of stuff that clojurebot doesn't do, but most of it isn't very useful for the purposes of this channel.

4:48 I believe he was considering the possibility of me adding walton to the bot.

4:48 Which would give the channel something new.

4:49 LauJensen: walton being?

4:49 Raynes: http://github.com/defn/walton

4:49 Only the coolest thing ever.

4:50 LauJensen: ah nice

4:50 That is cool

4:50 Does it take in account all the failed examples?

4:50 Raynes: You'd have to ask defn about that.

4:51 LauJensen: defn: Does it take in account all the failed examples?

4:52 * Raynes wonders if he should use JSON or properties to store API keys and passwords and such.

4:52 Raynes: I don't guess it really matters.

4:52 But at 4:00am, it's a difficult decision.

4:52 LauJensen: properties

4:53 Raynes: Any specific reason? To be honest, I don't really know what property files are for.

4:54 Except storing information.

4:54 That's obvious. It's the general use case I'm not sure of.

4:54 LauJensen: And what is JSON for ?

4:54 Raynes: All sorts of stuff.

4:55 It's for keeping me from having to use XML.

4:55 :D

4:55 LauJensen: hehe

4:56 Ok, I guess you're right in saying that is has several purposes, specially storing data is not one of its design objectives, but properties are - does that help you make a decision? :)

4:56 Raynes: I suppose, but I use JSON to store data in other parts of the bot anyways.

4:57 LauJensen: I guess if its important to repeat mistakes then you should go with JSon :)

4:58 Raynes: I didn't use properties because they didn't seem to fit with the quote-like stuff.

4:59 LauJensen: I guess what matters most is, do you need to pass it along again, via some webservice or is it for internal use

5:00 Raynes: It's for internal use.

5:00 inb4propertiesidiot

5:01 But, aren't properties mainly just for outside configuration and such? It seems silly to use them to dynamically store quotes and such. Of course, that is probably something a database should be used for, but it feels like overkill.

5:04 bsteuber: Raynes: why not clojure data structures?

5:05 Raynes: bsteuber: Indeed, I could just as easy use a map in place of the JSON in general.

5:05 bsteuber: you just get problems if you need to reed the stuff from outside clojure

5:06 Raynes: Which would never happen.

5:06 ,(read-string "{\"hai\" \"thar\"})

5:06 clojurebot: EOF while reading string

5:06 Raynes: ,(read-string "{\"hai\" \"thar\"}")

5:06 clojurebot: {"hai" "thar"}

5:07 LauJensen: Raynes: I'll side with bsteuber - Go with a native struct

5:08 Raynes: bsteuber, LauJensen: thanks for the input. I'll rewrite existing code to use plain ol' clojure files with maps and such.

5:09 LauJensen: Oh and Raynes - Maybe you should stop coding at 4am :)

5:09 Raynes: LauJensen: I'm considering not sleeping tonight.

5:10 LauJensen: In an attempt to get back to a normal routine?

5:10 Raynes: Well, that and I have to go to the bank in around 5 hours anyway.

5:10 LauJensen: Ok

5:11 Raynes: Slurp is my friend.

5:11 LauJensen: Its annoying, I have this fn, everything is primitives, profiled and optimized. And its still slow

5:14 Raynes: (doc spit)

5:14 clojurebot: "([f content]); Opposite of slurp. Opens f with writer, writes content, then closes f."

5:17 Raynes: Aw man.

5:18 Loud noise outside. Probably burglars. I don't have any shells handy. :(

5:20 LauJensen: Don't you love it when stuff works the first time?

5:20 LauJensen: I sure do

5:20 Raynes: I actually didn't have to change much code. In fact, it make it made it smaller.

5:20 :D

5:20 LauJensen: it make it made it smaller? thats great :)

5:21 Raynes: LauJensen: No json/decode-from-writer and such.

5:21 I'm just read-stringing a map.

5:21 Clojure maps make for a great configuration format as well, imo. Readable if indented right and such.

5:21 Borkdude: From Twitter: ghoseb: Planet Clojure [http://planet.clojure.in] will now redirect to Planet Scala. That's because Scala is my current favorite language.

5:22 LauJensen: Aprils fools :)

5:22 Borkdude: omg

5:22 hahaha

5:22 Raynes: Man, I haven't heard a decent april fools joke all day. :(

5:22 From Twitter: greenrd: I've had it up to here with Linux. From now on it's going to be Vista and Visual Studio all the way. Also, I'm joining UKIP.

5:26 LauJensen: Linux is for freetards anyway

5:35 ambient: hi, anyone having trouble with Counterclockwise (Eclipse plugin)? "java.lang.NoClassDefFoundError: clojure/contrib/repl_ln" I got JDK 1.6 installed and in path, installing CCW through Eclipse doesn't just seem to work

5:36 Borkdude: I have seen that error before in Eclipse, but I don't remember what it was

5:36 LauJensen: Installed without any problems a couple of weeks ago

5:36 ambient: my version is 0.0.52.STABLE

5:37 Eclipse 20100218-1602

5:39 Raynes: lpetit might be of assistance.

5:40 LauJensen: ambient: I used 20090917-0800 from Ubuntu repos

5:40 And just installed like lpetit shows in the video - Had to retry once due to some server thing, but then it worked

5:40 ambient: yeah, it might be best to also mention that I'm on Windows

5:40 lpetit: ambient: let's try see exactly what your problem is

5:41 ambient: I guess you have this problem when you try to launch a REPL, right ?

5:41 ambient: run as > clojure repl, yes

5:41 lpetit: ambient: so it's not an installation problem, for one :-)

5:41 ambient: i got simple test.clj that has "(print "foo")"

5:42 inside a clojure project and java perspective

5:43 oh dam. *foreheadsmack*

5:43 lpetit: I'm thinking more of something along those lines: the clojure-contrib.jar your project is currently referencing does not have repl_ln precompiled. Since ccw makes the (only) hypothesis that your project has clojure-contrib correclty AOT compiled in your classpath, this may explain the problem.

5:43 ambient: i had an ancient clojure project from earlier and i tried using new CCW

5:43 clojurebot: clojure is a language to use if you want to up your game

5:44 ambient: it put clojure-src.jar and clojure-contrib-src.jar on different places (i dont think they even existed back then)

5:44 excuse me for the hassle

5:44 lpetit: ambient: np

5:45 ambient: everything back to normal now ?

5:45 ambient: yes

5:45 lpetit: good :)

5:45 poll: do you appreciate the recent paredit-like additions ?

5:46 ambient: i'll get back to you on that

5:47 although i think i just crashed it

5:48 (slurp "foobar.txt") > error: wrong path bla bla => *me fixes right path* => crash

5:48 yep, eclipse hangs and nothing happens

5:49 * lpetit exits via the backdoor

5:49 ambient: :D

5:51 Raynes: lpetit: I see you added auto-indentation.

5:51 Good show, frenchman.

5:51 lpetit: thx :)

5:52 ambiant: maybe this is totally unrelated to the new version. Calling slurp on *big* files on the console/repl can cause it to haaaannnngg

5:52 ambient: yeah, its about 10 meg

5:52 not a big fil per se imo

5:53 lpetit: Raynes: yes, and paredit-like functionalities: wrap round, auto-paren inserting. Still missing some, working on it these days by night

5:53 Raynes: Neato.

5:54 lpetit: ambient: but you called (slurp "foobar.txt") in the REPL directly, without placing it in a variable and preventing it from being printing via the classical (do (def foo (slurp "foo")) nil) kind-of trick ?

5:54 your console is currently trying to display at once 10 meg of textual content !

5:54 ambient: my bag of tricks is a bit limited when it comes to clojure

5:54 i havent written that much with it

5:54 aaa

5:55 it doesnt have the environment variable set to something sensible?

5:55 *text-length-print-something*

5:55 lpetit: default one. So no, not set to sensible, I guess :-(

5:55 ambient: i see

5:56 funny, that i can still shoot myself in foot with this high level language ;)

5:57 Raynes: You can shoot yourself in the foot with a snorkel if you try hard enough.

5:58 ambient: python has proven itself to be fairly idiot proof so far

5:59 LauJensen: :)

5:59 Borkdude: ,(/ 1 .999)

5:59 clojurebot: java.lang.Exception: Unable to resolve symbol: .999 in this context

5:59 Borkdude: ,(/ 1 0.999)

5:59 clojurebot: 1.001001001001001

6:04 ambient: lpetit ok the paredit type functionality is already confusing me

6:05 i cant get other parenthesis to go inside my other ones

6:06 Borkdude: I also think inserting parens inside existing sexps is confusing in CC

6:07 but maybe I'm not doing it right

6:07 ambient: its just something i have to learn i guess

6:07 Borkdude: ambient: you can select the portion which you want to wrap with new parens and then type (, [, or {

6:08 ambient: yeah, that doesnt really work at all

6:08 Borkdude: it works here, but I have to get used to it

6:10 ambient: it just marks )'s with red and when i try to type "(" anywhere it just creates ()

6:11 Borkdude: can you give the code you're editing?

6:11 it might be explainable

6:11 ambient: (first (split-with '\n filu))

6:12 that newline might be very wrong

6:13 Borkdude: (doc split-with)

6:13 clojurebot: "([pred coll]); Returns a vector of [(take-while pred coll) (drop-while pred coll)]"

6:14 ambient: the issue was with paredit like functionality though

6:15 trying to type ( at the beginning creates (), trying to paint the whole thing and type ( again does nothing

6:15 Borkdude: deleting parens is something I'm fighting with in CC

6:15 tomoj: why not M-( ?

6:15 ambient: its not emacs

6:15 tomoj: M-( is not bindable?

6:16 ambient: seems that it is not

6:18 looks like it wont work for top level s-exps

6:23 deleting double parentheses like ((+ 1 1)) seems to be impossible

6:24 Borkdude: yes exactly

6:24 I use Ctrl-x for it, but that's a bit clumsy...

6:26 ambient: correction to my previous statement: its only the bottom top-level s-exp that is bugged

6:28 Borkdude: ambient, sorry, what was bugged exactly?

6:29 ambient: put cursor inside the bottom top-level s-exp, press shift + alt + up-arrow, press (

6:29 nothing happens

6:31 Borkdude: what should happen?

6:31 ambient: (+ 1 1) => ((+ 1 1))

6:31 that's what happens everywhere else

6:32 Borkdude: you're right

6:32 there was also an earlier bug with the last line

6:33 that got solved in this version, but apparently they still haven't got the edge cases very well handled ;)

6:33 most irritating thing for me is deleting parens though, if anyone has a good tip

6:39 maacl: What is the recommended way of getting a correct result from (- 2.0 1.1) in Clojure? Do I have to resort to BigDecimal?

6:39 ambient: i dont think you can get correct results with floating points in general

6:40 but then again i dont know that much

6:40 Borkdude: (doc rationalize)

6:40 clojurebot: "([num]); returns the rational value of num"

6:42 Borkdude: (float (- (rationalize 2.0) (rationalize 1.1)))

6:42 ,(float (- (rationalize 2.0) (rationalize 1.1)))

6:42 clojurebot: 0.9

6:43 maacl: Borkdude: thanks but yikes not pretty

6:43 ambient: ,(- 2 11/10)

6:43 clojurebot: 9/10

6:44 Licenser: morning

6:44 maacl: ,(- (BigDecimal. "2.0") (BigDecimal. "1.1"))

6:44 clojurebot: 0.9M

6:48 maacl: ,(- 2.0M 1.1M)

6:48 clojurebot: 0.9M

6:48 Borkdude: maacl: please read section 4.3 of The Joy of Clojure

6:48 maacl: That's better.

6:48 Borkdude: called "Try to be rational"

6:48 BigDecimals are also due to precision problems

6:49 maacl: Borkdude: Due to? prone to?

6:49 ambient: or if you have fixed point arithmetic you could just use integers everywhere

6:50 Borkdude: prone, sorry

6:51 maacl: Borkdude: really? I thought it was really solid - a lot of banks use it...but that of course does not say much these days

6:51 ambient: banks?

6:51 use integers

6:52 Borkdude: sorry I might be wrong

6:52 maacl: ambient: well, not all numbers are integers, not in banks either

6:53 ambient: i wonder what values in money transactions are not integers

6:54 maacl: ambient: interest rates

6:54 ambient: but if you have 17.34% interest rate thats just 1734

6:54 i digress

6:55 Borkdude: ,(/ 1 3M)

6:55 clojurebot: java.lang.ArithmeticException: Non-terminating decimal expansion; no exact representable decimal result.

6:55 cemerick: no sane person in a financial inst would use anything other than integers

6:55 Borkdude: that's where you are going to run in trouble maybe

6:55 maacl: cemerick: apparently they do

6:56 cemerick: Sure, that's doesn't mean it doesn't happen, but there are very real consequences.

6:56 ambient: one would ask oneself how long will that bank stay afloat

6:59 maacl: ambient: a lot of them don't for very long

6:59 http://bit.ly/cGf6ln

7:00 ambient: i've seen some really crappy programming in some banks that are still alive, after 5 years

7:00 maacl: Story about Groovy at Mutual of Omaha highlighting BigDecimal

7:01 LauJensen: cemerick? 5 AM already?

7:02 ambient: hmm, enclojure latest release is 2009-08-25. trouble?

7:02 cemerick: LauJensen: nah, it's 7 :-)

7:03 ambient: you're looking at a stale page somewhere: http://github.com/EricThorsen/enclojure/downloads

7:03 ambient: ok, thanks

7:03 cemerick: ambient: where were you looking?

7:04 ambient: too tired, too much caffeine equals too much typing on irc much nonsense, apologies

7:04 cemerick enclojure home page

7:05 cemerick: ah, the download link redirects properly, but that headline isn't helpful, is it? :-/

7:05 ambient: i suppose that was a rhetoric question, but no, it isn't

7:12 lpetit: Borkdude: yes, there is a trick for removing parens = add a space, and kill paren+space all at once

7:12 I note the problem with the bottom sexpr, will correct it tonight hopefully

7:14 When more of paredit is ported, those problems will hopefully have a more decent solution. I intend to provide the "Escape" touch as a way to disable paredit for a while, for example

7:18 Borkdude: why won't it let me just remove a paren if I want to?

7:23 Raynes: Borkdude: Because mismatched parens make paredit cry.

7:24 Borkdude: Raynes: what about the inverse of typing ( with a selection?

7:25 Raynes: Say what?

7:25 Borkdude: Raynes, for example: ((foo)), remove the inner or outermost matches

7:26 Raynes: M-s

7:28 Borkdude: Raynes: doesn't work here

7:28 Raynes: It works in Emacs.

7:29 Borkdude: I'm in Eclipse + CC

7:29 Raynes: Is there any tools for line number analysis for Clojure?

7:32 Borkdude: What is this about in core.clj?

7:33 (defn rationalize "returns the rational value of num" [num] (. clojure.lang.Numbers (rationalize num)))

7:33 rationalize calls itself or what?

7:33 hoeck: Borkdude: place your point after the opening paren you want to remove and then press M-<up>

7:34 Borkdude: no, it calls the rationalize static method of c.l.Numbers

7:34 Borkdude: hoeck: are you talking Eclipse here?

7:34 hoeck: Borkdude: sorry, you're in Eclipse

7:35 * hoeck was typing too fast

7:35 Borkdude: (doc .)

7:35 clojurebot: I don't understand.

7:35 Borkdude: hm

7:35 hoeck: . is a special symbol

7:35 Borkdude: it's hard to search for in Google ;)

7:36 hoeck: ,(clojure.lang.Numbers/rationalize 1)

7:36 clojurebot: 1

7:36 Borkdude: ,(clojure.lang.Numbers/rationalize 0.9)

7:36 clojurebot: 9/10

7:37 hoeck: (. bla bah) is non-idiomatic syntax, only suitable when writing macros

7:38 Borkdude: I used it once to write a macro yes

7:38 but I didn't know you could do (. bla (bah foo bar))

7:39 at first sight I would think it would first evaluate (bah foo bar) and then continue, but it's more like mimicing java syntax?

7:42 hoeck: yes, its a strange way of calling java methods, see http://clojure.org/java_interop

7:43 it took a while for the .method syntax to emerge

7:45 SynrG: so Programming Clojure is dated and doesn't teach current idiomatic clojure?

7:45 Borkdude: (. Clojure.lang.Number (rationalize 1))

7:45 ,(. Clojure.lang.Number (rationalize 1))

7:45 clojurebot: java.lang.ClassNotFoundException: Clojure.lang.Number

7:45 Borkdude: ,(. clojure.lang.Number (rationalize 1))

7:45 clojurebot: java.lang.ClassNotFoundException: clojure.lang.Number

7:46 * hoeck has not read programming clojure

7:46 Borkdude: ,(. Clojure.lang.Numbers (rationalize 1))

7:46 clojurebot: java.lang.ClassNotFoundException: Clojure.lang.Numbers

7:46 Borkdude: damn

7:46 hoeck: :)

7:49 ambient: there was an easy way to split a string into substrings from newline?

7:51 Borkdude: ambient: http://richhickey.github.com/clojure-contrib/string-api.html#clojure.contrib.string/split-lines

7:51 SynrG: ,(. clojure.lang.Numbers rationalize 1)

7:51 clojurebot: 1

7:51 Borkdude: ,(. clojure.lang.Numbers (rationalize 1))

7:51 clojurebot: 1

7:52 Borkdude: (doc split-lines)

7:52 clojurebot: Pardon?

7:53 ambient: looks like that one came after 10.

7:53 1.0

7:53 Licenser: ~ns

7:53 clojurebot: amespaces are (more or less, Chouser) java packages. they look like foo.bar; and corresponde to a directory foo/ containg a file bar.clj in your classpath. the namespace declaration in bar.clj would like like (ns foo.bar). Do not try to use single segment namespaces. a single segment namespace is a namespace without a period in it

7:53 Borkdude: (find-doc "split")

7:53 Licenser: ~defmacro ns

7:53 clojurebot: http://clojure.org/transients

7:54 Borkdude: ,(find-doc "split")

7:54 Licenser: hmm I fail

7:54 clojurebot: ------------------------- clojure.contrib.seq-utils/partition-by ([f coll]) Applies f to each value in coll, splitting it each time f returns a new value. Returns a lazy seq of lazy seqs. ------------------------- clojure.core/split-at ([n coll]) Returns a vector of [(take n coll) (drop n coll)] ------------------------- clojure.core/split-with ([pred coll]) Returns a vector of [(take-while pred coll) (drop-while pred coll

7:54 Borkdude: ,(doc split-lines)

7:54 clojurebot: Excuse me?

7:55 Borkdude: hmm, this comma in front of sexps is a bit annoying, is there a reason why ( is not simply the character that clojurebot listens to?

7:55 Licenser: ,(doc clojure.contrib.seq-utils/split-lines)

7:55 clojurebot: No entiendo

7:55 Licenser: ah does not work :P

7:55 (comment) becase he might get confused :P

7:56 ~defn split-at

7:56 clojurebot: Titim gan éirí ort.

7:56 Borkdude: (comment (+ 1 1 )) ; really?

7:56 Licenser: Borkdude: I think that is the reason

7:56 but on the other hand it might come handy

7:56 Raynes: Morning Licenser

7:56 Licenser: hi Raynes

7:57 Borkdude: well I don't usually start a new sentence with (

7:57 , but also not with comma very often. ;)

7:57 clojurebot: java.lang.Exception: Unable to resolve symbol: but in this context

7:59 Borkdude: gtg

7:59 later

8:00 lpetit: Borkdude: expect M-s to be available in a future version of paredit. It's planned.

8:21 opqdonut: what's the easiest way to turn a java.lang.HashMap into a clojure map

8:22 err, java.util.HashMap

8:25 SynrG: opqdonut: hmm. i think http://stackoverflow.com/questions/1665103/clojure-working-with-a-java-util-hashmap-in-an-idomatic-clojure-fashion gives the answer (accidentally? :)

8:25 bsteuber: ,(into {} (doto (java.util.HashMap.) (.put 4 6)))

8:25 clojurebot: {4 6}

8:27 bsteuber: opqdonut: (into {} hm) seems most simple to me

8:27 Fossi: into {} is nice

8:27 SynrG: oh! there is an FAQ that gives the same answer: http://en.wikibooks.org/wiki/Clojure_Programming/FAQ#Q:_How_can_I_convert_a_Java_HashMap_to_a_clojure_map.3F

8:28 not a very big FAQ :p

8:30 lpetit: All: the current way of splitting an sexpr in emacs paredit is M+S . We (cgrand & me) intend to use another scheme for this command in ccw. It could just be hitting the closing kind of paren : e.g. "(a | b)" -> hit ")" -> "(a )|( b)". Reactions ?

8:33 Fossi: would work for )}], but not really for "

8:33 bsteuber: lpetit: in emacs I sometimes use ) to navigate to the end of my expression

8:33 but I guess it's all a matter of getting used

8:33 Fossi: except if you do something else to insert \"

8:34 bsteuber: on the long run, I hope all clojure modes converge to more or less the same bindings

8:34 but now is still time for experiments, I would say :)

8:35 lpetit: best way would be allowing for different profiles, maybe

8:35 so you can have one paredit-compliant mode, a CC-default-mode and a user-custom mode

8:36 but doesn't eclipse already do so?

8:36 hoeck: lpetit: sounds quite useful, I do not like the paredit behaviour for ")" - its pretty useless for me

8:37 lpetit: Fossi: yes, introducing "insertion modes" (like string insertion mode) could help, but I guess it could complefy the thing,too

8:37 bsteuber: yes, sort of.

8:37 bsteuber: I guess splitting a string happens more often than inserting \"

8:38 defn: Anyone play with mustache at all?

8:38 moustache, sorry

8:38 bsteuber: so I would happily lose the latter if I get the former :)

8:38 * bsteuber always wondered why paredit doesn't allow M-s in strings

8:39 lpetit: bsteuber: so inserting \" would just fall back to ... inserting \" (with \ being a dead-letter, maybe)

8:39 bsteuber: I didn't know M-s would not work in strings in paredit;el

8:39 defn: I have something like (def myapp (app ["test" [text #".*"]] {:get (my-function-which-returns-html-as-a-string text)}))

8:39 lpetit: thanks guy, interesting stuff to think about.

8:40 Licenser: hmm how can I let in a macro? I kind of fail here :(

8:40 tomoj: bsteuber: it does...

8:40 defn: unfortunately this isn't working -- so i tried encapsulating: [(my-function-which...)], still nothing -- so i append an empty string... ["" (my-function-which...)] -- this gets me the actual string printed on the page, but not rendered as html

8:40 any ideas?

8:41 tomoj: defn: I ran into some problems like that as well

8:41 defn: tomoj: hmmm -- am i missing something or is that just something you haven't figured out?

8:42 tomoj: well, I think there are just some problems with the way those values are interpreted

8:42 if the first thing isn't a string, it tries to do crazy stuff

8:42 and it's a macro, so

8:42 I think what you put there needs to just be the name of a handler for best results

8:42 but I haven't done much with it yet

8:43 hoeck: Licenser: (defmacro m [] (let [a 1] `(list ~a))) ??

8:43 Licenser: hoeck: just figured I failed because I forgot to ~ some var :P

8:43 thank you!

8:43 bsteuber: lpetit,tomoj: I get this error: paredit-kill-surrounding-sexps-for-splice: Splicing illegal in strings.

8:43 hoeck: np :)

8:43 Fossi: M-s works in strings doesn't it?

8:44 bsteuber: but maybe my version's too old

8:44 or I need an extra line in my .emacs

8:44 tomoj: need 23 beta

8:44 er, 22 beta

8:45 dnolen: defn: that won't work, the argument to get needs to be a function. it will be passed the request.

8:45 bsteuber: M-x emacs-version gives GNU Emacs 23.1.1

8:45 and paredit from elpa

8:45 defn: dnolen: how do you mean?

8:45 tomoj: and yet, the walkthrough has examples like (app ["hi"] "hello world!")

8:45 bsteuber: from the start, it also didn't work with {}, but I fixed that in my .emacs

8:46 tomoj: but we didn't understand that that only worked for literal strings

8:46 dnolen: tomoj: yes moustache handles literal string as a special case.

8:46 (def myapp (app ["test" [text #".*"]] {:get fn-which-returns-html-as-a-string)}))

8:46 tomoj: bsteuber: yeah, 22 beta fixes that too

8:46 bsteuber: so 22 beta is better than 23?

8:46 tomoj: but you have to add M-[ and M-{ or whatever for wrapping them

8:47 defn: dnolen: how do i give fn-which-returns-html-as-a-string the argument text?

8:47 dnolen: (defn fn-which-returns-htmls-as-astring [req] (ring.utils.response/response ...))

8:47 tomoj: there is no 23, I believe

8:47 defn: dnolen: ahhhh

8:47 dnolen: thank you

8:47 dnolen: defn your function will always be passed the html request

8:47 bsteuber: tomoj: but it happens to be installed on my machine - or do the ubuntu versions lie?

8:48 tomoj: bsteuber: C-h v paredit-version

8:49 bsteuber: paredit-version is a variable defined in `paredit.el'. Its value is 20

8:49 oh

8:49 now I get it

8:49 tomoj: http://mumble.net/~campbell/emacs/paredit-beta.el

8:49 defn: which ring version is everyone using -- the one from clojars?

8:50 bsteuber: I thought you were talking bout emacs versions lol

8:50 dnolen: defn: yeah 0.2 from clojars

8:50 defn: dnolen: cool, thank you again

9:12 dnolen: still no luck :\

9:12 dnolen: defn: ?

9:12 defn: paste?

9:12 defn: I wrapped the html output in a (response (html-tree [:html [:head ...]]))

9:13 dnolen: does html-tree produce strings?

9:13 defn: and have (app ["test" [input #".*"]] {:get function}))

9:13 dnolen: ive checked and yes im just getting a long html string back

9:14 dnolen: do you have a simple case all in one file that you can paste?

9:14 defn: yeah let me whip something up since this is across a few files

9:17 dnolen: http://gist.github.com/351781

9:18 dnolen: defn: that won't work. your handle gets passed the html request *not* the matching text from the route.

9:19 looking over moustache cgrand doesn't put the matching part anywhere, I think he assumes you'll use it in a closure or something.

9:20 defn: http://gist.github.com/351783, this should work.

9:21 defn: ahhhh!

9:24 dnolen: still nothing :\ hmmm

9:24 dnolen: defn: can you add your server code to my gist?

9:25 defn: sure

9:26 dnolen: http://gist.github.com/351783#comments

9:27 dnolen: maybe the way im planning on accessing this is wrong?

9:27 http://localhost:8080/examples/anything

9:28 where anything is the string arg to the test-fn*

9:31 dnolen: defn where is defhtml from?

9:32 defn: clj-html

9:32 im going to use enlive -- but i was just testing since im already more familiar with it

9:32 it is definitely a string

9:33 i can see the response body {:status 200, :headers {}, :body "<html><head>...."}

9:34 dnolen: so perhaps the route is just wrong?

9:36 defn: i dont see the catch-all route though, but i do elsewhere

9:36 dnolen: i see the catchall route

9:36 pasting my code

9:37 defn: you see the catch all route at localhost:8080/examples/foo?

9:39 dnolen: defn: gist updated. the example route doesn't work because it's just wrong from what I can tell.

9:42 defn: dnolen: wrong in what sense?

9:44 dnolen: defn: sorry perhaps I'm wrong. it looks like the html logic is off now that I'm debugging.

9:44 defn: (application text (code-list (code-block text)))

9:45 defn: (code-block "foo") doesn't work for me at all.

9:45 defn: dnolen: http://gist.github.com/351817

9:45 that works -- im not sure what changed -- but it works now...

9:46 dnolen: defn: you stopped matching text with the regex #".*"

9:46 defn: oh duh -- yeah ["examples" blah]

9:46 you were right, the #".*" is bad

9:47 i guess i just wonder why -- /me peers at the code

9:49 dnolen: anyway dnolen, thanks for the help

9:49 dnolen: defn: fwiw, this works for me ["examples" [text #".*"]] (fn [req] (response (str "examples" text)))

9:50 defn: to be perfectly clear that matches /examples/anything NOT /examples/anything/

10:17 defn: dnolen: ahhh, good to know, thank you

10:31 Is it possible to combine two maps when doing destructuring

10:31 like: [[x y] (map first coll) (map second coll)]

10:31 to combine those maps somehow?

10:32 chouser: do you want zipmap?

10:32 hm, maybe not. is "coll" there a map already?

10:33 defn: maybe i do...no it's a list of vectors

10:43 chouser: so coll is like [[:x 1] [:y 2]] and you want something that ends up like (let [x 1 y 2] ...) ?

10:44 cgrand: defn, dnolen: http://gist.github.com/351783#gistcomment-120

10:45 dnolen: cgrand: nice. so do you plan on providing any sort of helper to pass the destructured bits to a fn? Right now you have to (fn [req] (handler x y req)) or something like that.

10:47 defn: chouser: hmmm, yes

10:47 cgrand: thanks for that

10:47 chouser: defn: (let [{:keys [x y]} (into {} coll)] ...)

10:50 cgrand: dnolen: I like closures :-) but I think that (defn give-me-a-name [f & args] #(apply f % args)) could be useful both with moustache and enlive

10:51 (fn [req] (handler req x y)) would be (delegate handler x y)

10:51 dnolen: cgrand: great!

10:52 now moustache will be 151LOC instead of 150LOC

10:53 cgrand: so, delegate? partial1? another idea?

10:55 dnolen: I like delegate.

10:56 it is partial1, but delegate give it's contextual meaning in moustache.

10:56 give it's -> gives it

10:59 cgrand: I must confess that the special case of strings in handler position is only there for demo and tweet purposes :-)

11:00 dnolen: so delegate?

11:00 dnolen: cgrand: well I like it. I suppose the moustache is crew is fairly small so I don

11:00 't think we'll hear many other opinions :)

11:02 SynrG: been thinking. DENIED is rather harsh. maybe change it to "I'm sorry <nick>, I'm afraid I can't do that."

11:03 hiredman: DENIED

11:03 SynrG: :p

11:04 i guess the joke would get old fast

11:04 hiredman: well, you'd want a list of similar responses to pick from at random

11:04 cgrand: dnolen: I know you'll spread the good word :-)

11:05 hiredman: clojurebot: bleep bloop blop

11:05 clojurebot: Pardon?

11:05 hiredman: clojurebot: bleep bloop blop

11:05 clojurebot: I don't understand.

11:06 dnolen: cgrand: I'll try. I want to do something that shows how moustache let's you always build services that are api ready. If you want HTML decorate with enlive, if you want data, just call the fn directly.

11:06 middleware with enlive rather.

11:07 cgrand: or have a higher-order middleware which select the better rendering-middleware based on content negotiation

11:08 dnolen: cgrand: hmm, i see where you're going. do you have a specific example you have in mind?

11:22 stuartsierra: I'm confused by behavior of the "extends?" function http://paste.lisp.org/+2301

11:22 Is this a bug?

11:31 qbg: You will get true from extends? if the type was extended using extend-type

11:32 stuartsierra: But not if the protocol was extended inline in the deftype?

11:33 qbg: I'm not sure extends in the right word for what happens in deftype

11:33 stuartsierra: hmm, ok

11:33 qbg: either that or deftype implicitly extends a protocol

11:44 webwanderer: Can someone help me set up clj-processing with emacs and slime? I've got the clojure repl via emacs starter kit and ELPA. What do I do next?

11:48 Anybody?

11:51 stuartsierra: webwanderer: start simpler

11:51 webwanderer: stuartsierra: what do you mean?

11:51 dnolen: webwanderer make a lein project from the command line: "lein new my-p5-app"

11:51 stuartsierra: Figure out the command-line REPL first, then EMACS inferior-lisp mode, *then* try to configure SLIME

11:51 webwanderer: dnolen: and then?

11:51 dnolen: change your project clj to include clj-processing from clojars to your project.clj :dev-dependencies

11:52 then in Emasc run swank-clojure-project, and select your projects directory

11:52 profit

11:52 * chouser still has only completed stuartsierra's first step

11:52 stuartsierra: :)

11:52 dnolen: taht

11:52 webwanderer: oops, that M-x swank-clojure-project

11:53 webwanderer: dnolen: so should I not need to install lein?

11:53 dnolen: webwanderer: lein is fairly easy to install if you're comfy with the commandline. instructions on github

11:54 webwanderer: cool. but should i for getting clj-processing running?

11:54 dnolen: well it makes it easier to have different processing sketches without futzing around with your classpath every time.

11:55 webwanderer: are you sure this leads to profit?

11:55 :)

11:56 I'll try anyhow.

11:56 dnolen: if you just want to run examples, go with stuartsierra suggestion

11:57 webwanderer: dnolen: I need to clj-processing. Whatever leads to that is profit.

11:59 stuartsierra: webwanderer: You need to start Java with a classpath that includes: 1) clojure.jar, 2) the clj-processing source files, 3) any JARs that clj-processing depends on

12:00 lein/maven will help you with that, assuming clj-processing is on clojars.org

12:00 defn: http://gist.github.com/351984 :: Any advice on this fn? Is this too terse? Too long?

12:01 I realize the docstring is a little iffy, pay no attention to the :a :b, just assume they're "a" and "b". :)

12:01 webwanderer: stuartsierra: I read that. It says something about 'the proper way to set up CLASSPATH' etc.. I'm sure that's up to no good for me.

12:01 As i don't know anything about Java.

12:02 stuartsierra: webwanderer: well, start learning :)

12:02 The classpath is the -cp argument to the "java" command line.

12:02 It consists of directories and .jar files.

12:02 webwanderer: stuartsierra: I thought the whole idea of clojure was to get the L away from Java.

12:02 stuartsierra: No

12:02 The idea of clojure is to leverage Java.

12:03 defn: also, clojure makes java suck a lot less

12:03 an order of magnitude or more IMO

12:03 dnolen: webwanderer: or not. I never use Java unless I have to. I prefer using wrappers around Java.

12:03 bozhidar: defn: java doesn't suck that much

12:03 Borkdude: it all compiles to jvm class files in the end

12:03 bozhidar: the language is certainly primitive

12:03 but the platform has always been great

12:04 defn: right, we're talking about the JVM versus Java -- two different things

12:04 fogus: defn: So Clojure is O(tehcool) and Java is O(meh)?

12:04 bozhidar: fogus: Clojure + JVM = Cosmic Synergy ;-)

12:04 webwanderer: Isn't it implied that it's Java the language that people refer to when they say Java sucks?

12:05 bozhidar: I have no idea how clojure fares on the CLR

12:05 Borkdude: Clojure is intended as a hosted language. Hosted on JVM, CLR and what's to come?

12:05 webwanderer: Parrot?

12:05 stuartsierra: to-be-determined inside-every-web-browser VM

12:05 webwanderer: Javascript is very good.

12:06 No need for clojure there IMHO.

12:06 I don't know clojure but still..

12:06 Borkdude: I would like to use Clojure instead of Javascript

12:06 stuartsierra: There's an (incomplete) port of Clojure to Javascript.

12:06 cheezey: can i use a "dynamic" regular expression pattern? i can't seem to do something like #(str ..)

12:07 stuartsierra: cheezey: You need (Regexp/compile "...")

12:07 sorry, java.util.regex.Pattern/compile

12:08 fogus: webwanderer: js is very good, but it has its flaws that can be addressed by alternative languages in the browser

12:09 cheezey: stuartsierra: thanks, i'll check it out

12:09 * cemerick can't wait for clojurescript's return

12:09 Borkdude: you did an asynchronous call in clojurescript?

12:10 webwanderer: fogus: Not very pressing as many other concerns are.

12:10 fogus: webwanderer: I'm sorry, but I don't follow

12:11 webwanderer: for one thing, the browser is a very primitive environment.

12:12 chouser: cheezey, stuartsierra: or re-pattern

12:12 webwanderer: There's not much gain with having multiple languages hosted on the browser.

12:13 Borkdude: webwandered, but there is gain knowing one language very well and able to use it on different hosts

12:13 bozhidar: btw a quick question about swank-clojure-project

12:13 what might be causing this to happen

12:13 Polling "/tmp/slime.25499".. (Abort with `M-x slime-abort-connection'.) [57 times]


12:13 Borkdude: webwandereR, sorry

12:13 fogus: webwanderer: Maybe, but I think that is a matter of debate

12:13 bozhidar: indefinately...

12:13 webwanderer: yes.

12:13 .....

12:13 stuartsierra: bozhidar: Look at the *inferior-lisp* buffer, it's probably showing an error.

12:13 naeu: I just started reading the clojure version of SPEL

12:14 dnolen: webwanderer: that is unless you're tired of current situation. I like JS and know it well, but apps are getting more and more complicated. Thus the existence of monstrosities such as GWT

12:14 naeu: and noticed: `(there is a ~(second path) going ~(first path) from here -))

12:14 this doesn't seem like idiomatic Clojure

12:14 webwanderer: But you don't need GWT. I think it's misguided.

12:14 I would recommend all of Douglas Crockfords recommendations.

12:15 cheezey: stuartsierra: thanks it worked, chouser: that's even easier loL :D

12:15 naeu: but it did remind of of Ruby string interpolation: "there is a #{path.second} going #{path.first} from here -"

12:15 what would be the most idiomatic way of representing string interpolation like this in Clojure?

12:15 dnolen: webwanderer: you need something like GWT for sufficiently complex apps. Thus Cappucino. Douglas Crockford be damned. He says the same thing over and over. He's a smart dude but not the only smart dude doing JS stuff.

12:15 brandonw: do you think there would be a way to re-use the optimizations of javascript in a secondary (or tertiary) language?

12:15 bozhidar: stuartsierra: you're correct and I'm absent-minded

12:16 brandonw: i know a lot of work is being done to get javascript highly optimized, and if you had several languages to choose from, it seems like it would detract from overall web usability

12:16 not that i am defending javascript; i would love to use something like clojure instead

12:16 webwanderer: dnolen: But why is GWT like Java of all things? I think that it is pathological or some mental infection.

12:16 chouser: naeu: http://muckandbrass.com/web/display/~cemerick/2009/12/04/String+Interpolation+in+Clojure

12:16 brandonw: but realistically, there is so much work being done specifically for javascript, it would be an absolutely huge undertaking to start using alternatives

12:16 cemerick: as I said earlier, the only thing js has going for it is distribution

12:17 chouser: cemerick: js isn't *that* bad.

12:17 defn: 11:04 < fogus> defn: So Clojure is O(tehcool) and Java is O(meh)?

12:17 naeu: chouser: thanks a lot

12:17 webwanderer: cemerick: you've obviously not used javascript.

12:18 chouser: for pages that have a little js sprinkled on them, up through smallish "web 2.0" sites, js with something like jquery is probably just fine.

12:18 cemerick: chouser: That's a tired response, IMO. If distribution weren't the key issue, you wouldn't use js for anything.

12:18 defn: fogus: I'm not trying to come across like that

12:18 fogus: I don't think the best path is providing multiple language interpreters in the browser, but rather multiple languages targeting js

12:18 * stuartsierra tunes out

12:18 chouser: cemerick: that's true, but I guess I didn't see it as an equivalent statement

12:18 stuartsierra: wise. :-)

12:19 cemerick: chouser: Sure, I should've been more precise.

12:19 stuartsierra: but what else is there to do during lunchtime? :-P

12:19 brandonw: that sounds like an interesting goal, except that you either have to dynamically compile it into javascript, adding an overhead to using an alternative, or you have to pre-compile it and you effectively have a code generator (and everyone loves those)

12:19 naeu: chouser: that looks nice - are there any plans to include something like that in clojure or contrib?

12:19 dnolen: webwanderer: I could go on but won't. GWT exists because _sometimes_ (not all) you need to write complex apps. You would prefer to have the illusion of a single codebase instead of two different codebases front and back because as application complexity increases, interop front/back complexity increases. /done

12:19 chouser: I've worked on apps with a few thousand lines of javascript, and at that scale I'd much prefer something else. Probably not Java (GWT) though. :-)

12:21 fogus: dnolen: inc

12:22 chouser: naeu: not sure. I think rhickey has been cold on the idea, but apparently it showed up at his and Halloway's pragmatic studio training session. So who knows. :-)

12:22 * lithpr plans on looking at generating coffeescript from clojure

12:22 cemerick: naeu: I'm hoping, very much, tho I suppose I'm biased.

12:22 chouser: naeu: if you like it, use it.

12:23 naeu: i love string interpolation in ruby

12:23 cemerick: it's one of the few things I :use everywhere

12:23 chouser: it won't be called << I bet, since rhickey wants that for cells

12:23 naeu: i just wondered whether i was missing an idiomatic approach for clojure

12:23 cemerick: ...and I *so* liked << for that :-(

12:24 chouser: the ~{n} is the ugliest bit afaic

12:24 cemerick: naeu: language extension via macros *is* the idiomatic approach for many things in clojure :-)

12:24 naeu: chouser: it's similar to #{n} from Ruby, and the ~ matches the macro flop

12:24 chouser: but I've failed to come up with better alternatives, so I should keep my mouth shut.

12:24 cemerick: chouser: yeah, I'm not so hot on that either, but I don't have any better ideas

12:24 chouser: I think you told me why ~n wouldn't work

12:25 cemerick: because you wouldn't know when to stop glomming the symbol

12:25 chouser: oh, right "~n."

12:25 naeu: you'd also want to substitute whole sexps

12:25 cemerick: that's ~(:blah foo)

12:25 chouser: "right, ~(:foo bar) is beautiful"

12:26 ~(identity n) heh

12:26 clojurebot: android is http://github.com/Nafai77/helloandroid/tree/master

12:26 chouser: ok, lunch

12:26 naeu: chouser: cheerio

12:35 underdev: i wonder why maps don't return seqs against seq functions

12:36 because thier inherently pairs?

12:37 stuartsierra: they do return seqs

12:37 ,(seq? (map identity {:a 1 :b 2}))

12:37 clojurebot: true

12:38 * fogus http://groups.google.com/group/emerginglangs

12:38 underdev: ,(class (first {:a :b :c :d}))

12:38 clojurebot: clojure.lang.MapEntry

12:38 underdev: ,(seq (first {:a :b :c :d}))

12:38 clojurebot: (:a :b)

12:38 underdev: ,(seq? (first {:a :b :c :d}))

12:38 clojurebot: false

12:39 underdev: okay, so sometimes they do, and sometimes they don't?

12:40 ,(seq? (first [a b c]))

12:40 clojurebot: java.lang.Exception: Unable to resolve symbol: a in this context

12:40 underdev: ,(seq? (first [:a :b :c]))

12:40 clojurebot: false

12:41 underdev: okay, so it's a "first" thing

12:41 fogus: underdev: seq returns a seq, maps are built from mapentries. mapentries are vectors. vectors are not seqs

12:42 (first '[a b c]) is a symbol

12:42 underdev: fogus: thanks

12:42 fogus: ,(isa? clojure.lang.MapEntry clojure.lang.IPersistentVector)

12:42 clojurebot: true

12:42 fogus: ,(seq? [])

12:42 clojurebot: false

12:45 fogus: ,(seq? (seq [1]))

12:45 clojurebot: true

12:48 underdev: okay, that may be handy

12:55 Borkdude: Can one compare a Clojure symbol with a Common Lisp symbol in that it has a propertly list etc?

12:56 joshua-choi: I'm looking for a tutorial for using Swing to create a syntax-highlighting text editor.

12:56 The best I could find is at http://ostermiller.org/syntax/editor.html, but the source is gone missing.

12:56 bsteuber: borkdude: not really - but they can have meta data attached

12:56 joshua-choi: Anyone have any good websites?

12:57 bsteuber: which is somewhat comparable to property-lists

12:57 dpritchett: Today I'm going to read Ch. 4 of Joy of Clojure... I hope the next MEAP update is ready soon!

12:57 bsteuber: jochua-choi: Are you gonna write clojuremacs, finally? :)

12:58 Borkdude: dpritchett: me2!

12:58 joshua-choi: bsteuder: Eh heh heh. Maybe, but probably not.

12:59 dpritchett: I can't read Alex Comfort at work so I'm counting on you two.

12:59 mfex: jochua-choi: the zip seems to contain the source files @ http://www.gjt.org/servlets/JCVSlet/list/gjt/com/Ostermiller/Syntax/Syntax.zip

12:59 joshua-choi: mfex: I get a server error page. :(

13:00 I'm not quite sure what's up with the Giant Java Tree.

13:01 mfex: jochua-choi: then click download between documentation and checkout latest at the top of the listing here: http://www.gjt.org/servlets/JCVSlet/list/gjt/com/Ostermiller/Syntax

13:02 joshua-choi: mfex: That gives me another error, "Failed to open '2401@cvs.gjt.org'."

13:02 mfex: msg me an email address then and I'll send it over

13:02 joshua-choi: Oh, really? Thank you very much!

13:05 brian_: as a newbie, I'm trying to clarify "map", ie this works: (map vector a), but this doesn't (map (re-seq #"b") a), for that I need to include an argument like this (map #(re-seq #"b" %1 ) a) , whats the difference between "vector" and "re-seq" ?

13:07 Borkdude: bsteuber, tnx

13:09 chouser: brian_: vector is a function, (re-seq #"b") is not

13:10 brian_: (vector) is also not a function. Both (vector) and (re-seq #"b") are attempts to *call* a function, and whatever they would return would be passed as the first arg to map

13:11 but (re-seq #"b") doesn't return anything because re-seq requires 2 args

13:11 so it throws an exception instead.

13:11 parens matter. anyone who says that the parens "disappear" after a while must mean something else.

13:12 brian_: thx chouser,i need to think about it

13:12 defn: http://thinkslate.com:8080/examples/concat

13:12 if you refresh you can see it build in real time :)

13:12 chouser: ,(map #(vector %) [1 2 3])

13:12 clojurebot: ([1] [2] [3])

13:12 chouser: ,(map #(vector :a %) [1 2 3])

13:12 clojurebot: ([:a 1] [:a 2] [:a 3])

13:13 wooby: ,(map (partial vector :a) [1 2 3])

13:13 clojurebot: ([:a 1] [:a 2] [:a 3])

13:13 defn: http://getclojure.org/examples/partial

13:13 * wooby is a big fan of partial for no particular reason

13:13 Borkdude: (doc ->>)

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

13:13 defn: oh no

13:13 http://getclojure.org:8080/examples/partial

13:13 there we go

13:14 http://getclojure.org:8080/examples/insert-your-fn-here

13:14 anyway, off to bed -- gnight

13:15 Borkdude: gnight defn

13:15 wooby: neato

13:24 alexyk: what's ret in amap? someone has a good example of amap?

13:40 stuartsierra: ret is the array that will be returned, same size as the input array

13:49 Borkdude: Is there an idiomatic way to do (?? x '(f1 f2 f3)) -> (f3 (f2 (f1 x))... compose or smth?

13:50 danlarkin: (doc comp)

13:50 clojurebot: "([f] [f g] [f g h] [f1 f2 f3 & fs]); Takes a set of functions and returns a fn that is the composition of those fns. The returned fn takes a variable number of args, applies the rightmost of fns to the args, the next fn (right-to-left) to the result, etc."

13:53 Borkdude: tnx

13:53 mattrepl: Borkdude: do you need to programmatically compose them? otherwise there's ->

13:58 Borkdude: I have a list of anonymous functions, I have to (apply comp l) them to make it one function

13:59 fogus: comp returns a function and ->/->> return "results"

14:06 alexyk: are amap/areduce intended only for Java arrays?

14:06 Chousuke: do they even work on anything else?

14:07 alexyk: nope...

14:08 so no equivalent reduce on a clojure vector, with index?

14:09 Chousuke: index? I guess not

14:09 stuartsierra: easy enough to write; there's "indexed" in contrib seq-utils

14:10 Borkdude: http://stackoverflow.com/questions/2553668/how-to-remove-list-of-words-from-strings/2556696#2556696 <-- I used comp for this

14:10 alexyk: stuartsierra: thx

14:11 is there an update-in for array?

14:12 meaning, for vector?

14:12 tomoj: alexyk: update-in?

14:12 alexyk: tomoj: how do you set a vector at position i?

14:13 tomoj: ,(update-in [[1 2 3] [4 5 6]] [1 2] inc)

14:13 clojurebot: [[1 2 3] [4 5 7]]

14:13 alexyk: ah

14:13 !

14:14 tomoj: matrices I guess

14:22 alexyk: cute how update-in applies to maps and vectors alike

14:26 naeu: OK, so here's my proposal for a string interpolation syntax, it would be implemented with a reader macro using the magic # as follows: (let [bar "quux"] #"foo ~bar ~(+ 2 3)")

14:26 alexyk: ,(update-in {:a [1 2]} [:a 1] #(+ % 3))

14:26 clojurebot: {:a [1 5]}

14:26 alexyk: now scala do that

14:27 bsteuber: naeu: #" is used for regexps

14:33 Borkdude: that looks pretty cool

14:33 (update-in {:a [{:b 1} 2]} [:a 0 :b] #(+ % 3))

14:33 ,(update-in {:a [{:b 1} 2]} [:a 0 :b] #(+ % 3))

14:33 clojurebot: {:a [{:b 4} 2]}

14:34 Borkdude: I think I'll use it for my daily example on Twitter :)

14:40 alexyk: Borkdude: I'm @khrabrov there :)

14:40 how do you typehint a clojure vector?

14:41 Chousuke: IPersistentVector

14:41 alexyk: kk

14:41 Chousuke: or hm

14:41 well, something like that :P

14:41 Borkdude: alexyk, great

14:44 alexyk: or, should I use a precondition to make sure a parameter is a vector?

14:45 stuartsierra: Type hints are not type assertions.

14:46 So if you want a check, us a precondition.

14:47 alexyk: ah right

14:48 wooby: or you can (vec arg) and hope for the best :)

14:48 i've done that in some functions to make seqs out of sets

14:53 cemerick: wooby: vectors are not seqs

14:53 wooby: err to turn into vectors i mean :)

15:19 alexyk: is clojure-contrib supposed to be compatible with clojure proper, both 1.2.0-master-SNAPSHOT github heads?

15:24 tomoj: yeah

15:27 alexyk: well it barfs for me :(

15:28 the dreaded java.lang.NoSuchMethodError: clojure.lang.RestFn.<init>(I)V

15:32 hiredman: clojurebot: suddenly!

15:32 clojurebot: Gabh mo leithscéal?

15:32 danlarkin: nooooooooooo

15:32 pjstadig: ~suddenly

15:32 clojurebot: CLABANGO!

15:32 danlarkin: yesssssss

15:33 pjstadig: clojurebot: suddenly

15:33 clojurebot: CLABANGO!

15:33 pjstadig: no exclamation point

15:34 alexyk: ~carramba!

15:34 clojurebot: I don't understand.

15:34 alexyk: ~привет, клоужербот!

15:34 clojurebot: excusez-moi

15:34 alexyk: ~what's your relationship with one hiredman?

15:34 clojurebot: hiredman <3 XeLaTeX

15:38 alexyk: clojurebot: does it mean hiredman doesn't <3 you anymore?

15:38 clojurebot: hiredman is slightly retarded

15:39 slyphon: is there an interactive debugger for clojure?

15:39 i.e. where you can set breakpoints, etc?

15:39 alexyk: println

15:39 slyphon: not quite

15:47 duncanm: if i want to write a Java method that can work in Clojure as something that returns multiple values, the return type to my Java method should return an ISeq, right?

15:47 is there a better interface?

15:47 Chousuke: You can return a sequence or a vector

15:48 IPersistentCollection might be the best

15:48 duncanm: if i return an object [], that will work too?

15:48 Chousuke: yes, but it will be a mutable array :/

15:48 Borkdude: aaaah, mutable, it hurts... nooooo

15:52 chouser: slyphon: many (most) java debuggers work with clojure code. jswat and netbeans at the very least.

15:53 slyphon: jswat, hm

15:53 chouser: ok, i'll have a look

15:53 chouser: do you know if slime/swank provide that kind of functionality?

15:54 chouser: slyphon: I don't use either, but I've heard recent chatter about a debug-repl. I don't know if that's based on the &env stuff or on the real java debugging api.

15:54 slyphon: ah

15:54 mm'kay

15:54 thanks

15:54 :)

16:08 alexyk: so I build clojure proper from git, contrib with it, and get the dreaded java.lang.NoSuchMethodError: clojure.lang.RestFn.<init>(I)V (NO_SOURCE_FILE:0) trying to (use 'clojure.contrib.str-utils2). ?

16:09 chouser: alexyk: built contrib using mvn?

16:09 alexyk: yep

16:09 installs as clojure-contrib-1.2.0-SNAPSHOT

16:09 which was confusing as I clojure proper is clojure-1.2.0-master-SNAPSHOT

16:09 chouser: hm, I was under the vague impression that did a clean first, but perhaps you should try mvn clean manually?

16:10 alexyk: chouser: did clean I think, but will again

16:10 chouser: hm...

16:11 alexyk: I wonder why "they" name them differently

16:11 also the readme files are named: readme.txt in proper and README.txt in contrib -- decide on a case already!

16:16 hmm, still the same...

16:18 hmm -- no duck-streanms in that contrib! is it still there?

16:19 or renamed?

16:20 dnolen: alexyk: renamed to io

16:21 alexyk: dnolen: so they killed 'e, ducks

16:21 'em

16:21 poor ducks!

16:21 what about str-utils2?

16:22 I guess I was picking those from some old crappy jar, they're no longer in contrib either

16:22 or, where's split now?

16:23 chouser: clojure.contrib.string

16:23 alexyk: yeah, grepped that

16:24 so, is there a big huge danger sign, all your legacy imports will fail, crap will be picked off classpath, and you'll pull your hair rebuilding contrib? :)

16:25 perhaps those legacy things should be left with asserts which fail and croak

16:25 chouser: I'm sure it'll be in the release notes for 1.2 when that's released. :-)

16:25 alexyk: chouser: pfft, who reads release notes :)

16:25 how 'bout pre-release notes?

16:25 or, release prenotes?

16:26 slyphon: alexyk: i think that's called "the dev mailing list"

16:26 chouser: also available as: #clojure

16:26 alexyk: slyphon: see, I suddenly want to partake of the named arguments goodness, change my project.clj, rebuild from git, and expect immediate nirvana!

16:27 which is the usual way of clojure

16:27 now I have to stare at the RestFn not found. This is not joyful!

16:27 chouser: note that the arugment order and some var names in string have changed against since str-utils2

16:28 alexyk: kk

16:28 LeNsTR: hhhhhhhhhhhhhhhhhh

16:28 ops

16:30 candeller: hi how can a function that takes a single argument be called for every element in a collection? Lets say I wrote a function that takes a number and sees if its a prime number and I want to iterate through a collection

16:31 Borkdude: candeller: map

16:31 ,(doc map)

16:31 clojurebot: "([f coll] [f c1 c2] [f c1 c2 c3] [f c1 c2 c3 & colls]); Returns a lazy sequence consisting of the result of applying f to the set of first items of each coll, followed by applying f to the set of second items in each coll, until any one of the colls is exhausted. Any remaining items in other colls are ignored. Function f should accept number-of-colls arguments."

16:31 candeller: (map myfunc [collection]) would work?

16:31 Borkdude: yes

16:32 chouser: ,(map odd? [0 1 2 3 4 5])

16:32 clojurebot: (false true false true false true)

16:32 Borkdude: ,(map (fn [x] (+ x 1)) [1 2 3])

16:32 clojurebot: (2 3 4)

16:32 candeller: oh indeed it does, i swear i tried it and it didnt:

16:32 thanks a lot:D

16:32 Borkdude: that's what we are waiting here all day for

16:34 erikcw1: I have a map that uses strings as keys (the data comes from JSON). {"country" "US" ...}. Is it possible to use destrucuring with a dictionary like this? Or does the key have to be a :key?

16:36 alexyk: why do they still insist on having a repeat in string which prevents a simple use suck-all names?

16:36 shouldn't they all at least not conflict with the core?

16:37 Borkdude: ,(let [{a "country"} {"country" "US"}] a)

16:37 clojurebot: "US"

16:38 Borkdude: erikcw1, seems to work

16:38 alexyk: and what's seq-utils now?

16:38 I guess seq?

16:39 chouser: ,(let [{:strs [country]} {"country" "US"}] country)

16:39 clojurebot: "US"

16:39 erikcw1: cool! thanks!

16:41 Borkdude: chouser, even better

16:41 ipostelnik: chouser, is :strs destructuring new in 1.2?

16:41 chouser: ipostelnik: nope, been there as long as :keys

16:41 bsteuber: but this is new:

16:42 chouser: Borkdude: well, you need both, especially for strings

16:42 bsteuber: ,((fn [& {:strs [a b]}] [a b]) "a" 42 "b" 77)

16:42 clojurebot: [nil nil]

16:42 cemerick: heh, I never knew about that

16:42 bsteuber: hmpf

16:42 alexyk: where can I read on the essence of the named arguments?

16:42 chouser: bsteuber: clojurebot's running old clojure

16:42 bsteuber: yeah, I just realized :)

16:42 I get [42 77]

16:43 Borkdude: what's the new thing, I don't know what the old thing is

16:43 everything is new to me ;)

16:43 astoddard: I am trying to understand "future-cancel". The doc says it will cancel the future "if possible". Is there some definition of possible?

16:44 bsteuber: Borkdude: map destructuring on &-arguments

16:45 candeller: hmm, regarding the map function: I wrote something like this: http://ideone.com/v6lNwBbu and it doesnt print anything, although I suppose it should. Is there anything I got wrong ?

16:45 chouser: astoddard: the vague definitions is "most blocking things" -- locks, IO and such will be interrupted

16:46 bsteuber: candeller: welcome to lazy sequences :)

16:46 chouser: astoddard: a simple compute loop like (loop [] (recur)) will not be interrupted.

16:46 candeller: bsteuber: whats that? I guess I will still need to read up :P

16:47 bsteuber: the sequence doesn't actually evaluate until needed

16:47 Borkdude: candeller, I think in ideone you need to call prn or some thing that causes side effects

16:47 bsteuber: but you can force it

16:48 Borkdude: candeller: http://ideone.com/mlytuebr

16:48 candeller: oh wait, you already called println... didn't even notice that hehe

16:49 candeller: maybe it only shows the result of the last expression

16:49 astoddard: What about the case where a future calls a includes "inner" functions mapped across a big list of file names, doing IO on the files, would the "outer" map be interruptable?

16:50 bsteuber: candeller: on a normal repl this should still print

16:50 astoddard: It seems that a lot of IO continued after I called future cancel.

16:50 candeller: hmm, it prints on the repl, just checked, I had it compiled in netbeans and it didnt

16:51 by the way, as I had just begun learning clojure, what do you mean by 'side-effects?'

16:52 bsteuber: ,(let [x (map print [1 2 3 4 5 6 7])] nil)

16:52 clojurebot: nil

16:52 Borkdude: a side effect is something that affects the outer world, like printing to a screen, writing to a file, etc

16:52 bsteuber: ,(let [x (doall (map print [1 2 3 4 5 6 7]))] nil)

16:52 joshua-choi: candeller: A side-effect is something like modifying a file, printing a message, or mutating a mutable object, as opposed to just calculating something.

16:52 clojurebot: 1234567

16:52 joshua-choi: Purely mathematical functions lack side-effects.

16:52 candeller: ah i see

16:52 bsteuber: candeller: a doall might do the job for you

16:53 ,(doc doall)

16:53 clojurebot: "([coll] [n coll]); When lazy sequences are produced via functions that have side effects, any effects other than those needed to produce the first element in the seq do not occur until the seq is consumed. doall can be used to force any effects. Walks through the successive nexts of the seq, retains the head and returns it, thus causing the entire seq to reside in memory at one time."

16:53 bsteuber: ,(doc dorun)

16:53 clojurebot: "([coll] [n coll]); When lazy sequences are produced via functions that have side effects, any effects other than those needed to produce the first element in the seq do not occur until the seq is consumed. dorun can be used to force any effects. Walks through the successive nexts of the seq, does not retain the head and returns nil."

16:54 candeller: hmm, ok i guess i will need to read up a little, as i had been exploring on my own browsing the api, will probably make it clearer, either way thanks a lot :)

16:55 bsteuber: candeller: yeah, there's really a lot of new stoff for post people - so a guided tour might be helpful

16:56 Borkdude: ,(doc map)

16:56 clojurebot: "([f coll] [f c1 c2] [f c1 c2 c3] [f c1 c2 c3 & colls]); Returns a lazy sequence consisting of the result of applying f to the set of first items of each coll, followed by applying f to the set of second items in each coll, until any one of the colls is exhausted. Any remaining items in other colls are ignored. Function f should accept number-of-colls arguments."

16:56 Borkdude: ah map returns a lazy sequence

16:56 bsteuber: hm, the "post" was not supposed to be there :)

16:57 Borkdude: bsteuber: post people, is that something like "ubermensch" but then different? ;)

16:57 so dorun is like force in other fp languages?

16:57 alexyk: why cannot do this:

16:58 ,(let [points [1 2 3]] (map #([points %]) [1 2]))

16:58 clojurebot: java.lang.IllegalArgumentException: Wrong number of args passed to: PersistentVector

16:58 alexyk: but can do this:

16:58 ,(let [points [1 2 3]] (map #(get points %) [1 2]))

16:58 clojurebot: (2 3)

16:59 ipostelnik: alexyk, (let [points [1 2 3]] (map #(points %) [1 2]))

16:59 ,(let [points [1 2 3]] (map points [1 2]))

16:59 clojurebot: (2 3)

17:00 ipostelnik: alexyk, vectors is an IFn with index as the arg

17:00 Borkdude: ,([1 2 3] 1)

17:00 clojurebot: 2

17:00 Borkdude: ah I see

17:00 alexyk: ah right

17:04 erikcw1: Is it possible to do destrucuting in a multimethod? Basically I want to pass a dict to the multimethod, but then do some destructuring inside the methods...

17:05 Borkdude: erikcw1, why don't you just try and see?

17:06 dnolen: erikcw1: you can.

17:06 erikcw1: I've been playing with it and I keep getting errors

17:07 http://pastebin.com/V9tnk1XL

17:10 dnolen: erikcw1: that works for me

17:10 what errors are you getting?

17:11 erikcw1: Yeah -- that works -- but I'm trying to figure out how to move the let into the arg list and do the destrucutring there.

17:13 dnolen: erikcw1: http://pastebin.com/8aWbMNE0 should work

17:14 erikcw1: dnolen: that's what I was after! Thanks -- I'm still trying to get up to speed obviously...

18:53 nteon: how can I expose a clojure function (in a :gen-class file which is implementing an interface) as a static function to java?

18:58 n/m should have read the docs

18:58 I can do it iwth :methods

19:52 dnolen: is it possible to type hint arguments to the methods of deftype?

19:57 alexyk: how do you get clojure version from repl?

19:58 dnolen: *clojure-version*

19:58 ,*clojure-version*

19:58 clojurebot: {:interim true, :major 1, :minor 1, :incremental 0, :qualifier "master"}

20:04 dnolen: also how do you type-hint deftype'd instances?

20:08 alexyk: dnolen: this is Chouser-Level Question, or CLQ :)

20:08 thx for the version

20:08 dnolen: heh, yeah I was hoping more people had played around with deftype and typehinting

20:14 Raynes: Turtles all the way down.

20:14 Oops, wrong channel. :|

20:14 chouser: dnolen: the type hint would go on the interface that the deftype is implementing

20:15 Raynes: yeah, that doesn't apply here. Here we have turles all the way down to the JVM.

20:15 turtles

20:15 dnolen: chouser: but how do you type-hint a deftype'd thing?

20:16 chouser: you can put type metadata on the fields, but all the method signatures are defined elsewhere.

20:16 you can't add a new method in a deftype

20:17 oh, the instance, I'm sorry.

20:17 hang on

20:17 dnolen: chouser: thx

20:17 chouser: let's see -- you shouldn't need to. Again, hint using the interface that's being implemented

20:19 dnolen: chouser: so hint the protocol? or the actual method?

20:19 here's what I'm trying to do. I'm trying implement a simple vector math lib with deftype.

20:20 chouser: protocol method calls don't need hinting

20:20 dnolen: a method needs to take a another vec3 instance. don't I need to type hint this for perf?

20:20 chouser: ahhh

20:21 you want to do a field lookup on a datatype instance -- so just use (:fieldname vec3)

20:29 dnolen: chouser: hmm, deftype is fast, creation, access. but I guess no matter what you do mutable math is just going to be faster (you don't have the overhead of object creation?)

20:30 chouser: hm... changing a value in a mutable array will be faster than creating a new datatype instance with an update value.

20:30 the math itself should be the same speed as java, as long as you're using primitives.

20:31 dnolen: sadly more than an order of magnitude faster it seems.

20:31 chouser: the way to avoid that I think is to move the boundary on mutability up higher.

20:32 dnolen: chouser: this is what my code looks like http://gist.github.com/352580

20:32 chouser: hm...

20:33 protocols don't yet support primitives

20:33 oh, I see you don't need it to

20:34 yes, I'd bet (:x other) is still boxing the return value

20:34 hmmm

20:36 dnolen: chouser: some perf numbers from my machine

20:37 I know getting close to mutable math is pointless. but I'd like to get close to mutable math+clone

20:37 or maybe this is a silly exercise and I just to all this stuff in a cell :)

20:37 chouser: if you AOT compile that, the deftype will actually produce a your.namespace.vec2 class -- you can hint that

20:37 (.x #^vec2 other)

20:40 dnolen: chouser: so you don't think the fact that "other" in the method definition is not a problem?

20:40 chouser: heh, can't parse that question

20:40 but this is interesting, from the deftype docstring:

20:40 dnolen: I don't see how the JVM get fast dispatch w/o (add [#^vec3 other] ...) in the deftype

20:40 chouser: "In the method bodies, the (unqualified) name can be used to name the class (for calls to new, instance? etc)."

20:41 did you try that?

20:41 from that quote I just pasted, it might work

20:41 dnolen: "Can't find matching method: add, leave off hints for auto match."

20:41 :)

20:41 chouser: then you'd do (.x other) instead of (:x other). This is about primitives, not type hinting.

20:41 ah!

20:41 ok, try hinting it when it's used instead

20:41 (.x #^vec2 other)

20:42 dnolen: HOLY MOLY

20:42 chouser: you're the man.

20:43 as fast as mutable math + clone

20:45 chouser: well, good. :-)

20:46 it's weird but usually if you see a 30-40x slowdown it's because of reflection, 8-10x is usually boxing

20:46 dnolen: that worked without AOT compilation?

20:46 Raynes: LauJensen: Let's write a chouserbot in J.

20:47 chouser: will I be replaced by a very small J script?

20:48 dnolen: chouser: yes! rhickey is a genious and you're the messenger :) I updated the gist.

20:48 the body of add needs to look like this (vec2. (+ x (.x #^vec2 other)) (+ y (.y #^vec2 other)))

20:48 chouser: ok. that's interesting -- inside the deftype, vec2 can be used as a classname even though there may be no class by that name.

20:49 dnolen: 1000000 vectors added in 27ms.

20:49 Raynes: chouser: A very, very small J script. :D

20:49 chouser: Raynes: not sure there's eny such thing as a large J script.

20:49 Raynes: chouser: Indeed.

20:52 defn: Raynes: don't know if you saw this but: http://getclojure.org:8080/examples/function-name-goes-here

20:52 i dont have it auto-updating from #clojure yet, and it's still pretty ugly as far as formatting goes, but...

20:53 chouser: defn: are the examples getting pulled from some manual list? or is it somehow automatic?

20:54 defn: it parses all of the logfiles in a background thread at first, and then (eventually) will just add to that ref as people write into the channel

20:54 chouser: oh, it's pulling from #clojure?

20:54 defn: *nod*

20:54 not yet, but it will be

20:54 chouser: does it compute it's own return value, or use clojurebot's?

20:54 defn: i mean, all the logfiles are from #clojure, but it's not doing up-to-the-moment parsing

20:55 Raynes: defn: That's great. I'll slap something in my bot asap.

20:55 defn: chouser: it computes it's own return value using Licenser's clojure sandbox

20:55 chouser: defn: that's a really clever idea

20:55 defn: chouser: still pretty rough around the edges but it's getting there -- Licenser helped a lot

20:55 Raynes: Something like $example func -> http://getclojure.org:8080/examples/func

20:56 Licenser is awesome.

20:56 chouser: http://getclojure.org:8080/examples/ref is taking a while

20:56 Licenser: Yea I agre Licenser is totally awsome

20:56 :P

20:56 defn: haha

20:56 chouser: yeah that doesn't look good :)

20:57 Raynes: ;)

20:57 Licenser: is that web walton?

20:57 defn: Licenser: yeah, sort of :)

20:57 Raynes: Licenser: Made any progress on that . bug?

20:57 Licenser: neat

20:57 Nah sorry, my brother demands some of my awsomness :P (just kidding, he's staying over easter)

20:58 defn: chouser: yeah something is broken site-wide it looks like

20:58 * defn investigates the repl

21:02 defn: uh oh... :)

21:02 okay try now

21:03 if you refresh you can see them being added in real team

21:03 which is sort of neat

21:05 chouser: so it caches the results? starting when you first ask?

21:05 maybe "ref" breaks it

21:06 defn: it just starts searching log files, finding sexps, and then it tests them in a try/catch -- it adds things to a *sexps* ref by tagging them with :good or :bad depending on if it runs or not

21:06 if none are returned, it will show you :bad tag results

21:07 chouser: it seems like it happens over time

21:07 this was running all day and had no problems but then it just went unresponsive like you saw a minute ago

21:07 chouser: I saw it earlier, but it seems broken again.

21:07 defn: noo!

21:07 ugh

21:08 yeah my repl is hung

21:09 and here i was feeling all proud of myself

21:09 chouser: it's a really fantastic idea

21:09 Licenser: ref isn't in the whitelist I think

21:10 defn: Licenser: how do we know if something is in the whitelist?

21:13 Licenser: defn: well you can look in it

21:13 or you can try to run it it will tell you which functions fail the whitelist

21:21 defn: http://github.com/Licenser/clj-sandbox/blob/master/src/net/licenser/sandbox/safe_fns.clj

21:24 Raynes: Which is my doing. :D

21:24 Licenser: Raynes: yap

21:25 Raynes: J is confusing. :(

21:30 Licenser: defn: you can esaiely extend yor own matcher :) also you can send either me or Raynes functions that we forgot

21:34 Raynes: defn: You might want to send them to me. I never sleep. :|

21:34 :p

21:35 Licenser: Raynes: yes you do but in a different timezone: p

21:35 Raynes: Hehe.

21:37 defn: Raynes: I don't think any of us sleep

21:38 crowbar7: nope

21:38 defn: I think I slept for 4 hours yesterday and I was able get a response from Licenser within 15min the whole time

21:38 :)

21:39 When I get done with work I go home and code (I get less done, but it is a nice way to relax)

21:39 Crowb4r: defn: Yeah, same here

21:41 Don't need my other account online at the moment

22:00 brian__: what is the covention java booleans ,ie it seems java returns 0 when true and -1 when false, ie

22:01 nteon: brian__: ugh, what java does that? i though java programmers hated c-style int return types

22:02 brian__: (.compareTo "A" "A") 0

22:02 0

22:02 (.compareTo "A" "A")

22:02 0

22:02 (.compareTo "A" "A")

22:02 0

22:02 (.compareTo "A" "A")

22:02 0

22:02 (.compareTo "A" "A")

22:02 sorry about that

22:03 nteon: brian__: oh, thats because its a tri-state. it returns -1, 0 or 1

22:03 brian__: (.compareTo "A" "B")

22:03 -1

22:03 (.compareTo "A" "B")

22:03 -1

22:03 (.compareTo "A" "B")

22:03 -1

22:03 when is it 1?

22:04 cemerick: brian__: that's sort order, not equality

22:04 nteon: ,(.compareTo "B" "A")

22:04 clojurebot: 1

22:04 nteon: :)

22:04 brian__: ok

22:04 nteon: -1 is <, 0 is ==, 1 is >

22:04 cemerick: brian__: see java.lang.Comparable

22:04 javadocs are your friend

22:05 brian__: yea but in clojure, how do you deal with java boolean, to be "idiomatic"

22:06 cemerick: clojure boolean are java booleans

22:06 to generalize, all of clojure scalars are java scalars

22:07 nteon: ,(= "a" (.toLowerCase "A"))

22:07 clojurebot: true

22:07 nteon: ,(= "b" "a")

22:07 clojurebot: false

22:07 brian__: ok, thanks

22:07 nteon: ,(doc =)

22:07 clojurebot: "([x] [x y] [x y & more]); Equality. Returns true if x equals y, false if not. Same as Java x.equals(y) except it also works for nil, and compares numbers and collections in a type-independent manner. Clojure's immutable data structures define equals() (and thus =) as a value, not an identity, comparison."

22:09 brian__: i was using (if (java boolean)), which is true for -1 and 0

22:09 cemerick: brian__: that's...unadvisable

22:10 brian__: yea, actally compareTo, as you said, is not a boolean, oops

22:10 JonSmith: is there a fleetdb version that runs in clojure 1.2?

22:14 brian__: i dont understand this though "Clojure's immutable data structures define equals() (and thus =) as a value, not an identity, comparison.""

22:15 cemerick: brian__: I would suggest picking up Halloway's book to start, "Programming Clojure"

22:15 it provides a very solid and gentle introduction

22:15 brian__: yea, i have it

22:15 JonSmith: is like, lets say you have 2 strings "foo" and "foo"

22:16 or like (let [f "foo", g "foo"] (= f g))

22:16 if it is value that's true

22:16 if it is identity that is false

22:16 so pretty much, it works the way you would expect it to

22:17 brian__: ok , i think i get it

22:17 f ang g are different identities with equal values

22:17 cemerick: Put another way, persistent data structures allow you to treat maps, lists, vectors, etc. as values more similar to numbers than the mutable objects that are common elsewhere.

22:18 JonSmith: yup

22:18 alexyk: in lein-swank, how do you specify the clojure version for the repl?

22:18 brian__: however Im still trying to grasp that kind of mystical idea

22:19 JonSmith: well it also ties into that every time you do an operation on an immutable datastructure, you get a 'new' datastructure

22:20 so using identity comparison doesn't make a lot of sense, as most of the time you will be getting something with a different identity

22:21 cemerick: brian__: e.g. if you perform addition -- (+ 1 1) -- you're not changing either of the 1's, and the result you get is a particular value that will itself remain unchanged forever. Same thing with (merge {:a 5} {:b 6})

22:23 Licenser: well I go to nap, see you later

22:23 Raynes: cemerick: <p>How's it going?</b>

22:24 p*

22:24 /fail

22:24 cemerick: Raynes: good, you?

22:24 Raynes: Oh, forget it now. Smartassery doesn't work when you screw up a closing tag.

22:25 brian__: yes, i understand that, its seems more concrete than "data and programs are one and the same"

22:25 cemerick: oh, I see. That was an XML pun. Clever. 9.9

22:25 Raynes: It was supposed to be. :x

22:25 cemerick: brian__: homoiconicity is a higher-level topic, I'd say. Very worthwhile tho

22:26 brian__: ok, i will follow the path

22:26 cemerick: brian__: welcome :-)

22:32 alexyk: so, how do I defn split depending on the version of clojure, form c.c.str-utils2 or c.c.string, with opposite order of regexp strarg? is it a job for a macro?

22:33 defn: alexyk: is there a back story to this?

22:33 i just walked in

22:33 alexyk: defn: that's the whole story

22:34 defn is used in generic sense :)

22:34 in 1.2.x things a-changing'

22:34 cemerick: I guess we're starting to need those ifdef-esque things from CL

22:35 * cemerick can't remember what they're called :-(

22:36 alexyk: hmm, this just works: (if 1 (defn f [x] (inc x)) (defn f [x] (dec x)))

22:36 so I guess this will serve for the toplevel...

22:36 defn: alexyk: haha trust me i removed that nick highlight ages ago :)

22:37 alexyk: in my own defense i had this nick pre-clojure

22:37 alexyk: defn: my client on Mac shows a pop-up via Growl on my nick... so it's unfortunate :)

22:38 defn: heh -- i use irssi so i have a hilight window, i pick very generic nicknames it would seem

22:38 im "code" on another network

22:38 * defn facepalm

22:40 cemerick: alexyk: here's what we'll need in clojure eventually: http://www.faqs.org/faqs/lisp-faq/part2/section-17.html

22:41 alexyk: "The nascent Common Lisp standard" :)

22:41 the young Simula-67...

22:41 cemerick: indeed! :-)

22:45 alexyk: here's my reader conditionalization: http://paste.pocoo.org/show/196610/

22:45 horrible kludgilization

22:46 (+ bgs000 100)

22:46 defn: I think I write clojure code in a very weird way. I use many many newlines, the indentation helps me. Is that "wrong"?

22:46 cemerick: yeouch

22:47 alexyk: do you really need to support 1.1 and 1.2?

22:47 alexyk: defn: it's treason. leave immediately

22:47 cemerick: defn: you'll get people flinching at you forever :-)

22:47 alexyk: cemerick: I'm writing a code for a job interview. It must no matter where :)

22:47 run it must

22:47 on Mars in a jar of acid lava

22:48 cemerick: alexyk: can't just pack clojure into your jar, and ship it in one shot?

22:48 defn: ^

22:48 cemerick: Regardless, I certainly don't mind getting samples that have particular requirements.

22:48 defn: cemerick: flinching in fear of how awesome I am?

22:49 alexyk: cemerick: hmm... I describe how to get things with lein... but reviewers may have their own idiosynracies

22:49 cemerick: Those sorts of things are totally orthogonal to what actually goes into a hiring decision.

22:49 defn: likely no, but you can think whatever you like ;-)

22:49 alexyk: cemerick: true, but I just like to overdo it

22:49 defn: http://mumble.net/~campbell/scheme/style.txt

22:49 I often wonder if that's relevant for clojure

22:50 cemerick: alexyk: personally, I'd find what you pasted to be a distraction if I were evaluating interview samples, etc.

22:50 alexyk: how long you guys think before some IronSteel Clojure compiles into x64_86 and runs at the speed of light

22:50 cemerick: defn: a lot of it is very sensible. I don't agree with the indentation mentioned there, but that's minor.

22:51 alexyk: cemerick: that's just a support piece of code. I might think is shows a concern for legacy software :)

22:51 or general production-cycle awareness

22:51 or whatnot

22:51 when people start talking identation, the language moves too slow

22:51 wait 5 years and come back

22:52 by then, there will be a Steve Jobs Tab, self-identing and iPad-compatible

22:52 with embedded AI

22:53 * alexyk goes back to the code

22:54 riddochc: I'm having a heck of a time with some classpath issues. Not a java person... On trying to :use or :require things from jars, I get NoClassDefFoundErrors...

22:55 This is with current master on clojure and clojure-contrib. I'm trying to hunt down a bug in another library that's a result of changes in clojure, by bisecting clojure itself, and for the life of me, I'm having an impossible time scripting runs of building clojure & contrib and running the result with some existing jars.

22:57 cemerick: riddochc: that sounds painful in general

22:58 What class is it failing to find?

22:58 defn: alexyk: :)

22:58 it is a terrible difficult bit of "standardization" to be concerned with (indentation and style)

22:59 alexyk: defn: imaging the glee of a Clojure Style Nazi, beating a new unruly hire into tabulation

23:00 the Company White Space and Parentheses Policy (sign here)

23:00 defn: heh -- although there are some things which i sort of prefer that IMO increase readability

23:01 alexyk: defn -- see, I may hide the IRC window, but Growl will show a pop-up if you mention me! the power of Growl is immence. True, I think uniformity is most important in big teams (more than one person)

23:01 so uniformity is what matters, as readability is subjective

23:01 defn: specifically when you do something like (reduce (fn [x] (comment a very long and complicated function)) {})

23:01 riddochc: Interesting. It seems to be a problem with *recent* versions of clojure. My 1.1.0-master-SNAPSHOT from January works fine. Garg.

23:01 alexyk: and the Style Nazi is whoever got there first in a company, and has sadistic inclinations

23:02 defn: being able to have that {} on the same level as the initial reduce is nice

23:02 at the end of a line it makes me think a bit harder

23:02 alexyk: that's all subjective IMHO

23:02 defn: yeah im not trying to tell anyone this is the right way

23:02 just something ive noticed about the way i read clojure

23:02 alexyk: I write 200 character one-liners in REPL and then unroll them in the editor once they work

23:03 kinda all one big line to me :)

23:03 heck, 500 characters sometimes

23:03 rlwrap works wonders

23:03 defn: alexyk: same here

23:03 what's rlwrap?

23:03 alexyk: the thing which is better than jline

23:03 C-r in slime

23:04 standalone GNU readline for commandline anything

23:04 defn: hmm, never used C-r

23:04 it's not like C-j is it?

23:04 alexyk: defn: now that's inexcusable

23:04 defn: :X

23:04 alexyk: C-r is the basis of history! :)

23:05 incremental backward search

23:05 through commandline history

23:05 defn: oh duh

23:05 alexyk: in emacs-like thingies

23:05 defn: im sorry about that -- i wasnt putting 2 and 2 together

23:05 (which equals 5 btw)

23:05 alexyk: np, kidding

23:06 cemerick: when's the next New England Clojure meetup at your place again?

23:07 cemerick: alexyk: Not sure -- it's been a while! You mean the wmassdevs group, or a clojure-specific meetup at the Snowtide offices?

23:08 alexyk: cemerick: I guess I saw some mentions of a latter! I'm on the VT/NH border so guess you cannot be too far from a Dartmouth-Boston line can you?

23:09 defn: cool: http://github.com/swannodette/macros-tutorial/

23:09 <--still has no clue about macros

23:09 riddochc: Great, check this out. With master on clojure and clojure-contrib:

23:09 (ns bughunt (:require [clojure.contrib [duck-streams :as ds]]))

23:10 cemerick: alexyk: we had Rich up for a talk almost exactly two years ago, which was great http://muckandbrass.com/web/pages/viewpage.action?pageId=2752684

23:10 riddochc: java.io.FileNotFoundException: Could not locate clojure/contrib/duck_streams__init.class or clojure/contrib/duck_streams.clj on classpath: (NO_SOURCE_FILE:3)

23:10 alexyk: cemerick: well perhaps it can be a bi-annual tradition! :)

23:10 every even minor version

23:11 cemerick: we haven't had anything clojure-specific since then. You can certainly come down for a wmassdevs meetup, which is a lot more informal.

23:11 Clojure folk scattered through there, too.

23:11 alexyk: Scala people got the Boston Area Scala Enthusiasts going monthly at the Boston Google HQ

23:11 riddochc: contrib *is* on my classpath, is what's weird about this.

23:12 cemerick: alexyk: http://wmassdevs.com/ although most of the action (FWIW) is on the list @ http://groups.google.com/group/wmassdevs

23:12 alexyk: riddochc: The ducks are dead. (use 'c.c.io) instead

23:12 cemerick: riddochc: there's been a significant reorg of contrib

23:12 there's a thread about it on the clojure-dev list

23:12 defn: (ns sort-of-funny (:require [clojure.contrib.duck-streams :as dick-streams]))

23:13 riddochc: cemerick: Evidently. So much for easily bisecting contrib...

23:14 alexyk: headius you don't know what was one line above you

23:14 headius: oh yeah?

23:15 alexyk: cemerick: now what "e strip mall with the Wal-Mart and the Barnes and Noble" is meant there, out of 1,000,000,000 in the US? :)

23:15 cemerick: feh, what a bad description :-P

23:15 alexyk: headius: defn can tell you! :)

23:16 cemerick: alexyk: In Hadley; it's the only Panera around

23:16 defn: haha no thanks -- while parsing all the clojure logs i found someone did that awhile back and juvenile as it was, I chuckled

23:16 btw -- when are we switching to clojure.contrib.io*

23:16 riddochc: So, the bug I *intended* to be hunting down was in a library, clj-peg. Two different runs, the only difference being which version of clojure I'm loading in the classpath. With 1.1.0 from early january, (ns bughunt (:use (com.lithinos.clj-peg core string-wrapper))) gives me nil, conveniently. With master, it gives me this: java.lang.ExceptionInInitializerError (NO_SOURCE_FILE:1)

23:17 alexyk: cemerick: ha, I can take Amtrack to Amherst!

23:17 riddochc: Same classpath, *except* for the pointers to clojure and clojure-contrib.

23:17 alexyk: almost a straight line from Dartmouth

23:18 cemerick: alexyk: how far is that?

23:18 alexyk: 2 hours

23:18 cemerick: riddochc: yeah, I got one of those a while back. They're buggers to track down.

23:18 alexyk: but I love Amtrak and have people to visit at U Amherst

23:18 so may be one day

23:18 cemerick: Amherst or UMass?

23:19 alexyk: UMass

23:19 riddochc: cemerick: Guess I'll be bisecting clojure for a couple reasons...

23:19 alexyk: cemerick: so you're practically at Amherst right

23:19 cemerick: riddochc: bisecting seems like a long path to take. I'd trace the dependencies of the libs in that :use and find the root of the problem.

23:20 alexyk: about 30 min away, yeah

23:20 alexyk: gogole maps shows Hadley almost in Amherst

23:20 google maps

23:20 slyphon: oh man

23:20 cemerick: riddochc: it's not like you'll want to patch clojure

23:20 slyphon: hadley!

23:20 wikkid awesome!

23:20 cemerick: alexyk: we're not in Hadley, but the wmassdevs meetings are

23:20 alexyk: ah ok

23:20 cemerick: slyphon: another local-yocal?

23:21 slyphon: cemerick: former UMass student

23:21 alexyk: I wonder why not in Amherst than in a nice academic cafe...

23:21 slyphon: cemerick: used to live in Butterfield

23:21 cemerick: alexyk: amherst doesn't have any good spaces for a meetup

23:21 slyphon: cemerick: from what i can remember, it was nice :)

23:21 cemerick: slyphon: it is :-) Where are you now?

23:21 slyphon: Noo Yawk

23:21 alexyk: cemerick: academics must gather somewhere! just open the laptops and scare them away!

23:22 slyphon: cemerick: you a student?

23:22 faculty member?

23:22 Pioneer Valley townie?

23:22 cemerick: slyphon: ugh, ouch :-)

23:22 small software company owner

23:22 slyphon: hahahahaha

23:22 ooooh

23:22 cool!

23:23 cemerick: alexyk: ech, regardless, I try to stay out of amherst for the most part. Hadley and Northampton are more my style.

23:23 slyphon: northampton is the shit

23:23 cemerick: slyphon: where are you working?

23:23 alexyk: cemerick: yeah, need to visit to see. Only read "An Arsonist's Guide to New England Writer's Houses" set in Amherst so far, but get the idea :)

23:23 * slyphon has seen more good shows at the Iron Horse than anywhere else

23:24 slyphon: cemerick: I'm working for a startup in NY, strangely enough, right across the street from Goldman Sachs

23:24 motionbox.com is the site

23:24 alexyk: slyphon: did you see the new mural described in the New Yorker then?

23:24 cemerick: downtown is the new hip spot for small co's these days I guess

23:24 riddochc: cemerick: Though it sounds like clojure is the issue, since it's not loading things consistently with :require between 1.1.0 and master.

23:24 slyphon: alexyk: hah, that's behind the bulletproof glass and the bomb-sniffing dogs

23:25 alexyk: slyphon: but still can you see it at all?

23:25 slyphon: cemerick: yeah, well, the real estate prices down there are stupid cheap (after GS totally ruined the world economy)

23:25 alexyk: i'll have to take a look next time i go by

23:26 cemerick: riddochc: Certainly possible, but I'd bet on some code you control not tracking changes in clojure that aren't going to be reverted. Either way, you know your codebase better than clojure's, and it's likely simpler and smaller.

23:26 slyphon: i usually try to avoid it, i have some phobia that i'm going to run into Darth Vader coming out of a meeting

23:26 alexyk: slyphon: are you using clojure for work?

23:26 slyphon: alexyk: yeah, I'm the systems architect, so i'm using it as part of a little beta project

23:26 cemerick: alexyk: Interesting-looking book, I'll have to check it out.

23:27 slyphon: trying to make our encoding queue a little smarter

23:27 alexyk: cemerick: I think if you disprefer Amherst you'll enjoy it :)

23:27 slyphon: we're mainly a rails shop, which gets you so far

23:27 cemerick: alexyk: nice :-D

23:28 alexyk: slyphon: interesting, thought clojure startups are only in the Bay Area

23:28 slyphon: well, i'm adventurous

23:28 :)

23:28 cemerick: we looked at rails before jumping in bed with compojure...and *wow* there's a lot there. Way, way too complex and magical for me.

23:28 slyphon: rails is good for what it does

23:28 it's not quite as magical as people think, and a lot of the time you're trying to un-magic it

23:28 cemerick: That's what I hear. It seemed like too much to grok, especially given that we're fully committed to clojure otherwise.

23:29 riddochc: rails is okay until you actually need something beyond what it's designed to make easy.

23:29 slyphon: yeah

23:29 we've gone pretty far with it

23:29 and it does scale, despite what people think

23:29 it's just that scaling is hard, no matter what language you're using

23:30 riddochc: So long as you don't need anything the rails people haven't already thought of, you're fine with rails.

23:30 slyphon: ehh

23:30 that's not exactly true

23:30 we've plugged in MongoDB and a lot of other stuff

23:30 our encoding queue is based in rails

23:31 it's not a *good* choice, but it's served us allright for the last 2 years or so

23:31 riddochc: Okay, it might not be completely true. I gave up on rails long enough ago that things have likely changed a lot in the meantime.

23:31 slyphon: riddochc: yeah, i mean

23:31 look, rails is better than PHP

23:32 (j)ruby is a good language that I've found covers 90% of the cases i need it to cover

23:32 jruby actually lets you scale horizontally more easily

23:32 albino: what 10% are you missing?

23:32 defn: jruby is exceedingly awesome

23:32 riddochc: Oh, absolutely. You won't hear me advocating PHP over pretty much anything... though I suppose I might consider it before doing a web app in forth, I suppose.

23:32 slyphon: albino: macros?

23:32 riddochc: HAH

23:33 albino: i dunno, it's more the fact that we have a large legacy codebase

23:33 that's stuck in rails-2.1 and on c-ruby 1.8.7

23:33 albino: slyphon: ugh

23:33 slyphon: that makes it difficult to scale without "throwing hardware at the problem"

23:33 so we've had to get creative

23:33 riddochc: Hm. Then again, forth might actually have a stronger tendency to stylistic consistency than PHP. I might reconsider that...

23:33 albino: throwing hardware is fun if you have the budget to do so

23:33 slyphon: and try to chip away at the hairball (to mix metaphors)

23:33 indeed

23:34 defn: php is i think without a doubt the ugliest mixture of language i've ever seen

23:34 i have to write some of that at work in the next few days -- and i am absolutely dreading it

23:34 slyphon: i'm using clojure for a specific case where i need JTA/2PC

23:35 and i didn't dig Scala, and I got tired of doing stuff in jruby

23:35 riddochc: Okay, I might use PHP for a web app before hand-coding assembly for the same... ;)

23:35 slyphon: riddochc: heh

23:35 albino: riddochc: what about coding a webapp in C, would you take php over that?

23:35 slyphon: or classic C cgi with embedded HTML

23:35 defn: poor PHP'ers -- I sort of feel bad for them

23:35 all this hatred

23:35 slyphon: defn: it's hard being dumb

23:35 albino: well deserved

23:36 riddochc: albino: That's a tough question. I dislike C rather strongly, too. Though I probably shouldn't say that *too* loud...

23:36 defn: some of them just dont know any better -- lisp is a scary thing to many people unfortunately

23:36 slyphon: is there a way of seeding the random number generator that 'shuffle' uses?

23:36 defn: i just got my friend started on clojure -- he has been watching me for 4-5 months over my shoulder. at first he thought it was "weird", and then it was "kind of interesting", and now it's "wow"

23:36 slyphon: that's why i like clojure, it's like CL without the bullshit

23:36 plus the JVM

23:37 defn: he's doing project euler and im critiquing his code -- he started things off with a loop/recur -- i said NO! MUST NOT LOOP!

23:37 slyphon: :)

23:37 defn: it's fun to see it from the other angle, knowing a tiny bit about clojure now

23:37 i immediately was like "okay where's my for loop"

23:38 _ato: ,(java.util.Collections/shuffle [1 2 3] (java.util.Random. 57))

23:38 clojurebot: java.lang.UnsupportedOperationException

23:39 _ato: ,(seq (doto (java.util.ArrayList. [1 2 3]) (java.util.Collections/shuffle (java.util.Random. 57))))

23:39 clojurebot: (1 3 2)

23:39 slyphon: oh

23:39 right on

23:39 so that's totally not lazy

23:40 * slyphon tries rand-elt instead

23:43 _ato: shuffle would be tricky to do efficiently and lazy, I think

23:43 slyphon: _ato: oh, i don't doubt it

23:43 kind of sucks you can't set up a random-number generator specifically for clojure's core though

23:43 cemerick: shuffle is by definition not lazy, no?

23:44 _ato: yeah :(

23:44 slyphon: i mean

23:44 _ato: cemerick: ah yes, you're right, since you need all the elements in RAM to do it

23:44 slyphon: monkey-patching it would work, but that's really...nasty

23:44 _ato: wouldn't you need only the list of indexes of a vector?

23:44 oh, wait, i see your point

23:44 _ato: but suppose the first index is the last element ;-)

23:44 slyphon: yeah, totally

23:48 riddochc: So, I'm curious. I'm still really new to clojure, but I'm more familiar with CL than scheme. Which would you say it's closer to, in general?

23:50 alexyk: how do I obliterate a symbol from a namespace again?

23:50 cemerick: riddochc: strong elements of both, really

23:51 it feels more like a scheme in general usage because of the lisp-1 heritage

23:51 but it has CL-style macros

23:51 but they're hygenic

23:51 + reader macros

23:51 _ato: alexyk: ns-unmap?

23:51 cemerick: so, it's a mix

23:51 alexyk: _ato: o!

23:53 _ato: say I have a symbol aliased to another namespace. Can I still ns-unmap it, or is there an unalias?

23:54 _ato: alexyk: there's a ns-unalias

23:55 riddochc: cemerick: That makes sense. I only really started looking at scheme around the same time as I discovered clojure, for other reasons...

23:55 alexyk: _ato: will it do the same thing for an alias?

23:55 riddochc: cemerick: Though I've used CL for a few years.

23:57 _ato: alexyk: not sure what you mean. If you do (require '[clojure.contrib.seq-utils as foo]) you can do foo/partition-by, but then (ns-unalias *ns* 'foo) and you can't do it anymore

23:57 s/as/:as/

23:58 alexyk: _ato: right; say I do (ns-unmap *ns* 'foo) instead -- same effect? foo still alive in c.c.seq-utils?

23:59 _ato: ah, no. foo and foo/* are totally different. By creating an alias you're not mapping the symbol

23:59 eg you can alias foo to seq-utils and then define foo be a function, and both will work

23:59 they're independent

Logging service provided by n01se.net