#clojure log - Feb 24 2011

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

0:00 hugod_: sritchie: we're also in #pallet

0:01 joshua__: If I wanted to contribute to Incanter for Google Summer of Code what do you guys think I should do?

0:05 amalloy: joshua__: seems pretty obvious: you should contribute to Incanter for Google Summer of Code

0:06 jacortinas: amalloy: that does not seem to be a useful response :-\ although I do understand what you mean

0:06 joshua__: amalloy, :P I love doing that to people

0:07 amalloy: jacortinas: see, it's about knowing your audience

0:07 joshua__: amalloy, "Would you like milk or coffee?" "Yes."

0:07 jacortinas: haha

0:10 Sgeo_: Why do I keep having the impression that Clojure is too... enterprisey for hobbyist development?

0:20 amalloy: in lieu of competing theories, i'm going to propose that it's because you're nuts

0:30 i think i just misused "lieu" there. i probably mean "in the absence of"

0:43 Scriptor: can someone link me to the source for the persistent hashmap nodes?

0:43 Sgeo_: I'm not sure, it's pretty unenterprisey

0:44 it's a different way of thinking, but still pretty simple

0:47 Sgeo_: I guess I'm thinking in terms of dealing with Ant and Java in general etc.

0:47 amalloy: Scriptor: http://blog.higher-order.net/2009/09/08/understanding-clojures-persistenthashmap-deftwice/ good enough?

0:48 Scriptor: amalloy: I was looking at that, there's something that confused me a little

0:48 basically, the whole point of the index() function

0:48 afaict, you can get that just by looking at the 5-bit block of the hash

0:49 Sgeo_: you only deal with those if you want to

0:50 and there are some really nice build tools that let you use clojure itself, no xml silliness

0:52 joshua__: Sgeo_, have you used lein?

0:53 Sgeo_: I'm a bit scared to even learn what it is, tbh. Build managers scare me

0:53 >.>

0:53 tomoj: you'd rather fetch every dependency by hand all the time?

0:53 Sgeo_: Oh, it's just a package manager?

0:54 tomoj: not just, but how else were you planning to do that

0:54 Sgeo_: Is Lein similar to Racket's PLaneT?

0:54 I should probably actually look up Lein

1:01 Scriptor: amalloy: any idea what index() is used for, when you can just use the hash?

1:02 amalloy: Scriptor: haven't read that for ages, and too busy to get back into it atm

1:02 Scriptor: ok

1:02 amalloy: (plus i probably never knew)

1:02 Scriptor: damn, I'll ask Ritch next clojure meetup :D

1:08 technomancy: ,google leiningen tutorial

1:08 clojurebot: java.lang.Exception: Unable to resolve symbol: google in this context

1:08 technomancy: clojurebot: put a sock in it

1:08 clojurebot: excusez-moi

1:10 amalloy: technomancy: i know someone who can introduce you to lein if you're having trouble

1:11 technomancy: amalloy: I've heard lmgtfy is a pretty good site; is that what you're talking about?

1:12 amalloy: technomancy: never heard of lmgtfy. how would i find out more about it?

1:12 Scriptor: amalloy: altavista

1:14 technomancy: if you type /whois lmgtfy.com, it will show you their address; maybe you could send them a postcard.

1:16 joshua__: http://lmgtfy.com/?q=what+is+lmgtfy

1:18 amalloy: joshua__: sexpbot actually has a lmgtfy plugin for when you're too lazy to launch a browser to be snarky at someone

1:18 $lmgtfy lmgtfy

1:18 sexpbot: http://www.lmgtfy.com/?q=lmgtfy

1:18 joshua__: Very nice.

1:25 amalloy: joshua__: by the way, have you paid any attention to the findfn plugin since you wrote it? the functionality is still basically the same but i've had to turn it into a monster: https://github.com/Raynes/sexpbot/blob/master/src/sexpbot/plugins/clojure.clj#L146-206

1:27 joshua__: amalloy, ! what have you done to my beautiful code

1:27 amalloy, =) at least it works

1:28 amalloy: mostly, sandbox it more robustly

1:28 $findfn [1 2] 1

1:28 sexpbot: [clojure.core/first]

1:29 amalloy: aw. i like it when rand-nth makes the list

1:29 $findfn [1] 1

1:29 sexpbot: [clojure.core/last clojure.core/count clojure.core/peek clojure.core/first clojure.core/rand-nth]

1:30 joshua__: amalloy, imagine writing a test case for this thing that is fairly robust... everyone would keep wondering why sometimes it would be failing because of stray rand-nths etc

3:27 nunb: does slime's machine-instance work equivalently with swank-clojure?

