#clojure log - Oct 09 2010

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

0:02 TeXnomancy: scottj: nice work with clojars

0:03 I kinda thought alex wasn't accepting patches, being MIA or something

0:03 kotarak submitted some fixes that didn't seem to go anywhere

0:08 scottj: TeXnomancy: he said he's been really busy

0:09 I made sure he was willing and able to merge the changes before I started working on them

0:11 he's also just provided better docs and a dump of the db for running and testing locally

0:13 TeXnomancy: actually you were the reason I made those changes :) with multiple ppl committing to swank-clojure I was getting upset not knowing if you'd pushed them to clojars

0:19 TeXnomancy: cools

0:20 making it easier to run/test clojars locally is really important for getting contributors, I'm glad it works better now

0:20 just added you to the swank clojars group

0:21 oh... I can run a local clojars for my conj talk and demo scp uploads without needing a network connection... slick.

0:25 we really need to get clojars on a server where others can help admin it though

0:28 scottj: there's a mailing list (1 member) and a maintainers list mentioned on the clojars-web repo readme so he's probably moving that way just waiting for someone to volunteer

0:28 TeXnomancy: actually four people have volunteered

0:29 he just hasn't given anyone access yet because it's still on a shared server that he's not the owner of

0:29 gotta get things moved over to the VPS at new.clojars.org

0:31 scottj: ahh

0:56 TeXnomancy: the similarities between John Rose's "larval" ideas and Rich's pods are pretty striking: http://blogs.sun.com/jrose/entry/larval_objects_in_the_vm

0:56 VM-level support for podlike behaviour would be great

2:08 slyrus_: TeXnomancy: what do you mean by VM-level support for podlike behavior?

2:29 amalloy: slyrus_: did you read the article? i don't know a lot about pods, but larva seem like useful thing for clojure to have

3:00 morning ohpauleez

3:01 ohpauleez: evening for me

3:01 Just wrapped up a small host party

3:01 house*

3:01 amalloy: fwiw i decided not to use clojure-hadoop, at least not yet. it looked a lot harder to modify it to read input from cassandra than it would be to adjust cassandra/contrib/wordcount to do the processing i need to do

3:01 ohpauleez: nonetheless, morning amalloy

3:02 amalloy: heh, well, evening for me too. but you just signed on, it's morning!

3:02 ohpauleez: I've had pretty good experiences with cassandra

3:02 I have a high performance wrapper on my github

3:03 tomoj: ooohh

3:03 ohpauleez: But I think I need to push the final working project

3:03 tomoj: what's your github account name?

3:03 ohpauleez: I'll check in about 8-10 hours

3:03 tomoj: I have been greedily eyeing cassandra

3:03 ohpauleez: I believe ohPauleez, full name will be Paul deGrandis

3:03 it has some weird long term running behaviors

3:04 but for a simple key value store that scales with writes

3:04 it's an awesome choice

3:04 Mongo is real nice too, the company I work with is pushing forward with mongo. And the old company I built uses it for things

3:05 amalloy: i looked at cassandra-wrapper on github, but it didn't look very good. that one's not yours, is it?

3:06 ohpauleez: nope

3:06 cassaforte is mine

3:07 I just checked, I need to push the final code, it's currently just a bunch of random hacks

3:07 but I've had issues with clj and cassandra, and ended up using the Thrift java wrapped

3:08 which is what led me to generalize and make cassaforte

3:09 amalloy: hmm. well, when i get finished with the "what the hell is hadoop" experimentation phase, i'll give cassandraforte a closer look

3:10 ohpauleez: if you have a map reduce problem, hadoop is a bunch of fun

3:11 amalloy: yeah, we're just chewing through a large set of logs to generate aggregate data for the existing SQL code

3:11 poster child for hadoop and cassandra both

3:12 carkh: so you managed to reach the "scaling limit" of sql ?

3:12 or is it just for learning ?

3:13 amalloy: carkh: well, i joined the company a few months ago, and while we could scale sql for another year or two if we had to and could spare the money...

3:13 carkh: what database engine were you using ?

3:13 (if i may ask)

3:14 amalloy: ummmm, myisam in production, i think, and maybe transitioning to innodb

3:14 (on mysql)

3:14 carkh: right

3:14 damn you must be processing an awefull lot of transactions

3:15 ohpauleez: carkh: I have scaled out MySQL and Postgres in HUGE deployments. The truth is, if you're facing a system that has a scaling problem and doesn't require certain needs, mongo or something similar is nice

3:15 if you have to number crunch or build a search index on something huge

3:16 hadoop is a gem

3:16 amalloy: carkh: ~100k per hour, i think? 400k at super-peak times

3:17 ohpauleez: really just tools in a tool box

3:17 just like RBDMSs

3:17 carkh: i'm not doubting your needs ... I just personally never needed anything more than sharding, but that's only me

3:18 ohpauleez: whatever fits the problem space

3:18 amalloy: carkh: oh, i'm sure we could shard too, but since we're keeping a bunch of unrelational data, cassandra is better-suited

3:18 ohpauleez: carkh: Depending how those transactions happen, and how you grow, "just sharding" can be hard, even with mysql

3:19 I'm not a nosql fanboy, very much the opposite

3:19 but I have ran into scenarios where it fit nicely into the solution space

3:20 carkh: so, cassandra or haddoop ?

3:20 amalloy: both

3:20 cassandra for storage, hadoop for processing

3:20 carkh: and how many computers are participating in your "cluster" ?

3:20 ohpauleez: amalloy: if you're not extremely write heavy, I would caution with cassandra. But do some tests and look at the numbers

3:21 amalloy: carkh: not sure yet - it's still in the development phase, and i imagine we'll do performance testing to see how many nodes we need

3:22 ohpauleez: for sure

3:22 amalloy: ping me if you need any help or insight. More than happy to pass along tips

3:22 amalloy: thanks ohpauleez

3:22 carkh: well, good luck on your projects, seems interesting

3:23 amalloy: i know you have experience with hadoop and cassandra; have you used them together? that's what i'm currently stumbling on

3:25 ohpauleez: I haven't used them both directly together

3:25 I used one for a stats reporting, and I fed that to another data store that later fed into hadoop for BI and number crunching

3:45 notsonerdysunny: I keep getting ... "/home/sunil/bin/cake:307: warning: Insecure world writable dir /media/disk/user in PATH, mode 040777" is there a way to disable this?

3:47 amalloy: notsonerdysunny: take that directory off your PATH...? it's a warning because anyone could put a malicious program named, for example, ls into that directory, and when you typed ls it would run that program with all your permissions

3:48 notsonerdysunny: hmm.. I realize that .. but is there a way to suppress it...

3:49 I am the only user of this computer...

3:49 amalloy: what's in that directory that you want to be able to execute?

3:49 notsonerdysunny: k .. I guess I will remove it from path

3:50 amalloy: or chmod o-w /media/disk/user

3:52 er, a-w? something like that

3:52 fhd: Hi. Is there a pair datatype in Clojure? In Emacs Lisp I could use (1 . 2) or (cons 1 2), doesn't work in Clojure.

3:53 amalloy: ,(vector 1 2)

3:53 clojurebot: [1 2]

3:53 amalloy: ,[1 2]

3:53 clojurebot: [1 2]

3:53 fhd: clojurebot: That's not exactly a pair, is it?

3:53 clojurebot: It's greek to me.

3:53 fhd: clojurebot: I mean, this would be possible: [1 2 3 4]

3:53 clojurebot: Titim gan éirí ort.

3:53 amalloy: lol, i'm not clojurebot

3:54 fhd: oh, reading helps :)

3:54 amalloy: is that the way to use pairs in Clojure?

3:54 amalloy: I've seen the intimidating syntax necessary to create a cons...

3:55 amalloy: fhd: usually, if you want to return a group of data, you can return a hashmap, or a list, or a vector. i don't think there's much need for an explicit pair

3:55 fhd: amalloy: Wouldn't hurt I guess, just got used to it. Would a list or a vector be better then?

3:55 hiredman: if you want pairs you can create a pair protocol and extend it to vectors, hashmaps, lists, and seqs

3:56 fhd: hiredman: I'd rather go with the existing language features for the simple stuff I'm doing ATM.

3:56 amalloy: ,(cons 1 [2]) ; if you like the reassuring cons syntax :)

3:56 clojurebot: (1 2)

3:57 _ato: fhd: to answer your question directly, no there's no pairs

3:57 kumarshantanu: ,(doc cons)

3:57 clojurebot: "([x seq]); Returns a new seq where x is the first element and seq is the rest."

3:57 amalloy: fhd: i think it depends on what you want. if your pair represents two different things, maybe you want a map

3:58 fhd: I wouldn't use that weird syntax. (1 . 2) is okay, but I find even (cons 1 2) too long, so I'll probably go with [1 2]

3:58 amalloy: ,(let [pair {:x 10, :y 11}] (pair :x))

3:58 clojurebot: 10

3:58 fhd: ,(* 2 10)

3:58 clojurebot: 20

3:58 fhd: I see.

3:59 hiredman: (cons 1 2) won't even work

4:00 amalloy: hiredman: it will in CL, which he was saying he finds too long

4:00 fhd: hiredman: Yeah, that's the problem. One has to create a seq or something, I'll pass.

