#clojure log - May 12 2009

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

1:25 pjolk: so what is the advantage of clojure over scala?

1:26 tWip: that seems like a loaded question

1:27 slashus2: It is dynamic? It is a lisp (homoiconicity).

1:27 hiredman: the persistant immutable datastructures, the s-expressions, the simple core

1:27 the lack of a dog slow compiler

1:27 tWip: don't know scala (at all really), I've always favored lisps over anything else

1:27 pjolk: , (let [f (compose (+ 1) (* 3))] (f 10))

1:27 clojurebot: java.lang.Exception: Unable to resolve symbol: compose in this context

1:27 pjolk: yes the scala compiler takes forever

1:28 hiredman: clojure doesn't do automatic currying

1:28 or uncurrying

1:28 pjolk: but scala works well with the JVM

1:28 hiredman: whicheever

1:28 so does clojure, that is what it is made for

1:28 pjolk: isnt dynamic typing a problem when you start to get 5K loc +?

1:29 dnolen: pjolk: no

1:29 pjolk: unittests for things the compiler can show(and doesnt miss)

1:29 dnolen: pjolk: SmallTalk implementation have 300,000 LOC of code.

1:29 hiredman: ,((comp (partial + 1) (partial * 3)) 10)

1:29 clojurebot: 31

1:29 slashus2: That is a strawman argument with respect to dynamic typing.

1:29 pjolk: , (let [f (comp (+ 1) (* 3))] (f 10))

1:29 clojurebot: java.lang.ClassCastException: java.lang.Integer cannot be cast to clojure.lang.IFn

1:30 pjolk: slashus2: why?

1:30 hiredman: pjolk: did I not just say clojure does not automatically curry functions?

1:30 slashus2: It is also specious.

1:31 dnolen: pjolk: because your statement is not backed up by anything, at least in the real world. in anycase, are you trolling? or you actually trying to assess something.

1:31 pjolk: slashus2: how is it a strawman?

1:31 im trying to decide what to use, scala or clojure

1:31 i might do an app for the android as well

1:31 slashus2: It is an argument that is easily knocked down. Therefore it is a strawman argument.

1:32 pjolk: dnolen: isnt it backed up by the fact that most big projects in the world are written n static languages like retard-java and monster-c++

1:33 dnolen: pjolk: no.

1:33 slashus2: I don't think the fact that most projects are written in static languages leads to the conclusion that dynamic languages have problems with programs over 5K lines of code.

1:34 pjolk: ok 20K?

1:34 50K?

1:34 but nce if it doesnt

1:34 slashus2: It is very dependent on the skill level of the programmer.

1:35 pjolk_: but do you compensate with loads of unittests?

1:37 slashus2: I would think a healthy amount of unit tests would help.

1:37 dnolen: pjolk: in static languages you'll need to write unit tests as well. anyways, write some code Clojure and Scala, and decide for yourself. there is no quick answer to your question.

1:38 pjolk_: i like scala better than java but it feels like wielding a 200pound broad sword to slice bread. heavy and clumsy

1:38 hiredman: have you spent anytime in #scala?

1:38 pjolk_: yes

1:39 hiredman: the constant gripingabout compiler bugs doesn't scare you away?

1:39 well

1:39 pjolk_: gripingabout?

1:39 you mean there are a lot?

1:39 hiredman: constant is an exageration

1:40 pjolk_: and clojure doesnt have (m)any?

1:40 hiredman: at least once a day

1:40 I am sure it must have some

1:40 I mean, come on, this is the real world

1:40 pjolk_: well the compiler is slow, thats a bit annoying

1:41 hiredman: it sounds like scalas complexity is a real problem

1:42 which is often the problem with static typing, you end up with large complex codebases

1:43 and the zest the scala guys have for all kind of crazy haskell stuff doesn't help, I am sure

1:45 dnolen: ,(let [f (comp (partial + 1) (partial * 3))] (f 10))

1:45 clojurebot: 31

1:46 hiredman: and, I mean, come on, scala isn't even a lisp

1:47 pjolk: zest?

1:47 slashus2: hehe

1:47 pjolk: well i love haskell but i think for it to work it needs perhaps its own environment. it needs purity, laziness etc

1:48 otherwise it is just having features that doesnt really work

1:48 and scala really is a kitchen sink

1:48 hiredman: it is java all over again

1:49 scala is to functional programming what java is to oo programming

1:50 pjolk: you mean a horrible clusterfuck and misinterpretation?

1:50 but maybe it will make functinal rpogramming popular

1:51 then well have people using haskell in 2020

1:51 hiredman: nah

1:52 2012 to 2112 is the century of clojure

2:25 replaca: sometimes I wonder which is the bot, clojurebot or hiredman. Neither seems to sleep.

2:25 maybe clojurebot invented hiredman so that hiredman could invent clojurebot

2:26 slashus2: That is a paradox.