3:40 G0SUB: nunb: no :(

4:06 xkb: is there any way to "find" an agent back if u dont keep a reference to it somehow?

4:06 so I start an agent from within a function and directly send it it's behaviour

4:07 there's no function like (find-all-agents) :)

4:12 TobiasRaeder: morining

4:12 *morning

4:14 anyone used lein-ring to build a war in here?

4:48 tscheibl: hey there

5:51 nunb: GOSUB: no partic. reason it can't be done, right?

6:23 tscheibl: when I want to override deref/@ for a specific var, should I do this using reify, implementing clojure.lang.IDeref/deref? This smells so bad of relying on implementation details...

6:26 any ideas?

6:28 cemerick: tscheibl: IDeref is a widely-implemented interface.

6:29 what do you mean by "override deref for a specific var"?

6:29 tscheibl: e.g.

6:29 (let [server-channel* (atom (closed-channel))]

6:29 (def server-channel

6:29 (reify clojure.lang.IDeref

6:29 (deref [this] ...

6:30 cemerick: sure, that's OK

6:30 tscheibl: I need to recreate the channel if it is closed before dereferencing

6:30 cemerick: You're defining deref for that reify-defined instance though, not the var.

6:31 tscheibl: I'm using a local binding and a closure for the underlying atom to hide it from unqualified access

6:31 cemerick: sure; what I'm saying is, you're not modifying the var in that case

6:31 `def` defines the var

6:32 you're defining what's going into the var

6:32 #'+ vs. +

6:32 ,#'+

6:32 clojurebot: #'clojure.core/+

6:32 cemerick: ,+

6:32 clojurebot: #<core$_PLUS_ clojure.core$_PLUS_@15ee9d9>

6:32 octe: hm

6:33 tscheibl: yes.. for the atom instance...

6:33 octe: what's the most idiomatic way to create a def that can be changed globally

6:33 an atom?

6:34 tscheibl: octe: depending on your needs: attom, ref or agent... I suppose

6:34 octe: yes

6:34 it's for keeping a reference to for example the jetty instance my program runs

6:35 tscheibl: octe: "The Joy of Clojure" Book describes the differences very well

6:35 octe: i can't def it immediately to that since the compiler would start a jetty server.. so i define it as an (atom nil)

6:35 and in my main-method use swap!

6:35 tscheibl, right. i forgot i bought that book, i should really read all of it ;-)

6:37 cemerick: vars can be changed just as the other reference type can

6:38 Choosing among them is a question of the change / concurrency semantics you're after.

6:38 octe: in my case i don't really see any reasons for chosing one over another

6:39 cemerick: an atom is most idiomatic in your case

6:52 octe: how annoying that manning timelimits the download links

6:56 tscheibl: octe: btw... did you manage to create a user account at mannings? It didn't work for me

6:57 octe: tscheibl, um, i don't remember if i had to create an account

6:57 i just bought joy of clojure a while ago and received an email with a link.

6:59 tscheibl: me, too... that has worked so far. But they say you could create an account using your email as login where you can download all your purchases at any time.. in case you delete something accidentally

7:00 .. trying that showed me an error

7:01 .. actually I could ask the guys at Mannings...just wanted to know if it actually worked for someone

7:01 .uhm.. anyone

7:02 octe: tscheibl, that sounds nice, didn't know about that

7:02 tscheibl: octe: yep.. nice... if it worked ;)

7:06 octe: tscheibl, the download link i got expired.. but going to http://ebook.manning-sandbox.com and filling in the order number and email, i got a new download link

7:06 can't find anything about registering an account though

7:07 tscheibl: ah, well

7:07 it said something about "beta phase"... whatever that means ;)

7:08 https://account.manning.com/

7:08 octe: https://account.manning.com/

7:11 octe: tried it again, this time it worked! :)

7:11 got my Manning account

7:11 octe: tscheibl, that worked for me

7:11 yeah

7:11 nice

7:12 that will probably make me buy more books from them :-)

7:14 tscheibl: .. if they bother to release more clojure stuff... I don't think I want to do any other language again ;)

7:14 maybe some other Lisp dialect...

7:15 ... but only if oracle destroys the JVM

8:08 raek_: speaking of books... what is the estimated date for the dead-tree version of The Joy of Clojure?

8:28 kencausey: raek_: March - http://manning.com/fogus/

8:30 kencausey: I wonder about that though considering the last meap has a fair number of errors and hasn't been updated in months. Which is not to say that they aren't fixed, it's just odd that manning is not issuing fixed digital versions. The authors have complained a bit that they have little more input or awareness into this than anyone else.

8:30 * kencausey tries to avoid talking to himself in future

8:53 clgv: what does the ^:static metadata cause in a defn statement?

9:23 octe: the joy of clojure book is quite interesting

10:17 jcromartie: tscheibl: on other Lisp dialects... I am a fan of Scheme if I have to get closer to the hardware

10:17 Chicken Scheme is quite awesome

10:17 it compiles to run on pretty much anything with a C compiler

10:18 same with Gambit

10:27 Sgeo_: Meh

10:28 I intended to have a part message

10:39 tscheibl: jcromartie: how does scheme handle concurrency? Is it somewhat comparable to Clojures concurrency features (STM and so on)?

10:40 Dranik: tscheibl, I guess the enhanced syntax of clojure also counts :-)

10:40 jcromartie: tscheibl: it doesn't have a strong opinion

10:41 there are systems built on top of Scheme to handle it

10:41 tscheibl: what about a native implementation of Clojure?

10:42 ..implemented as Scheme Macros... lol

10:45 hmm.. there are quite some eggs available fpr chicken scheme

10:46 pppaul: anyone used clojure for something like a command-line tool?

10:47 i made a command and try to execute it like: java -jar uberjar.jar <file

10:48 and the args variable says that it is empty

10:48 the file has a list of things in it, though

10:48 cat <file works

10:49 Raynes: pppaul: You're passing the name of a file as a command-line argument? And then getting the name from the *command-line-args* var, right?

10:49 pppaul: i want to give the contents of the file as input

