#clojure log - Jun 28 2011

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

2:30 ebaxt: Hi, I'm currently working on my first real clojure project, and I find myself wanting a mocking tool. So I was wondering what you are using? I tried googling, but I can't seem to find the "Mockito of the clojure world" :)

2:32 raek: ebaxt: https://github.com/marick/Midje is built for top-down TDD

2:33 haven't used Mockito, so dunno if this is what you are really looking for

2:38 ebaxt: raek: Thanks. Mockito has sort of turned into the "next generation" mocking fwk for Java (JMock being first generation), and since the adoption is huge there is little risk of it being abandoned by it's maintainers.

2:39 raek: Searching for a mocking tool in Clojure it looks like there is a lot of small tools being thrown together, but maybe not being used by many. But would you say Midje is a safe bet in that regard?

2:43 raek: ebaxt: I don't have much experience with the mocking tools, so I don't know...

2:43 ebaxt: also consider asking this on the google group

2:44 ebaxt: raek: Sure, I'll do that as well

4:24 Cozey: is it possible to use swank-cdt to break on ring middleware ? Usually the actual function called is a closure returned by some wrap-*

5:18 bsteuber: ,(:foo :bar)

5:18 clojurebot: nil

5:19 bsteuber: I expected this throws an exception

5:20 Fossi: why should it?

5:20 clojure rarely throws exceptions

5:20 and :foo is just an accessor

5:21 it can't find :foo in :bar, so...

5:21 ,(:foo {})

5:21 clojurebot: nil

5:21 Fossi: same really

5:56 lnostdal-laptop: hi guys; (refer 'clojure.core :exclude '(resultset-seq)) works .. but (use 'clojure.core :exclude '(resultset-seq)) states "unsupported option :exclude"

5:56 though, IIUC, the docs for USE state that i can use :exclude as done for REFER

6:00 terom: (use '[clojure.core :exclude (resultset-seq)])

6:00 lnostdal-laptop: ..but whyyyy? ... heh :}

6:01 terom: use behaves likes require, which takes a libspec which is a vector

6:01 refer on the other hand does not

6:02 lnostdal-laptop: ok, thanks

6:02 :)

6:02 the docs should state these things btw.

6:08 terom: well, (doc require) states that, but the docs does not have very many examples

6:09 this could be helpful: http://blog.8thlight.com/articles/2010/12/6/clojure-libs-and-namespaces-require-use-import-and-ns

7:59 khaliG: (foo 20 [10 20 30]) -> [10 30] .. is there such a foo?

8:01 TobiasRaeder: well

8:01 &(remove #(= % 20) [10 20 30])

8:01 sexpbot: ⟹ (10 30)

8:01 TobiasRaeder: should do the trick

8:01 ;)

8:01 remove is pretty much a inverse filter

8:02 jcromartie: ,(remove #{20} [10 20 30])

8:02 clojurebot: (10 30)

8:02 khaliG: thanks :)

8:03 TobiasRaeder: (defn remove

8:03 "Returns a lazy sequence of the items in coll for which

8:03 (pred item) returns false. pred must be free of side-effects."

8:03 {:added "1.0"

8:03 :static true}

8:03 [pred coll]

8:03 (filter (complement pred) coll))

8:03 so yeah it is exactly the same

9:04 jcromartie: I find it odd when the clojure docs say "_ must be free of side effects"

9:05 that's never really true

9:07 gfrlog`: jcromartie: why not?

9:07 jcromartie: ,(doc filter)

9:07 clojurebot: "([pred coll]); Returns a lazy sequence of the items in coll for which (pred item) returns true. pred must be free of side-effects."

9:08 jcromartie: if pred has side-effects, filter will go right along its merry way

9:08 gfrlog`: jcromartie: ooh, I thought you meant that all functions have side effects

9:08 jcromartie: ,(filter print [1 2 3])

9:08 clojurebot: 123

9:08 ()

9:08 jcromartie: the world didn't end

9:08 gfrlog`: jcromartie: maybe there are edge cases where something is repeated

9:08 jcromartie: definitely

9:09 gfrlog`: jcromartie: so wouldn't that justify the clause?

9:09 jcromartie: but I just find the language "must" to imply "otherwise it won't work"

9:09 gfrlog`: yeah...I guess "should" might be clearer.

9:11 clgv: well, it's written as condition for guaranteed functionality so "must" is alright ;)

9:12 gfrlog`: it's unnecesarily restrictive

9:12 it could also say that the function must return a boolean

9:13 jcromartie: I'm wondering if there's any case where a pred with side-effects would break filter

9:13 clgv: well, if you want a guarantee you must follow the rules ;)

9:13 jcromartie: yes

9:13 * gfrlog` looks at the source

9:13 gfrlog`: clgv: we're saying there's not a clear relevance -- what's being guaranteed?

9:14 clgv: filter is lazy, so if the side-effect state of the predicate changes from definining the lazy filter sequence until it consumption, you might get an entirely different result

9:15 gfrlog`: clgv: side effects don't have to change the return value of the function

9:15 clgv: I think, if you are using doall on filter you can use any predicate you like - side-effect free or not

9:15 gfrlog`: and you can have a side-effect-free function that still depends on state

9:15 so I think that issue is orthogonal

9:16 clgv: gfrlog`: well then it's "practical side-effect free" if the side-effects have no impact on any result of that predicate ;)

9:16 gfrlog`: on another note, looking at the source, I can't imagine pred being called twice

9:16 clgv: elsewhere "side-effect-free" is a requirement because the function might be called multiple times (e.g. swap!)

9:17 clgv: gfrlog`: calling a function multiple times is only one case where side-effects can do harm

9:17 gfrlog`: calling it delayed is another

9:17 gfrlog`: it seems rather arbitrary to tack that onto the filter docs though. If it works there, I would think it could apply to any higher-order-function

9:18 jcromartie: I guess if the pred has some mutable state

9:18 gfrlog`: if you're not using pure functions, you could get unexpected results. has nothing to do with filter

9:18 jcromartie: say, if the pred uses and changes an atom or ref

9:19 gfrlog`: jcromartie: certainly, but I think that issue is orthogonal to the behavior of filter

9:19 jcromartie: I think that's probably the meaning

9:19 clgv: gfrlog`: but thats very likely the reason for the side-effect free requirement in the docs when you look at the source

9:20 * gfrlog` looks for an HOF that doesn't have the requirement

9:20 gfrlog`: ,(doc map)

9:20 clojurebot: "([f coll] [f c1 c2] [f c1 c2 c3] [f c1 c2 c3 & colls]); Returns a lazy sequence consisting of the result of applying f to the set of first items of each coll, followed by applying f to the set of second items in each coll, until any one of the colls is exhausted. Any remaining items in other colls are ignored. Function f should accept number-of-colls arguments."

9:21 gfrlog`: clgv: you would want the requirement on map as well?

9:21 DerGuteMoritz: how about dorun

9:21 clgv: gfrlog`: lol, so you want to reason with probably incomplete documentation? :P

9:22 DerGuteMoritz: oh well, not really a HOF

9:22 gfrlog`: clgv: I just think it's distracting; any clojure user should know that pure functions make things simpler

9:22 jcromartie: I think it's fine to require side-effect free functions for things like map and filter

9:22 clgv: gfrlog`: and I guess documentation in clojure is intended to be used to get the programmers started - dont confuse it with exact specification

9:22 gfrlog`: there's nothing mystical about how filter works that makes it unclear how a stateful function would behave

9:22 DerGuteMoritz: "just follow the simple rules"

9:22 jcromartie: I just think it's odd to say "must" when the language can't enforce anything

9:22 it's not Haskell

9:23 :P

9:23 gfrlog`: lol, here's a fun contrast: ##(doc swap!)

9:23 sexpbot: ⟹ "([atom f] [atom f x] [atom f x y] [atom f x y & args]); Atomically swaps the value of atom to be: (apply f current-value-of-atom args). Note that f may be called multiple times, and thus should be free of side effects. Returns the value that was swapped in."

9:23 gfrlog`: in that function, where it really matters, it uses "should" :)

9:24 clgv: jcromartie: I guess you have to read "must" as dont "cry and complain if it doesnt work otherwise" ;)

9:24 sritchie: gfrlog`, what does hof stand for?