4:00 hiredman: in clojure cons doesn't not create a "cons cell" it only adds an element to the start of seq

4:00 amalloy: it's been a while since i wrote CL; is (1 . 2) actually legal? it seems like the reader ought to try to evaluate 1 as a function

4:00 fhd: amalloy: I know that from Emacs Lisp to be honest, never did much CL.

4:01 amalloy: That's true, I always found it a bit weird too.

4:01 amalloy: fhd: well, there you go! an excuse to get away from inconsistent syntax :)

4:02 kryft: How is clojure for shell scripting, btw?

4:02 fhd: amalloy: Yeah. BTW, it has to be quoted, so it's kinda legal '(1 . 2)

4:02 amalloy: ah

4:02 ,'(1 2)

4:02 clojurebot: (1 2)

4:03 fhd: ,'(1 . 2)

4:03 clojurebot: (1 . 2)

4:03 fhd: HM.

4:03 amalloy: fhd: that's a list with three elements

4:03 ,(count '(1 . 2))

4:03 clojurebot: 3

4:03 fhd: amalloy: Ah, lol :)

4:04 I'll just go with a vector I guess, nicest syntax.

4:04 amalloy: the vector syntax is convenient for longer lists too, since you don't have to quote the whole list to avoid calling it

4:05 ,(let [a 10] ['f a 'a])

4:05 clojurebot: [f 10 a]

4:05 _ato: kryft: Clojure is terrible for shell scripting, the JVM is really unsuited to that sort of thing due both to startup time and the lack of unixy IO functions (no way to create a symlink for example, at least until JDK 7 is released).

4:06 at least if you mean actuing like a traditional shell anyway ;-)

4:09 amalloy: anyway good luck fhd. i'm often around if you want some more unhelpful answers, but for now i'm off to bed

4:09 fhd: amalloy: Yeah, thanks!

4:09 I'll have to continue working, so I'm off as well :)

4:11 kryft: _ato: Actually I guess 'shell scripting' was a bit misleading; I was thinking of stuff that I'd normally do with a python script (as opposed to stuff that I'd do with a bash script)

4:16 _ato: I typically use python for mangling data (machine learning research); the scripts often do require some IO (writing files and maybe creating symlinks) once the mangling is done.

4:17 hiredman: the jvm is generally not so good for short running processes, the startup time being prohibitive

4:19 _ato: I tend to use Pythoon/Ruby/Perl for quick-running stuff, or stuff that needs to do unixy things (fork, posix IO etc). For longer running text processing (like parsing log files and generating stats) I'll use Clojure

4:20 it depends though, often I just run things out of an emacs buffer so there's no startup time there. But it's not so easy to pipe into other commands and that sort of thing

4:40 lypanov: _ato / hiredman: whats wrong with using cake or nailgun to solve the startup time issue?

4:41 quizme: http://pastie.org/1209316 <--- :~(

4:41 *sniff*

4:41 is there a function version of and?

4:41 logical and

4:42 and in general what do you do if you want to use a macro in apply?

4:42 write a function version of the macro?

4:56 sandGorgon: I was looking at the alioth shootout between F# Mono and Clojure - CPU performance quite similar... but F#/Mono uses drastically less memory : in some cases 61X less memory!

4:56 http://shootout.alioth.debian.org/u32q/benchmark.php?test=all&lang=fsharp&lang2=clojure

5:07 lypanov: sandGorgon: clojure on mono or jvm?

5:07 * lypanov would like to have the time to write a port of clojure running on top of llvm.

5:08 sandGorgon: lypanov, I think it is the jvm clojure that alioth uses. Is the clojure-on-clojure work done ? because I guess that would be the precursor to clojure being implemented on a lot of backends

5:09 lypanov: sandGorgon: could just be that sun/oracle suck. :) ;)