10:49 the contents of the file as arguments

10:50 jweiss: if I define (defn blah [& {:keys [x y z] }] ...) is there a way to get the list of keys that were actually passed in?

10:50 clojurebot: Please do not ask if anyone uses, knows, is good with, can help you with <some program or library>. Instead, ask your real question and someone will answer if they can help.

10:50 Raynes: Alright, but you're looking at *command-line-args* right? There is no 'args' var.

10:50 clojurebot: Shush.

10:50 clojurebot: Gabh mo leithscéal?

10:50 pppaul: i'm using -main [args]

10:50 via lein

10:51 let me see about the *command-line-args* thing

10:52 Raynes: jweiss: (defn blah [& {:keys [x y z] :as all}] (keys all))

10:52 pppaul: You're doing it properly.

10:52 raek_: pppaul: if you execute your program with "java -ajr ubserjar.jar a b c", it will result in the call (-main a b c)

10:52 jweiss: Raynes: ah thanks

10:52 Raynes: *command-line-args* is only relevant if you're not calling the uberjar.

10:52 raek_: pppaul: *command-line-args* is only for when clojure.main is used as the main class

10:53 Raynes: raek_: What is the -aj for there?

10:53 That shouldn't be necessary for passing command-line arguments.

10:53 pppaul: ok, i'll try -ajr

10:53 raek_: pppaul: also note that when you execute it with "<file", file is not an argument

10:54 pppaul: sorry. that was a typo for "-jar"

10:54 Raynes: Oh.

10:54 pppaul: ok, i'm confused as to what <file does

10:55 i thought it would redirect the file as input to the command

10:55 raek_: sorry for diverting you...

10:55 pppaul: yes. it will cause that file to be opened and used as

10:56 pppaul: ?

10:56 as what?

10:56 raek_: ... as *in*

10:56 pppaul: ok

10:56 Raynes: pppaul: Be patient with him. He is probably typing on a phone.

10:56 pppaul: oh

10:56 raek_: (gah! my computer switched keyboard layout in the middle of that sentance)

10:56 pppaul: lol

10:56 Raynes: Even more likely on a bumpy bus ride somewhere. :p

10:57 pppaul: i want my file, which is a list of arguments to my command, to be fed into my command

10:57 i thought <file would do so, but i guess not

10:57 raek_: yeah. on a phone on a bumby buss ride. *whistles*

10:57 pppaul: :)

10:57 Raynes: I'm not sure that doing that is very common with command-line tools.

10:58 You'd probably be better off just reading from *in* or taking the name of the file and calling line-seq on it.

10:58 raek_: pppaul: that sounds more like java -jar uberjar.jar `cat file_with_args`

10:58 pppaul: hmmm

10:58 raek_: if I understood you correctly

10:59 pppaul: ok, i'll try that

10:59 raek_: <file will replace the "keyboard input" with the contents of that file

11:00 so you have to decide to either read the commands from the input stream or from the command line arguments

11:01 pppaul: hmmm

11:01 this is over my head

11:01 `cat` worked, sorta

11:01 dnolen: consumer quad-core laptops mmm ... Clojure.

11:14 _fogus: Marginalia v0.5.0 is a go

11:55 cinch: yey! 2k requests per second on jetty with on disk cache of the html (~40/s without)

11:57 rata_: hi

11:57 I'm protocolifying my library

11:57 is that encouraged?

11:59 (or protocolizing?)

12:01 ejackson: protocollating ?

12:06 rata_: is it common that protocols are like IProt and implementation (types and records) are AProt?

12:06 ejackson: i thought the other way around ?

12:06 rata_: sounds weird with Prot, but IFoo and AFoo?

12:07 ejackson: dunno though

12:07 rata_: really? implementation are IFoo?

12:07 I thought I was for interfaces

12:07 I mean "I", the letter

12:10 ejackson: http://clojure.org/protocols shows Rich using AProt at least

12:11 sattvik: rata_: In some naming schemes, I... is for interfaces and A... is for abstract concret types.

12:12 I don't know if there is any convention for protocols and records, aside from using camel case.

12:12 rata_: mmm ok

12:13 well then I'll use AFoo for protocols as http://clojure.org/protocols says

12:13 and, well, I don't know for the concrete type... maybe just Foo

12:18 ejackson: another approach is using protocol names such as Countable, Serializable, FooBarable.

12:18 i find that very readable

12:22 rata_: ejackson: but that approach doesn't apply to my case because I'm using the protocol to define a foo-like thing

12:23 ejackson: k

12:24 rata_: are there any problems using for example name or merge as methods of my protocol? will they collide with name and merge from c.core?

12:25 ejackson: don't think so, you use them (.method-name ....)

12:26 try and see :)

12:26 robonobo: hi

12:28 soi'm trying to draw a triangle on a JPanel using .drawLine 3 titmes in a doto block, but it only draws one of the lines

12:28 https://gist.github.com/842487

12:30 amalloy: robonobo: seems like it ought to work. maybe you need to send a .repaint?

12:31 rata_: $source str

12:31 sexpbot: str is http://is.gd/cn9qbS

12:31 amalloy: though btw, in (do (doto ...)) there's no need for a do

12:33 __name__: The implementation of cartesian-product in contrib is really putting me of.

12:33 I don't think I ever could parse this.

12:34 amalloy: __name__: meh, just write it as (for [x xs y ys z zs] [x y z]). not much need for contrib there