9:24 gfrlog`: sritchie: higher-order-function

9:24 sritchie: I've been seeing hof? in the cascalog code and can't figure it out

9:24 there we go :)

9:24 thanks

9:24 gfrlog`: np

9:24 TimMc: let's see...

9:24 hof?

9:24 gfrlog`: hand-over.

9:24 TimMc: clojurebot: hof?

9:24 clojurebot: Huh?

9:24 gfrlog`: foot?

9:25 jcromartie: (defn hof? "Returns true if x is David Hasselhoff" [x] ...)

9:25 TimMc: Someone inform the bot.

9:25 clgv: clojurebot: HOF is Higher-Order Function

9:25 clojurebot: c'est bon!

9:25 clgv: HOF?

9:25 clojurebot: HOF is Higher-Order Function

9:25 sritchie: Hippies on Funyuns

9:25 clgv: :)

9:25 TimMc: yay

9:25 gfrlog`: ~hof

9:25 clojurebot: HOF is Higher-Order Function

9:25 sritchie: nice, clojurebot

9:26 clgv: he is quite a learner ;)

9:26 gfrlog`: ~botsnack

9:26 clojurebot: Thanks! Can I have chocolate next time

9:26 TimMc: sometimes a little too much of one

9:26 gfrlog`: ~botsnack chocolate

9:26 clojurebot: Cool story bro.

9:26 sritchie: haha

9:26 ~42

9:26 clojurebot: I don't understand.

9:26 gfrlog`: clojurebot: #42

9:26 clojurebot: 42. You can measure a programmer's perspective by noting his attitude on the continuing vitality of FORTRAN.

9:26 clgv: clojurebot: #1

9:26 clojurebot: 1. One man's constant is another man's variable.

9:27 clgv: lol

9:27 TimMc: Where's the list?

9:27 Are these Perlisisms?

9:27 gfrlog`: $google "attitude on the continuing vitality of FORTRAN"

9:27 sexpbot: First out of 41 results is: Vitality Quotes Page 2 - BrainyQuote

9:27 http://www.brainyquote.com/quotes/keywords/vitality_2.html

9:27 gfrlog`: hmm

9:28 I'm going to guess it googled w/o quotes

9:28 TimMc: Looks like Alan Perlis, yeah.

9:28 clgv: seems to be brainyquote statements

9:28 gfrlog`: man googling with quotes isn't much better

9:28 TimMc: http://www.cs.yale.edu/quotes.html

9:29 gfrlog`: if you add clojurebot to the query it just returns IRC logs

9:30 clojurebot: #41

9:30 clojurebot: 41. Some programming languages manage to absorb change, but withstand progress.

9:30 clgv: clojurebot: #128

9:30 clojurebot: Titim gan éirí ort.

9:31 gfrlog`: they're all turing-complete, what's the difference

9:33 DerGuteMoritz: why does a Ring request split the URI into its components and associate the path component with the :uri key?

9:33 gfrlog`: DerGuteMoritz: you mean splitting the path from the host and port?

9:34 DerGuteMoritz: gfrlog`: and the query-string, yes

9:34 I would expect the path to end up under :path

9:34 but its under :uri

9:34 hysterical raisins?

9:34 gfrlog`: well the host and port part I would say is because they're not ever together in HTTP I don't think

9:34 as to why it splits the query string...I dunno, but it doesn't seem all that weighty either way :)

9:35 DerGuteMoritz: yeah sure, and :scheme is also not in there explicitly

9:35 oh well

9:35 now I know it anyway

9:58 khaliG: is there a but-nth?

9:59 gfrlog`: $findfn [1 2 3 4 5 6 7] 3 [1 2 3 4]

9:59 sexpbot: []

9:59 gfrlog`: $findfn 2 [1 2 3 4 5 6 7] [1 2 3 4 5]

9:59 sexpbot: [clojure.core/drop-last]

9:59 gfrlog`: khaliG: that looks like it?

10:01 khaliG: mm not quite!

10:01 raek: ,(loop [v [1 2 3 4 5 6 7], n 3] (if (zero? n) v (recur (pop v) (dec n))))

10:01 clojurebot: [1 2 3 4]

10:01 khaliG: $findfn [1 2 3 4 5] 2 [1 2 4 5]

10:01 sexpbot: []

10:02 raek: khaliG: or did you want to remove a certain element?

10:02 khaliG: raek, yes

10:02 i have a list of row data and wish to remove a given row item (indexing the list by row)

10:02 raek: khaliG: well, there's remove

10:03 if the row has place structure (i.e. there are a fixed number of element and each mean something special) one way is to use destructuring and then build a new one

10:04 wastrel: i went to that 99 lisp questions site but what's a "box"

10:04 raek: wastrel: cons cell

10:05 ,(let [row [123 "abc" 456], [x y z] row] [x z])

10:05 clojurebot: [123 456]

10:05 wastrel: thx

10:05 raek: khaliG: do you use the row as a collection with varying number of elements or as a tuple with fixed number of elements

10:06 (vectors no dot have an efficient way of removing elements from the middle)

10:06 khaliG: raek, my collection is made up of rows - and i wish to remove one, sorry i wasn't very clear before!

10:07 terom: would something like this be inefficient?: (defn but-nth [coll n] (concat (take (dec n) coll) (drop n coll)))

10:07 raek: khaliG: do you want to remove rows based on a certain rule or by index?

10:07 khaliG: raek, by index

10:07 raek: where do you get the index from?

10:07 DerGuteMoritz: terom: you could use split-with to avoid traversing the list twice

10:08 khaliG: raek, from a user click on a JTable

10:08 raek: ah, Java stuff...

10:08 khaliG: yep!

10:09 raek: you can do it like this: (defn remove-from-vector [v i] (into (subvec v 0 i) (subvec v (inc i))))

10:10 which is basically like terom's solution but with vectors

10:10 it's probably best to keep the data in vectors since the Java stuff wants to access the data by index

10:11 khaliG: sure, thank you

10:13 raek: I've seen code where people do tons of operations with indices that would simply have been much cleaner with functions like remove and filer...

10:13 khaliG: raek, okay. well, i could look for the row and then remove the result?

10:13 raek: so that's why I'm a bit reluctant to "accept" a solution that uses indices exstesively

10:13 khaliG: ah, understood

10:14 raek: in this case, the design decision was not yours... :)

10:14 khaliG: :)

10:16 terom: DerGuteMoritz: how to write the predicate for that? I assume the predicate fn gets the value from coll, but now it should filter by index. (Ok, probably could iterate the coll with some index...)

10:17 clgv: &(println (System/currentTimeMillis), (System/nanoTime))

10:17 sexpbot: ⟹ 1309270635780 4587247584252735 nil

10:17 DerGuteMoritz: terom: true, that's a bit tricky

10:18 clgv: hmm nanoTime seems to be something different than I thought

10:18 Is it related to a timer that was zero when the hosting system booted?

10:20 gfrlog`: you could see if that's plausible by converting it to seconds

10:20 in this case it's 1mo22days

10:21 I guess by "seconds" I meant "normal time"

10:21 clgv: hmm I had a look at the javadoc: it is a timer of the hosting system

10:21 gfrlog`: the milliseconds is ~41 years as you'd expect

10:22 clgv: so I'll use currentTimeMillis since I need a timestamp

10:22 gfrlog`: nanos I guess would be gooder for execution time and such

10:23 clgv: yep. that's where I found it in my code base ;)

10:23 gfrlog`: &(System/femtoTime)

10:23 sexpbot: java.lang.NoSuchFieldException: femtoTime

10:24 clgv: lol. even nanoTime has no guaranteed accuracy of nano seconds ;)

10:25 gfrlog`: I don't think a Long is big enough to measure time in planck units :/

10:26 Fossi: it would just wrap pretty often

10:26 gfrlog`: :)

10:27 clgv: hmm if I have a function there is no possibility to get back a symbol of it's var, right?

10:27 gfrlog`: functions don't have vars

10:27 clgv: all my defns have :P

10:27 gfrlog`: it might have some info in the metadata some of the time though

10:27 ,(meta remove)

10:27 clojurebot: {:ns #<Namespace clojure.core>, :name remove, :file "clojure/core.clj", :line 2145, :arglists ([pred coll]), :added "1.0", :doc "Returns a lazy sequence of the items in coll for which\n (pred item) returns false. pred must be free of side-effects."}

10:28 gfrlog`: looks like you could get the var from :ns and :name there