5:55 quizme: how do you do this? (apply and '(true true false))

5:57 mrBliss: ,(every? identity '(true true false))

5:57 clojurebot: false

5:57 mrBliss: quizme: you can't apply macros

5:57 jarpiain: is there a function that returns a seq on a sorted-map starting from a given key?

5:58 mrBliss: jarpiain: you could use (drop-while #(not= % the-key) the-sorted-map)

5:58 jarpiain: mrBliss: but that takes O(n) to find the key

5:59 mrBliss: you're right

5:59 quizme: mrBliss is there a way to turn a macro into a function so that it can be applied?

6:00 or does that not make sense ?

6:00 mrBliss: quizme: rewriting the macro as a function ;-)

6:00 _ato: ,(subseq (sorted-map 1 :a 2 :b 3 :c 4 :d) > 2)

6:00 clojurebot: ([3 :c] [4 :d])

6:00 _ato: jarpiain: ^

6:00 mrBliss: quizme: when you want to apply a macro, you don't have enough information at compile time

6:01 quizme: mrbliss right...

6:01 _ato: quizme: http://richhickey.github.com/clojure-contrib/apply-macro-api.html :p

6:02 mrBliss: but remember:^^ "This is evil. Don't ever use it."

6:04 jarpiain: _ato: thanks, somehow missed that

8:09 mada: hi all!

8:12 I am building a small recipe database and have a question. In Clojure, if I want to loop over all the ingrediences in a number of recipies and summarize the ammount of each, assuming each recpipe is just a list/seq on the form (name number measure), what would be the standard way to do it? In elisp or other more imperative lisp I would just define a list variable with let and then increase each unique ingredient, but

8:12 in Clojure things are immutable (apart from defs) so how would it work there?

8:13 carkh: you might use reduce

8:14 mada: carkh: k, will look that up

8:14 carkh: (let [summary (reduce add-receip-list-to-map-result {} receipes)] (print-summary summary))

8:14 jaley: mada: map the collection of recipes to a collection of amounts, then reduce with +

8:25 is there a function to break a map into a collection of [key value] vectors? i'm using (for [[k v] m] [k v]) right now, just wondering if it's necessary?

8:26 mrBliss: ,(seq {:a 1, :b 2})

8:26 clojurebot: ([:a 1] [:b 2])

8:26 jaley: mrBliss: that's better - thanks!

8:43 LLLLL: hey guys

8:44 where do I read about ~' in macros, how does it work

8:44 seems to me like it doesn't do anything

8:46 mrBliss: ,(let [x 1] `(x))

8:46 clojurebot: (sandbox/x)

8:46 mrBliss: ,(let [x 1] `(~x))

8:46 clojurebot: (1)

8:46 mrBliss: can you see what ~ does? It evaluates x

8:47 LLLLL: it wasn't what I was looking for

8:47 for instance you have a long macro `( some code blah blah then ~'something)

8:48 ,(let [x 1] `(~'x))

8:48 clojurebot: (x)

8:48 LLLLL: like this

8:48 mrBliss: sorry, I didn't read it well enough

8:49 ,(let [x 1] `(x))

8:49 clojurebot: (sandbox/x)

8:49 mrBliss: the sandbox/ is the difference

8:49 LLLLL: I can see it lacks namespace, but I'm unsure what that's used for

8:49 carkh: it allows you to capture the symbol name in order to make it available to your macro user

8:50 mrBliss: if the x you want is in another namespace. I'll try to come up with a good example

8:52 LLLLL: i get it now

8:52 thx

9:25 jaley: (doc min)

9:25 clojurebot: "([x] [x y] [x y & more]); Returns the least of the nums."

11:15 neotyk: Hi Clojurians

11:15 anyone here using org-mode?

11:15 abrenk: yeah

11:16 neotyk: I'm trying to get second Wed of every month into my agenda <%%(diary-float t 3 2)>

11:16 abrenk: neotyk: sorry, that's more than I ever wanted

11:16 neotyk: why it doesn't appear in agenda view

11:16 :(

11:16 #org-mode is silent

11:17 google doesn't know

11:17 source code will talk to me

11:17 phaer: neotyk: It works for me. Maybe you missed some settings in your agenda file? the org mode mailinglist is much more responsive than the irc channel

11:18 neotyk: agenda file?

11:18 I generate agenda from org file

11:22 phaer: neotyk: Ah sorry, i was talking about the agenda settings in your .emacs[.d] like "agenda-files".

11:30 neotyk: phaer: I do C-c a L

11:35 phaer: neotyk: Don't you have an org-agenda-file setting in your .emacs? I have one which includes serveral org files. And i've got a binding of "org-agenda-list" to f2. And if i press f2 i see all my tasks including the repeating one for which i use <%%(diary-float t 6 1)> etc.

11:39 neotyk: phaer: no org-agenda-file

11:39 let me create one

11:46 Guest74051: How can I turn ((("banana" 3) ("apple" 2)), (("banana" 1) ("apple" 4) ("orange" 2))) into (("banana" 4) ("apple" 6) ("orange" 2))?

11:48 raek: ,(merge-with + {:banana 3, :apple 2} {:banana 1, :apple 4, :orage 2}) ; a slightly different variant

11:48 clojurebot: {:orage 2, :banana 4, :apple 6}

11:50 raek: mada: normally the map data structure is used. there are many useful functions for them.

11:52 I happened to use keywords as keys here, but you can use strings (or anything, actually) for keys if you like

11:53 neotyk: phaer: with org-agenda-files it works

11:53 phaer: thank you

11:53 +1 phaer

11:54 mada: raek: I plan to get the input as strings from a user, won't that be a problem?

11:54 raek: sorry, I see now what you added :)

11:54 raek: then strings would be fine

11:54 mada: great

11:54 raek: and I assume I can convert a list of pairs like this into a map easily?

11:56 jarpiain: ,(into {} '(("banana" 3) ("apple 2")))

11:56 clojurebot: java.lang.ClassCastException: java.lang.String cannot be cast to java.util.Map$Entry

11:58 raek: ,(into {} (map (fn [[k v]] [k v]) '(("banana" 3) ("apple" 2))))

11:58 clojurebot: {"banana" 3, "apple" 2}

11:59 jkkramer: ,(into {} '(("banana" 3) ("apple" 2))) ;misplaced quote

11:59 clojurebot: java.lang.ClassCastException: java.lang.String cannot be cast to java.util.Map$Entry

11:59 jkkramer: ok guess not

11:59 raek: ,(into {} (map vec '(("banana" 3) ("apple" 2))))

11:59 clojurebot: {"banana" 3, "apple" 2}

12:00 mada: raek: excellent! thanks!

12:00 raek: the thing conjed to a map has to be a MapEntry or a IPersistentVector of size 2

12:01 jkkramer: the norm is to keep data in vectors rather than lists

12:02 ,(into {} [["banana" 3] ["apple" 2]])

12:02 clojurebot: {"banana" 3, "apple" 2}

12:02 mada: jkkramer: I see, a bit different than what I am used to but I guess it works as well.

12:03 jkkramer: does a vector have any major disadvantages compared to a list for simple things like this?

12:03 jkkramer: mada: nope

12:04 raek: it is ideomatic to use vectors for literals for sequential things

12:04 jkkramer: lists are normally only used for code forms and special circumstances

12:05 raek: ,(seq {"banana" 3, "apple" 2}) ; you can go the other way around too

12:05 clojurebot: (["banana" 3] ["apple" 2])

12:07 mada: k, thanks both of you!

12:07 phaer: neotyk: np :)

12:30 LLLLL: is there any good clojure API list like java has javadoc of whole Java 5 Api

12:30 just to see what functions are out there and what do they do

12:30 MayDaniel: clojure.github.com/clojure ?

12:30 LLLLL: since I keep finding myself programming functions just to find out they already exist

12:31 raek: http://clojuredocs.org/Clojure%20Core and http://clojuredocs.org/Clojure%20Contrib

12:31 kumarshantanu: LLLLL: you may try (1) (doc form), (2) ClojureDocs or (3) Autodoc

12:31 LLLLL: ok

12:31 raek: and http://clojuredocs.org/quickref/Clojure%20Core

12:32 (by category)

12:32 and this http://faustus.webatu.com/clj-quick-ref.html

12:32 :-)

12:32 kumarshantanu: or perhaps this cheatsheet -- http://clojure.org/cheatsheet

12:33 LLLLL: thanks a lot

12:37 hm I seem to be missing a lot of namespaces

12:37 ohpauleez: LLLLL: What do you mean?

12:38 raek: some of the clojure.* namespaces was added in 1.2

12:38 LLLLL: well I can't find clojure.inspector

12:38 which is 1.0 I believe?

12:39 says it can't find inspect function

12:39 raek: how do you access things in them?

12:39 LLLLL: (ns test (:require clojure.inspector))

12:39 (inspect some-thing)

12:39 raek: LLLLL: use use in that case :)

12:39 KirinDave: You know, something that I've been wondering...

12:40 is it possible in an ns declaration to alias a namespace with only 1 path component?

12:40 LLLLL: what's the difference?

12:40 KirinDave: like let's say

12:40 raek: with require, it is (clojure.inspector/inspect some-thing)

12:40 KirinDave: (alias e 'example1)

12:40 raek: or (ns test (:require [clojure.inspector :as ins])) (ins/inspect some-thing)

12:40 LLLLL: works now thanks

12:40 ohpauleez: LLLLL: or you can use the ns qualifer. (ns test (:require clojure.inspector :as inspector))(inspector/inspect some-thing)

12:40 raek: (ns test (:use clojure.inspector)) (inspect some-thing)

12:41 LLLLL: the thing that worries me is if I write just

12:41 clojure.

12:41 and hit autocompletel

12:41 raek: (ns test (:use [clojure.inspector :only (inspect)])) (inspect some-thing)

12:41 LLLLL: it offers me very few namespaces

12:41 KirinDave: LLLLL: How many?

12:41 LLLLL: Should be just a handful.

12:42 raek: LLLLL: could e because they haven't been loaded. after a require or use, they should appear

12:42 LLLLL: shows me 10

12:42 raek: ohpauleez: you need to have a vector there, right?

12:42 ohpauleez: yes

12:43 I messed it up

12:43 LLLLL: ok seems I need to load them with before they appear

12:43 raek: yes, I think it queries the clojure runtime for existing namespaces

12:43 which only gets added if they are loaded

12:43 LLLLL: ok

12:44 good to know that

12:44 so "use" adds the functions of the namespace to use as unqualified

12:44 raek: yes

12:45 a process called "referring"

12:45 "use" is basically "require" and "refer"

12:46 refer is very rarely used manually, though

12:47 heh, I discovered C-c M-p yesterday... ("Switch the repl namespace to match the current buffer")

12:47 KirinDave: Oh.

12:47 raek: no need to write (in-ns 'se.raek.some.of.my.insanely.long.namespace.names) anymore...

12:47 KirinDave: That's a good key

12:48 I finally got autocomplete working in all my slime buffers. :\

12:48 It's still sorta janky how I do it, but it works!

12:48 raek: all the ones listed at http://github.com/technomancy/swank-clojure are very handy

12:49 KirinDave: C-c C-k is one I _never_ use.

12:49 raek: it's neat for getting line numbers for the fns

12:50 LLLLL: C-c TAB is autocomplete? Just TAB works for me

12:50 raek: they are not set if one sends them for evaluation with C-M-x

12:50 I think that different in repl and code buffer for me

12:52 _ulises: hello all

12:54 ohpauleez: hi _ulises

12:55 _ulises: I have the newbie's dillema

12:55 I have read Programming Clojure and I'm about to read The Joy of Clojure

12:56 however, I don't feel like I'm doing enough progress

12:56 I know it sounds silly, but after learning the basics of Clojure and learning how to write simple code, I'm sort of stuck using only clojure.core and following a semi-imperative semi-fp style

12:56 ohpauleez: _ulises: You'll the most from working through an entire project

12:56 _ulises: so, got any ... ah! good stuff ...

12:57 ohpauleez: The Joy of Clojure will help answer the "when" questions for you

12:57 _ulises: What do you typically work on

12:57 _ulises: I am suffering the problem described here: http://prog21.dadgum.com/80.html

12:57 well, I work on many things really

12:57 :S

12:58 ohpauleez: I think a parallel web-scraper, that collects data, performs some ops on it, and does some viualization with it, is fun and a good project

12:58 _ulises: oh

12:58 nice

12:58 carkh: how about something that helps you

12:58 _ulises: I could try a port of scrappy (a cawler written in python)

12:58 ohpauleez: Building a web system is fun too, let's deal with data and you have a usable product afterwards

12:58 _ulises: well, that blog post actually says: if you don't know what to work on, just work on something you would use

12:59 ohpauleez: _ulises: Porting might lead you the wrong way

12:59 _ulises: I feel rather silly coming to you with such dillemma :)

12:59 ohpauleez: because you'll try to take an imperative approach and force it into a functional one

12:59 Don't ever feel silly

12:59 _ulises: ohpauleez: well, not strictly porting, but writing something similar, that's what I mean :)

12:59 ohpauleez: _ulises: Take a look at Enlive

12:59 _ulises: yeah, I guess I'm too eager

12:59 I've only started learning/working with Clojure 1 1/2 months ago

12:59 ohpauleez: Thing about how you can use futures, maybe promises, perhaps agents

13:00 and pmap

13:00 _ulises: ,(doc pmap)

13:00 clojurebot: "([f coll] [f coll & colls]); Like map, except f is applied in parallel. Semi-lazy in that the parallel computation stays ahead of the consumption, but doesn't realize the entire result unless required. Only useful for computationally intensive functions where the time of f dominates the coordination overhead."

13:00 _ulises: ooh

13:00 nice

13:00 ohpauleez: Then take a look at incanter,

13:00 and do some nice data visualization with it

13:01 _ulises: interesting

13:01 tomoj: if you want it to be parallel, look at aleph too

13:01 ohpauleez: tomoj: You're beating me to it!

13:02 _ulises: I am writing the ant demo at the moment just to get my dev-env set up properly and warm up

13:02 ohpauleez: _ulises: I would, generally speaking, just think about fun projects or areas I always wanted to play in (machine learning, AI, web stuff, etc), and just do a small project

13:03 once you move forward, you'll get more ideas on other things you want to do

13:03 _ulises: that's a nice approach

13:03 I think that my ultimate goal is to learn the language inside out

13:03 and I think that by coding in it you do that

13:03 so, yeah, great stuff, thanks ohpauleez :)

13:04 ohpauleez: _ulises: totally happy to help

13:04 _ulises: I will take a look at those libs/projects you mentioned and see what I can come up with

13:04 carkh: also when you feel your code is too imperative when it shouldn't, come here and show us, there are many helpfull people here

13:05 _ulises: ah, yes, that'd be very valuable

13:05 ohpauleez: for sure

13:05 _ulises: I've also realised that I tend to overcomplicate solutions

13:05 pretty much all the time

13:05 ohpauleez: even those of us who do lot of clojure will post snippets for opinions

13:06 _ulises: there was this email to the ml about an fn that would take an input like [[:foo [1 2 3] [:bar [\a \b \c]]] and it would produce ({:foo 1 :bar \a} {:foo 2 :bar \b}...)

13:06 and I came up with a really long and convoluted solution :/

13:08 ohpauleez: _ulises: That has more to do with familiarity of apply functions than anything else

13:08 s/apply/applying

13:09 _ulises: heh, my solution involved lots of (apply map fn ...)

13:09 on the happy side of things, I learnt that a sequence of apply will unpack a nested list structure

13:09 which is awesome :D

13:09 raek: _ulises: I think the best way to learn and familirize with the libs is simply to code a lot.

13:10 _ulises: raek: yes, that's what I think as well, but when you don't know what to code, you're stuck reading blogs and trying silly things out in the repl but not much more

13:10 raek: and at the same time I don't want to create any more abandon ware

13:10 *abandonware

13:10 tomoj: unavoidable

13:10 _ulises: but ohpauleez has a point: I will just play with stuff I've always wanted to to and learn that way

13:10 raek: my first big project was a web system for tracking debts between the persons in my circle of friends

13:11 tomoj: great idea

13:11 raek: lately, I have been coding on an IRC library

13:11 tomoj: math is usually hard when I owe my friends money

13:12 _ulises: hah

13:12 raek: not much libs in that project. it used compojure, refs and files, basically

13:12 yavuz: raek: hmm...sounds like you could be the clearing house to net the debts and pocket a small fee...many a financial fortune is based on that idea ;P

13:14 _ulises: anyway, thanks for the advice chaps

13:14 perhaps I should pay you for the psycoanalysis session :)

13:15 defn: wow this sucks.

13:15 no more rooms left for clojure-conj

13:15 im screwed.

13:20 Raynes: defn: I'll cry myself to sleep tonight. :(

13:20 defn: @clojure-conj tweeted that we had until the 11th and that there were plenty of rooms available. *sigh*

13:21 I have a damn ticket, taboot.

13:21 Not sure what I'm going to do now...

13:21 Raynes: A ticket to what? The conj?

13:21 :o

13:22 defn: Yeah I have a conj ticket

13:22 but no room

13:22 Raynes: And nobody has offered you the floor of their room yet?

13:22 :\

13:23 _ulises: defn: did you see the email from the chap wanting to share a room?

13:23 sorry, to the ML

13:23 carkh: maybe there is a park around with a comfortable bench =)

13:24 Raynes: carkh: It's in a park. :p

13:25 LauJensen: Hi guys :)

13:25 _ulises: hi LauJensen

13:26 esj: Evening Lau

13:27 Raynes: Afternoon, LauJensen.

13:27 defn: _ulises: i didnt but ill check it out

13:28 _ulises: defn: recently there was this chap wanting to share a room and his last email was along the lines of "ok, booked a room, it'll be $X for whomever wants to share it w/me"

13:28 :)

13:29 Raynes: defn: If that doesn't work out, if you post an ML thread, I'm sure there is someone who would be happy to let you use a sofa bed or something. I mean, I'd happily let you sleep in our room if it came down to it, but I'm not sure they'll be anything in there but the floor for you.

13:30 * esj is sad to me on the wrong side of the pond

13:30 _ulises: esj: whereabouts are you?

13:30 (if you don't mind me asking)

13:30 defn: _ulises: if you can point out where that thread is id be obliged

13:30 searching for clojure conj is somewhat difficult on the ML :)

13:30 _ulises: defn: sure, one sec.

13:31 Raynes: defn: http://groups.google.com/group/clojure/t/5d147246206ff586

13:31 esj: _ulises: Her Majesty's Green and Pleasant Land

13:31 _ulises: esj: heh heh, that makes two of us I guess

13:32 defn: what Raynes just said :)

13:33 defn: _ulises: got it, thanks Raynes -- email sent.

13:34 * defn prays it's not too lte

13:34 defn: late*

13:34 _ulises: defn: g'luck

13:35 defn: thanks :)

13:41 Raynes: defn: Keep me posted.

13:51 yayitswei: hello.

13:51 how do i iterate through every two elements in a list: for example (1 2 10 11) i want (1 2) (2 10) (10 11)

13:52 i want to remove numbers that are within 1 distance of the previous-- in the above case, the correct answer would be (1 10)

13:53 Raynes: -> (partition 2 (range 11))

13:53 sexpbot: ⟹ ((0 1) (2 3) (4 5) (6 7) (8 9))

13:53 Raynes: -> (partition-all 2 (range 11))

13:53 sexpbot: ⟹ ((0 1) (2 3) (4 5) (6 7) (8 9) (10))

13:53 hiredman: ,(iterate rest [1 2 10 11])

13:53 er

13:53 clojurebot: Execution Timed Out

13:53 _ulises: woot! I've been needing that fn all along and wrote my own :(

13:53 yayitswei: ah, partition .. thanks

13:53 hiredman: ,(take-while identity (iterate rest [1 2 10 11]))

13:53 yayitswei: haha _ulises

13:54 clojurebot: Execution Timed Out

13:54 hiredman: ,(take-while (comp identity seq) (iterate rest [1 2 10 11]))

13:54 clojurebot: ([1 2 10 11] (2 10 11) (10 11) (11))

13:54 _ulises: :'(

13:55 Raynes: Partition doesn't do quite what you want here.

13:55 I didn't read your message thoroughly enough.

13:55 hiredman: ,(map (partial take 2) (take-while seq (iterate rest [1 2 10 11])))

13:55 clojurebot: ((1 2) (2 10) (10 11) (11))

13:55 hiredman: ,(butlast (map (partial take 2) (take-while seq (iterate rest [1 2 10 11]))))

13:55 clojurebot: ((1 2) (2 10) (10 11))

13:59 mfex: ,(partition 2 1 [1 2 10 11])

13:59 clojurebot: ((1 2) (2 10) (10 11))

13:59 Raynes: -> (doc partition)

13:59 sexpbot: ⟹ "([n coll] [n step coll] [n step pad coll]); Returns a lazy sequence of lists of n items each, at offsets step apart. If step is not supplied, defaults to n, i.e. the partitions do not overlap. If a pad collection is supplied, use its elements as necessary to complete last partition upto n items. In... http://gist.github.com/618424

13:59 Raynes: Oh! a step!

13:59 Awesome.

14:00 _ulises: indeed

14:00 yayitswei: ,(partition 2 1 [1 2 10 11])

14:00 clojurebot: ((1 2) (2 10) (10 11))

14:02 _ulises: ,(partition 2 (interleave [1 2 3] [\a \b \c]))

14:02 clojurebot: ((1 \a) (2 \b) (3 \c))

14:02 _ulises: woop

14:02 good bye map

14:05 yayitswei: ok, so I got this

14:05 ,(keep #(if (< 1 (- (last %) (first %))) (last %)) (partition 2 1 [1 2 10 11 20 21]))

14:05 clojurebot: (10 20)

14:06 yayitswei: a very newbie way of doing I'm sure, and it misses the first element

14:06 xcthulhu: Is there a way to use clojure to do concurrent programming (ie, map-reduce) over a bunch of computers on a LAN?

14:06 yayitswei: should be (1 10 20)

14:06 but otherwise it does what I want

14:11 hiredman: ,(map first (filter #(= 1 (- (apply max %) (apply min %))) (butlast (map (partial take 2) (take-while seq (iterate rest [1 2 10 11 20 21]))))))

14:11 clojurebot: (1 10 20)

14:15 LauJensen: xcthulhu: Well, there's clojure-hadoop, and terracotta to look at

14:16 xcthulhu: LauJensen: Thank you! :D

14:16 LauJensen: xcthulhu: np. I actually have a blogpost on how to get started with clojure-hadoop of you need a kick start

14:17 LLLLL: (butlast "12345")

14:18 ,(butlast "12345")

14:18 clojurebot: (\1 \2 \3 \4)

14:18 LLLLL: ,(str (\1 \2 \3 \4))

14:18 clojurebot: java.lang.ClassCastException: java.lang.Character cannot be cast to clojure.lang.IFn

14:18 LLLLL: hm

14:18 how do I get it back into string again

14:18 LauJensen: ,(->> "12345" butlast (apply str))

14:18 clojurebot: "1234"

14:19 LauJensen: LLLLL: Or in short, instead of str, use (apply str (\1 \2...

14:19 LLLLL: whats ->> ?

14:19 LauJensen: ->> threads the first item through the remaining forms as the last argument of them

14:19 sexpbot: ⟹ #<core$_GT_ clojure.core$_GT_@189c698>

14:19 LauJensen: (->> 3 (+ 2)) becomes (+ 2 3)

14:20 (apply str (butlast "1234")) is the same as (->> "1234" butlast (apply str))

14:22 LLLLL: ,(apply str (\1 \2 \3))

14:22 clojurebot: java.lang.ClassCastException: java.lang.Character cannot be cast to clojure.lang.IFn

14:22 LLLLL: ,(apply str '(\1 \2 \3))

14:22 clojurebot: "123"

14:23 LLLLL: (str '(\1 \2 \3))

14:23 ,(str '(\1 \2 \3))

14:23 clojurebot: "(\\1 \\2 \\3)"

14:23 LLLLL: this clojure is funny shit

14:23 :P

14:23 kumarshantanu: ,(apply str '(\1 \2 \3))

14:23 clojurebot: "123"

14:24 LLLLL: so many ways one can screw up

14:24 kumarshantanu: LLLLL: the key is - you should know what you are doing :)

15:09 yayitswei: hiredman: just saw your solution.. thanks!

15:12 ordnungswidrig: anybody using rainbow-parens?

15:13 amalloy: ordnungswidrig: i am, though i'm probly gonna stop soon

15:13 hiredman: I am getting used to having it off, it really bogs down moving around in a large file or a deeply nested expression

15:14 ordnungswidrig: for me it conflicts with clojure-test-mode

15:16 hiredman: what slows me down more is that fontifying the slime compilation buffer takes longer than the compilation itself...

15:16 hiredman: even for "0 compiler notes". Any chance to improve that?

15:17 Raynes: I still have rainbow parens. No particular reason. I don't look at parens anymore. I just haven't bothered to turn it off.

15:20 hiredman: *shrug*

15:21 ordnungswidrig: *shrug* who?

15:21 * ordnungswidrig wonders whether it's "*knock* *knock*" or "*shrug* *shrug*"

15:33 jaley: hi guys! would I be right in thinking the easiest way to use a SOAP service from clojure will be javax.xml.soap? I did some googling and couldn't find anything obvious in clojure...

15:51 LauJensen: jaley: Judging from the silence I think javax.xml.soap is your best bet :)

15:52 jaley: LauJensen: heh thanks.. actually I realized that's server-side now. seems apache axis is my best bet

15:52 LauJensen: Ah ok. Ive worked with Axis in the past. Was a little painful as I recall

15:52 jaley: LauJensen: d'oh...

15:53 LauJensen: jaley: Homer, is that you? :)

15:53 jaley: LauJensen: Marge?

15:54 ordnungswidrig: Maggie?

15:56 Raynes: Bart?

16:12 Derander: I am new to clojure. I have a list of CommPortIdentifiers from a java library. I have converted it to a lazy seq. I want to return a specific object from the list if it matches a predicate, and throw an exception if the object I'm looking for isn't in the list

16:14 Where should I look to figure out how to do this? Would it be idiomatic to filter it with reduce, return the result if there is one or throw an exception if the size is 0?

16:15 Raynes: -> (some #(= 4 %) (range 11))

16:15 sexpbot: ⟹ true

16:15 Raynes: Bad example.

16:15 Derander: http://gist.github.com/618562 <-- this is the code that I'm trying to make better.

16:15 the goal is to return the CommPortIdentifier that matches the name I'm looking for

16:16 Raynes: -> (some #(and (= 4 %) %) (range 11)) ; was what I was trying to do.

16:16 sexpbot: java.lang.IllegalArgumentException: Don't know how to create ISeq from: clojure.lang.Symbol

16:16 Derander: Raynes: reaing clojure doc on some

16:16 MayDaniel: ,(some #{4} (range 11))

16:16 clojurebot: 4

16:16 * Raynes facepalms

16:16 Derander: hhaha.

16:17 Raynes: MayDaniel: hi5

16:17 I knew I was forgetting something. :\

16:18 -> (some #(and (= 4 %) %) (range 11))

16:18 sexpbot: java.lang.IllegalArgumentException: Don't know how to create ISeq from: clojure.lang.Symbol

16:18 Raynes: That must be a sexpbot bug.

16:18 ,(some #(and (= 4 %) %) (range 11))

16:18 clojurebot: 4

16:19 Raynes: Anyways, some returns the first truthy result of applying the predicate function to an element of the list. You should be able to do what you want with it.

16:19 Derander: http://gist.github.com/618562

16:20 is what I came up with. it returns true if it finds the match. I'm not sure how you're getting some to return the actual value

16:20 Raynes: I used and.

16:20 -> (and true "a value")

16:20 sexpbot: java.lang.ClassCastException: java.lang.Character cannot be cast to clojure.lang.IFn

16:20 Raynes: What the hell, sexpbot.

16:20 ,(and true "a value")

16:20 clojurebot: "a value"

16:20 Derander: oh, I see.

16:20 missed the second %

16:21 Raynes: #(and (= (.getName %) port-name)) %) will do the trick.

16:21 Derander: yeah.

16:21 I didn't see the significance of the "and" and the %

16:21 second %

16:21 Raynes: Minus one of the inner closing parens, anyway.

16:22 Derander: Raynes, MayDaniel: thanks for your help.

16:23 Raynes: Also, if you're curious about his #{4} trickery, it's because sets are functions that look up their argument within themselves and return it if it exists, or nil otherwise.

16:24 -> (#{4} 4)

16:24 sexpbot: ⟹ 4

16:24 Raynes: -> (#{4} 3)

16:24 sexpbot: ⟹ nil

16:24 Derander: that's nifty.

16:24 Raynes: When you're checking a sequence for literals, it's perfect.

16:26 Derander: clojure is frustrating because I'm used to writing in ruby. and ruby has a semi-functional style when it's idiomatic, so I recognize the names and concepts but can't implement them in clojure

16:26 because I don't know clojure's vocab yet.

16:32 yayitswei: what's the recommended way to deal with dates in clojure- joda? or is there a clojure date class

16:33 Raynes: yayitswei: The Java way. joda is a popular option. Check out clj-time.

16:33 yayitswei: raynes: ah, perfect. thank you

16:37 jk_: does anyone here know how the clojure run-time manages redefinining vars in a running program? is it atomic? is it safe to do "in production"? would the new values only get used for new threads? etc. maybe there is a good place to read about this.

16:39 ordnungswidrig: jk_: http://clojure.org/vars

16:40 ,(doc set!)

16:40 clojurebot: excusez-moi

16:41 ordnungswidrig: jk_: you might want to use refs or atoms

16:41 jk_: ordnungswidrig: thanks. i had read that earlier but i'm wondering about the safety of, for example, using a remote repl into a running server app to redefine functions on-the-fly, like you might do in erlang. i don't get a good feel for how that works from this reading. it's not a local binding but rather redefinining a global

16:42 ordnungswidrig: jk_: ah, I see.

16:42 jk_: ordnungswidrig: more like applying bug fixes as hot code swaps

16:43 ordnungswidrig: so your question is more about the thread safety of (def)

16:44 jk_: well, as i understand it, all you are doing is binding to a var in def, defn, etc

16:44 ordnungswidrig: i mean when you are providing a value, obviously :)

16:44 ordnungswidrig: yes, it's a root bound var.

16:44 yayitswei: enlive question: how do you select for the working node? something like "self" ?

16:46 jk_: ordnungswidrig: so yes, i guess the question is about the thread safety of changing a root bound var.

16:47 ordnungswidrig: jk_: I think using (def foo x) works like (alter-var-root foo constantly x) and for alter-var root only atomicity is given. which means that every thread will see the change instantly.

16:47 yayitswei: for example the model is <li>some stuff</li> and I want to set the id attribute, <li id="1">some stuff</li>

16:47 ordnungswidrig: jk_: http://richhickey.github.com/clojure/clojure.core-api.html#clojure.core/alter-var-root

16:47 jk_: ordnungswidrig: is it normal to try doing this kind of thing on a running system in production?

16:49 ordnungswidrig: jk_: for lispers in general yes. I don't know how safe it's in clojure, to be honest

16:50 jk_: ordnungswidrig: ok, thanks. and i didn't know about alter-var-root so that's good to know

16:50 ymasory: why does "" count as true in an if expression but not when you compare them using =?

16:51 amalloy: ymasory: *everything* but nil and false counts as true in an if

16:51 but "" is not equal to true, because they are clearly different values

16:52 ymasory: oh i see, so if isn't really looking for a boolean result necessarily

16:52 bhenry: ,(boolean "")

16:52 clojurebot: true

16:52 jk_: ,(= "" "")

16:52 amalloy: right. i think it actually coerces to boolean, but that coercion turns almost everything to true

16:52 clojurebot: true

16:54 ymasory_: thanks amalloy

16:54 jarpiain: ,(if (Boolean. false) "foo" "bar")

16:54 clojurebot: "foo"

16:54 jarpiain: it compares against null and the literal false, which is the same as Boolean/FALSE

16:55 ,(identical? false Boolean/FALSE)

16:55 clojurebot: true

16:55 jarpiain: ,(identical? false (Boolean. false))

16:55 clojurebot: false

16:55 bhenry: ,(identical? false (boolean false))

16:55 clojurebot: true

16:56 amalloy: (the lesson here is if you ever see Boolean. in your code you might as well commit suicide now and save yourself the trouble)

17:00 jk_: ,(if (.booleanValue (Boolean. false)) "foo" "bar")

17:00 clojurebot: "bar"

17:01 ordnungswidrig: jk_: you shall not use (Boolean.) :-)

17:01 jk_: i guess if you run out of memory, jarpiain's call might produce "bar" :)

17:02 ordnungswidrig: yes, there's no good reason to, unless some java interop demands it i guess. but calling a constructor isn't going to return nil or false in any case

17:02 ordnungswidrig: I hope oom throws and oome

17:04 AWizzArd: _ato: hi

17:18 how can I type-hint a local with a primitive initializer in Clojure 1.3? I put a ^:static after defn, but this didn't work. I can’t say: (dotimes [^int i 80] ...)

17:20 ordnungswidrig: AWizzArd: Integer/TYPE

17:21 AWizzArd: produces the same error message

17:21 "Can't type-hint a local with a primitive initializer."

17:24 LauJensen: AWizzArd: (defn ^:static [^long i] (dotimes [x i] ...)) If you want to make a primitive long inside the code, use (long 80)

17:24 hiredman: AWizzArd: (int 80)

17:24 KirinDave: And thus begins the perf poisoning.

17:24 hiredman: thats how you always type hint a local

17:25 KirinDave: In which everyone suddenly thinks that static binding is the _single most important_ feature of your code.

17:25 AWizzArd: yes, int 80 is what I use, but my aset is surprisingly slow

17:25 LauJensen: IIRC in 1.3 (class (int 3)) is Long

17:25 AWizzArd: Probably due to reflection then ?

17:25 AWizzArd: yesterday _ato pasted http://gist.github.com/616655 - look at the microbench-nolock

17:25 LauJensen: I get no reflection warning.

17:25 LauJensen: AWizzArd: Which is the danger of arrays, they dont always warn on reflection

17:25 hiredman: then jump on one of the many "this is surprisingly slow on the alpha release of the code I am using" threads on the mailing list

17:26 AWizzArd: For _ato writing into a byte[] was 9x faster than writing into a ByteArrayOutputStream. For me writing into a baos is a bit faster than writing into an array.

17:26 ordnungswidrig: AWizzArd: you may publish my paste if you like.

17:28 AWizzArd: ordnungswidrig posted this too: http://clojure.pastebin.com/6Z0sW00E

17:30 LauJensen: AWizzArd: Both Christophe and I have posts where we show how to speed up slow asets which arent giving reflection warnings

17:31 jk_: is it idiomatic in clojure to use underscore '_' for unused parameters?

17:31 AWizzArd: LauJensen: you don’t happen to have a link, do you?

17:31 MayDaniel: jk_: Yes.

17:31 LauJensen: AWizzArd: no, but I can find them, sec

17:31 KirinDave: I'm slowly approaching the finish line for the first chapter I'm writing of my clojure book.

17:32 AWizzArd: ,(let [ba (byte-array 100000000)] (time (dotimes [i 80000000] (aset ^"[B" ba (int i) (byte 0)))))

17:32 clojurebot: java.lang.OutOfMemoryError: Java heap space

17:32 AWizzArd: well, this is what I tried

17:32 LauJensen: AWizzArd: http://clj-me.cgrand.net/2009/10/15/multidim-arrays/

17:36 AWizzArd: hiredman: can you compare (let [baos (java.io.ByteArrayOutputStream. 100000000)] (time (dotimes [i 80000000] (.write baos 0)))) vs (let [ba (byte-array 100000000)] (time (dotimes [i 80000000] (aset ba i (byte 0))))) ?

17:36 For me baos is faster, but I need to say (int 0)

17:36 LauJensen: maybe you can paste those two too?

17:36 into your repl

17:37 LauJensen: 1) 558ms, 2) 93ms

17:37 Nikelandjelo: Is there a functions, which for seq (1 2 3 ) will return sequence of it's subseq, starting from beginning? f( [1 2 3] ) -> ( (1) (1 2) (1 2 3) )

17:38 MayDaniel: Nikelandjelo: I doubt it.

17:38 AWizzArd: LauJensen: excellent, exactly what I would expect. Because the BAOS is doing 80 mio calls that need to be locked, as .write is synchronized. But on my machine I get with Clojure 1.3: 1050 msecs for baos vs 1400 msecs byte[]

17:39 LauJensen: ,(reductions vector [1 2 3])

17:39 clojurebot: (1 [1 2] [[1 2] 3])

17:39 LauJensen: Nikelandjelo: almost :)

17:40 AWizzArd: LauJensen: and please one more timing: (let [bb (java.nio.ByteBuffer/allocate 100000000)] (time (dotimes [i 80000000] (.put bb (byte 0)))))

17:40 LauJensen: AWizzArd: 163ms

17:41 AWizzArd: as expected

17:41 thanks for trying those

17:43 MayDaniel: Nikelandjelo: (reductions #(conj %1 %2) [] [1 2 3]) is close.

17:44 LauJensen: ,(letfn [(f [s] (reduce (fn [acc _] (conj acc (take (-> acc count inc) s))) [] s))] (s [1 2 3]))

17:44 clojurebot: java.lang.Exception: Unable to resolve symbol: s in this context

17:44 LauJensen: ,(letfn [(f [s] (reduce (fn [acc _] (conj acc (take (-> acc count inc) s))) [] s))] (f [1 2 3]))

17:44 clojurebot: [(1) (1 2) (1 2 3)]

17:45 Nikelandjelo: Thanks :)

17:52 jaley: is it idiomatic to just call setters on a java object in a (do ) form? it makes me sad

17:53 TeXnomancy: jaley: doto is more common, but yes, sadness is a documented side-effect of side-effects.

17:54 LauJensen: Doto really helps make interop tolerable

17:55 jaley: TeXnomancy: :) I guess doto just saves me typing the object name a squillion times?

17:55 TeXnomancy: jaley: and it clearly delineates the extent of the setup of the java object

17:56 jaley: TeXnomancy: ah i see it returns the object, so presumably one would typically use it in a let?

17:57 TeXnomancy: then you're done with the nasty

17:58 LauJensen: jaley: exactly. The returning of the object is the key to happyness

18:00 iisjmii: Bit of a newbie question; I trying to install swank-clojure, for which I need swank-clojure.jar but I can't find it anyhwere. Where do get it? Do I need to compile it?

18:00 amalloy: ,(drop 1 (reductions conj [] [1 2 3]))

18:00 clojurebot: ([1] [1 2] [1 2 3])

18:00 amalloy: LauJensen, Nikelandjelo: ^ seems nicer

18:01 LauJensen: amalloy: no doubt :)

18:01 iisjmii: ELPA

18:02 iisjmii: LauJensen: I installed swank-clojure via ELPA succesfuly, when I start slime I get the question if I want to install clojure, it fails to do this, so I want to do it by hand, but I can't find swank-clojure.jar

18:03 LauJensen: iisjmii: http://github.com/technomancy/swank-clojure - should be easily buildable

18:03 iisjmii: LauJensen: Thx, I try and build it

18:03 jaley: iisjmii: I had issues with ELPA too - I pulled the code down from LauJensen's link, built it and stuck a symlink in ~/.clojure to the target jar

18:04 iisjmii: jaley: Thx, I try that

18:04 TeXnomancy: iisjmii: "lein install swank-clojure 1.3.0-SNAPSHOT" will do it

18:04 then you can just do "swank-clojure" at the shell and have it launch a standalone swank server

18:04 M-x slime-connect works from there

18:04 clojurebot: http://haacked.com/images/haacked_com/WindowsLiveWriter/IConfigMapPathIsInaccessibleDueToItsProt_1446B/works-on-my-machine-starburst.png

18:05 TeXnomancy: clojurebot: got some attitude today, I see

18:05 clojurebot: everyday is Rich Hickey Appreciation Day

18:05 mrBliss: http://graphjam.com/2010/10/09/funny-graphs-lonely-black-sheep-of-the\

18:05 iisjmii: Texnomancy: thx!

18:09 kutku: im trying to run: (def text (slurp "./text.txt"))

18:09 where should I put that file?

18:10 amalloy: kutku: try this to find out: (.getCanonicalPath (java.io.File. "."))

18:11 kutku: "C:\\Program Files\\NetBeans 6.9.1"

18:11 so I put the file there I assume :)

18:11 amalloy: well then, that's where to put it

18:11 Adamant: is Rich Hickey on here at all?

18:12 amalloy: Adamant: ping rhickey and find out (ie, he is here sometimes, but maybe not now)

18:12 Adamant: lol, that's all I needed to know

18:13 LauJensen: kutku: also see (System/getProperty "user.dir")

18:14 kutku: hes in :)

18:15 iisjmii: jaley: Thx it works

18:18 kutku: thank you

18:34 AWizzArd: hiredman: yes yes, I just tried Clojure 1.2 stable vs 1.3 from build.clojure.org, and 1.2 is much faster on aset

18:34 must be cause of Alpha

18:42 gilbertleung: hi, i have a question regarding keys in clojure

18:42 for example, if my map has keys ":key" and ":value"

18:42 (sorry, just the key ":key")

18:42 would it not be error prone to type ":key" all over my code

18:43 if i make a typo ":keyy", then the value would be nil

18:43 and it wouldn't be so obvious that i have made the mistake

18:43 is there any good practice to solve this problem?

18:44 iisjmii: gilbertleung: what would you want to happen?

18:44 jarpiain: ,(doc clojure.contrib.map-utils/safe-get)

18:44 clojurebot: I don't understand.

18:44 hiredman: gilbertleung: well you are just as likely to mistype the name of a function

18:44 gilbertleung: it seems to me that if i mistype the name of a function

18:44 i'd probably get an error that's more noticeable

18:44 hiredman: it depends

18:45 gilbertleung: e.g "symbol blah not found"

18:45 hiredman: unless the symbol exists and is bound to something else

18:45 gilbertleung: where as if i mistype a key, i'd run into no troubles unil the "nil" value screws sth up

18:47 AWizzArd: gilbertleung: you are right, this is a source of error. So, do a: (def my-key :key)

18:47 and then access your map with my-key

18:47 gilbertleung: jarpiain: yes, i guess safe-get does kinda solve my concern

18:47 AWizzArd: This will be your constant, and if you make a typo, then there is a good chance that Clojure will catch it.

18:47 gilbertleung: AWizzArd: i considered doing that also

18:48 AWizzArd: In principle, a constant name should be surrounded by +’s

18:48 gilbertleung: but that would make it impossible to destructure a map in the function params

18:48 AWizzArd: (def +key+ :key)

18:49 This is one of the disadvantages when working with flexible maps.

18:49 More room for typos.

18:49 TeXnomancy: AWizzArd: you're thinking of Common Lisp

18:50 gilbertleung: hmm, okay thanks

18:50 AWizzArd: TeXnomancy: it makes senso to follow the established patterns of naming def’ed things with stars, and constants with +. It informs the reader and is good style.

18:50 gilbertleung: guess life can't be perfect

18:50 AWizzArd: gilbertleung: you can work with deftype, which needs predefinde keys

18:51 TeXnomancy: AWizzArd: calling some things "constant" and others not is leftover baggage from non-functional language

18:52 AWizzArd: TeXnomancy: objects that live in a def’ed var can change. This is why Clojure is not doing type inference on them. When I (let [something ..] ...) then something is known to be immutable and its type can be inferred, hints are not required. The pluses are a nice thing for people to catch.

18:53 Stars and pluses allow me to fast see what is local and what is not. And what I have in stars might be changed in bindings, or for different program runs. What I see in plusses never changes.

18:53 TeXnomancy: AWizzArd: they don't change at runtime unless (a) they are reference types, in which case it will be obvious for other reasons or (b) you're doing something very wrong.

18:53 AWizzArd: the wrong thing could be (binding [hi ...] ...)

18:53 TeXnomancy: if you're rebinding you use earmuffs, because that's a special case

18:53 constants are not a special case

18:54 AWizzArd: They are a special case. I want to explain readers of my code what is fixed in the world.

18:54 It is just good style and friendly for readers.

18:54 _ato: hehe.. in Clojure the default is constant so you mark the things that can change

18:55 in other languages the default is non-constant so you mark the things that are constant

18:55 AWizzArd: Everything named with *var* is subject to change, be it by binding or by changing the parameters for a program run.

18:55 _ato: things that you (def ..) can hold different objects, even of different types via binding.

18:56 _ato: TeXnomancy: by the way, cut Clojars over to the new server last night. Were having trouble SSHing to it?

18:56 s/having/you having/

18:56 sexpbot: <_ato> TeXnomancy: by the way, cut Clojars over to the new server last night. Were you having trouble SSHing to it?

18:56 TeXnomancy: _ato: oh sweet! no, I haven't tried yet.

18:56 AWizzArd: Or people are supposed to edit the values. Or like in the ant.clj example of Rich we use the run variable at runtime on the repl, to stop the program.

18:56 (def *running* false)

18:56 TeXnomancy: _ato: thanks for getting it moved over; I'm happy to see progress on that front

18:57 AWizzArd: everyone agrees about stars around rebound vars; it's the plusses for constants that are non-idiomatic

18:57 AWizzArd: I can agree that they are not used often. This is very rare indeed. But it definitly is cleaner to have a naming style for constants. And there are constants used from time to time.

18:58 (def +second+ 1) (def +minute+ 60) (def +hour+ (* 60 +minute+)), etc

18:58 TeXnomancy: ok, I'm just saying that most people when they see that are going to think, "Oh, this code was written by a CL user, not someone who's gotten used to Clojure."

18:59 AWizzArd: When I see it then I think: oh, how nice of her to give me more information :-)

18:59 _ato: do you name functions like that as well? (defn +format-time+ ...) for they are also constants :p

19:00 AWizzArd: They are not.

19:00 Often I start writing one, and later change it.

19:00 I fix bugs, etc.

19:00 Pi I never change.

19:00 Or 16 I never change.

19:00 _ato: ah, so you only use it for magic numbers?

19:01 that sort of thing

19:01 AWizzArd: it is very rare

19:01 But sometimes I def things and I know that there will never be a patch or bugfix or need to ever change them.

19:01 My intention about this should be documented.

19:02 For example, even if declaring something as 'final' in Java would never give performance advantages, I would still strongly suggest to use it always.

19:03 This info is more useful than getting more performance (which is also nice of course)

19:03 TeXnomancy: that's because java is a language that encourages mutability

19:03 AWizzArd: There it is even more important.

19:03 But in Clojure i can not know 100% that something will never changed.

19:04 There could be patch that changes stuff

19:04 (def x 19) might be (def x 22) in a week

19:04 _ato: I wouldn't call "things that are never changed in the source code" constants (that's not what final means). I don't know what I'd call them though, I guess the "stable API" but that just refers to the interface (their existence) not their value.

19:05 TeXnomancy: well, pi might be calculated with more accuracy in a future JDK; since it's irrational your representation of it is only an approximation

19:06 AWizzArd: I would even think about naming it π

19:06 Anyway, naming constants with + is doing no harm, it is no loss of productivity, and well tell readers that something does not change.

19:06 iisjmii: When I edit a clj file in emacs and use C-c C-c to compile it I get the error "No such namespace:". I can prevent this by first compiling (in-ns 'clojure.core) in that file but it is annoying. Is this normal?

19:07 TeXnomancy: you're free to use your own coding conventions in your code, as fogus elegantly puts it: http://blog.fogus.me/2010/08/30/community-standards/

19:07 iisjmii: a) you need an ns form in your file and b) try C-c C-k for compiling in Emacs

19:07 AWizzArd: It is not my coding convention alone, but pretty much globally a convention for lisps

19:08 TeXnomancy: never seen it in elisp

19:08 AWizzArd: But sure, if somebody dislikes it, she can omit the +’s.

19:08 iisjmii: TeXnomancy: Ah thx

19:09 AWizzArd: Something that worries me much more is that I have seen so much Clojure code, and trillions of fns that don’t have doc strings.

19:09 Good that at least in Clojure and Contrib nearly everything has one.

19:13 dnolen: Beyond JavaScript Prototype Chains, http://dosync.posterous.com/beyond-javascript-prototype-chains, comparing JS prototype chains and Clojure ad-hoc type hierarchies

19:13 feedback appreciated as usual

19:14 AWizzArd: dnolen: did you spend a bit time with diving into types and Clojures way of handling them?

19:15 dnolen: AWizzard: yeah I'm suing the ad-hoc type stuff in a current project, so I got interested in doing a series comparing to JS, in particular because I know JS well and JS is popular, but has a different take on OO

19:15 s/suing/using

19:15 AWizzArd: Because I got a maybe interesting question, and you may be able to shed some light on it.

19:16 dnolen: AWizzard: shoot

19:16 AWizzArd: For my high-performance Clojure serialization library I want to implement a new type. It will act mostly like a (java.io.DataOutputStream. (java.io.BufferedOutputStream. stream)), but much more efficient for serialization.

19:16 Now there are many ways to do this. I could do it in Java, and it would be pretty clear how to do it.

19:17 I want to do it in Clojure, and there I could use deftype.

19:17 But: deftype can not inherit from classes, such as java.io.OutputStream.

19:17 Then I thought that rhickey did this by purpose, because he understands that inheritance can lead to big problems.

19:17 Now my question is: why can it lead to problems?

19:18 Why is it good that the is-a of a type should come from Interfaces/Protocols, while classes should go into a has-a relationship?

19:18 When I deftype this, there could be three slots: :output-stream :buffer and :counter, while the :counter will be mutable.

19:19 dnolen: AWizzard: I thought about this today and have only my own perspective, before and after methods in CL are a symptom of a problem

19:19 AWizzArd: The result is that my deftype will *not* be an OutputStream, and can not be used in such places.

19:19 dnolen: people think before and after methods are cool, but they actually are there to a problem that sucks

19:19 when you override a inherited method you have to know "when" to call it

19:20 AWizzArd: dnolen: yes, because those before/after methods can sit in totally different files, and I also stumbled upon this in the past. Very dangerous, as suddenly my state changed, and I did not understand why, until I found the after modifier.

19:20 dnolen: particular nasty during construction or tear down

19:20 but it's a direct results of inheritance

19:21 AWizzArd: So, this basically means that Sun should have made OutputStream an Interface I guess.

19:22 dnolen: in Objective-C it rears it's ugly head in the notion of the "designated initializer"

19:22 AWizzArd: Concretly for my situation I have to decide what I want: high-performance deftype, but this will not be an OutputStream then. Or I can go with gen-class and have a :state slot, but this would be a ref as I understand it, and is not as efficient as deftypes mutable slots.

19:22 dnolen: inheritance is basically effed

19:24 AWizzard: but defrecord is plenty fast, if you don't mind a bit of memory tradeoff I think, if you're not making a bunch of them it's not a big deal.

19:24 AWizzArd: deftype.. I think I will go with deftype.

19:25 dnolen: AWizzard: why are you making many instances?

19:25 AWizzArd: no, but I will probably need a counter.

19:25 And that needs to be mutated

19:27 _ato: dnolen: I'm enjoying your Javascript/Clojure series. The way you're comparing them really makes for an interesting read. :-)

19:27 dnolen: _ato: thx!

19:27 kutku: I assume this is the definition of a clojure function, can someone please explain what attr-map is?

19:27 (defn name doc-string? attr-map?

19:27 ([params*] body)+ )

19:28 chouser: kutku: I think that's just metadata

19:28 a map that will be applied as metadata to the var and function

19:28 kutku: ok, ill leave that for now then

19:29 and also, what does the + sign after body men?

19:29 mean*

19:29 chouser: one or more

19:29 AWizzArd: dnolen: also it is about the idea behind my type. It feels more baic to me, so it should be a deftype, not a defrecord.

19:29 IO streams don’t feel like maps.

19:29 dnolen: AWizzard: that's true

19:29 chouser: kutku: you can have multiple param-body pairs for different number of params

19:30 ataggart: anyone run into an issue with cake/lein trying and failing to find org.apache.maven:super-pom:jar:2.0

19:30 AWizzArd: But the issue stays: when Sun decided to go with an abstract base class, then my deftypes can't be an is-a of that type.

19:31 kutku: chouser: ok thanks, similar to a java consuctor?

19:31 AWizzArd: and it is even a bit more complicated, because a deftype can not even have-an instance of such class

19:33 TeXnomancy: ataggart: super-pom just means "the thing you're trying to build". you've probably got a typo in :dependencies

19:33 ataggart: I haven't touched the project.clj file gen'd by lein.

19:34 I used lein new <proj name>

19:34 cd to that prooject, run lein repl, it starts downloading, then dies on the above

19:34 TeXnomancy: must be a network glitch

19:36 chouser: kutku: sure, or any java method. but you don't repeat the name of the method in the source code, and the overloading is only on the *number* of args, not their types.

19:38 kutku: ok thanks!

19:41 is it true that functions with names ending with ? only return true or false?

19:42 chouser: kutku: that is a recommended naming scheme, but not enforced by the language in any way

19:42 Raynes: That is a convention for functions that return either true or false. That doesn't mean that everybody will adhere to the convention, and it isn't enforced.

19:42 chouser: You beat me by 3 seconds thanks to my verbosity. :(

19:42 chouser: As the gentleman from Alabama said.

19:43 TeXnomancy: kutku: they return a value that's intended to be interpreted as truthy or falsey, not necessarily *the* true/false value

19:43 kutku: thx

19:44 Raynes: It appears that the convention is to name functions with a question mark *only* if they return true or false. As demonstrated by every? and some in clojure.core.

19:44 At least, that's what I gathered.

19:44 amalloy: clojure surely has an exponentiation function built in, doesn't it? i can't find it

19:44 freakazoid: Yeah, they're called predicates.

19:45 TeXnomancy: Raynes: clojure.core/some shouldn't be taken as a paragon of naming; it's a terrible name taken from common lisp

19:45 freakazoid: amalloy: presumably in clojure.contrib.math

19:46 chouser: amalloy: Math/pow

19:46 it's built into Java. :-)

19:46 amalloy: oh, that silly java

19:46 won't get integers back though, for large integral base

19:47 AWizzArd: amalloy: you can also try BigDecimals .pow

19:47 ,(.pow 2M 16)

19:47 clojurebot: 65536M

19:48 amalloy: i found it in clojure.contrib.math

19:48 kutku: how come this does not work:

19:48 TeXnomancy: is there a subvec for arrays?

19:48 kutku: ,(re-split #"\W+" "A fine day it is" )

19:48 clojurebot: java.lang.Exception: Unable to resolve symbol: re-split in this context

19:48 AWizzArd: I thought that one is a static method

19:48 bhenry: amalloy: this isn't so hard (defn pow [x y] "x to the y" (apply * (repeat y x)))

19:48 amalloy: kutku: you need to escape the \, i think

19:48 AWizzArd: TeXnomancy: no, not as you probably want

19:48 kutku: ohh, I need to import the function

19:49 freakazoid: bhenry: that would be quite slow

19:49 particularly with bignums

19:49 bhenry: ah true

19:54 chouser: TeXnomancy: you could use (PersistentVector/create the-array) and subvec that.

19:55 oh, nm

19:55 TeXnomancy: chouser: thanks... I think I should be working with strings instead of byte arrays anyhow here in retrospect

19:55 chouser: that used to return a PersistentArrayVector or something I think -- now it's basically just (into [] the-array)

19:58 AWizzArd: what about a (vector-of :byte)?

19:59 ,(doc vector-of)

19:59 clojurebot: "([t]); Creates a new vector of a single primitive type t, where t is one of :int :long :float :double :byte :short :char or :boolean. The resulting vector complies with the interface of vectors in general, but stores the values unboxed internally."

20:09 karmazilla: are there any known issues with the combination of defprotocol, reify and AOT compilation?

20:10 scgilardi: mail

20:38 kutku: http://pastebin.com/hLwXBy38

20:38 that outputs to console right, how do I output to file?

20:42 bhenry: ,(doc spit)

20:42 clojurebot: "([f content & options]); Opposite of slurp. Opens f with writer, writes content, then closes f. Options passed to clojure.java.io/writer."

20:43 kutku: I was thinking about using Java I/O

20:46 bhenry: kutku: http://gist.github.com/487537

20:46 you should get the idea from that

20:49 kutku: txh

20:52 bhenry: I found this code online, how can I use it?

20:52 http://pastebin.com/edW73fi5

20:53 bhenry: looks like that's how you'd create an output stream without using clojure.java.io/output-stream the way i did in that gist.

21:22 gilbertleung: hi

21:22 is there anyway to "throw an error" in clojure

21:22 scottj: (Exception.)

21:26 ataggart: (throw (Exception.))

21:28 scottj: I always forget that part :)

21:29 kutku: im suprised that you don't need a println or system.out to print strings in clojure

21:31 scottj: how do you print them w/o a println?

21:31 kutku: (defn is-small? [number]

21:31 (if (< number 100) "yes" "no" ))

21:32 or maybe im missing something here

21:32 scottj: it just displays in the repl

21:33 it wouldn't actually print to the screen in a running program

21:33 kutku: what's the difference?

21:33 oh..

21:33 it's like printing to console

21:34 scottj: it's like a function that returns a string

21:34 s/like//

21:34 sexpbot: <scottj> it's a function that returns a string

21:41 ataggart: anyone know of non-trivial examples/documentation for compojure?

21:44 kutku: srsly, what does this mean: This is an example of a side effect. The println doesn’t contribute to the

21:44 return value of is-small? at all. Instead, it reaches out into the world

21:44 outside the function and actually does something.

21:50 amalloy: kutku: functions return things. in an ideal world, what they return would be the thing they did

21:51 if the behavior of functions depends on, or influences, external factors, then it becomes much harder to confirm that they will always do what you expect

21:52 *would be the ONLY thing they did

21:52 kutku: ok makes sense thanks

21:55 what does conj do?

21:56 amalloy: ,(doc conj)

21:56 clojurebot: "([coll x] [coll x & xs]); conj[oin]. Returns a new collection with the xs 'added'. (conj nil item) returns (item). The 'addition' may happen at different 'places' depending on the concrete type."

21:56 kutku: tx

21:56 thx

21:57 .... (recur (conj result x) (dec x))))

21:57 what triggers first, dec or conj?

21:57 amalloy: kutku: conj, probably, but it doesn't matter because neither of them has side effects

21:58 kutku: hmm, I need to get into that way of thinking

21:58 I would of guessed dec, conj and then recur

21:59 blbrown_win3_: can I do a static import on a class in the default package. import static Function.compose;

21:59 amalloy: kutku: in C, it would look like recur(conj(result, x), dec(x)), right?

21:59 kutku: or ur right, they are paremeters to the function recur, so it does not matter

21:59 ya

21:59 I see it now.

21:59 blbrown_win3_: well that is wacky. http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4989710

22:02 amalloy: blbrown_win3_: java discourages the use of the default package. if something doesn't work for the default package, you probably shouldn't be doing it anyway :)

22:07 kutku: what is mutable

22:15 what does it mean when they say "no direct mutable variable"

22:15 amalloy: kutku: modifiable

22:15 kutku: thx

22:16 brweber2: hey, anyone around?

22:16 amalloy: kutku: i'm not paying much attention to irc, but if you say amalloy it'll make some noise and i'll check back for your question

22:16 kutku: thats very nice of you, thanks

22:27 it is important that I cover metadata?

22:40 amalloy: kutku: eventually, it's probably a good idea. but i have only a vague idea of how it works and i get by

Logging service provided by n01se.net