12:34 jkdufair: Interesting that .NET 4.0 has all sorts of concurrency stuff baked in. Wonder if that will help clojure on the CLR.

12:35 __name__: amalloy: Could they not have made a macro for that?

12:35 amalloy: And I know that, still, I never think I will understand this code.

12:35 amalloy: link me?

12:35 __name__: Oh, I forgot. Excuse me.

12:35 https://github.com/richhickey/clojure-contrib/blob/2ede388a9267d175bfaa7781ee9d57532eb4f20f/src/main/clojure/clojure/contrib/combinatorics.clj#L107

12:37 amalloy: haha wtf is this code. gross

12:38 __name__: So this is not what Clojure is supposed to look like I guess.

12:39 amalloy: well i can't read it either. *maybe*, though i'm highly dubious, this is the "best" way to write it from scratch

12:39 but there's no reason to do that when you have lots of lovely functions available to do this already

12:39 __name__: If that's the best way I am sad :(

12:39 What if you data is runtime, then the for will not work.

12:39 Despite: as i recall the combinatorics lib is highly optimized

12:40 __name__: i.e. the amount seqs

12:40 Despite: i guess readability was not a concert

12:40 concern

12:40 __name__: How can one maintain this?

12:44 amalloy: __name__: take chunks of code out and turn them into independent functions. pick tolerable names for them. that probably helps a lot

12:45 __name__: amalloy: Yes; so they just did not do that for performance reasons?

12:45 amalloy: *shrug*

12:45 rata_: is this right? (deftype Foo [a] AFoo (bar [_] a))

12:45 or is it better to write (deftype Foo [a] AFoo (bar [f] (.as f)))?

12:46 danbell: The :or keyword in function parameters

12:46 : or

12:46 amalloy: one possibility is it's just hard to factor out closures because you don't want to pass them as arguments all the variables they close around (but it shouldn't have performance implications afaik)

12:46 danbell: ran across it in Incanter, can't find any documentation

12:46 anyone know where it's described?

12:46 amalloy: danbell: it's a destructuring feature

12:47 __name__: typo? http://clojure.github.com/clojure/clojure.core-api.html#clojure.core/defonce

12:47 ‘iff’

12:47 amalloy: http://stackoverflow.com/questions/3337888/clojure-named-arguments looks like it explains it, danbell

12:48 __name__: mathematicians use "iff" to mean "if and only if". if that makes sense in context that's probably why

12:48 danbell: ha, after you told me it was destructuring, I plugged it into google and found that same question ;)

12:48 __name__: amalloy: ah, thank you

12:49 danbell: amalloy: awesome, thanks

12:56 bobo_: When wrapping a java library, where you need to set properties on the objects al the time. whats a good syntax for that? any good example to look at?

12:58 Vinzent: bobo_, doto?

12:58 bobo_: well if im going to write a wrapper so i dont need doto.

13:00 rrc7cz: from a high level, how is security provided when implementing something like clojurebot or sexprbot?

13:00 my first thought was a java policy on the JVM to prevent system calls, though that wouldn't really address blowing out the heap on purpose, etc.

13:04 amalloy: bobo_: perhaps (defmacro set-fields! [fields object] `(do ~@(for [[k v] fields] `(set! (. ~object ~(name k)) ~v)) object)) or some such?

13:04 if your goal is to make it easy to set several fields at once

13:05 bobo_: my goal is to make it easy to use

13:05 i realised swing might be a good example.

13:05 or rather, my goal is to make it look more like clojure and less like java

13:05 amalloy: rrc7cz: have you looked at clojail? it's what powers sexpbot's sandboxing

13:06 rrc7cz: amalloy: thanks, I didn't know about that. I've been trying to pick out where in those two bots the security is implemented

13:07 Aisling: Hello; are there packages for statistical inference on clojure?

13:07 amalloy: rrc7cz: well i'm your man, more or less. i've been maintaining sexpbot's security model more or less on my own for a couple months :P

13:08 rrc7cz: amalloy: awesome. I'll definitely be interested to see how you prevent memory issues

13:10 amalloy: Aisling: not sure what statistical inference actually is, but incanter has a lot of math and statistics

13:11 rata_: Aisling: https://github.com/getwoven/infer?

13:11 Aisling: amalloy: thanks, I'll take a look!

13:11 rata_: thanks

13:12 pppaul: anyone do webprogramming with clojure here?

13:12 rata_: pppaul: many... ask

13:13 amalloy: rrc7cz: step into #sexpbot perhaps?

13:13 rata_: how would you make a type behave as a map that's in one of its fields?

13:13 pppaul: how hard would it be to use clojure to create a website with user authentication and a members area (everything is static HTML/JS)

13:14 rrc7cz: pppaul: I just checked in an example/skeleton webapp in Clojure today: http://bit.ly/esJtCV

13:14 rata_: pppaul: mmm I was wondering the same thing =)

13:16 pppaul: thanks

13:16 rrc7cz does your app have user login?

13:16 i guess if it doesn't, it wouldn't be too hard to add

13:16 rrc7cz: pppaul: shouldn't be very difficult. Check out Compojure and Ring for the Session middleware. Serving static files is supported out of the box by both

13:16 pppaul: cool

13:17 so, what does your app skel do?

13:17 rrc7cz: pppaul: not yet, but I'll probably add it. I was more concerned with showing restful crud