10:28 ,(meta #(% %))

10:28 clojurebot: nil

10:28 gfrlog`: the point being don't assume an arbitrary function has such a thing

10:29 ,(let [m (meta remove)] (class ((:ns m) (:name))))

10:29 clojurebot: java.lang.ClassCastException: clojure.lang.Namespace cannot be cast to clojure.lang.IFn

10:30 clgv: I have defns so it should work with meta

10:30 DerGuteMoritz: ,(:name (meta remove))

10:30 clojurebot: remove

10:30 DerGuteMoritz: no?

10:30 gfrlog`: ,(let [m (meta remove)] (class ((ns-map (:ns m)) (:name))))

10:30 clojurebot: java.lang.IllegalArgumentException: Wrong number of args passed to keyword: :name

10:30 gfrlog`: ,(let [m (meta remove)] (class ((ns-map (:ns m)) (:name m))))

10:30 clojurebot: clojure.lang.Var

10:30 gfrlog`: ah hah there it is

10:31 DerGuteMoritz: ##(-> remove meta :name class)

10:31 sexpbot: ⟹ clojure.lang.Symbol

10:31 clgv: well the symbol with name and namespace is enough

10:31 DerGuteMoritz: oh I thought he just wanted the name

10:31 gfrlog`: clgv: I'm not sure if you can get the name from a var...hmm

10:31 clgv: it's both in meta

10:32 gfrlog`: ,(meta (var remove))

10:32 clojurebot: {:ns #<Namespace clojure.core>, :name remove, :file "clojure/core.clj", :line 2145, :arglists ([pred coll]), :added "1.0", :doc "Returns a lazy sequence of the items in coll for which\n (pred item) returns false. pred must be free of side-effects."}

10:32 gfrlog`: nope there it is

10:33 ,(= (meta remove) (meta (var remove)))

10:33 clojurebot: true

10:33 clgv: I just need a full qualified symbol to be able to load that function again later if I need to.

10:34 gfrlog`: clgv: I'm curious what you're doing and what "load" means

10:34 clgv: :ns and :name will do

10:35 I am storing an execution configuration for later analysis. I might not have to load it later on but I must be able to identify which one was used

10:36 but with enough metadata (e.g. :doc) attached it would be easier to display what the function is supposed to do

10:37 gfrlog`: cool

10:38 clgv: yeah the execution framework with its configuration dsl turned out pretty cool :)

10:38 DerGuteMoritz: what is an execution framework?

10:39 a shell?

10:39 solussd_: it's a java threading framework

10:40 DerGuteMoritz: I see

10:40 clgv: nope in my case it's a framework that takes a dsl that specifies functions and parameters that shall be used and executes a given function for all possible combinations of those "values"

10:41 DerGuteMoritz: is there an auto runner for clojure.test?

10:45 jcromartie: clgv: what is that used for?

10:46 clgv: straight forward: running experiments with certain ranges and different strategies to see which one works best or what influences which parameter has.

10:47 s/ranges/ranges for parameters/

10:47 sexpbot: <clgv> straight forward: running experiments with certain ranges for parameters and different strategies to see which one works best or what influences which parameter has.

11:15 halfprogrammer: ,(list? '(0 1 2 3))

11:15 clojurebot: true

11:15 halfprogrammer: ,(list? (range 4))

11:15 clojurebot: false

11:16 halfprogrammer: why do we have this behavior?

11:16 jcromartie: ,(type '())

11:16 clojurebot: clojure.lang.PersistentList$EmptyList

11:16 jcromartie: ,(type (range 4))

11:16 clojurebot: clojure.lang.LazySeq

11:17 halfprogrammer: jcromartie: hmmm. just the printed representation of (range x y) looks like a list...

11:17 jcromartie: yes

11:17 there are more general predicates

11:17 halfprogrammer: coll? etc..?

11:17 raek: halfprogrammer: a seq and a persistent list is not the same thing, but all lists are seqs

11:17 ,(seq? '(0 1 2 3))

11:17 clojurebot: true

11:18 raek: ,(seq? (range 4))

11:18 clojurebot: true

11:18 jcromartie: ,(map (juxt seq? coll? vector? list?) '(() [] (range 10)))

11:18 clojurebot: ([true true false true] [false true true false] [true true false true])

11:18 raek: a list keeps track of the length

11:18 halfprogrammer: what is the difference between seq? and sequential?

11:18 raek: halfprogrammer: vectors and sorted sets are sequential, but not seqs

11:18 jcromartie: ,(map (juxt seq? coll? vector? list? sequential? assocaitive?) '(() [] (range 10) {} #{}))

11:18 clojurebot: java.lang.Exception: Unable to resolve symbol: assocaitive? in this context

11:18 halfprogrammer: raek: oh.. I dint know that

11:18 jcromartie: pp[s

11:18 ,(map (juxt seq? coll? vector? list? sequential? associative?) '(() [] (range 10) {} #{}))

11:18 clojurebot: ([true true false true true false] [false true true false true true] [true true false true true false] [false true false false false true] [false true false false false false])

11:19 jcromartie: this could go on :)

11:19 gfrlog`: jcromartie: then there's seqable as well

11:19 halfprogrammer: jcromartie: that's a nice table you have generated :)

11:19 jcromartie: ,(sequential? (sorted-set))

11:19 clojurebot: false

11:20 jcromartie: wasn't sure about that one...

11:20 raek: I think that is a bug...

11:20 gfrlog`: here's an error that could be reported better: ##{:a}

11:20 raek: I recall hearing about it before

11:20 gfrlog`: &{:a}

11:20 sexpbot: java.lang.ArrayIndexOutOfBoundsException: 1

11:20 jcromartie: gfrlog`: what's the problem?

11:21 gfrlog`: jcromartie: it just took me a dang while to figure out what was going on :)

11:21 raek: gfrlog`: iirc, they made that throw a better message in 1.3

11:21 jcromartie: ah o

11:21 manutter: &{:a 1 :b}

11:21 sexpbot: java.lang.ArrayIndexOutOfBoundsException: 3

11:21 gfrlog`: I had (fn [{:keys method path-pattern}] on one line

11:21 manutter: interesting

11:21 gfrlog`: raek: that is good news

11:23 halfprogrammer: guys, what's the coolest clojure code you've seen?

11:24 i was looking into the destructuring code a couple of days back. It was nice

11:24 gfrlog`: halfprogrammer: I never admit that anybody else's code is cool, so my answer is http://twitter.com/#!/gfrlog/status/38726503944552448

11:25 manutter: I saw a blog post where somebody used closures to manipulate a red-black tree in a loop/recur

11:26 halfprogrammer: gfrlog`: short & sweet

11:26 gfrlog`: halfprogrammer: yeah I was surprised

11:27 manutter: http://goo.gl/XlYHR

11:30 halfprogrammer: manutter: looks scary when people go out of the way to write a (awesome) tail recursive algorithm

11:31 jcromartie: gfrlog`: that's cool

11:31 manutter: halfprogrammer: I was certainly impressed

11:33 halfprogrammer: any word on cemerick's clojure survey?

11:34 cemerick: halfprogrammer: the squirrels are working on the results post right now

11:34 honestly, I'm swamped with the book at the moment, which has put a pinch on my blogging deadlines

11:35 The results post will go out either later today or Thursday

11:36 halfprogrammer: cemerick: excited both abt the book & the survey results :)

11:37 cemerick: :-)

11:39 * gfrlog` thinks vim will be the surprise winner

11:39 * halfprogrammer thinks it gfrlog` is wrong :-P]

11:39 jcromartie: ed

11:39 halfprogrammer: gfrlog`: so, how's ur experience with emacs been?

11:40 gfrlog`: halfprogrammer: I've totally resisted doing anything besides clunking around ERC

11:40 my flashiest skill is that I can pull up previous statements using Alt+p

11:41 halfprogrammer: is lisp development with vim good?

11:41 gfrlog`: it might be halfway good, but I'm not even good at it :) I just use it as a text editor and if it colors things then I'm happy

11:42 everything else for me is just tmux and lein

11:42 TimMc: halfprogrammer: No, iti s chartreuse.

11:42 Stupid ergonomic keyboard.

11:43 halfprogrammer: :P

11:43 TimMc: typonomic

11:45 halfprogrammer: clojure vs scala war has started in my office (ThoughtWorks)

11:46 some clojure fanboy (I think) wrote an internal mail with "is scala dead?" as the subject

11:46 sritchie: hey all, is anyone here using marginalia 1.6?

11:46 0.6.0, rather

11:46 gfrlog`: have a competition to see who can write parsers for their respective languages the fastest

11:46 halfprogrammer: whole discussion was both heated & informative

11:50 Cozey: does leiningen plugin has some kind of an init function?

11:50 i'd like to create a plugin which creates hooks for other plugins

11:52 solussd: scala seems 'over-engineered' to me. It's a continuation of the layering of features on top of fortran and C-like languages to modernize them rather than the more natural approach to new features available to lisp/lisp-like languages. Didn't Backus warn us about scala 35 years ago? :D

11:53 halfprogrammer: solussd: :D

11:54 jcromartie: gfrlog`: spend some time with paredit-mode

11:54 it's really really really great

11:55 halfprogrammer: how big is ThoughtWorks, BTW? I got the impression that it was small

11:56 halfprogrammer: approx 1600 people I guess

11:56 including ppl other than engineers

11:58 jcromartie: oh wow, huh

11:58 is Clojure really in use there?

11:59 halfprogrammer: I find a lot of guys using it for their personal projects and stuff.

11:59 No client projects in Clojure yet

11:59 fliebel: where?

11:59 clojurebot: where is log

11:59 halfprogrammer: ThoughtWorks

12:07 bpr: does anyone know why https://github.com/briprowe/timer-oddity would hang the clojure compiler?

12:07 i type "lein jar" and it hangs

12:08 TimMc: clojurebot: forget where is log

12:08 clojurebot: You don't have to tell me twice.

12:08 bpr: oddly if i remove ":main timer-oddity.core" from the project.clj file it compiles fine

12:09 hiredman: bpr: making a jar is not compiling

12:09 bpr: ok

12:09 * halfprogrammer sometimes forgets clojurebot is a bot. clojurebot is so cool

12:09 bpr: but, i still need to compile the thing

12:10 halfprogrammer: clojurebot: you're awesome

12:10 clojurebot: Pardon?

12:11 bpr: hiredman: lein compile hangs as well (also, only when i declare a "main")

12:13 jcromartie: bpr: I cannot accept the Eclipse Public License to troubleshoot this

12:13 :P kidding of course

12:13 bpr: haha

12:14 yeah that's leinengen boilerplate

12:15 cemerick: bpr: my guess is that the Timer you're creating isn't using a daemon thread, and so will prevent the JVM from exiting

12:15 use (Timer. true)

12:16 bpr: cemerick: that's most likely it... /facepalm

12:17 ty

12:17 cemerick: :-)

12:17 jcromartie: RTFMFTW

12:19 semperos: I've asked a similar q recently, but wanted to get more details

12:19 I'd like to use Clojure datastructures for defining configuration files in my app

12:19 these files should not be kept under version control

12:20 does it make sense just to use a regular namespaced Clojure file with vars for hodling config values, and just provide a "blank" file for the user to fill in and possibly rename (to be able to pass around a consistent .gitignore)

12:23 jcromartie: look at how project.clj works in Leiningen

12:23 I think that's a decent model

12:24 the idea is to just read the file (as in the "read" functions) and use that result

12:24 you can control the loading of the file that way, and what is executed and what is not

12:24 technomancy: leiningen's model is a little different as it involves the defproject macro

12:24 but you can just use load-file on a file that contains an arbitrary data structure

12:25 gfrlog`: technomancy: read would be safer than load-file, right?

12:25 jcromartie: load-file looks good

12:25 technomancy: gfrlog`: only if you disable eval-at-read

12:26 gfrlog`: ah hah

12:26 technomancy: even then, if someone's compromised your config files, it's probably a lost cause

12:26 gfrlog`: which only concerns #=(), right?

12:26 technomancy: aye

12:27 semperos: yeah, for config files, dealing with "malicious" code not as big a deal

12:27 technomancy: we have some code in our config files that allows things like queue names to be uniquified during concurrent test runs but uses canonical names in production.

12:27 which you can't do with read

12:27 semperos: hmm

12:27 thanks for the feedback, everyone, I'll play around with it

12:33 halfprogrammer: I am having to write stupid code like (is (= true (falsey? (before lst 2 1)))) etc

12:34 because (false? nil) is false

12:34 hiredman: clojure.test's (is ) treats nil the same as false

12:34 halfprogrammer: is there any proper way to write these things?

12:35 bendlas: ,(nil? nil)

12:35 clojurebot: true

12:35 bendlas: ,(nil? false)

12:35 clojurebot: false

12:35 halfprogrammer: ,(false? nil)

12:35 clojurebot: false

12:35 halfprogrammer: this is the problem for me

12:36 dakrone: why do you need to use 'false?' ?

12:36 cemerick: ,(doc false?)

12:36 clojurebot: "([x]); Returns true if x is the value false, false otherwise."

12:36 halfprogrammer: hiredman: you mean (is (not before lst 2 1)))