2:26 :-(

2:27 replaca: only if you assume time is linear

2:27 and a western model of causality

2:27 slashus2: I do assume that.

3:03 unlink: nth says it will be O(n) for sequences, but this is incorrect--it should be ?(n)

3:05 jdz: so most people don't understand its performance?

3:05 pjolk_: omega(n)? what does that mean?

3:05 jdz: exactly

3:06 opqdonut: pjolk_: Omega(n means lower bound

3:06 with a large omega, with a small one it means "truly asymptotically larger than"

3:29 pjolk: , (map inc (range 10))

3:29 clojurebot: (1 2 3 4 5 6 7 8 9 10)

3:29 pjolk: , (reduce + (map inc (range 10)))

3:29 clojurebot: 55

3:31 pjolk: > (filter #(> 5) '(1 23 45 4))

3:31 , (filter #(> % 5) '(1 23 45 4))

3:31 clojurebot: (23 45)

3:31 pjolk: , (filter #(> 5) '(1 23 45 4))

3:31 clojurebot: java.lang.IllegalArgumentException: Wrong number of args passed to: sandbox$eval--5472$fn

3:32 jdz: pjolk: don't you have a repl?

3:48 hiredman: httpunit demanding valid and trusted ssl certs is amazingly frustrating

3:52 __mac: I've never used that, is it good besides the cert frustration?

3:52 hiredman: hard to say

3:52 it looks like it

3:53 but I hit the ssl block very early

3:53 __mac: I've used selenium before but depending on a browser is very slow and frustrating at times

4:14 unlink: jdz: Your sequence is free to take n^n time each iteration if it wants.

4:14 jdz: unlink: umm, what's that about?

4:15 omega?

4:15 unlink: nth

4:17 jdz: when i see O(n), i expect a linear time access behaviour, when i see ?(n) i'm not really sure what to expect

4:18 except that it's quite similar to O(n) with some nitpicking from academics added

4:18 unlink: no, O(n) is an upper bound, which is wrong

4:19 jdz: why is it wrong?

4:19 unlink: it can take arbitrarily long, it should be a lower bound

4:19 jdz: since when nth can take arbitrarily long?

4:20 unlink: when your sequence does expensive computations each iteration

4:20 jdz: it's still O(n)

4:21 unlink: not if it's, say, O(n^2)

4:22 imagine a naive implementation of a fibonacci sequence

4:23 nth is O(2^n)

4:23 jdz: and in Clojure it's O(n)

4:23 unlink: why do you think that?

4:24 clojure doesn't automatically optimize your slow algorithms

4:24 jdz: well, it does

4:25 this hand waving is not gonna get us anywhere, let's talk about code!

4:25 where is the code?

4:29 unlink: (nth (map (fn fibs [n] (condp = n 0 0 1 1 (+ (fibs (- n 1)) (fibs (- n 2))))) (iterate inc 0)) N)

4:29 nth takes O(2^N) time

4:30 jdz: it's not nth that takes O(2^N) time, it's the map

4:31 unlink: No, the map is lazy. The nth forces evaluation.

4:31 And it is certainly not O(N)

4:35 jdz: nth does exactly N steps to get at the required element

4:36 so it's O(N)

4:36 opqdonut: nth destructures n conses

4:36 that's all that can be said, really

4:36 but it is true that the 2^N effort happens "inside" map

4:37 with laziness you really can't look at when the work happens, you have to look at inside which closure it happens

4:40 hiredman: ~javadoc javax.net.ssl.X509TrustManager

4:41 ugh, void return methods

4:46 I think I will pretend to sleep

4:46 __mac: hiredman: Yeah that bothered me as well when I did some X509 stuff a while back. In fact, void returns always bother me these days :/

4:47 But it's particularly bad there because a boolean return would have sufficed but instead they use an exception in case of denied access etc.

4:52 tWip: it's bad legacy api... but easy to wrap and be done with

5:23 jdz: unlink: btw, Clojure way of generating fibonacci numbers is (def fibs (concat [0 1] (map + fibs (rest fibs)))); a lot simpler.

5:24 and nth on fibs in this case might work in less than O(n) time

5:25 Holcxjo: Less?

5:26 jdz: yes

5:26 because of the caching

5:26 unlink: http://en.wikipedia.org/wiki/Big_O_notation

5:26 __mac: Can kill your heap though ;)

5:27 Holcxjo: It's a list; and nth of a list is O(n), right?

5:27 jdz: Holcxjo: it's a sequence.

5:27 lazy at that one

5:28 unlink: nth walks a sequence "sequentially", so it's run time is O(n). end of story.

5:34 AWizzArd: one could make nth O(1) by making it much slower

5:35 unlink: user=> (use 'clojure.contrib.seq-utils :only '(indexed))

5:35 java.lang.IllegalArgumentException: Don't know how to create ISeq from: Boolean (NO_SOURCE_FILE:0)

5:35 am I doing something wrong here?

5:36 AWizzArd: (use '[clojure.contrib.seq-utils :only [indexed]])

5:38 unlink: Thanks.

5:41 Why is the library wrapped in a vector?

5:42 AWizzArd: the [indexed] itself could as well be a list if you wish

5:42 unlink: I noticed.

5:43 AWizzArd: You can also do some magic such as (use '[clojure.contrib [def :only [defvar-]] [seq-utils :only [indexed]]])

5:43 unlink: That's what I was looking for. Thanks.

5:53 tWip: I miss nil punning

5:54 unlink: You mean from CL?

5:55 tWip: from previous versions of clojure

5:55 unlink: or vs old lazy sequence semantics

5:56 Why? What can't you do now?

5:56 tWip: well, just tongue in cheek assertation really :P

5:57 I had to change 2 lines of my old code, which frustrated me

5:57 unlink: Sorry to hear it. It happens sometimes.

5:59 tWip: but all joking aside, upgrading from the dec 2008 release to 1.0.0 has been pretty painless

6:05 unlink: Don't you wish every upgrade could have been like the road to Django 1.0?

6:40 tWip: unlink: what's django? isn't that some python thingy

6:41 __mac: Could also be an australian animal, but I doubt they have version numbers.

6:56 rsynnott: __mac: young earth creationists would no doubt disagree with you there :)

6:56 * rsynnott is puzzled as to what was so wonderful about the road to django 1

6:56 rsynnott: oh, anyone know if swank works with clojure 1?

6:57 * rsynnott is unwilling to upgrade if it will break his SLIME

7:01 jdz: rsynnott: works for me

7:01 rsynnott: cool

7:02 jdz: i think it should have been: works for me (TM)

7:49 asbjxrn: Mostly works for me. I've got a strange "slime-compile-defun" compiles everything in the user namespace.

7:49 But then, I didn't use slime before, so it might have been there earlier as well. Probably related to my setup more than clojure 1

9:26 chessguy_work: so here's something i've been thinking about re: macros

9:26 in some ways, macros aren't any different from functions

9:26 in that both can take a clojure program and transform it

9:26 the real difference is WHEN it happens

9:26 Chouser: yes

9:27 in fact a macro *is* a function, with a flag on its Var's metadata

9:28 ,^#'if-let

9:28 clojurebot: {:macro true, :ns #<Namespace clojure.core>, :name if-let, :file "clojure/core.clj", :line 1107, :arglists ([bindings then] [bindings then else & oldform]), :doc "bindings => binding-form test\n\n If test is true, evaluates then with binding-form bound to the value of test, if not, yields else"}

9:28 chessguy_work: so the question of whether to write a macro or a function becomes "when do you have the code that needs to be transformed?"

9:29 if you can get it at run-time, you write a function. if you can't, you write a macro

9:33 stuartsierra: more or less

9:33 Chouser: well, most macros return forms that are meant to be eval'ed

9:33 while most non-macro functions do not.

9:34 chessguy_work: hmm. not sure what you mean by that

9:34 Chouser: if your function returns a list (1 2 3), it would cause an error when run as a macro

9:34 chessguy_work: you mean things like (f 1 2 3) as opposed to '(1 2 3)

9:34 gotcha

9:42 __mac: What about suppressing evaluation of arguments? A macro does not eval it's arguments, when using a regular function a user has to use quote to get the same effect. I know it's functionally equivalent with quotes but it's an important difference for me regardless because you can make stuff like [x & body] in with-open for example.

9:46 dobrekone: (hi 'there)

9:48 jdz: macros are for source code transformation. if the arguments were evaluated before passing them to macro, it would no longer be able to transform anything

9:48 rhickey: the purpose of a macro is that you want to write THIS and you want the compiler to see THAT. Thinking about them as functions that don't evaluate their arguments get fuzzy real quick.

9:57 stuartsierra: For everyone in NYC, my presentation tonight was canceled - venue problems. LispNYC will still meet for drinks.

9:59 dnolen: is a future just an agent or it's own thing entirely?

10:02 stuartsierra: it's a little different

10:02 futures use java.util.concurrent.Future

10:02 durka42: is there a function i can call, like, macroexpand, to see what the compiler might inline?

10:03 stuartsierra: The Clojure compiler or the JVM compiler? Either way, I think the answer is no.

10:03 durka42: the clojure compiler

10:04 like (inline-expand '(+ 2 3)) ==> (. clojure.lang.Numbers (add 2 3))

10:05 stuartsierra: No such thing exists, but it wouldn't be hard to write, since inlined functions have :inline metadata.

10:05 dnolen: stuartsierra: thx

10:06 stuartsierra: dnolen: welcome

10:09 durka42: i think (defn inline-expand [form] (if-let [inline (clojure.lang.Compiler/isInline (first form) (count (next form)))] (.applyTo inline (next form)) form))

10:10 from analyzeSeq in Compiler.java

10:10 clojurebot: ?

10:28 durka42: this code is evil

10:28 :inline-arities (proxy [clojure.lang.IPersistentSet] [] (contains [i] (> i 2)))

10:30 stuartsierra: Where did you find that?

10:30 durka42: i wrote it

10:30 stuartsierra: ah

10:31 That will inline all calls, right?

10:31 durka42: all calls with more than 2 arguments

10:32 stuartsierra: But definline doesn't work with variadic functions.

10:33 durka42: well

10:33 the function/macro/thing at :inline can be variadic

10:33 stuartsierra: ok

10:34 durka42: ~def int-array

10:35 stuartsierra: I see

10:36 So in theory you could write :inline-arities (proxy [clojure.lang.IPersistentSet] [] (contains [i] true))

10:37 durka42: which would then be almost equivalent to defmacro

10:37 stuartsierra: yeah, almost

10:37 Chouser: it has to be a set? seems a shame.

10:38 durka42: ,(contains (proxy [clojure.lang.IPersistentSet] [] (contains [_] true)) (java.util.Date.))

10:38 clojurebot: java.lang.RuntimeException: java.lang.RuntimeException: java.security.AccessControlException: access denied (java.lang.RuntimePermission accessDeclaredMembers)

10:38 Chouser: seems like it could just be a predicate, since sets are callable.

10:38 durka42: c.l.Compiler/isInline calls .contains

10:38 Chouser: I wonder if it has to.

10:39 durka42: also it casts the {:inline-arities (meta func)} to an IPersistentSet

10:39 i mean (:inline-arities (meta func))

10:39 Compiler.java:4437 or thereabouts

11:08 jmaness: does anyone have any good resources that describe the actual cost of object creation in Java (# of instructions, memory overhead, etc.)?

11:53 dobrekone: jmaness: you've the "javap" tool included in the JDK that allows you to disassembling into bytecode

11:54 jmaness: dobrekone: thanks I'll look at that

11:54 dobrekone: "new" is a JVM instruction so creating a new object is a single instruction for the JVM

11:55 0: new #2; //class java/lang/Object

11:55 3: dup

11:55 4: invokespecial #1; //Method java/lang/Object."<init>":()V

11:55 clojurebot: ?

11:55 dobrekone: 7: pop

12:03 stuartsierra: Some material on Java Object initialization cost: http://lingpipe-blog.com/2009/05/11/javaobject-allocation-costly-inner-loops/

12:05 jmaness: stuartsierra: thanks

12:43 * rhickey joins the modern world: http://github.com/richhickey/sdb/tree/master

12:44 thickey: rhickey: wow!

12:45 tWip: me too... if anyone is interested Webjure is now on github (http://github.com/tatut/Webjure/tree/master) and works with Clojure 1.0.0

12:47 stuartsierra: rhickey: cool

12:48 * drewr chokes on his coffee

12:49 gnuvince: damn...

12:50 * gnuvince had hoped Mercurial would've prevailed.

12:50 * bitbckt rejoices

12:50 gnuvince: I guess I'll clone at the end of the summer

12:50 drewr: gnuvince: You don't have to care! http://hg-git.github.com/

12:51 jmaness: yeah and "This plugin was developed by the folks at GitHub"

12:51 StartsWithK: drew: tried it? any problems?

12:52 gnuvince: StartsWithK: there's a big ACHTUNG that it's still very in development.

12:52 drewr: StartsWithK: No. I use git so I haven't really needed it.

12:52 What I need is git-hg.

12:52 StartsWithK: :)

12:53 drewr: I figured stuff like this would eventually come around. Conceptually they're similar enough that they should be able to talk to each other.

12:53 It might be a harder problem than I realize though.

12:55 stuartsierra: I thought git could already speak hg.

12:56 drewr: It would be nice if we could agree on a storage mechanism and create porcelains that cater to everyone's tastes.

13:40 rhickey: stick your iTunes library in sdb: http://github.com/richhickey/sdb/blob/386815b51f727902d2a286c42a9db22e39175143/src/examples/itunes-to-sdb.clj

13:42 durka42: cool!

13:44 rhickey: having sdb sitting around at all times waiting for you to squirrel away things from the repl is really neat

13:46 durka42: doesn't line 27 have the args backwards?

13:49 ciaran: what is sdb?

13:49 Raynes: Something database.

13:50 svdm: http://aws.amazon.com/simpledb/

13:50 rhickey: durka42: fixed -thanks

13:50 Raynes: Simple database.

13:50 :D

14:06 jmaness: if sdb supports blobs, rhickey can upload his mp3s

14:13 stuartsierra: sdb has a maximum of 1000 bytes per field value

14:13 But you can use S3 for anything up to 5GB.

14:13 jmaness: ah iteration 2 then

14:23 stuartsierra: 2nd announcement: Clojure talk at LispNYC canceled tonight, but still meeting for drinks.

14:24 ataggart: east-coasters get all the fun

14:28 jmaness: is there anyone in the RDU involved with Clojure?

14:28 RTP I mean

14:29 stuartsierra: What's RTP?

14:29 jmaness: Research Triangle Park in NC

14:29 stuartsierra: ah

14:30 unlink: hmm... monads sans type classes is an interesting idea

14:36 rhickey: anyone get sdb working yet?

14:37 stuartsierra: haven't had time to try it yet, but I'll play with it some time soon

14:37 I use SDB a little.

15:13 cp2: afternoon

15:14 stuhood: heya

15:41 someguy98249234: If I have a java file in the current directory, how can I import it from clojure?

15:42 cp2: if by current directory you mean working directory

15:42 (import 'classname)

15:43 ideally you should package it

15:43 (import 'org.myself.Blah)

15:44 stuartsierra: Well, the java file has to be compiled, and the .class file has to be on the Java classpath.

15:45 someguy98249234: ah

15:45 cp2: yeah, important details i left out

15:45 someguy98249234: *reads about classpath*

15:46 cp2: well, if its not in an archive, and it is in the working dir, it will be in the classpath

15:47 stuartsierra: only if "." is on the classpath, I think

15:48 cp2: yeah, its there by default iirc

15:48 twism: hmmm

15:48 cp2: not sure if it gets removed with -cp

15:48 i would include it just to be safe though

15:49 -cp foo:bar:baz:.

15:49 twism: (clojure.contrib.json.write/json-str [[[nil {:test "test"}]]]) -> "[[[]]]"

15:49 is that rihgt?

15:50 someguy98249234: ok Foobar.java: "public class Foobar { public Foobar() { System.out.println("hi"); } }"

15:50 I should be able to import with (import 'Foobar)?

15:50 stuartsierra: twism: no

15:50 cp2: someguy98249234: if it is in classpath then yes

15:50 danlarkin: twism: clojure-json, clojure-json! :)

15:50 cp2: so uh

15:50 stuartsierra: twism: But you can't have non-string keys.

15:50 someguy98249234: cp2: How can I check if . is in the classpath

15:51 cp2: it should be already

15:51 twism: stuartsierra: ah

15:51 danlarkin: i was using clojure-json

15:51 cp2: lisppaste8: url

15:51 lisppaste8: To use the lisppaste bot, visit http://paste.lisp.org/new/clojure and enter your paste.

15:52 danlarkin: twism: was, like past tense? why did you stop

15:52 twism: but wanted the library im working on to use cllojure.contrib so as to minimize dependencies

15:53 since most people have clojure.contrib

15:53 lisppaste8: cp2 pasted "cp stuff" at http://paste.lisp.org/display/80095

15:53 cp2: someguy98249234:

15:53 twism: danlarkin: but i guess i have to plug your stuff :P

15:54 i heart clojure-json

15:54 stuartsierra: twism: fixed, SVN 803

15:55 twism: stuartsierra: thanks!

15:55 someguy98249234: it works! But not from the interpreter...

15:56 cp2: someguy98249234: hmm, are you doing java -jar clojure.jar

15:56 to spawn a repl?

15:57 twism: danlarkin: i still have to use clojure-json

15:57 someguy98249234: it's the ':.'

15:57 I wasn't doing that

15:57 cp2: oh

15:57 k

15:57 someguy98249234: thanks!

15:57 cp2: btw, on linux the seperator is :

15:57 but on windows its ;

15:57 twism: so i will be giving you a shout out when i release

15:57 danlarkin: twism: :)

15:57 cp2: no problem =p

15:57 someguy98249234: good to know

15:59 danlarkin: twism: why do you have to use clojure-json even in light of this bug being fixed?

16:00 stuartsierra: ,{:foo 1, :foo 2}

16:00 clojurebot: {:foo 1, :foo 2}

16:01 stuartsierra: Is that a bug?

16:01 Chouser: nope

16:01 danlarkin: ,(identical? :foo :foo)

16:01 clojurebot: true

16:01 durka42: ,(:foo {:foo 1, :foo 2})

16:01 clojurebot: 1

16:01 cp2: no bugs, just features

16:01 durka42: ,(:foo {:foo 2, :foo 1})

16:01 clojurebot: 2

16:01 Chouser: ,(assoc {:foo 1} :foo 2)

16:01 clojurebot: {:foo 2}

16:01 stuartsierra: ,(hash-map :foo 1 :foo 2)

16:01 clojurebot: {:foo 2}

16:02 durka42: ,(sorted-map :foo 1 :foo 2)

16:02 clojurebot: {:foo 2}

16:02 durka42: ,(type {:foo 1, :foo 2})

16:02 clojurebot: clojure.lang.PersistentArrayMap

16:02 Chouser: ,(let [x :foo, y :foo] {x 1, y 2})

16:02 clojurebot: {:foo 1, :foo 2}

16:02 svdm: ,(keys {:foo 1, :foo 2})

16:02 clojurebot: (:foo :foo)

16:03 Chouser: it's been brought up before and ruled not-a-bug

16:04 dnolen: interesting, what's the use case for this?

16:04 Chouser: ,(apply array-map [:foo 1 :foo 2])

16:04 clojurebot: {:foo 1, :foo 2}

16:04 stuartsierra: Chouser: ok

16:04 Chouser: it's undefined behavior

16:05 stuartsierra: fair enough

16:05 dnolen: ,(zipmap [:first :first :second] [1 2 3])

16:05 clojurebot: {:second 3, :first 2}

16:05 Chouser: most programmatic ways for building a map will not allow duplicate keys.

16:05 the (apply array-map ...) case there worries me a bit, but anyway.

16:06 one major benefit of array-maps is efficiency of creation, that you can just wrap one around an existing array.

16:06 stuartsierra: ok

16:06 Chouser: if Clojure had to check the keys for uniqueness, you'd lose that.

16:06 I guess if you're not sure the keys are unique, use a hash-map instead.

16:07 dnolen: ,(merge {:foo 1 :foo 2} {:foo 3 :foo 4})

16:07 clojurebot: {:foo 4, :foo 2}

16:07 dnolen: that's pretty weird

16:07 cp2: haha what

16:08 Chouser: hm...

16:09 dnolen: that's freaks me out a little

16:09 stuartsierra: totally

16:10 dnolen: yeah, of course I'm not sure, but perhaps this undefined behaviors can be a source of really strange accidental bugs.

16:11 svdm: conj seems to replace the [:foo 1], so when merge conj's on [:foo 3] and [:foo 4] it just overwrites the entry twice

16:11 Chouser: well... as long as the weirdness is only on initial map creation, and only for array-maps, I could be placated.

16:11 stuartsierra: ,(merge {:foo 1 :bar 2} {:bar 3 :foo 4})

16:11 clojurebot: {:foo 4, :bar 3}

16:12 * stuartsierra cowers before the angry Chouser

16:12 Chouser: but yeah, having it leak through and mess with 'merge' later.

16:12 * danlarkin dislikes "undefined behavior"

16:12 Chouser: hm. I guess it was still an error to create such a map in the first place.

16:12 stuartsierra: true

16:13 twism: danlarkin: beacouse the library i'm working it would be better for users to have keywords as keys

16:14 dnolen: ,(let [m {:foo 1 :foo 2}] (merge m m))

16:14 clojurebot: {:foo 2, :foo 2}

16:14 stuartsierra: woah!

16:15 dnolen: I guess there's no way to repair a borked map?

16:15 Chouser: stuartsierra: were you seeing breakage in a real program and track it back to this?

16:15 dnolen: sure, just put it in a hash-map

16:15 or a sorted-map

16:16 stuartsierra: No, I didn't start this thread.

16:16 Chouser: oh

16:16 stuartsierra: Or did I?

16:16 Chouser: dnolan: were you seeing breakage in a real program and track it back to this?

16:16 sorry. :-)

16:16 stuartsierra: Yes, I did, but I was checking c.c.json.write.

16:16 Chouser: uh

16:16 twism: danlarkin: where im using contrib.json is a private library that isn't going to be touched

16:16 dnolen: Chouser: no, I was just following along :)

16:17 Chouser: yeah, sorry. I'm all confused.

16:17 {:started-thread 'dnolan :started-thread 'stuartsierra}

16:17 Chousuke: :P

16:17 dnolen: Chouser: so how to repair a borked map with hash-map? this eludes me at the moment.

16:18 bstephenson: ,(merge {:foo 1} {:foo 2})

16:18 clojurebot: {:foo 2}

16:18 stuartsierra: ,(into (hash-map) {:foo 1 :foo 2})

16:18 clojurebot: {:foo 2}

16:18 Chouser: ,(into {} {:foo 1 :foo 2})

16:18 clojurebot: {:foo 2}

16:18 bstephenson: ,(merge {:foo 3} {:foo 4})

16:18 clojurebot: {:foo 4}

16:18 bstephenson: ,(merge (merge {:foo 3} {:foo 4}) (merge {:foo 1 :foo 2}))

16:18 clojurebot: {:foo 2}

16:18 bstephenson: odd

16:19 dnolen: great thx!

16:19 Chouser: no, the only way thing that's undefined here is the result of building a new array-map with identical keys.

16:20 if the array-map has all unique keys (a.k.a. non-b0rked map), then any operation on it will be fine: conj, merge, assoc, etc.

16:21 bstephenson: ! OIC

16:21 Chouser: but building a new array-map either with {...} or (array-map ...) allows you to create a b0rked-map.

16:22 the only way to prevent it would be for Clojure to build a set of the keys in order to check uniqueness, at which point you've lost the main reason for using an array-mao

16:22 array-map

16:22 so if you're not sure about uniqueness, better put them in a hash-map in the first place.

16:23 stuartsierra: ,(into {} [[:foo 1] [:foo 2]])

16:23 clojurebot: {:foo 2}

16:34 dnolen: so there's not reasonable way to modify the classpath at runtime right? (sorry I know this has come up many times)

16:44 perhaps too many times :) reading about the deprecation of add-classpath...

16:48 grzm: anyone know of a way to get at the HTTP headers sent with a request in compojure? I'm trying to switch off of the Accept header.

16:48 thought I could use headers (if I'm reading http://en.wikibooks.org/wiki/Compojure/Core_Libraries correctly)

16:48 but that symbol doesn't seem to be available

16:57 hiredman: anyone know how to get java to accept "invalid" ssl certificates?

16:58 durka42: buy new ones?

16:58 hiredman: not mine to buy

16:59 StartsWithK: in java-utils there is 'with-system-properties', is that even thread-safe? shoudn't that be removed or something

17:03 * hiredman dies

17:03 hiredman: in various blog and mailing list posts people say httpunit's WebClient has a setUseInsecureSSL

17:04 but it doesn't

17:04 Chouser: maybe they took it away

17:04 too insecure

17:05 hiredman: this blog post is from january 09, and the last httpunit release was may 08

17:06 ah

17:06 httpunit vs. htmlunit

17:06 wonderful

17:26 baggins: so in my job, i write java. i'm a known fan of lisp there.

17:26 a guy was asking for help with a problem.

17:26 we are all in moods at the moment there

17:26 so i managed to help him see the problem.. and then he basically dismissed us who were lingering

17:27 and i said

17:27 "so what? I want CLOSURE dammit!"

17:27 stuhood: heh

17:27 kli: n1

17:27 baggins: and he said to me: "no you know management would never go with clojure"

17:27 "... it's not 'proper' java!"

17:28 i just didn't see the pun coming...

17:28 kli: just sneak it in anyway

17:28 baggins: just thought i'd share it

17:28 Chouser: ahh... hah

17:28 baggins: i guess it was funnier at the time

17:29 Chouser: well, I doing C++ now. again.

17:29 Which would be perfectly fine if it had closures.

17:29 and garbage collection. and immutable containers.

17:30 baggins: well i was talking about closure on the narrative of solving his problem... nothing computing... i guess it loses in translation (to irc)

17:30 Chouser: baggins: yeah, I got it, but I had to re-read it a few times.

17:30 baggins: heh

17:30 Chouser: too many meanings for "closure" I guess

17:31 oh, I also need clojure's reference types. I could make do with the remaining deficiencies.

17:39 StartsWithK: Chouser: hide lua in c++ project, modify clojurescript to target lua instead of javascript, they are almost the same language :) no one needs to know :)

17:46 Chouser: :-)

17:57 well, rhickey wants to have an ObjectiveC target. If that can be done, I don't see why not C++.

17:57 I believe there are garbage collection libraries for C++, even.

17:57 unlink: yes, there are

17:57 Chouser: which raises the question...

17:58 why isn't it done alread?

17:58 unlink: Compiling clojure to C++?

17:58 Chouser: yes

17:58 unlink: It's a lot of work?

17:58 Chouser: hm.

17:59 sounds like an excuse.

18:00 StartsWithK: why not one of the javascript vm, or lua?

18:00 unlink: If you're going to target C++, you might as well target LLVM. (Or JVM :)

18:00 StartsWithK: lua has very simple register machine, excelent c and c++ bindings

18:01 * StartsWithK likes lua :)

18:01 Chouser: I just need to convince the rest of the team that the JVM would be fast enough.

18:01 unlink: Yeah on second thought the JVM would probably be unworkable.

18:13 Who do I appeal to to get stuff added to contrib?

18:20 mrsolo_: anybody knows the release date for programming clojure?

18:36 hiredman: ~book

18:36 clojurebot: book is http://www.pragprog.com/titles/shcloj/programming-clojure

18:38 hiredman: "->" works pretty well with htmlunit

18:39 (-> (WebClient.) (.getPage "someurl") (.getAnchorByName "foo") .click)

19:15 eee: yo

19:15 rhickey I'd like to list the heap stuff as a third party lib. is that appropriate?

19:33 eyeris: What is the syntax for applying a type hint to a function?

19:34 I want to do it in the defn, rather than hinting every use of it because I want to return a DataColumn[] where each member is really an object of a class derived from DataColumn

19:35 gnuvince_: eyeris: (defn read-buffer [#^ByteBuffer buf] ...)

19:35 adapt for the type you need

19:35 eyeris: gnuvince_: doesn't that hint the type of buf?

19:36 gnuvince_: yes

19:36 eyeris: I want to hint the type of read-buffer

19:36 gnuvince_: Is that not what you want?

19:36 oh

19:36 I don't know that there's a syntax for that

19:36 Would it help though?

19:37 eyeris: I think it would help in my situation.

19:37 gnuvince_: I mean, if *warn-on-reflection* doesn't warn you...

19:38 Cark: function return values are always boxed

19:38 eyeris: I have a vector of objects of classes derived from a common base class. I need to create an array from this list with the type DataColumn[] to feed to a constructor in a Java lib that only accepts DataColumn[]

19:39 Cark: gnuvince : i've seen you've been trying to talk to me, sorry i'm way busy right now =/

19:39 eyeris: I would like to be able to use (to-array [(DataColumnString. "one") (DataColumnInteger. 1)])

19:39 and type hint the that as [#^DataColumn[]]

19:39 gnuvince_: Cark: no problem, just wanted to inform you I was able to get a 12% speed increase in my program if that interests you.

19:39 Cark: gnuvince : though i did read your blog post, and it was very informative

19:39 gnuvince_: It was the no destructuring binding one.

19:40 Cark: right

19:40 gnuvince_: removed it from two tight loops

19:40 eyeris: I guess I will have to use make-array and then populate it.

19:40 gnuvince_: (doc into-array)

19:40 clojurebot: "([aseq] [type aseq]); Returns an array with components set to the values in aseq. The array's component type is type if provided, or the type of the first value in aseq if present, or Object. All values in aseq must be compatible with the component type. Class objects for the primitive types can be obtained using, e.g., Integer/TYPE."

19:40 Cark: i would have expected a seq on a vector to be really fast

19:41 gnuvince_: Cark: I guess direct vector access is fater that first/rest recursion

19:41 Cark: heh abstraction is both a curse and a blessing =P

19:42 gnuvince_: Indeed

19:43 I think my next move will be to try and switch all the little vectors that represent fields to arrays, see if that can help

19:44 Cark: you're not doing clojure anymore =/

19:44 eyeris: gnuvince_: It looks like into-array is what I need, but I am having trouble with the syntax

19:44 Cark: mhh though the use is pretty simple in this program, so i guess it's no big deal

19:44 gnuvince_: eyeris: the syntax for arrays of references is sort of weird

19:44 eyeris: hang on...

19:44 eyeris: k

19:45 gnuvince_: Oh wait

19:45 that's for type hints

19:45 Can't you do (into-array DataColumn my-vector)?

19:46 eyeris: Yep, apparently I can

19:46 Cark: does it really need to be type anyways ?

19:46 typed

19:46 eyeris: I was trying (into-array #^DataColumn my-vec) :]

19:46 Cark yes, read your scrollback buffer for an expl

19:46 That is, it does for this purpose.

19:46 gnuvince_: Cark: maybe not regular Clojure code, but it's still fun to play around with.

19:47 Cark: I would really like to have my cake and eat it too: write my code in a nice declarative way and still be within 1.5-2x of Java's performance

19:48 Cark: well on the other hand i don't see where it would be usefull to be faster than it is now

19:48 what's the use case ?

19:48 maybe a web page with stats on a single game

19:48 how long to parse it then ? fast enough for a very fast web page =P

19:49 gnuvince_: Cark: one of the use case I have in mind is being able to take a collection of replays (and some people have tens of *thousands* of them) and generate statistics.

19:50 There's also a large part of just wanting to see where I can take that program.

19:50 Cark: i can understand that

19:51 still

19:51 if you want it to be fast, there must be a use case ....if it's a one time computation, i'd say it's good enough

19:52 or get dirty and go down to c =P

19:52 or completely change your access method

19:52 use memory mapped files

19:52 and cherry pick what you want to decode

19:54 anyyways got to go, gnight all

19:54 gnuvince_: see ya

20:07 slashus2: Have you all heard of Axum? I just read about it from Microsoft�'s website.

20:08 I wonder if Novell� will implement it on Mono.

20:09 technomancy: I think I will stick with the Java� Programming� Language�.

20:09 slashus2: Okay�

20:14 albino: they're way too far behind to implement it anytime soon, if they do it will be like 5 years from now

20:15 technomancy: albino: clojure is little over 2 years old. =)

20:16 cp2: haha

20:16 i love this channel

20:16 technomancy: but one person can move much faster than a team. yay Brooks' law.

20:18 powr-toc: Just seen that Rich has posted a library hosted on github... Could this be him familiarising himself with git/github for clojure?

20:18 technomancy: powr-toc: I noticed that... fingers crossed. =)

20:19 powr-toc: technomancy: yeah, git rocks! :-)

20:20 technomancy: I have no idea if github's issue tracker is as good as google's though.

20:20 and a big transition is a tough sell after we just got everyone used to the fact that no, we are not on sourceforge anymore...

20:20 we'll see

20:21 ataggart: when your VCS is a cobbled together mess of C executables and everything has to be done at the command line and there's no authoritative server... no thanks.

20:22 albino: a naysayer

20:23 ataggart: made as such by the git-vocates

20:24 in any case, I thought googlecode was adding mercurial, not git

20:24 technomancy: the elisp interface for it is badass

20:25 sweet; I'm on the evri page for Clojure: http://www.evri.com/product/clojure-0x151efb

20:27 cp2: can i have an autograph?

20:30 technomancy: cp2: I used to work for them. =)

20:30 cp2: ah

20:31 so uh, getting a new laptop soon hopefully

20:31 anyone have any recommendations (based on personal experience of course)

20:32 technomancy: cp2: I've been very happy with the thinkpads I've owned

20:32 never seen one break

20:32 cp2: hm

20:33 technomancy: the downside there is that you don't get an excuse to upgrade your laptop as often since they last forever.

20:33 cp2: hah

20:33 powr-toc: technomancy: did you sell them on the benefits of clojure? :-)

20:33 technomancy: powr-toc: actually I didn't start Clojure until I left that job. =)

20:33 immediately after I left; not sure if that counts as irony?

20:34 powr-toc: lol

20:34 dnolen: so I've started messing around with with Google App Engine, what do you all think of a community (by invite) maintained package/dependency system hosted there?

20:34 cp2: technomancy: so what model of thinkpad do you use most often

20:35 powr-toc: well what with clojure being a lisp, and lisp being classically used in linguistics you'd think it'd play into their problem space

20:35 * gnuvince_ is back

20:35 cp2: i want to know who decided to put an s in the word lisp

20:35 gnuvince_: John McCarthy?

20:35 cp2: think of the people who have to explain their impediment

20:36 heh gnuvince_, not the language

20:36 gnuvince_: oh

20:37 technomancy: cp2: right now I have a X61 tablet. it's very nice, but it's not an LED screen, so you'll get a brighter display with a newer model

20:37 cp2: i see

20:37 technomancy: cp2: I move around a lot though, so I need a smaller model. before I had a T61 that was solid as a rock and had a much bigger screen.

20:38 cp2: well, what i would be upgrading from is a dell latitude cpx with only one functional ram slot

20:38 so anything is good really =P

20:38 yeah technomancy, that doesnt matter so much to me

20:38 i just need something that i can move

20:38 because my laptop is somewhat unusable now

20:38 not that i used it much in the first place

20:40 technomancy: that looks like a nice tablet though

20:41 technomancy: cp2: as long as you don't use it outside (or next to bright sunny windows) it's a great screen

20:41 ataggart: in case anyone hasn't see this: http://james-iry.blogspot.com/2009/05/brief-incomplete-and-mostly-wrong.html

20:42 cp2: yeah technomancy thats alright

20:42 technomancy: cp2: I have the 1440x1024 one; it's extremely crisp. (like an iPhone screen in terms of DPI)

20:42 cp2: oh nice

20:42 technomancy: they're pretty affordable now too since the newer X300 models have come out

20:42 cp2: mhm

20:42 technomancy: unfortunately you can only get the high-res screen in the tablet X61

20:42 cp2: what os are you running on it?

20:43 also, how is battery life and such

20:43 technomancy: latest ubuntu. it detects everything out of the box, even the tablet input device.

20:44 cp2: I got 4 hours when it was new, now it's down to 3 if I turn off wifi and don't use 100% brightness.

20:44 cp2: hm

20:44 technomancy: it's a year and a half old now

20:44 cp2: yeah, was about to say

20:44 still looks decent though

20:45 whats the story with these 'ideapads'

20:47 p_l: aka netbooks, but from Lenovo? :P

20:47 cp2: heh

20:48 technomancy: cp2: I think they're the consumer-level ones

20:48 cp2: sounds about right

20:48 * p_l dislikes the term 'netbooks' and the whole hype around them like they are new

20:49 cp2: technomancy: well, im trying to spend under a thousand, so i might end up with one of those

20:49 but im still looking

20:49 oh my

20:49 =p

20:50 unlink: XMLisp is incredible.

20:50 p_l: judging from my experience, I'd recommend getting something that has better resolution than 1280x800 if you're buying something around 15,4"

20:50 cp2: yeah p_l, thats one of my deciding factors

20:51 i dont like small screens much

20:51 p_l: I wasn't bothered so much by it before, but in last few months I find myself screaming at lack of display space

20:51 cp2: yeah

20:51 im so used to having 2 20" widescreen displays

20:51 p_l: if it's a ~12", then it's alright, but 15,4"? No thanks. Unfortunately I missed my chance to get 1920x1200 15,4"

20:51 cp2: would like to avoid shock hah

21:21 Modius_: cp2 I recommend the Samsung netbook

21:30 cipher: what's the easiest way to make a timer... just want something to happen on a regularly scheduled basis.

21:36 hiredman: Timer

21:36 actually

21:37 just send-off to an agent

21:38 (send-off (agent nil) (fn this [& _] (send-off *agent* this) do stuff here (Thread/sleep 1000)))

22:08 ataggart: hiredman: can you please explain how that timer function works? I've read up on 'send-off' but I'm getting thrown by the fn's bindingd and the second call to send-off.

22:09 hiredman: _ is conventional used as the name for bindings you don't care about

22:10 ataggart: ahh ok

22:10 hiredman: send-offs inside an agent action are held until the action completes

22:10 ataggart: all clear now

22:10 hiredman: so the send-off at the top acts like you would imagine a send-off at the bottom would act

22:10 ataggart: thanks very much

22:10 yep

22:10 hiredman: sure

Logging service provided by n01se.net