13:17 pppaul: i read the link btw

13:17 i haven't heard of crud before

13:18 rrc7cz: pppaul: just means create/retrieve/update/delete, basically the standard operations you perform on entities

13:18 pppaul: is there admin work with your app?

13:18 Bennyl: Hi, I wondering about the dispatch (#) operator, reading from the site documentation I didn't understand how it exactly worked

13:18 pppaul: do i need to setup the DB or something before running your app?

13:19 rrc7cz: pppaul: not sure I understand. Really it's just meant to be a bare min example of restful crud, not a rails or django by any means

13:19 pppaul: it comes with an embedded db so you don't have to worry about it

13:19 pppaul: ok cool

13:19 i may try it out for a site a friend wants help with

13:19 :D

13:20 rrc7cz: pppaul: good luck, and make sure to check out ring/compojure's session support in case I don't add it

13:20 amalloy: Bennyl: # activates various "special" parsing modes for the compiler

13:21 https://github.com/clojure/clojure/blob/1.2.x/src/jvm/clojure/lang/LispReader.java#L75 is a relevant part of the source if you're into that sort of thing

13:22 Bennyl: amalloy: thanks! I will look at it

13:23 rata_: how would you make a type (deftype) behave as a map that's in one of its fields?

13:24 Chousuke: rata_: that sounds rather weird.

13:24 bobo_: il try with an example, https://gist.github.com/842596 either of thoose look sane? or any other ideas? as syntax for using jbutton for example. Im just thinking so far.

13:27 sattvik: rata_: try defrecord

13:28 rata_: sattvik: defrecord isn't useful as I don't know the keys at compile time

13:29 Chousuke: it's not that wierd... I just want to have a map that has additional information outside that map but in the same object

13:29 I've been using meta before, but I'm trying to protocolize my code

13:29 sattvik: rata_: Hmm... then I think you'll need to implement IPersistentMap in your deftype

13:30 rata_: I thought that protocolizing it would perhaps make my code cleaner

13:30 sattvik: is it just IPersistentMap?

13:33 sattvik: rata_: That's the main interface, you'll also have to implement the various methods from inherited interface like Associate, Iterable, etc. Depending on what you need, you may be able to get away with lesser interface, such ILookup.

13:35 rata_: I want it to behave as a map

13:37 sattvik: where is the interface Iterable?

13:37 amalloy: rata_: java.lang

13:37 rata_: oh ok

13:38 amalloy: rrc7cz: poking around at my dev copy of sexpbot in #sexpbot if you're interested. he seems to survive OOM errors with no harm done

13:39 rata_: amalloy: hmmm that seems difficult to implement from clojure

13:39 Dranik: hi all!

13:40 what is the difference between the type hints #^ and ^

13:41 amalloy: Dranik: #^ is old

13:41 rata_: is there an easy way to redirect a bunch of methods from a type to a field of that type?

13:44 amalloy: rata_: if your heart is set on this you could probably generate some kind of proxy class

13:45 rata_: amalloy: do you any recommendations on what to do otherwise?

13:45 I'm interested in other viewpoints

13:46 amalloy: rata_: can't really suggest an alternative without context. all i know is you want to do X, don't know why

13:47 Dranik: amalloy, ok, but is it still usable? and are there any details: which is the difference?

13:48 amalloy: i don't think there's any difference at all

13:48 as long as your version of clojure supports ^, you can use either (but should use ^ of course)

13:50 rata_: I'm trying to protocolize my code... in particular, I have three domain-specific kind of objects... two of them were implemented as records and the other one as a map

13:50 amalloy: ^

13:50 clojurebot: amalloy: therfor I return [previous] if rest is empty

13:51 amalloy: lol thanks clojurebot

13:51 rata_: hahaha

13:52 amalloy: and the map usually had some meta, which I'm trying to put together in a type with the map

13:52 but I still want the type to behave as the map it was

13:53 to minimize the amount of code I'll have to change

13:53 amalloy: rata_: just put meta on the record object?

13:53 rata_: no record object, as I don't know the keys beforehand

13:53 that's the reason it was a map

13:53 and not a record, as the other two

13:59 dnolen: rata_: why do you need to know the keys before hand? records work like maps.

14:00 (defrecord Foo [])

14:00 rata_: dnolen: yes, but otherwise they don't perform better afaik

14:00 nor will a record help me in any way

14:00 compared to a map

14:01 dnolen: rata_: you get protocol dispatch perf. if you don't know the keys beforehand then you want a map.

14:03 you have to know the keys if you want performance. if you don't, then you have to accept the performance hit. or resort to runtime compilation of types/records which seems icky.

14:05 rata_: dnolen: I know I want a map... that's not the point

14:06 I wasn't saying I don't want a map

14:06 dnolen: rata_: yet you want to use protocols to make things 'cleaner'

14:06 that seems suspect to me.

14:08 rata_: dnolen: that's ok... I'm not sure if it's a good decision

14:08 dnolen: therefore I said that perhaps protocols could help me make this cleaner

14:08 and I asked if it encouraged to protocolize libs

14:09 to make things a little clear, here's the protocol and type https://gist.github.com/842663

14:10 before the as field (which is a map) was the whole "type" and cs was put in the meta of that map

14:12 the library I'm talking about is this one https://github.com/rhz/kapjure

14:12 specifically this file https://github.com/rhz/kapjure/blob/master/src/kappa/language.clj

14:14 is there a way to collect the name of the methods of an interface from the REPL?

14:15 Licenser: for the record, clojure does well with soap - the mistake was mine :) also M$ sucks