12:36 cemerick: ,(if nil 5 6)

12:36 clojurebot: 6

12:36 halfprogrammer: something like ^ this would work?

12:36 raek: (is (not (before lst 2 1)))

12:36 hiredman: halfprogrammer: what do you mean?

12:37 halfprogrammer: raek: sorry, i left out a pair of ()

12:37 hiredman: have you just tried it?

12:37 halfprogrammer: hiredman: am about to try it...give me 1 sec

12:38 raek: halfprogrammer: if you have something that is truthy or falsey, just use it in the (is ...) form directly.

12:38 you can use the 'boolean' function in cases where you really need it to be either true of false (e.g. calling a java method that takes a boolean)

12:39 halfprogrammer: raek: hiredman: that works. I don't know why I dint try it :D

12:40 * halfprogrammer has to modify a few tests now

13:08 derp__: dang it, yesterday I had "lein swank" working fine, and today when I try it I get this: https://gist.github.com/1051619

13:09 man I have bad luck with computers

13:09 technomancy: derp__: you have multiple versions of swank again

13:11 derp__: technomancy: again, you were right :P

13:14 should I include swank as a :dev requirement for my projects? I mean if that conflicts with lein, what's the point?

13:14 technomancy: better to keep it as a user-level plugin

13:15 theoretically non-emacs-users could work on your project; why make them pull in a dep they won't use

13:15 derp__: okay, well thank you for that explanation technomancy

13:18 technomancy: sure

13:22 gfrlog`: somebody creating a clojure library for dating?

13:22 cemerick: Hot Clojure singles are waiting for you!

13:23 * cemerick apologizes deeply

13:23 gfrlog`: :)

13:24 cemerick: Most apps I've written don't need much more than milliseconds since the epoch + ISO date strings.

13:24 For anything beyond that, I presume simply using jodatime is recommended.

13:25 gfrlog`: leap-seconds might get removed from UTC

13:26 cemerick: This is all I've ever needed, but again, I'm a simpleton in this area: https://github.com/cemerick/utc-dates

13:26 technomancy: that's it; I'm switching to Stardates

13:27 gfrlog`: one simplifying technique I use is to never make software that will be used by people in different time zones

13:28 cemerick: things get a whole lot simpler if you just assume everyone is in London.

13:28 gfrlog`: because they are, aren't they?

13:28 technomancy: and if they aren't, they wish they were

13:28 gfrlog`: we're just helping them fantasize

13:29 jcromartie: gfrlog`: that's a great idea

13:29 we just added a "country" dropdown which includes Canada, but we still only list US states

13:29 hiredman: cemerick: OH'ed

13:31 gfrlog`: jcromartie: it's easy enough to imagine that Canada is a US State, so that makes sense to me

13:31 hiredman: imagine?

13:32 gfrlog`: hiredman: rather than two US states of Canada and Quebec?

13:32 jcromartie: gfrlog`: agreed

13:33 hiredman: :/

13:50 cemerick: It looks like lein-ring is not yet 1.3-friendly?