14:20 amalloy: rata_: clojure.contrib.repl-utils/show

14:20 dnolen: rata: only glanced quickly, but your code doesn't look particularly 'not-clean' to me.

14:22 rata_: dnolen: thanks =)

14:22 you're right, it's not particularly not-clean

14:22 but the question then is: is it encouraged to protocolize libs?

14:24 Chousuke: rata_: why not?

14:24 rata_: Chousuke: why yes?

14:24 dnolen: rata_: I see only a couple cases for protocolizing a lib. You really, really, really want the performance. You have solid interfaces that you want to expose to downstream users.

14:24 Chousuke: for performance?

14:24 rata_: though my understanding is that optimally your users shouldn't need to care whether you're using protocols or functions or multimethods

14:25 so that you're free to use whatever you need.

14:26 rata_: dnolen: well, I really, really, really want the performance, but I'm not sure protocols are helping me with the performance here

14:26 dnolen: also, it'd be nice to expose my interfaces to downstream users, but not required

14:30 dnolen: rata_: what is the bottleneck in yr code?

14:41 rata_: got disconnected

14:43 if two interfaces requires the same method, I don't have to mention that method twice in deftype, do I?

14:43 cemerick: anyone here use rhickey's sdb library?

15:06 technomancy: ping

15:07 pppaul: is there a way for me to see the code that defines a def?

15:08 cemerick: def defines a var

15:08 mids: grep?

15:08 pppaul: ok

15:08 is there a way for me to see the code that is in a var?

15:08 like a macro expand, but for a var

15:08 cemerick: def is a special form, not a macro

15:09 pppaul: actually, not really like macroexpand

15:09 cemerick: If you want to see what def does, you need to dig into the Clojure runtime

15:09 pppaul: i don't want to see what it does

15:10 (def a (map ....)) -> (map....)

15:10 cemerick: ah!

15:10 pppaul: i want to see the code i wrote for a

15:10 cemerick: ,(source +)

15:10 clojurebot: java.lang.Exception: Unable to resolve symbol: source in this context

15:10 pppaul: thanks :D

15:10 cemerick: bleh

15:10 yeah, use `source` :-)

15:10 clojurebot: I don't understand.

15:10 cemerick: clojurebot: that's because you're a fool.

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

15:10 cemerick: Perfect. :-D

15:10 pppaul: that's not working for me :(

15:11 cemerick: pppaul: what version of clojure are you using?

15:11 pppaul: 1.2

15:11 i'm using the repl, and i lost my code

15:11 cemerick: hrm, it should be bound in your REPL already

15:11 pppaul: i want to find it again

15:11 cemerick: try

15:11 (clojure.repl/source var-name)

15:11 pppaul: thanks

15:12 still doesn't work

15:12 cemerick: what's the error?

15:12 pppaul: source not found

15:12 cemerick: oh, I see, you typed the code into the repl, you didn't load it from a file.

15:13 pppaul: yup

15:13 cemerick: ,(doc clojure.repl/source)

15:13 clojurebot: "([n]); Prints the source code for the given symbol, if it can find it. This requires that the symbol resolve to a Var defined in a namespace for which the .clj is in the classpath. Example: (source ...

15:13 cemerick: sorry, man

15:13 pppaul: hmm

15:13 do you think what i want is possible?

15:14 should i avoid using the repl to write code without saving it to a file frequently?

15:14 cemerick: No, probably not.

15:14 pppaul: ok, thanks

15:14 cemerick: If you are using an environment that keeps REPL command history, then it's fine.

15:15 pppaul: I take it you're just on the command line?

15:16 pppaul: in emacs

15:16 i really like the relp

15:16 maybe too much

15:16 cemerick: Surely emacs/swank/whatever has command history in the REPL?

15:17 pppaul: yup, but i clear the screen sometimes

15:17 cemerick: no, I mean a recallable command history

15:17 e.g. Ctrl+up, whatever

15:17 pppaul: it gets slow after i fill it up with thousands of lines of crap from whatever i'm doing

15:17 yeah it has that

15:17 mids: pppaul: maybe interesting discussion for you: http://groups.google.com/group/clojure/browse_thread/thread/4812633ea878c59a

15:18 pppaul: thanks!

15:18 cemerick: You can't bounce up through your prior entries until you get your function definition?

15:18 arohner: pppaul: your slime input history is stored in another buffer, so it's still accessible after a C-c C-l

15:19 as long as M-P still works, you can find it

15:21 pppaul: my slime completions go back way too far

15:25 robonobo: hello

15:31 jhirn: Hello. Newb question. What is the best way to filter nil from a list? I am trying all combinations of (filter (not nil?) list) but I'm starting to think there's a different way.

15:32 dnolen: ,(remove nil? [1 nil nil 2 3])

15:32 clojurebot: (1 2 3)

15:33 dnolen: jhirn: ^

15:33 jhirn: that did the trick =)

15:33 danke

15:36 morphling: $findfn [1 nil nil 2 3] [1 2 3]

15:36 sexpbot: []

15:37 Raynes: That's too clever for him.

15:37 morphling: $findfn [1 2 3] [2 3 4]

15:37 sexpbot: []

15:37 morphling: no higher order functions at all?

15:37 Raynes: Nope. That would be really time consuming and difficult.

15:38 Fossi: it's impressive enough as is imho

15:39 Raynes: amalloy and I have talked about adding support for arbitrary expressions with placeholders for functions that would make that sort of thing plausible.

15:40 morphling: cool

15:44 rata_: $findfn nil? [1 nil nil 2 3] [1 2 3]

15:44 sexpbot: [clojure.core/remove]

15:48 raek_: ,(for [x [1 2 3 4] :when (odd? x)] (* x 100))

15:48 clojurebot: (100 300)

15:49 raek_: hrm, I should use the various of 'for' more often...

16:19 TeXnomancy: cemerick: pong

16:20 cemerick: TeXnomancy: was going to ask you: http://groups.google.com/group/clojure/browse_frm/thread/8912e783aeba6b02

16:21 TeXnomancy: cemerick: oh... my dirty little secret is that I sometimes don't delete github forks in order to skew the Github language high-score board.

16:22 I think I may have done a couple tweaks to it two years ago in vague exploration-mode, but I haven't touched it since

16:22 cemerick: ah-ha

16:22 TeXnomancy: that's a good strategy, tho :-)

16:23 hiredman: last time I thought about playing with sdb the dependencies as a zip was too high a barrier to entry

16:23 Raynes: amalloy deletes all of our forks. :(

16:24 amalloy: Raynes: well stop giving me push access to your repos if you want me to keep forks around

16:52 jweiss: anyone know of a git browser whose clj highlighting >= github, but can be hosted yourself (eg, on corp network)

16:52 looked at gitorious, clj highlighting is not good

16:54 amalloy: jweiss: just use SyntaxHighlighter for the highlighting, then it doesn't matter what git browser you use?

16:55 jweiss: amalloy: i'd have to integrate syntaxhighlighter into whatever it is, wouldn't i?

16:56 amalloy: SH is pure javascript; you can just tell it to render some dom element

16:57 so let the browser load up its stuff, and add some js afterwards. doesn't sound like a heavy integration burden

16:58 jweiss: amalloy: this isn't for me - it's for people who won't be bothered to load up extra js

16:58 it needs to be included in the pages as they browse

18:00 ossareh: jweiss: I might be misunderstanding something but SyntaxHighligher is js that gets thrown into your page and then looks for <pre/> tags with a "brush" defined on it.

18:01 jweiss: the source of this page shows this effectively: http://alexgorbatchev.com/SyntaxHighlighter/manual/demo/

18:25 maacl: Does the cake deploy task exist? I don't see any documentation anywhere

18:37 raek: anyone know how to go from \A to "U+0041 LATIN CAPITAL LETTER A", btw?

18:39 TeXnomancy: M-x describe-char?

18:39 oh wait, wrong channel

18:43 amalloy: raek: http://www.unicode.org/Public/6.0.0/ucd/UnicodeData.txt

18:44 looks like a CSV-ish file describing zillions of charactera

18:45 raek: amalloy: most of that data seems to be accessible from the methods of Character, but I haven't found how to get the name

18:46 in python there is a method for that, so was hoping there was one in java too

18:48 amalloy: anyway, thanks for the link. looks like I need to use it.

18:48 joegallo: google says to use icu4j

18:49 raek: TeXnomancy: ah, that might come handy. thanks!

18:50 joegallo: ok, will check out. :)

18:50 joegallo: http://icu-project.org/apiref/icu4j/com/ibm/icu/lang/UCharacter.html#getName(int)

18:50 neato.

19:03 raek: (com.ibm.icu.lang.UCharacter/getName "𐌰" "") => "GOTHIC LETTER AHSA"

19:03 nice.

19:03 sildaleiks!

19:05 joegallo: bangarang!

19:07 Sgeo: Yesterday, I would have asked if Clojure has something like C#'s thing where the fact that two different interfaces that define the same function name can be made to not conflict. Today, I realized that that's automatic in Clojure

19:16 TimMc: Sgeo: Via :as?

19:17 I like that about Python too.

19:17 Having to use the original author's names seems so backwards now. :-P

19:17 Sgeo: I don't even know what that is. Just that implementing protocols/interfaces requires naming the protocol/interface

19:18 So one protocol's somefunc doesn't interfere with the other protocol's somefunc when defining that something implements those protocols

19:18 TimMc: Oh! Nvm, misread.

19:19 Was thikingabout (require ... :as ...)

19:33 Sgeo: Are all impure functions supposed to use io! ?

19:37 TimMc: I use side-effects all the time from within dosync. I just make sure they're idempotent.

19:37 (I don't know if that's bad, though.)

19:47 Sgeo: Is ->> inside -> a commonly used idiom?

19:48 amalloy: Sgeo: not very

19:58 tscheibl: bb

19:58 gn8

20:53 Sgeo: How do multimethods interact with protocols?

20:54 brehaut: Sgeo: what do you mean? they are seperate mechanisms

20:55 Sgeo: They seem to do similar things to some extent.

20:56 brehaut: Sgeo: they both provide polymorphic facilities yes

20:56 and in both cases they look like functions

20:57 multimethods have creator defined dispatch functions whereas protocols are type based single dispatch

20:59 additionally protocols provide built in support for grouping functions