13:51 or, it depends upon hiccup apparently, which isn't? (e.g. Can't dynamically bind non-dynamic var: hiccup.core/*html-mode*)

13:52 technomancy: wait, lein-ring depends on hiccup? =(

13:52 amalloy: cemerick: i'm a leetle surprised lein-ring has anything to do with hiccup

13:52 more likely, it seems to me, your app is trying to bind hiccup, and lein is just obediently starting your server

13:52 cemerick: Not sure what to say; I've never used it before, but `lein deps`; `lein ring server` dumps on me.

13:53 amalloy: this is a hello world app — no hiccup anywhere in my code

13:53 davekong: Is sort guarenteed to be a stable sort?

13:53 amalloy: well, gross

13:53 &(doc sort)

13:53 sexpbot: ⟹ "([coll] [comp coll]); Returns a sorted sequence of the items in coll. If no comparator is supplied, uses compare. comparator must implement java.util.Comparator."

13:54 davekong: That does not say

13:54 amalloy: davekong: looks like it's not guaranteed, but i wouldn't really mind relying on it myself

13:54 cemerick: Is there any dependency graph visualization in lein?

13:55 technomancy: hiredman: you had something like that, didn't you?

13:55 amalloy: since (a) j.u.Collections.sort has been stable for like a decade, and (b) clojure is likely to keep using it

13:55 cemerick: technomancy: nm, I just used Eclipse

13:55 hiredman: not really, mine was on the namespace level, not project level

13:55 hugod: lein pom; mvn dependency:tree

13:55 cemerick: The ironies are deep. ;-)

13:55 technomancy: dependency:tree *is* really nice.

13:55 I still keep mvn around mostly for that.

13:56 cemerick: so, it goes: lein-ring ----> ring-devel ----> hiccup

13:56 technomancy: I'm permanently hooked on m2eclilpse's dep hierarchy view.

13:56 so, yeah, hiccup is required by lein-ring. Why, I can't imagine.

13:57 technomancy: I would have a hard time classifying that as anything but a bug.

13:58 cemerick: https://github.com/mmcgrana/ring/blob/master/ring-devel/project.clj

13:58 :-(

13:58 been like that for a while; likely not going to change quicly

13:58 quickly*

13:59 technomancy: exclusions maybe?

14:01 oh, it may be that it uses hiccup to generate HTML versions of stack traces? that seems not unreasonable.

14:01 cemerick: This is for the book (thus why I'm tripping around with lein-ring to begin with); if I can't get the simple stuff to be simple, then the point is lost. Hopefully a message to the list will prompt the 1.3-ification of hiccup.

14:02 technomancy: definitely

14:03 cemerick: is there not a dedicated ring ML?

14:03 hiredman: there is

14:03 a google group

14:03 cemerick: ah, ring-clojure, thanks

14:03 hiredman: very low traffic

14:04 I asked a question a week or two ago and have yet to get a response

14:04 cemerick: We'll see how it goes. I'd lobby for the elimination of hiccup entirely, but one step at a time. :-P

14:05 hiredman: http://groups.google.com/group/ring-clojure/browse_thread/thread/8f35a9c811a2c381

14:05 cemerick: yuck

14:07 technomancy: I wonder why the prags' ring book fell through.

14:08 jcromartie: technomancy: maybe there wasn't enough to say?

14:08 It's a pretty small librarry.

14:09 technomancy: jcromartie: well, I think it was targeting ring and the ring ecosystem

14:09 jcromartie: I am pretty sure that things like Ring and Rack are just chapters in books on frameworks sitting on top.

14:09 technomancy: and they were shooting for a shorter ebook

14:09 but perhaps things were just changing too rapidly

14:09 jcromartie: oops

14:09 cemerick: It's really early for topical books like that, I'd think.

14:09 jcromartie: Command + W'ed

14:10 cemerick: I know people would appreciate a dedicated Incanter book, but again, really small market.

14:10 technomancy: probably true, though mini-ebooks have a much lower barrier

14:11 but it would probably be a better book if it waited for the ecosystem to solidify a bit

14:11 have a few more tools for common tasks like user handling and form construction

14:15 derp__: if I have a bunch of clojure projects folder, should I run swank in the toplevel directory containing them all, or can I only run it within project folders?

14:37 Dranik: hi all!

14:38 timvisher: hi

14:42 derp__: is there a way to run swank on multiple projects simultaneously?

14:42 or do I have to run separate versions and connect to each independently

14:43 manutter: derp__: I don't think you necessarily want to, at least in the general case

14:43 derp__: ?

14:44 manutter: you should run each swank in its own project because of the classpaths

14:44 derp__: but how do you work on multiple projects simulataneously

14:44 and then connect to each separately?

14:44 manutter: that said, you may have a specific case where all your projects are using the same libs, in which case my caveat would be moot

14:45 but I'm not sure the usual tools will find the classpaths for multiple projects at once

14:47 i'm guessing you can connect to multiple swanks, but I don't know what that would cost in ram terms

14:47 derp__: um, how do I connect to different versions? I am running "lein swank 4011" and trying to connect, but I get this weird warning: "Close old connections first? (y or n)"

14:48 amalloy: i'd say, press y if and only if you want to close your old connections first :P

14:48 manutter: use different ports

14:48 derp__: yeah, I am using 4010 for the other swank server

14:48 manutter: oh wait I see what you mean

14:49 you're trying to connect to different swank servers from the same session

14:49 derp__: yep

14:49 manutter: I'd run separate emacs instances myself

14:49 derp__: really?

14:49 manutter: but that may be just because I don't know any better

14:49 technomancy: manutter: no, that's what I do

14:50 slime is pretty crappy at handling multiple connections

14:50 manutter: I'm going to have to bail out now, later all

14:50 technomancy: derp__: you might be interested in checkout dependencies though; see lein help readme in the faq

14:52 coopernurse: general design question.. let's say you're writing an app that consumes a web service, does some transforms on the data and saves to a sql db. I assume the functional approach would be to isolate the i/o (impure) code off from the pure transform code.

14:52 is that the right way to think about things generally?

14:53 timvisher: coopernurse: i'd say yes

14:53 but i'm not authoritative

14:53 that's what i've tried to do in my apps

14:53 derp__: technomancy: so if I understand that faq right, I should do this: *project-dir*/checkouts/*sym-link-to-other-project-dir*

14:53 coopernurse: timvisher: great. are you using some mocking lib to test the functions that do i/o

14:53 derp__: and I can have multiple symlinks?

14:53 technomancy: derp__: indeed

14:53 derp__: sweet

14:53 Cozey: technomancy: hello. I've got an issue with Lancet's coerce multi function: https://github.com/technomancy/lancet/blob/master/src/lancet/core.clj#L28 in my scenario dest-cls is int, so I guess Integer/TYPE. the obj is Clojure number, so a Long. I'd like to add some coerce defmultis, but I'm not sure which ones: it would be good to cover also Short values - should we use (.intValue obj) yielding int, or should we just convert to Integer, and let

14:53 auto-unbox it to int, if it needs?

14:54 the problem is (cast int 123) will throw classcastexception

14:55 technomancy: Cozey: lein is on clojure 1.2, so all return values are going to have to be boxed

14:56 Cozey: mhm, so it sohuld be (Short. (.shortValue 123)) ?

14:56 technomancy: I'm not sure; I don't really know what coerce is used for

14:57 Cozey: it's used when an 'Scp' ant task wants setPort(int)

14:57 and lancet tries to fill in the properties

14:57 using coerce multi-fun to change clojure types to something ant task object can accept

14:58 technomancy: Integer. is probably what you want?

14:58 Cozey: under clojure 1.2, all numbers are Long or Integer ?

14:58 hiredman: you wonder why it just doesn't call it reflectively

14:59 Cozey: technomancy: yes for this case yes, but i want to commit a patch so I'd like to add Short support as well

14:59 and Long

14:59 but: clj 1.3 uses Long by default

14:59 and clj 1.2 ?

15:00 hiredman: yeah it uses some writermethod

15:00 hiredman: (clojure.lang.Reflector/invokeInstanceMethod obj "setPort" (into-array [port-number]))

15:01 Cozey: hiredman: any better idea?

15:01 hiredman: Cozey: ^-

15:01 Cozey: O_o

15:16 michigan101: https://market.android.com/details?id=com.game.WarStrategy

15:30 tufflax: Can I use hiccup for arbitrary XML, not just HTML?

15:31 amalloy: tufflax: i think you want c.c.prxml for that. hiccup might be based on it, even

15:31 but they take basically the same format

15:32 tufflax: ok, thanks

15:40 rindolf: Hi all.

15:40 When trying to follow the instructions here - http://dev.clojure.org/display/doc/Getting+Started+with+Eclipse+and+Counterclockwise - I'm getting this - http://pastie.org/2135881 . What should I do?

15:47 cemerick: rindolf: what version of Eclipse are you using?

15:49 rindolf: cemerick: eclipse-3.6.2-13.mga2.src.rpm

15:50 cemerick: Seems sane enough

15:51 rindolf: hrm, that's a src bundle from some linux distro?

15:52 rindolf: cemerick: it's the Mageia Cauldron source rpm.

15:52 cemerick: it ends up as eclipse-jdt-3.6.2-13.mga2

15:52 cemerick: rindolf: my first suggestion would be to go get a suitable binary from eclipse.org

15:52 rindolf: cemerick: why?

15:52 cemerick: it is a binary.

15:53 cemerick: I mean an officially-packaged binary.

15:53 Who knows what got left on the repository packager's cutting room floor.

15:54 That error indicates that eclipse is looking for a package (some OSGI dependency?, presumably a fairly sane thing to do), but the set of configured repositories you have doesn't include the one it needs.

15:55 rindolf: You could pass that paste to the people in #eclipse, and they might have a better clue.

15:55 rindolf: cemerick: OK.

15:56 cemerick: rindolf: let me know how it pans out either way

15:57 rindolf: cemerick: OK.

16:07 pcavs_: ,(seq? [1 2 3])

16:07 clojurebot: false

16:07 pcavs_: ,(doc seq)

16:07 clojurebot: "([coll]); Returns a seq on the collection. If the collection is empty, returns nil. (seq nil) returns nil. seq also works on Strings, native Java arrays (of reference types) and any objects that implement Iterable."

16:08 amalloy: &(map (juxt seq seq? sequential?) ['(1) [1] []])

16:08 sexpbot: ⟹ ([(1) true true] [(1) false true] [nil false true])

16:09 amalloy: huh, i didn't realize ##(seq? '(1)) returned a non-boolean

16:09 sexpbot: ⟹ true

16:09 amalloy: maybe i just can't read

16:11 jcromartie: ,(seq? (seq []))

16:11 clojurebot: false

16:11 jcromartie: :)

16:12 cemerick: It seems that lein-ring requires a :target-dir key in project.clj — but I don't see any documentation of this anywhere. Am I missing something obvious?

16:13 (e.g. perhaps :target-dir should be getting set to a default — "target" or ".", perhaps — but isn't for some reason in my environment?)

16:13 derp__: why is it that lein converts projects with dashes into underscores?

16:13 technomancy: cemerick: it's set by default since lein 1.5

16:13 derp__: my-project becomes my_project

16:13 hiredman: cemerick: didn't require it for me

16:14 technomancy: or rather, it defaults to the project root

16:14 hiredman: ah

16:14 well, there you go

16:14 cemerick: technomancy: Bah! I just did a clean self-install and I see I have 1.2.0! :-(

16:14 devn: cemerick: private msg

16:14 (when you have a moment)

16:15 cemerick: Bugger; an old `lein` bootstrap on my PATH.

16:15 technomancy, hiredman: thanks

16:17 technomancy: I hope to have .debs at some point to make that one less thing to worry about

16:17 though if you're on os x it's already in brew

16:18 cemerick: technomancy: no worries, my bad. I chafe at any repo manager in OS X anyways.

16:18 technomancy: agreed

16:18 though I chafe more at not having a package manager at all. but there's an easy solution to that.

16:20 cemerick: Lots of easy solutions, actually.

16:20 * cemerick has been contemplating becoming a farmer

16:20 wastrel: hi

16:20 my friend has a farm

16:21 cemerick: We should chuck all these newfangled computer things until they actually work properly.

16:21 wastrel: they rent their fields out to their neighbors, they don't farm on them actually

16:21 ibdknox: lol

16:21 that's awesome

16:21 tenant farmers

16:30 rpglover64: I come seeking enlightenment, after not finding it in the vast open web.

16:30 * devn hands you a paren

16:31 rpglover64: I'm using deftype to implement an interface

16:32 the problem is that it also needs to have a nullary constructor

16:33 how could I add one to it?

16:33 hiredman: which deftype has if you don't specify fields

16:33 rpglover64: but it needs to store data somehow

16:34 and the nullary constructor would have to do initialization

16:36 I guess i could ask, how could I have things that behave like private data fields without specifying them to deftype

16:37 rindolf: cemerick: it works fine with the Eclipse build from http://www.eclipse.org/ .

16:37 cemerick: rindolf: Excellent, good to know :-)

16:38 rindolf: tell your distro's package manager to stop messing with things ;-)

16:38 s/manager/maintainer

16:38 sexpbot: <cemerick> rindolf: tell your distro's package maintainer to stop messing with things ;-)

16:40 dnolen: rpglover64: not possible really.

16:40 rpglover64: That's what I thought

16:41 which is why I asked "how do I add a nullary constructor to a deftype'd class"

16:41 dnolen: rpglover64: deftype is hosty, but is opinionated enough that you can really think of it as interop.

16:42 s/can/can't

16:42 sexpbot: <dnolen> rpglover64: deftype is hosty, but is opinionated enough that you can't really think of it as interop.

16:42 dnolen: rpglover64: perhaps proxy is better suited for this task.

16:42 rpglover64: cool!

16:42 it actually needs to be a class :(

16:43 off to gen-class land? :(

16:43 dnolen: rpglover64: what interface are you implementing?

16:44 rpglover64: it's part of an intro to programming in java final assignment

16:45 rindolf: cemerick: OK, I'm following this - http://dev.clojure.org/display/doc/Getting+Started+with+Eclipse+and+Counterclockwise and it says: «Run it: Select the firstClojureProject>src>helloworld.clj file, then menu Run > Run as > Clojure REPL.» but I cannot find it anywhere under src/ in the project view.

16:45 rpglover64: so I'm using it to learn clojure

16:45 derp__: I'm trying to write documentation, when a word is in brackets it's assumed to be a dir, a la [dir], right?

16:46 or is that a fictitious standard I just muddled up

16:46 cemerick: rindolf: you created the helloworld.clj file, right?

16:46 rindolf: cemerick: yes, I did.

16:46 cemerick: rindolf: and you can't find that file in the project view?

16:46 rindolf: cemerick: yes, exactly.

16:47 cemerick: so you created the file somewhere other than `src`, I presume.

16:48 rindolf: cemerick: I did not.

16:48 rpglover64: dnolen: the problem is that to make the pretty graphical part of the assignment (that the instructor wrote) use the student's implementation of the logic, the object that would start the game expects to be passed in a class implementing the interface, and will proceed to use it for all its logic needs.

16:49 rindolf: cemerick: and I cannot find it anywhere else.

16:50 cemerick: rindolf: OK; right-click the src dir, and choose New > File; name it helloworld.clj, and go from there.

16:50 rindolf: cemerick: it says the file already exists.

16:50 cemerick: rindolf: did you create the file outside of eclipse (e.g. in a terminal?)

16:51 rindolf: cemerick: no, I did not.

16:51 * cemerick has entered the twilight zone

16:52 rpglover64: can a proxy be passed to a java method that expects a class (no, right?)

16:52 cemerick: rindolf: select the top-level project node, and hit F5 (refresh); does the file appear where you think it should be?

16:52 dnolen: rpglover64: interface dictating ctors seems weird, but perhaps normal in the Java world?

16:52 rpglover64: interface doesn't have constructors

16:52 java forbids it syntactically

16:53 rindolf: cemerick: no, it does not.

16:53 rpglover64: but in this case, it's like an obj-c informal protocol

16:53 the object receiving the class expects it to have a nullary constructor

16:53 rindolf: cemerick: nothing happens upon refresh.

17:01 coopernurse: I'm reading this page: http://freegeek.in/blog/2011/06/10-clojure-one-liners/

17:02 and when I try out #7 - (clojure.xml/parse "http://search.twitter.com/search.atom?&amp;q=clojure")

17:02 in emacs/slime I get a huge backtrace / debug buffer

17:02 that I'm not sure how to make sense of.. Is there anything obviously wrong with that #7 example? If I paste it into a browser I get XML back from twitter

17:02 rpglover64: ,(clojure.xml/parse "http://search.twitter.com/search.atom?&amp;q=clojure")

17:03 clojurebot: java.security.AccessControlException: access denied (java.net.SocketPermission search.twitter.com:80 connect,resolve)

17:03 rpglover64: makes sense

17:03 dnolen_: rpglover64: so the assignment requires you to create those ctors - in Clojure it's idiomatic to provide them as fns.

17:03 rpglover64: yes

17:04 hiredman: coopernurse: read the doc string for parse

17:05 rpglover64: dnolen_: do I pretty much need gen-class to do that?

17:05 coopernurse: hiredman: ok

17:05 hiredman: actually, I take that back, read the stacktrace instead

17:06 coopernurse: it hoses my swank process.. so I'm restarting it

17:06 hiredman: you're getting the same error I assume?

17:06 dnolen_: rpglover64: well I mean were you planning on writting it Clojure and converting it back to Java? :)

17:06 rpglover64: no, i'm not in the class

17:06 hiredman: coopernurse: no, I'm not

17:07 rpglover64: i'm just using the the final project to learn clojure interop

17:07 coopernurse: hiredman: ah. ok.. let me verify my clojure version real quick

17:07 rpglover64: and clojure in general

17:07 hiredman: coopernurse: I am not running the code at all

17:07 dnolen_: rpglover64: but why limit yourself to the arbitrary constraint?

17:08 rpglover64: dnolen_: i'm not sure i understand how it's an arbitrary constraint

17:09 i'm looking at it from the perspective of "I have some java code I need to interop with"

17:09 and to interop, I need to have the constructor

17:10 dnolen_: rpglover64: sorry, I forgot it's the Java code that will call your ctor.

17:11 rpglover64: and you said the Java code will call your initializer ?

17:12 rpglover64: initializer?

17:12 dnolen_: rpglover64: you said something about initialization.

17:13 rpglover64: the java code will call a nullary constructor, which is expected to do the initialization

17:15 dnolen_: rpglover64: what about a interop deftype which just calls the actual ctor fn?

17:17 coopernurse: I think perhaps the URL is getting mangled

17:17 going to try another URL.

17:19 rpglover64: dnolen_: that either doesn't implement the interface or needs to have something like a field that isn't a field (afa deftype is concerned)

17:20 dnolen_: rpglover64: because the Java side isn't functional, it's going to side effect the result of the ctor call?

17:21 rpglover64: dnolen_: it's going to construct the object and then start using it... i'm not sure what you mean by side effect in this case

17:23 dnolen_: rpglover64: in Clojure you construct instances, but using it means producing new instances.

17:24 not always of course, but a considerable amount of the time.

17:24 rpglover64: dnolen_: but isn't that the primary effect, not a side-effect?

17:26 DerGuteMoritz: is there a function like Scheme's string-prefix? in clojure.core or .contrib?

17:26 i.e. a function that checks whether one string is a prefix of the other

17:27 dnolen_: rpglover64: part of the problem is ctors in Java are notorious for state/concurrency bugs, since a nullary ctor means you have this gap between object instantiation and initialization. deftype avoids that, but it means it's hard to make it work for your use case.

17:27 amalloy: $google java lang string startsWith

17:27 sexpbot: First out of 23700 results is: String (Java Platform SE 6)

17:27 http://download.oracle.com/javase/6/docs/api/java/lang/String.html

17:27 technomancy: ,(.startsWith "stella" "ste")

17:28 clojurebot: true

17:28 amalloy: technomancy: ninja'd?

17:28 kinda not sure. yours might be more practical

17:28 technomancy: we'll call it a draw

17:28 DerGuteMoritz: ah, keep forgetting to check the Java APIs

17:28 thanks!

17:28 rpglover64: dnolen_: well, in this case, I expect the constructor to return an initialized object

17:29 * technomancy wonders if 50% of his direct Java method invocations are on strings

17:29 bhenry: is there a way to walk through a collection and have a counter given to me for each run?

17:29 amalloy: &(doc map-indexed)

17:29 sexpbot: ⟹ "([f coll]); Returns a lazy sequence consisting of the result of applying f to 0 and the first item of coll, followed by applying f to 1 and the second item in coll, etc, until coll is exhausted. Thus function f should accept 2 arguments, index and item."

17:29 amalloy: or, ##(map vector (range) [:a :b :c])

17:29 sexpbot: ⟹ ([0 :a] [1 :b] [2 :c])

17:30 derp__: I can't figure out how to call a function from another file

17:30 amalloy: technomancy: 50% seems like it might be low

17:30 derp__: https://gist.github.com/1052284

17:30 I ran lein uberjar and run the standalone, and then I get this error: https://gist.github.com/1052292

17:31 here's the original with syntax highlighting: https://gist.github.com/1052284

17:34 bhenry: amalloy: thanks

17:38 derp__: I must be screwing up something obvious, but it's not apparent to me

17:51 bpr: where does contrib.repl-utils live now that the contrib library has been broken up?

17:54 brehaut: bpr: not all the old contrib libs have been moved to new contrib yet (in fact, very few have)

17:55 bpr: looking at http://dev.clojure.org/display/design/Contrib+Projects it appears to be one of the libs not migrated yet

18:01 bpr: sweet, didn't know about that url. thanks, brehaut

18:11 rpglover64: brehaut: I was told that I should ask you about coming to clojure from a haskell background

18:12 brehaut: rpglover64: really? curious

18:12 rpglover64: how much haskell do you know?

18:13 amalloy: brehaut: surely i wasn't wrong to recommend you

18:13 brehaut: amalloy: if im one of the more experienced haskellers here, im surprised

18:14 amalloy: you're the loudest, as far as i've noticed

18:14 brehaut: fair enough

18:14 rpglover64: brehaut: enough that I think about whether to use the Applicative interface to Parsec instead of the Monadic one

18:14 brehaut: rpglover64: do you use Category with it?

18:14 (it being applicative)

18:15 rpglover64: brehaut: I haven't jumped into regularly using Category or Arrow yet

18:15 so no

18:16 brehaut: rpglover64: i think with category and applicative you can avoid most uses for arrow

18:16 clojurebot: arrows

18:16 clojurebot: arrows is http://ro-che.info/ccc/12.html

18:16 brehaut: gold

18:16 rpglover64: Aren't Arrows isomorphic to Applicative Categories?

18:16 brehaut: indeed

18:16 rpglover64: I remember reading something about that and not understanding it

18:17 brehaut: anyways, what do you want to know about clj from hs?

18:18 rpglover64: nothing in particular, unless there's a nice tutorial or introduction to it aimed at haskellers

18:18 it's just that your name was mentioned, and I saw it in scrollback and happend to be around

18:19 brehaut: i doubt it; clojure is largely straight forward. fnparse is approximately equivalent to parsec (although the combinators are different) you dont need monads for most things (for and doseq are list comprehensions) -?> and -?>> provide a good chunk of what you might use maybe for

18:20 and point free is uncommon (because it gets lumpy fast)

18:20 rpglover64: gathered as much

18:21 although the -> and ->> macros are nice sometimes

18:21 brehaut: definately, but they arent point free

18:22 rpglover64: they're kinda similar

18:22 brehaut: yeah they perform similar purposes

18:22 but its form rewriting rather than first class functions

18:23 rpglover64: right

18:23 but if I don't have a nice type system, I don't _want_ to be passing around and composing lots of first class functions

18:24 brehaut: news to me ;)

18:24 clojurebot: excusez-moi

18:24 AWizzArd: rpglover64: like the guys in Haskell I guess

18:25 rpglover64: also, I've realized that the weirdest thing for me to get used to is the lack of currying

18:26 brehaut: you do still have partial and the #(…) reader macro available;

18:27 its maybe not as elegant as currying, but it does the job well enough, and #() is particularly useful because it allows you to work with methods as well as functions

18:29 amalloy: brehaut: poor memfn. everyone uses #(...) isntead

18:38 * gfrlog` had never heard of memfn. But from now on he will use #(...) instead

18:38 amalloy: &(map (memfn length) ["test" "some strings"])

18:38 sexpbot: ⟹ (4 12)

18:39 gfrlog`: #(.length %) is shorter

18:39 and has three more punctuation marks

18:40 amalloy: sure, i usually use # too. but for one thing you can nest memfn inside of #() forms

18:40 brehaut: gfrlog`: potentially for a method with a really long signature memfn might become clearer because you name the arguments

18:40 tomoj: annotations in my deftype don't work when I use a macro to create it: https://gist.github.com/1052434 ideas?

18:41 must be dropping the metadata somewhere somehow

18:42 amalloy: tomoj: fwiw, that comment form doesn't "work":

18:42 &(comment works:)

18:42 sexpbot: java.lang.Exception: Invalid token: works:

18:43 gfrlog`: there's one thing that a with-dyslexia macro can't help you with

18:43 tomoj: also unreadable forms

18:43 had them ;;'d out but wanted syntax highlighting

18:45 (defmacro deffoo [name] `(deftype ~(with-meta name {Foo true}) []))

18:45 shouldn't (deffoo Bar) define a Bar class with the Foo annotation?

18:46 amalloy: tomoj: i think so. emitting metadata from macros always seems to have some traps for me

18:47 tomoj: (->> '(deffoo Bar) macroexpand-1 second meta) is as expected but no annotations...

19:40 gfrlog`: if I want to thread a map through a series of reduces, I need a threading macro that makes something the second argument :(

19:44 amalloy: or a reduce that wants the initial element first

19:46 gfrlog`: I'll bet you half a pence that exactly one of the two is in amalloy-utils

19:46 amalloy: hah, no

19:46 gfrlog`: you won't bet because I'm right!

19:47 amalloy: actually i accept your bet and tell you you're wrong

19:47 gfrlog`: aw dang

19:47 * gfrlog` shucks

19:48 gfrlog`: (defn preduce ...)

19:55 coopernurse: how can I tell what version of swank and clojure I'm running from a repl

19:55 after running: clojure-jack-in

19:55 I assume the clojure version is based on the project.clj?

19:55 hiredman: ,(clojure-version)

19:55 clojurebot: "1.2.0"

19:55 coopernurse: hiredman: thank you

19:58 yes, there's something odd going on with the swank/slime repl

19:58 with this line

19:58 (clojure.xml/parse "http://search.twitter.com/search.atom?&amp;q=clojure")

19:58 if I run: java -jar clojure.jar

19:58 and paste that in

19:58 it works fine

19:58 from the standard clojure REPL

19:59 but over swank I get dropped into a debugger

20:01 https://gist.github.com/1052546

20:02 "Unable to resolve symbol: q in this context" seems relevant

20:13 pcavs: Does anyone know (1) How Kawa Implements TCO (2) Why Clojure does something else (3) What that something else is?

20:13 technomancy: kawa is an interpreter, innit?

20:13 or is that just sisc?

20:14 DerGuteMoritz: pcavs: Kawa only has optional TCO and it's very expensive AFAIR

20:14 pcavs: Oh, I thought Kawa was a full Scheme implementation

20:14 DerGuteMoritz: Interesting...

20:14 DerGuteMoritz: if you enable it, yes :-)

20:14 technomancy: Kawa compiles to bytecode actually

20:15 well, it also has an interpreter of course

20:15 technomancy: ok, it just sacrifices by not compiling every function call to a method invocation

20:16 scgilardi: http://www.rhinocerus.net/forum/lang-scheme/559925-recommendations-kawa-sisc.html

20:17 DerGuteMoritz: ah, Per Bothner replies in that thread, he is the creator of Kawa

20:18 I have used Kawa for an Android app and have quite liked it

20:19 pcavs: Thanks DerGuteMoritz

20:19 DerGuteMoritz: you're welcome

22:03 symbole: What is the meaning of #^"[B"? Does that indicate that whatever follows is a byte array?

22:10 dnolen: ,(type (byte-array []))

22:10 clojurebot: [B

22:10 dnolen: symbole: yes it's a primitive byte array type hint

22:11 symbole: old type hint syntax tho. ^ preferred over #^ these days.

22:12 symbole: Ah, thanks.

22:14 gfrlog`: if I call (first (filter ...)) on a non-chunked seq, it shouldn't ever process more than necessary should it?

22:14 like...exactly 32 more than necessary? :(

22:29 dnolen: gfrlog`: filter does the chunking.

22:30 gfrlog`: dnolen: man. that sounds like valuable information.

22:30 wouldn't you want that kind of thing in the docs?

22:30 dnolen: gfrlog`: actually it's not filter so much as seq.

22:31 ,(type (seq [1]))

22:31 clojurebot: clojure.lang.PersistentVector$ChunkedSeq

22:31 gfrlog`: oh maybe it's cause I call (chunked-seq?) without calling seq

22:31 so I was wrong about it not being chunked

22:31 dnolen: ,(type (seq {1 2}))

22:31 clojurebot: clojure.lang.PersistentArrayMap$Seq

22:31 gfrlog`: ah yes

22:32 ,(chunked-seq? (seq (shuffle (range 1000))))

22:32 clojurebot: true

22:32 gfrlog`: that threw me off because it returned false w/o (seq)

22:32 Scriptor: ,(type (range 10000))

22:32 clojurebot: clojure.lang.LazySeq

22:32 dnolen: ,(type (seq (range 10)))

22:32 clojurebot: clojure.lang.ChunkedCons

22:33 dnolen: gfrlog`: in anycase, if you want to prevent chunking you need to wrap the seqable thing in something which ensures one at a time, which is easy to do.

22:33 gfrlog`: I used a manual (loop)

23:13 technomancy: any DDs in the house?

23:14 amalloy: technomancy: you need a ride home?

23:14 technomancy: hehe

23:14 Debian Developers

23:16 pcavs: technomancy: nobody's taking the bait...

23:18 technomancy: pcavs: well you never know, Debian has a reputation for moving very slowly.

23:18 zing!~

23:31 kencausey: technomancy: What do you mean by Developer in this sense? I use Debian and develop software on the platform, I have not packaged anything for Debian though.

23:32 s/sense/instance/

23:32 sexpbot: <kencausey> technomancy: What do you mean by Developer in this instance? I use Debian and develop software on the platform, I have not packaged anything for Debian though.

23:32 technomancy: kencausey: right... Debian Developer is a pretty specific term for people who have upload privileges

23:32 thanks though =)

23:33 it looks like clojure is up to date in sid, but contrib is still on 1.1.0

23:33 kencausey: yes, not me, sorry

23:35 technomancy: apparently to create a legit lein .deb I have to first package clucy, lancet, and hooke.

23:35 ...without the help of leiningen itself

23:36 curse you, self-hosting!

23:40 whooo-wee! apt-get install maven2 pulls in not one, not two, but _three_ languages.

23:40 amalloy: technomancy: a lein deb would be pretty great though

23:41 ibdknox: you can never have too many languages ;)

23:41 technomancy: amalloy: there will definitely be a deb. the question is whether it will be a compliant one or not.

23:41 the uberjar-in-a-deb approach is easy peasy

23:42 complying with every jot and tittle of the hallowed Debian Policy is daunting

23:45 ibdknox: unless one of them is groovy

23:45 ibdknox: hahaha

23:45 seriously? It bring down groovy for Maven2?

23:45 technomancy: if I released a lein deb that depended on groovy I would probably die of embarrassment

23:45 ibdknox: If you weren't shot first ;)

23:46 lol

23:46 technomancy: it looks like there's no way around Recommend'ing gcj though =(

23:46 amalloy: !

23:46 hiredman: ^- also an embarrassment

23:47 amalloy: technomancy: that sounds worse to me than groovy

23:47 technomancy: amalloy: for portability; apparently ant is too slow to be usable on non-i386 architectures using hotspot?

23:47 and you can't have arch-specific Recommends fields

23:47 though users can disable the auto-installation of Recommend'ed packages

23:47 amalloy: technomancy: gcj barely works at all. last i checked it didn't support all of jdk4, let alone 5 or 6

23:48 technomancy: yeah but think of the sparc users. or something.

23:51 hiredman: I think it is safe to presume that sparc users are a hardy bunch that need no hand holding

23:52 technomancy: hiredman: you should suggest this to the debian maintainers, I'm sure a lively discussion could be had.

23:52 "lively"

23:52 hiredman: continued use of sparc seems to point to a particular streak of hard headedness

23:53 technomancy: whoa; m86k is still supported as well

23:56 * cemerick can't tell if technomancy is brave or…

23:56 cemerick: ;-)

23:57 technomancy: cemerick: just looking to pick a fight =)

23:58 "no, I will _not_ put copyright boilerplate at the top of every source file. I prefer to use that 30% of my screen space for things that are relevant, like the code."

23:58 cemerick: technomancy: if it's with the .deb folks, I'm behind you :-)

23:58 technomancy: luckily that is only strongly recommended, not required.

Logging service provided by n01se.net