20:59 Sgeo: Which is used more for someone still in an OO mindset?

20:59 brehaut: and are a bunch faster than multimethods

20:59 Sgeo: that question breaks my brain

21:00 Sgeo: >.>

21:00 brehaut: Protocols are probably closest to what you are used to

21:00 ie, type based single dispatch

21:00 but you can do the same thing with multimethods

21:00 multimethods are much more general

21:01 some people would tell you to writing things with multies until you know you have a bottleneck that needs performance

21:02 Sgeo: Would it be possible to define the protocol macros etc. in terms of multimethods?

21:02 Would that make more sense than the current setup?

21:02 brehaut: no

21:02 and yes

21:02 in reverse order

21:02 furryreals: there'd probably be a performance hit

21:02 brehaut: what doesnt make sense about the current set up?

21:03 Sgeo: Just that two distinct non-interchangable mechanisms are used for basically the same thing

21:04 brehaut: Sgeo: if by 'basically the same thing' you mean 'polymorphism'

21:04 then you need to learn about more kinds of polymorphism than type based single dispatch

21:05 Sgeo: until you know enough to be able to understand the difference, pretend protocols dont exist and go learn multimethods

21:05 Scriptor: multimethods are also not difficult at all, a naive implementation can be done fairly quickly in clojure itself

21:06 Sgeo: I understand the difference just fine. I just don't see how two separate language mechanisms where one is just a subset of the other is necessarily a good idea

21:06 brehaut: Sgeo: then you dont understand the difference just fine

21:07 amalloy: Sgeo: good point. i'm not sure why we have * and + when you could just use - for all of those with a little more work

21:08 Scriptor: are protocols implemented in Java or Clojure?

21:08 er

21:08 technomancy: Sgeo: the short version is that multimethods are to slow for self-hosting Clojure

21:09 Sgeo: Ok

21:09 technomancy: if you're not implementing Clojure you can probably ignore them

21:10 they provide dispatch that hotspot is really good at optimizing

21:10 Scriptor: what, multimethods?

21:10 technomancy: sorry; protocols

21:10 Scriptor: ah

21:10 technomancy: but they are a lot less flexible than multis

21:10 Scriptor: right, that makes sense

21:10 so in the future would the sequence code for clj-in-clj be using protocols?

21:11 technomancy: I think primitive vectors are already there.

21:13 Sgeo: I guess I just want to mix protocols and multimethods freely

21:57 mattmitchell: i'm attempting to get a basic leiningen project running with swank. I've followed several tutorials/readme's and can't seem to get "lein swank" to work. I get a message from lein: "That's not a task. Use "lein help" to list all tasks."

21:57 anyone know what i could be doing wrong?

22:00 amalloy: mattmitchell: you need to install the swank plugin

22:00 mattmitchell: amalloy: ah, how do i do that?

22:00 Null-A: Is it possible to deftype with mutable fields, that aren't part of ctor parameters, but are private member variables?

22:01 amalloy: mattmitchell: ask technomancy. i use cake

22:03 mattmitchell: technomancy: would you mind telling me how to get the swank plugin installed?

22:07 amalloy: are you able to use swank with a cake project?

22:07 amalloy: yeah

22:08 just add :dev-dependencies [[swank-clojure "1.2.1"]] to ~/.cake/project.clj, and all your projects will have swank added as a default dependency

22:12 Null-A: is it possible to call clojure functions from java?

22:13 nvm

22:22 Sgeo: I think I misunderstood the concept of orthogonality of language features

22:39 technomancy: mattmitchell: lein plugin install swank-clojure 1.3.0-SNAPSHOT will do it

22:40 mattmitchell: technomancy: nice :) finally working. thank you.

23:08 * Sgeo reluctantly goes to install NetBeans

23:09 spewn: Is there something more idiomatic than (if foo foo bar)?

23:10 DespiteItAll: I'd do (or foo bar

23:10 spewn: That's the one; thank you.

23:18 amalloy: &(macroexpand '(or foo bar))

23:18 sexpbot: ⟹ (let* [or__3470__auto__ foo] (if or__3470__auto__ or__3470__auto__ (clojure.core/or bar)))

23:25 amalloy: spewn: anyway that's basically what (or foo bar) macroexpands to

23:27 Sgeo: http://www.infoq.com/interviews/hickey-clojure-protocols

23:27 Why can't I hear a single thing grrrr

23:27 Scriptor: I always wondered about that, does it get optimized?

23:27 using an entire if expression when you just want to or feels like it would have a lot of overhead

23:29 amalloy: Scriptor: huh? at the hardware level it has to be an if anyway (eg, jump-if-less-than a b), so there's nothing to optimize

23:29 Scriptor: oh, right

23:51 amalloy: Scriptor: it's actually the let that always "feels" wasteful to me. of course the guy writing the (or) macro has to allow for the fast that my first condition is a complex expression, and probably the compiler is smart enough to avoid copying when the let is unimportant, but it's like augh i already have a let, why are you making another?

23:52 forensic: does anyone have experience with lein daemon? I'm getting an error "jsvc error: Cannot locate Java Home" but $JAVA_HOME is definitely pointing to the right place... anyone know?

23:52 Scriptor: amalloy: true, but like you mentioned, the compiler is pretty advanced, probably good CoW optimization

23:57 * Sgeo yet again imagines an IDE similar to Racket's

Logging service provided by n01se.net