#clojure log - Jan 21 2011

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

0:15 Derander: amalloy: no kidding

0:17 amalloy: Derander: oh good, it's not just my browser then?

0:17 Derander: nope

0:18 also, I'm a little confused at how a ruby example on #2 would take 35 lines as opposed to python's 10. if I understand the python there is nothing particularly difficult to accomplish in ruby

0:21 hiredman: when reading anything on bestinclass.dk, it is important to remember that lau (the author) is an ignorant know nothing

0:21 I think that will explain any questions you may have

1:53 LauJensen: Morning all

1:57 Scriptor: morning LauJensen

2:09 notsonerdysunny: what is the official current source repository for clojure-contrib .. https://github.com/richhickey/clojure-contrib seems very old .. (last commit is 6 months ago .. )

2:10 tomoj: https://github.com/clojure/clojure-contrib

2:12 notsonerdysunny: thanks tomoj

2:18 where is data.finger-tree located .. it does not seem to be in either of clojure or clojure-contrib..

2:18 in sources that is..

2:19 I know there is a seperate repo for data.finger-tree .. but I was hoping it was going to be part of clojure or clojure-contrib.. am I missing something?

2:21 oh it is github.com/clojure/data.finger-tree.git .. ..

2:22 it is a seperate module .. how can I get the whole thing?

2:26 tomoj: I don't think the author considers it ready enough to publish it

2:27 .. or is it now?

2:27 it wasn't under clojure/ when I last looked

2:28 notsonerdysunny: oh ic ..

3:16 Licenser: morning

3:58 TobiasRaeder: morning :)

3:58 mduerksen: greetings ^^

5:53 LauJensen: Can I get some input on this please? http://gist.github.com/789530

7:14 bartj: is there a HTML Parser which does lazy evaluation of nodes

7:14 this is for web scraping btw

7:18 hoeck: LauJensen: nice! what about making sql-case more like a clojure cond? https://gist.github.com/789596

7:19 LauJensen: hoeck: Im actually working on that this very moment :)

7:19 hoeck: why the two ??'s after :alias

7:20 hoeck: LauJensen: because it looks like a "condp" or clojure "case" to me and at first I thought the :alias was the column to switch on

7:20 LauJensen: ah ok

7:20 hoeck: and then late recognized is was the sql "as alias"

7:21 LauJensen: It can be done exactly as condp actually, but Im not sure I want to support that syntax

7:21 hoeck: no, I guess thats not necessary, a nicer sql case, without the WHEN should be enough

7:21 a lispy case that is

7:22 LauJensen: yes - and its just one macro away :}

7:25 hoeck: LauJensen: how do you handle sql-"as" in select statements?

7:26 LauJensen: Are you asking me how to alias a column?

7:27 hoeck: LauJensen: no, rather subqueries in the select clause, like select (select ...) as bar from foo

7:27 LauJensen: hoeck: You never specify that yourself, ClojureQL works out when to do subselects

7:27 clojureql.core> (-> (table :t1) (sort [:id]) (sort [:wage]))

7:27 SELECT * FROM (SELECT t1.* FROM t1 ORDER BY t1.id asc) ORDER BY wage asc


7:38 * ZabaQ came to clojure from CL - so the first thing I typed into the REPL was (car '(a b c)). Fail.

7:38 ZabaQ: Are the eror messages always so java-esqe?

7:39 LauJensen: ZabaQ: Yes sir

7:39 ZabaQ: Ah wel.

7:41 LauJensen: ZabaQ: If you're a little nutty you could initialize your namespace like so (ns nuts (:refer-clojure :rename '{first car second cdr})) .... :)

7:42 ZabaQ: I'm not so traditionalist :-)

8:16 bsteuber1: where did incanter.chrono go?

8:16 or is there another recommended time conversion lib now?

8:17 fliebel: bsteuber1: I don't know, but I heard some people use clj-time, which is based in yoda, or something like that.

8:18 LauJensen: hoeck: there you go:

8:18 clojureql.core> (project (table :t1) [:id (case :alias (> :x 5) "low" (> :x 10) "high" :else "average")])

8:18 SELECT t1.id,CASE WHEN (x > ?) THEN low WHEN (x > ?) THEN high ELSE average END AS alias FROM t1


8:20 bsteuber1: fliebel: clj-time seems less complete than what I believe was stuart halloways example code in several talks

8:21 hoeck: LauJensen: fine :)

8:21 bsteuber1: e.g. for creating java.sql.Date from it - though I'm sure it's dead simple :)

8:22 hoeck: LauJensen: the only thing that bothers me is the :alias, though I admit that I don't have any better ideas where to place them instead

8:23 LauJensen: hoeck: :( I thought it was such a great idea

8:24 hoeck: [:id (case (< :x 10) :else foo :as :alias)] ?

8:24 LauJensen: ewww

8:24 Well... maybe...

8:25 hoeck: LauJensen: how do I write in clojureQL select id as foo?

8:25 LauJensen: Same way

8:25 clojureql.core> (project (table :t1) [[:id :as :foo]])

8:25 SELECT t1.id AS foo FROM t1


8:25 hoeck: LauJensen: then why not use this for case too?

8:26 LauJensen: Its only a matter of taste

8:26 hoeck: I mean, at least its constistent and you don't have to remember where to place your alias

8:26 LauJensen: Thats true

8:26 hoeck: LauJensen: taste, exactly :)

8:28 LauJensen: those where just my 2c, I hope I will not have to use sql-case too often

8:28 LauJensen: hoeck: And I appreciate them, thanks

8:30 fliebel: Hm… Exactly what overhead is eliminated by using chunks? Is it just the creation of a new seq for every step? If so, do transients still benefit from chunked behavior? Why isn't a chunk a seq? The implementation of map for example uses the .nth method(not in the IChunk interface) to iterate over the chunk in a one-by-one manner.

8:31 clgv: why not: (project (table :t1) [(as :id :foo)]]) ?

8:32 bsteuber1: interesting, calling bean on a java.sql.Date gives an exception

8:32 at least in 1.2.0

8:32 clgv: oops messed up a bracket

8:33 chouser: fliebel: Less allocation per seq step. Yes. Transients aren't seqs. What would be the benefit?

8:34 fliebel: if map used seq to walk the chunk, it would still have to allocate an object for each step, ruining the only value chunks have.

8:34 fliebel: chouser: Sorry, is you last message "fliebel: if map used seq…"?

8:35 I killed my irc client :(

8:35 chouser: fliebel: yep, you're all caught up

8:42 fliebel: chouser: I'm thinking about it… It seems a chunk does implement Indexed, which makes sense. So I could do (nth) on them rather than (.nth)(like map does) How 'private' are chunks?

8:43 clgv: is there something like a join-operation on to sequences?

8:43 s/to/two/

8:43 sexpbot: <clgv> is there something like a join-operation on two sequences?

8:44 fliebel: clgv: You mean like ##(doc concat)?

8:44 sexpbot: ⟹ "([] [x] [x y] [x y & zs]); Returns a lazy seq representing the concatenation of the elements in the supplied colls."

8:44 fliebel: clgv: Or like.. clojure.unify/join?

8:44 clgv: nope. I have an attribute that is a UID in the objects of both sequences

8:45 &(doc clojure.unify/join)

8:45 sexpbot: java.lang.Exception: Unable to resolve var: clojure.unify/join in this context

8:45 fliebel: My bad… http://clojure.github.com/clojure/clojure.set-api.html#clojure.set/join

8:46 clgv: &(doc clojure.set/join)

8:46 sexpbot: ⟹ "([xrel yrel] [xrel yrel km]); When passed 2 rels, returns the rel corresponding to the natural join. When passed an additional keymap, joins on the corresponding keys."

8:46 clgv: what is the "rel" supposed to mean? a map?

8:46 chouser: fliebel: I think chunks are a public interface, though it may be wise to think of it as a bit experimental yet and subject to change.

8:47 clgv: A relation -- a set of maps

8:48 fliebel: chouser: Okay, thanks.

8:48 clgv: chouser: I know the mathematical definition of relation. how does this relate to a set of maps?

8:49 relation: a->b c->d relates to #{ {a b} {c d} }?

8:50 fliebel: &(clojure.set/join [{:a 1 :c 2}] [{:a 1 :b 2} {:a 1 :d 4}])

8:50 sexpbot: ⟹ #{{:d 4, :a 1, :c 2} {:b 2, :a 1, :c 2}}

8:50 chouser: clgv: http://en.wikipedia.org/wiki/Relation_(database)

8:51 clgv: clojure.set uses a map instead of a tuple, so each item in the set knows the names of its attributes

8:51 clgv: lol database relations are conceptually mathematical ones ;)

8:53 hm ok. I can use that one, since I have a list of deftypes and not sets of maps ;)

8:53 *cant

8:53 fliebel: clgv: records, on the other hand, would implement the right interfaces I think...

8:55 clgv: fliebel: I would have needed a more general method using predicates ;)

8:56 chouser: defrecords should work fine, though you'd still need sets of them, not lists of them

8:58 clgv: but I have a more elaborate check to do that determines if two objects belong together. it cant be done with simple value matching.

8:59 chouser: ah. well, if you look at the implementations of the clojure.set functions, I think you'll find most of them to be pretty simple

9:01 clgv: I guess I'll break it down to a some or first-filter expression

9:39 arkh: is there a convention for magic numbers? ALLCAPS? I understand earmuffs are only for dynamic vars and things I def are 'constants' buf is there another naming convention for things like (def utc-offset 6) ?

9:39 .s/buf/but

9:40 stuartsierra: There is no fixed convention.

9:40 arkh: there should be ; )

9:40 but thank you

9:40 puredanger: Given (defprotocol P (foo [_])) (defrecord R [] P (foo [_] "foo")) is it a bug that (isa? R P) returns false but (isa? R user.P) returns true ? R does implement P as expected if you check with reflection.

9:40 chouser: I sometimes use allcaps because Java static final fields often do

9:41 arkh: I like having them stand out

9:42 stuartsierra: There was an old Common Lisp convention, used inconsistently, to have constants in + signs like +my-constant+

9:42 puredanger: ah, I see that (class P) returns PersistentArrayMap as that's the protocol mapping but user.P is the actual Java class

9:47 arkh: is the official clojure FAQ at http://en.wikibooks.org/wiki/Clojure_Programming/FAQ ? I'd like to contribute.

9:48 stuartsierra: It's probably moved to Confluence

9:52 arkh: one can get to the above link from clojure.org:Wiki -> en.wikibooks.org/wiki/Clojure_Programming:FAQ . Does clojure.org need to be updated?

9:54 ... and the first question wasn't meant to be a trap. I found the path from clojure.org after asking it :/

9:59 LauJensen: Finally! Something that worked on MySQL, Postgres AND sqlite3 without any tweaks! https://gist.github.com/789530

10:01 stuartsierra: arkh: I'll point it out to Core

10:02 arkh: stuartsierra: it's something I'd like to contribute to - thanks

10:03 stuartsierra: arkh: More recent FAQ is at http://dev.clojure.org/display/doc/FAQ

10:08 Contrib parent POM 0.0.20 released!

10:09 http://build.clojure.org/job/build.poms/74/

10:09 clgv: what is a POM?

10:09 stuartsierra: "Project Object Model" - the Maven build configuration file.

10:10 clgv: so what is the essential message?

10:10 stuartsierra: For authors with contrib libraries on build.clojure.org, time to update.

10:11 clgv: ok :)

10:14 chouser: stuartsierra: that's just cemerick and fogus`, right?

10:14 stuartsierra: chouser: want in?

10:14 finger-tree is yours, right?

10:14 fogus`: will do

10:15 chouser: stuartsierra: yep

10:15 stuartsierra: chouser: OK, that's next up then.

10:17 chouser: yay!

10:21 edoloughlin: Anyone know in clojureQl, if the PK is an auto-incremented int how do I get the value created after a (conj!)

10:21 LauJensen: edoloughlin: You're looking to execute the statement "SELECT LAST_INSERT_INDEX()" right?

10:22 fogus`: stuartsierra: Do you mean 0.0.21?

10:22 stuartsierra: No, 0.0.20 release

10:22 fogus`: Hmmm. I was already using that then

10:22 edoloughlin: Did not know about that fn. How does it behave if there are multiple threads doing inserts?

10:23 stuartsierra: fogus: no, I think you had 0.0.20-SNAPSHOT

10:23 edoloughlin: Haven't seen how to do transactions in clojureQl... (just started using it)

10:24 Can clojureQl be wrapped in contrib.sql transactions?

10:24 fogus`: stuartsierra: Yep. That's right

10:25 stuartsierra: So I want you to drop the "-SNAPSHOT"

10:25 LauJensen: edoloughlin: I havent built in transaction support yet - I want something similar to dosync, however you should be able to wrap your calls in clojure.contrib.sql/with-transaction for now. And no LAST_INSERTED_INDEX() is not usable in a multithreaded environment. I'll see if I can let the actual IDX be returned as metadata

10:25 stuartsierra: As soon as it hits Maven Central, that is.

10:26 fogus`: stuartsierra: I like how you dropped that last line in there so casually. :p

10:26 edoloughlin: Ok. Pretty new to Clojure, must find out about metadata now. Thanks.

10:26 stuartsierra: fogus: I keep forgetting about it, sorry.

10:26 fogus`: stuartsierra: Just playing. :-)

10:26 LauJensen: edoloughlin: Feel free to join us in #clojureql if you want more frequent updates

10:26 chouser: I'm ready when Maven Central is.

10:26 edoloughlin: Will do. See you there.

10:54 abedra: would anyone be interested in having a "pair with a core member" session on Fridays?

10:55 the idea being you are working on something in core or contrib that you would like some help on

10:55 pjstadig: do we get to choose what we work on? :)

10:55 abedra: pjstadig, yes as long as it is in contrib or core

10:55 pilot1123: hello

10:55 pjstadig: sounds like fun

10:55 abedra: pjstadig, which also means that you would have to have a signed CA

10:55 pjstadig: sure

10:55 abedra: the intent being that the work then gets pushed into the project

10:56 chouser: abedra: I think it sounds like a great idea, though I don't think I'd be likely to take advantage of it myself very often.

10:56 abedra: chouser, true, but you are already rocking

10:57 pjstadig: i hear grumblings about pet issues once in a while, perhaps pairing fridays would help people feel like their issues are being worked

10:57 abedra: chouser, the real intent is to help people get ramped up on the projects and the workflow and get settled into the patch routine

10:57 pjstadig, yes and fridays is when Clojure/core is the most accessible

10:57 pjstadig, this is certainly not something we are looking to make wildly public right now

10:58 pjstadig: understood

10:58 abedra: pjstadig, but it would be nice to give it a try a couple of times just to see how it works

10:58 pjstadig: like you said, you'd have to be a CA signer

10:58 stuartsierra: chouser: http://build.clojure.org/job/data.finger-tree/

10:59 abedra: pjstadig, and if the result is that a patch gets created, the issues is much more likely to get screened since there is a patch available

11:00 pilot1123: I'm using frm-save and frm-load from http://groups.google.com/group/clojure/browse_thread/thread/cb5246d07142a3dc?pli=1 . When I try load saved hashmap with structures I got error: No matching method found: create. In the saved file before every struct there is: #=(clojure.lang.PersistentStructMap/create {...})

11:00 chouser: stuartsierra: excellent! thanks!

11:00 pilot1123: What should I do to load this structurs?

11:00 abedra: stuartsierra, sweeeeeet

11:04 fbru02: abedra: I would love to help

11:08 stuartsierra: chosuer: finger-tree tests fail because of an `import` that uses hyphens in the package name.

11:10 fogus`: Yay. I'm all POM'd up

11:10 jsn: hey guys, total noob question

11:10 i'm trying to use gen-class

11:10 with lein swank

11:11 and just can't find the class anywhere

11:11 is there a for-dummies guide somewhere?

11:11 google has been failing me so far

11:11 bsteuber1: jsn: you need to tell leiningen to aot-compile that namespace

11:11 jsn: ok thanks

11:13 bsteuber1: jsn: so add sth. like :aot [my.ns another.ns] to your project.clj

11:14 fogus`: abedra: Late to the discussion, but yes, I would be interested one day

11:15 melipone: what's a predicate to test if something is a list or not?

11:16 tonyl: list?

11:17 Raynes: &(list? '(1 2 3))

11:17 sexpbot: ⟹ true

11:17 Raynes: &(list? [1 2 3])

11:17 sexpbot: ⟹ false

11:17 melipone: what's this ampersand for?

11:18 tonyl: for sexpbot

11:18 Raynes: sexpbot's evaluation prefix. It just tells sexpbot to evaluate the code.

11:18 melipone: cool, I didn't know about sexpbot here

11:20 tonyl: also there is ##() to evaluate

11:20 sexpbot: ⟹ ()

11:20 tonyl: like this ##(list? #{4 5 3})

11:20 sexpbot: ⟹ false

11:21 melipone: cool, how can I find a list of all predicates in clojure? I tried (find-doc "?") but that doesn't work

11:22 qbg: (apropos "?")

11:22 melipone: there's apropos in clojure too? (dance of joy)

11:23 qbg: apropos is from clojure.repl, but it is in user by default in 1.3

11:23 melipone: ah, that's why it didn't work for me

11:24 abedra: fogus`, awesone

11:25 qbg: Some CLers are hating on Clojure on reddit

11:26 So sad...

11:26 stuartsierra: So what else is new?

11:26 qbg: They made me install SBCL again to defeat their argument

11:27 I haven't needed to optimize CL code in some time

11:27 fogus`: http://knowyourmeme.com/i/000/062/355/original/Pigboots-Haters-gonna-hate.jpg?1280364642

11:27 qbg: In other news, enhanced primitive support FTW

11:28 puredanger: melipone: find-doc takes a regex so I think you'd want (find-doc "\\?")

11:28 qbg: puredanger: find-doc also searches docstrings

11:28 Probably not that useful here then

11:28 puredanger: melipone: or (find-doc #"\?")

11:29 qbg: true, it's a sledgehammer

11:29 qbg: You might get too many results

11:29 puredanger: qbg: I tried it and get you a bunch but they are almost all the actual predicates

11:29 qbg: Though I don't think ? appears much in a typical docstring...

11:29 puredanger: qbg: of which there happen to be a lot

11:31 fogus`: ,(for [[k v] (ns-map 'clojure.core) :when (re-find #"\?" (name k))] k)

11:31 clojurebot: (keyword? chunked-seq? is-annotation? instance? sequential? fn? nil? string? sorted? false? ...)

11:42 melipone: puredanger: thanks

11:42 how do I find the size of a list?

11:42 stuartsierra: `count`

11:43 melipone: stuartsierra: thanks

11:43 I didn't like clojure at first too

12:11 LauJensen: clojureql.core> (meta (conj! (table db :users) {:name "Frank" :title "Dev"}))

12:11 {:last-index 25}


12:31 Kruppe: Is there a situation to use StructMaps over records? I'm having trouble thinking of one.

12:32 chouser: Kruppe: I don't think so.

12:32 Kruppe: chouser: so StructMaps are basically obsolete?

12:32 chouser: Kruppe: I think that's right.

12:32 Raynes: Pretty much.

12:32 Kruppe: chouser: alright, thanks. That's sort of what I was thinking.

12:48 timvisher: hi all

12:50 tonyl: hello

12:50 timvisher: anyone have any opinions about whether or not it's a good idea to use a clojure data structure for maintaining a 'database' of a couple of thousand items rather than going with something like H2?

12:53 chouser: ,(time (let [db (into {} (for [i (range 5000)] [i (Math/sqrt i)]))] (db 3601)))

12:53 clojurebot: "Elapsed time: 36.778 msecs"

12:53 60.00833275470999

12:54 timvisher: perhaps some context is waranted. :)

12:55 chouser: timvisher: could be. :-)

12:56 timvisher: I've got a large collection of wallpaper. I read them in as structs/maps/records/?. Their attributes are {:file , :resolution , :tags}. Essentially I'm interested in being able to filter the collection based on :resolution and :tags.

12:56 This seems like something Clojure would be very efficient at

12:56 At the same time a DB would almost certainly be more efficient

12:57 but rather than test I was wondering if others thought this was a bad thing to even bother trying to do

13:00 I could always try both and profile

13:00 has anyone else tried this?

13:02 dakrone: timvisher: could check out datalog also for storing it if you want a db-ish thing

13:02 timvisher: partly I was thinking there'd be an ease of implementation. At the close of system I could write the contents of the seq out to a flat file and then read it in at start up.

13:02 dnolen: timvisher: DB has to deal with disk, I'd be very surprised if a DB was faster then doing thing in memory with Clojure. And I'd expect for in memory operations for Clojure to be as fast if not faster than in-memory DBs. Throw in a lot of concurrency and I think Clojure will blow those in-memory dbs away.

13:03 qbg: If there aren't that many, a seq of the maps would likely be good enough

13:04 timvisher: That was my thought. I don't think this would ever grow to more than a couple thousand

13:04 dnolen: timvisher: I would use clojure.set, you might still want to create indexes.

13:05 timvisher: My only concern would be the (File. ...) reference. I could always switch that to a path string and then coerce it into a File. whenever I needed a full-blooded reference

13:05 dnolen: could you explain that a bit further?

13:06 dnolen: timvisher: you might want faster queries on a particular property, you'll need an index in order to not have to search through everything.

13:07 timvisher: dnolen: I understand that. I was particularly interested in how clojure.set would help me with that. Reading the docs, though, I get where you're coming from. That's a good point.

13:08 replaca: timvisher: I've been building an in-memory structure to represent a 23000 bug bugzilla database with ~90000 discrete events (comments, reassignments, etc.). It does slow down a little when I do things the "dumb" way but mostly it works great. I just spit the datastructure out to a file periodically so I can reload and then I have a func that monitors bugzilla itself for new activity. Overall it works pretty well, and it's very simple

13:08 chouser: I really doubt a few thousand maps with 3 items each is going to stress anything, even with File objects in there

13:08 dnolen: timvisher: you can store the records and the indexed records in refs. Then when you add a record, you can update all the records and the indexes in a transaction.

13:08 timvisher: chouser: I don't mean for performance, I mean for the 'serialization'.

13:08 chouser: I'd be curious if even reading the directory entries was slow enough to bother you -- might might not need to maintain a separate copy of the items on disk at all

13:08 dnolen: timvisher: clojure.set has an index fn

13:09 timvisher: chouser: object references don't write out to disk in a reader friendly form right.

13:09 ?

13:09 chouser: timvisher: oh, probably not.

13:09 qbg: If you wanted to get nasty, you could serialize it

13:09 timvisher: qbg: no nastiness, please. ;)

13:10 chouser: oh, the tags aren't stored in the wallpaper files at all?

13:10 replaca: timvisher: one of the great thhings about working this way (in my app) is it's easy to write functions that think about actions in sequence (i.e., find the point in the history where the state of the bug changed so that y is true) which is hard when you're looking at individual changes

13:10 timvisher: replaca: that's an interesting report

13:10 replaca: that makes it sound like I should have no trouble whatsoever with this little endeavor

13:11 qbg: http://clojuredocs.org/clojure_core/clojure.set/index

13:11 timvisher: chouser: nope. The files are just dumb references

13:11 qbg: That is more helpful than the docstring

13:11 chouser: timvisher: I would be tempted, if I were you, to store the tags in the image files themselves.

13:12 even if they were also stored in an external db or file.

13:12 timvisher: chouser: reasoning?

13:12 guard against corruption or something?

13:13 chouser: right, less fragile. files can be renamed, moved, etc without losing their tags

13:13 timvisher: mmm

13:13 chouser: I'm not saying I recommended it necessarily, just that I'd be tempted.

13:14 I have these thoughts when dealing with photos as well, and am vaguely unhappy with all solutions.

13:14 timvisher: ultimately the goal is to have an 'iWallpaper' (*cringe*) app that maintains an app organized library of wallpaper

13:14 qbg: I wonder how much faster clojure.set/intersection would be if you did awesome tricks with the tree structure of hash sets

13:14 timvisher: so users shoudln't be down in the library messing with files.

13:15 however at some point I had the idea of also allowing user managed libraries and in that case I think you're probably right

13:16 qbg: SHA1 -> tags would be another (slower, more robust?) option

13:16 timvisher: I guess the biggest problem I'd see initially with that is that I'd be forced to read the whole file at start up somehow, rather than just loading the raw datastructure back into memory

13:16 qbg: nice idea

13:16 that could be a nice way to guard against corruption in the future

13:17 Well that gives me plenty to chew on. You guys rock. :)

13:17 If you're interested I'm mostly playing with this over [here](https://github.com/timvisher/wallpapers)

13:18 It's my first 'real' clojure project so we'll see where it goes.

13:18 chouser: qbg: that's really interesting, actually. hm...

13:18 what the world needs now is for me of all people to write a photo management app

13:19 KirinDave: chouser: The linux world, perhaps.

13:19 qbg: It would be simple in the sense that users can organize the files using anything they wish

13:19 KirinDave: Have you TRIED processing & managing RAW files on linux? It's about as simple as training a dog to scratch your back *gently*.

13:20 qbg: Apps like that in theory already exist

13:20 We had to write an app like that for kids for our software development class at my university

13:20 It was not good at all

13:21 timvisher: lol

13:22 qbg: It was also our second project using Swing

13:22 timvisher: i had played with the idea of munging this concept with something like Aperture/iPhoto but I somewhat like the idea of a library devoted just to wallpaper.

13:22 the other reason I'm doing it is because I'm attempting to have fine grained control over how and what is currently rotating on my desktop

13:22 so the library mangagement part of it is 1/2 of what I'm doing

13:22 The other goal is te be crossplatform, hense the JVM

13:39 ZabaQ: no describe, no apropos..I'm lost

13:41 dnolen: ,(doc doc)

13:41 clojurebot: "([name]); Prints documentation for a var or special form given its name"

13:41 dnolen: ,(doc find-doc)

13:41 clojurebot: "([re-string-or-pattern]); Prints documentation for any var whose documentation or name contains a match for re-string-or-pattern"

13:42 dnolen: ZabaQ: ^

13:42 ZabaQ: ah

13:48 thx

13:58 mefesto: Hey everyone. I'm trying to externalize the configuration for various parts an app im working on and would like to know if I'm heading in the wrong direction. This is the approach I'm using: https://gist.github.com/9fc92555710ac4d2b330

13:58 is that totally incorrect usage of defonce?

14:24 chouser: mefesto: you might consider making the config just an sexpr

14:25 like: {:home-dir "/home/myapp" ...}

14:25 that way you could read it without eval'ing it. Faster, less chance for abuse, though of course less flexible

14:26 mefesto: chouser: interesting. one thing that im doing, which might be totally wrong, is that i use the config namespace elsewhere so that it's the central place to look.

14:27 so in that case would i read in that expr and re-def some var in the config ns?

14:28 (def config {:home-dir "/home/myapp" ...})

14:29 for some reason i feel like im abusing namespaces :)

14:29 chouser: mefesto: yeah, you might consider that. treating the configuration as a value (a map) that can be passed around, stored, saved, recalled, etc. rather than a live, mutable, one-off namespace

14:30 but it also means you can't have code in your config, like that doto stuff you've got would have to be factored out somehow. Not sure if it's worth it in the end or not.

14:30 mefesto: do you know how people manage different configurations for, say, a ring/moustache app?

14:31 i'd imagine they'd have a similar setup to ruby on rails where there is a test, devel and prod configuration

14:31 technomancy: mefesto: read your config from the classpath

14:31 ohpauleez: mefesto: People use pallet or Chef

14:31 chouser: good libs don't depend on file layouts. :-)

14:32 you pass configuration details/functions to ring for it to use

14:32 technomancy: test config goes in dev-resources/config/whatever, default config goes in resources/config/whatever, then you can override it at deploy time with additional classpath entries

14:32 ohpauleez: that's the best answer

14:33 (chouser 's), but I like the classpath solution too

14:36 mefesto: what i'd like is to be able to distribute the jar to different servers here and run it with different configurations that could be very different from each other. Like on server1 we might want it to use a different database so at the command line something like this would be great: java -jar myapp.jar <config-file>

14:37 ohpauleez: mefesto: If you're doing different deployments, and they are true deployments, I would use Pallet or Chef

14:37 mefesto: i think for that case chouser's suggestion is the way to go.

14:37 ohpauleez: ok i'll look into those. thanks.

14:37 ohpauleez: the other option is yes, you make more functional, and take conf settings are params

14:37 mefesto: cool

14:38 raek: what is the easiest way of loading a file on the class path (e.g. using c.j.io)?

14:38 mefesto: raek: yeah i think there is a resource function in there

14:39 raek: is a "named resource" the same as a file on the classpath?

14:40 mefesto: raek: yeah something like (io/resource "com/example/app/blah.txt")

14:41 and for loading clojure code from the classpath there 'load

14:41 raek: ok, that's really simple. I wonder why I thought it was more complicated than that.

14:44 mefesto: is the ring-jetty-adapter just meant for rapid testing or is it appropriate for use in a production environment?

14:48 ohpauleez: mefesto: More for rapid development, but I've deployed it as a pool behind nginx before

14:48 for a low traffic service

14:49 depends on the demand of the production environment, and what kind of service you're putting up

14:50 mefesto: ohpauleez: i want put up a http/json service run internally for use by some of our web apps

14:51 ohpauleez: I'd either cut it over to use aleph, or if the load was low, I'd just leave it running on jetty like it is.

14:53 I personally like Jetty more than tomcat, but you see more tomcat deployments in prod

14:54 mefesto: yeah i was wanting to move to jetty but the ajp stuff seems to only work with tomcat

14:54 i did try to use mod_proxy to talk to jetty but ran into problems.

14:55 our setup is https -> apache -> mod_jk -> jboss/tomcat

14:55 trying to do: https -> apache -> mod_proxy -> jetty (http:8080) didn't workout for me :(

15:07 ugh i still can't seem to get my head around these configuration options :-\ here is a really lame example of some ring-ish code: https://gist.github.com/ca2c6bb1480411531a13

15:08 using some of the other techniques previously mentioned, how can i abstract out the config/dbspec stuff? or am i going about connection management in the wrong way with ring?

15:20 chouser: is this closer to what you were saying? https://gist.github.com/6b981042c27cacfd975a

15:21 chouser: mefesto: yeah. what do you think?

15:22 mefesto: yeah that works for me. still trying to figure out how to handle the file locations tho

15:23 chouser: thanks for the help :)

15:24 chouser: np. hope it works out well.

15:32 melipone: I'm having some problems with simple IO. here's my function: (defn printList [coll filename]

15:32 ;; scrape a url and save its content to filename

15:32 (let [out (java.io.FileWriter. filename)]

15:32 (doseq [reports coll]

15:32 (.write out report)

15:32 (.newline out))

15:32 (.close out)))


15:33 I get java.lang.IllegalArgumentException: No matching method found: write for class java.io.FileWriter (NO_SOURCE_FILE:0)

15:34 sorry, it should be: (defn printList [coll filename]

15:34 ;; scrape a url and save its content to filename

15:34 (let [out (java.io.FileWriter. filename)]

15:34 (doseq [report coll]

15:34 (.write out report)

15:34 (.newline out))

15:34 (.close out)))


15:34 bobo_: melipone: gist.github.com

15:34 qbg: use a gist please

15:34 melipone: what's a gist?

15:35 bobo_: melipone: its on http://gist.github.com

15:35 qbg: You should take a look at with-open

15:35 ,(doc with-open)

15:36 &(doc with-open)

15:36 sexpbot: ⟹ "Macro ([bindings & body]); bindings => [name init ...] Evaluates body in a try expression with names bound to the values of the inits, and a finally clause that calls (.close name) on each name in reverse order."

15:36 qbg: No clojurebot it seems

15:37 What are you passing to printList (BTW, print-list would be more idiomatic, and print-coll or print-seq might be better yet)

15:37 melipone: here's the gist: https://gist.github.com/790371

15:37 qbg: I suspect you want (str report) instead of report in the write call

15:37 melipone: ok, I like with-open because it's like Lisp

15:37 qbg: thanks

15:43 I modified my gist to use with-open but I still get the same error

15:44 qbg: Try my second suggestion

15:44 mefesto: melipone: and you are passing a string to .write ?

15:46 melipone: https://gist.github.com/f8ccca7765e204ca78f3

15:47 melipone: okay, let me try that

15:47 it's true that my doseq is not working as intended

15:48 mefesto: oops i guess there's no println on ... convert to a print writer or change to (.write out (str item))

15:50 updated:

15:50 https://gist.github.com/f8ccca7765e204ca78f3

15:53 melipone: okay, that's better

15:53 why isn't .newline working tho?

15:54 mefesto: are you using PrintWriter?

15:55 qbg: You should check out clojure.java.io/writer

15:56 melipone: it's working now with PrintWriter

15:56 mefesto: melipone: PrintWriter doesn't have a newLine method. clojure.java.io/writer returns a BufferedWriter which does have a newLine

16:16 chouser: my bases are covered. i feel much better about this setup :) https://gist.github.com/8cea49536a6288ee4d7e

16:19 pkinney: more idiomatic, and print-coll or print-seq might be better yet)

16:19 20:37 < melipone> here's the gist: https://gist.github.com/790371

16:20 (sorry, issues trying to copy + paste)

16:28 clizzin: is there a function that's like conj but guarantees addition of the item to the end of a sequence instead of possibly adding the item at the beginning of the sequence?

16:29 __name__: how do i make a multimethod that is safe for third party users of my code to add methods to? all tutorials so far suggest using a keyword for determining type, but i can collisions there.

16:29 *see possible

16:30 qbg: clizzin: Why do you need such a thing?

16:30 It would not be efficient in general

16:31 kumarshantanu: hi, is it possible to make a regular Java object to behave like a map for reading values?

16:31 mefesto: kumarshantanu: (bean obj)

16:32 kumarshantanu: mefesto -- it is not a bean I want to turn into a map

16:32 mefesto: ah

16:32 clizzin: qbg: eh, basically this is what i have right now: (clojure.string/join "-" (conj (map name fields) v)). but that puts v at the beginning of the resulting string and i want it at the end. the other way is obviously to do (str (clojure.string/join "-" (map name fields)) "-" v), but that seemed kind of unnecessarily cumbersome, plus makes me repeat the delimiter.

16:32 mefesto: kumarshantanu: so other than typical getter methods?

16:33 dnolen: __name__: namespaced keywords

16:33 ,::foo

16:33 clojurebot: :sandbox/foo

16:33 kumarshantanu: mefesto: i was wondering about extend-protocol etc

16:33 __name__: dnolen: thank you :)

16:34 dnolen: is this the way it's done by real clojurers too or am i just seeking a refugee for my oop thoughts?

16:34 qbg: clizzin: If you are only going to do it once, you could do (concat <seq> [v])

16:34 __name__: *refuge

16:34 dnolen: __name__: depends on whether you really, truly, actually need polymorphism. if you do, then you're on the right track. if you don't just use maps, way simpler.

16:35 maps and regular functions I mean.

16:35 __name__: dnolen: yes, i got that.

16:35 dnolen: clojure has somehow opened me the eyes that it is probably better to separate data from the way the data is viewed.

16:35 clizzin: qbg: nah, it's going to happen a bunch of times. i'll just use the latter method i mentioned. thanks for the help!

16:36 dnolen: clizzin: also concat

16:36 ,(concat '(1 2 3) [4])

16:36 clojurebot: (1 2 3 4)

16:37 clizzin: dnolen, qbg: isn't the concern here that it hurts performance to wrap that single value up in a vector?

16:37 qbg: It shouldn't be that expensive

16:37 dnolen: clizzin: not any more than it does trying to put something at the end of something that can't be put there quickly.

16:38 qbg: Using concat in a recursive loop will tend to be bad though because the thunks will pile up

16:39 dnolen: clizzin: if you're going for perf and you want to put something at the end might be better to replace the map with a custom fn that uses loop/recur + vector transient

16:41 clizzin: dnolen, qbg: i see. good info, thanks for the tips!

16:48 xf0: what is the best way to install clojure mode into Emacs if I already use slime with common-lisp and prefer not to use emacs starter kit?

16:49 qbg: Clone clojure-mode, put it on the load path, and require it

16:50 Also, use lein swank from leiningen for the server

16:50 Don't need to touch the slime configuration at all

16:50 mefesto: is clojure from elpa not recommended?

16:50 *clojure-mode

16:51 qbg: That would be another option

16:51 jweiss_: in terms of build/deployment (via leiningen), would it be proper for me to name a file that's valid clojure but just consists of a single data structure (no namespace) .clj and put in under src?

16:51 or should i name it .txt and put it in resources or something

16:52 i use the read function to pull this data into my program

16:52 tonyl: jweiss_: or load-file

16:52 I would put it in resources but still with a .clj suffix

16:53 qbg: Any reason why the file isn't in a namespace with a (def <name> <data-structure>) as being its contents?

16:53 Then just require/use the namespace from the places that need it?

16:54 jweiss_: qbg: the file is produced as output by another program that's not clojure

16:57 Raynes: $seen cemerick

16:57 sexpbot: cemerick was last seen quitting 21 hours and 12 minutes ago.

17:03 arkh: how do I call a function with items from a collection? e.g. (foo '(:one :two :three))

17:03 er.. instead of the above, making it (foo :one :two :three)

17:03 mefesto: arkh: (apply foo coll)

17:04 arkh: mefesto: thank you

17:08 jweiss_: anyone know why the resulting file here is empty? -> (pprint [1 2 3] (FileWriter. "/tmp/blah"))

17:09 mefesto: jweiss_: did you flush the writer?

17:09 jweiss_: mefesto: no, didn't realize i had to do that myself

17:09 mefesto: jweiss_: wrap it in a (with-open ...)

17:09 on close it should flush

17:11 jweiss_: mefesto: sweet, that did it. thanks

17:11 mefesto: np

17:18 __name__: why do the statements that use namespace data from ns not go into its body but rather as a separate expr?

17:20 amalloy: __name__: you mean, why isn't every clojure file wrapped with (ns blah (defn foo []...)...)

17:21 __name__: yes

17:21 it would allow different namespaces in one file.

17:21 amalloy: __name__: that wouldn't really be a feature :P

17:21 __name__: amalloy: i don't know.

17:22 amalloy: it's a java unfeature to only allow a class per file :)

17:22 amalloy: when you tell clojure to look up foo.bar, it has to either open up ./foo/bar.clj, or search every file in the classpath

17:22 __name__: does it not do the link upon compilation?

17:22 like java does?

17:22 amalloy: you don't have to compile clojure code until you want to run it

17:23 __name__: how does that make a difference?

17:23 it is compiled at some time …

17:24 amalloy: but the whole library isn't necessarily compiled at once

17:24 you're using foo.bar so you compile that file, and it needs foo.baz, so that gets compiled too. then later you use fdsa.fjei2 and that gets compiled

17:25 there's not any clear win for allowing multiple namespaces in a file; it'd likely be less readable most of the time

17:26 and it would make the (ns) macro way more complicated, and it would mean none of your code ever lives at the top level, which is bizarre

17:26 __name__: amalloy: thanks

17:27 amalloy: it just seemed to make more sense the other way to me

17:33 xf0: so swank-clojure doesn't contain any emacs functions anymore? you have to start swank manually and do M-x slime-connect?

17:45 zanes: Are there known issues with swank-clojure installation via ELPA?

17:45 I keep getting errors.

17:46 xf0: zanes: i had them too, that's one of the reasons i'm trying to do manual setup

17:46 I just don't understand where should I put swank-clojure files...

17:47 dnolen: zanes: xfo: use technomancy's version of package.el, don't try to do it manually.

17:47 https://github.com/technomancy/package.el

17:49 pdk: is clojure.contrib.io the preferred idiomatic means of clojure file i/o

17:49 amalloy: pdk: clojure.java.io is more standard if it has the features you need

17:52 xf0: dnolen: I think I tried package.el but my ~/.emacs.d/ became just too complex and quite a number things of things stopped working :(

17:52 dnolen: I prefer to understand what is going on in my .emacs.d

17:53 dnolen: xf0: well, getting everything setup manually is *very* hard and even harder to maintain :( good luck.

17:53 amalloy: dnolen: really? i think i set mine up manually and had no idea how to use emacs at the time

17:54 dnolen: amalloy: that's not my experience, I maintained my emacs setup for a year and a half. I also live on the cutting edge of Clojure versions, things were continually breaking. so I gave up.

17:55 mattrepl: technomancy: what's the recommended way for adding to the project classpath in lein now that eval-in-project's handler is deprecated?

17:55 amalloy: dnolen: hm, maybe not. i see that there's a ~/.emacs.d/init-clojure.el that i didn't write

17:55 dnolen: amalloy: perhaps things are better now, but I was burned too many times.

17:56 amalloy: but i don't know what that stuff is doing, because i downloaded clojure-mode to ~/opt, and added some stuff to .emacs to load clojure-mode from there

17:57 dnolen: amalloy: that's the other thing, I would continually forget exactly where things were. Exactly what things talked to each other. SLIME would break, swank would break, Clojure would break. etc. package.el all the way for me. reduce the variables and all that.

18:00 at one point I really wanted to run Common Lisp & Clojure too under Emacs, but it was too hard - LispWorks fills that gap now and all the Emacs commands work there just fine when I want to work through PAIP. Geiser/Emacs for Scheme.

18:03 zanes: dnolen: technomancy's version of package.el saved me a lot of pain. Thank you.

18:04 dnolen: zanes: np

18:27 zanes: If I installed clojure via homebrew how do I make swank-clojure aware of it? When I try to M-x slime I get: "It looks like Clojure is not installed. Install now? "

18:28 qbg: zanes: Why not use lein swank instead?

18:31 zanes: qbg: Don't I need a project for that? What if I just want a REPL?

18:34 bsteuber: zanes: (setq swank-clojure-classpath (list "path/to/clojure.jar" "contrib.jar" "swank-clojure.jar")

18:35 qbg: zanes: Yes, that is a downside.

18:35 Also, swank-clojure.el is deprecated

18:36 bsteuber: zanes: add the above to your .emacs, then M-x slime should work

18:36 at least for me it did

18:37 have to get some sleep - bye

18:39 amalloy: zanes, qbg: cake will launch a swank server from the "global project", and i know lein has a similar feature but i always need to ask technomancy how to make it happen

18:49 doubleagent: What is the preferred way to extend a class eg create a new HttpServlet?

18:49 amalloy: doubleagent: ##(doc proxy) is easiest, usually

18:49 sexpbot: ⟹ "Macro ([class-and-interfaces args & fs]); class-and-interfaces - a vector of class names args - a (possibly empty) vector of arguments to the superclass constructor. f => (name [params*] body) or (name ([params*] body) ([params+] body) ...) Expands to code which cre... http://gist.github.com/790661

19:26 raek: doubleagent: when deploying servlets, gen-class might be useful too. ring has a useful macro: http://clojuredocs.org/ring/ring.util.servlet/defservice

19:51 zakwilson: I'm having a problem wherin clojure.contrib.java-utils doesn't have as-str and hiccup needs as-str. This is with [org.clojure/clojure-contrib "1.2.0"] in leiningen and no other versions of contrib showing up in the classpath. Where should I start looking to track this down?

19:54 dnolen: zakwilson: did you try contrib 1.1.0 ?

19:55 zakwilson: dnolen: I did not. The function appears to exist in the source on github, but not in the jar: https://github.com/clojure/clojure-contrib/blob/1.2.x/src/main/clojure/clojure/contrib/java_utils.clj

19:58 dnolen: zakwilson: huh seems like it should work, isn't there a hiccup ML ?

20:00 zakwilson: If by ML you mean mailing list, I'm pretty sure there is, or a google group or some such.

20:14 dnolen: hmm, so is ISeq the most important indicator of a sequential interface for anything that is not a PersistentVector/Set/Map ?

20:14 I thought it was Sequential, but it seems to me it's really ISeq

20:16 hiredman: vectors implement Sequential, it really has nothing to do with seqs

20:16 amalloy: dnolen: (coll? x) might be what you want?

20:16 dnolen: hiredman: I know they do

20:16 but lazy seq don't

20:17 amalloy: I'm working with protocols and types.

20:18 I need to know what interface to use for sequential things that are not map/set/vector

20:18 amalloy: dnolen: and you're looking for one type that includes X, but not Y

20:18 dnolen: amalloy: exactly non-overlapping

20:18 otherwise you encounter the issue where you don't know what implementation you're gonna get with extend-type extend-protocol

20:18 hiredman: dnolen: sounds like sequential is exactly what you want

20:19 dnolen: hiredman: I have different algorithms for map/set/vector

20:19 i need map/set/vector/everything-else

20:19 amalloy: &(remove (set (mapcat (comp supers class) [#{} [] {}])) (set (mapcat (comp supers class) [() (list 1) (range)])))

20:19 sexpbot: ⟹ (clojure.lang.IReduce clojure.lang.Obj clojure.lang.ASeq clojure.lang.IPersistentList clojure.lang.ISeq)

20:20 amalloy: dnolen: not a 100% great algorithm but it looks like ISeq is your best bet?

20:20 hiredman: dnolen: do map/set/vector/sequential/seq

20:20 vectors are not ISeqs

20:21 dnolen: hiredman: but vectors are sequential, if I extend to vector and sequential one of those implementation might override the other right?

20:21 hiredman: are

20:21 oh

20:21 I didn't actually read the list and see vector there

20:22 ,(seq? '(1 2))

20:22 clojurebot: true

20:22 dnolen: amalloy: nice, I was guessing ISeq but I just wanted to hear from other folks.

20:23 amalloy: dnolen: note that my lame expr there found things "not implemented by any of set/map/vector, but implemented by *any* of list/seq" rather than *every* of list/seq

20:23 so use caution, but it's a good starting point

21:08 zanes: technomancy: Do you want bugs filed for v2 of the ESK?

22:00 ossareh: embedding a repl server into my app - should I be using nrepl or swank?

22:06 amalloy: ossareh: nrepl sounds right to me but i don't know how finished it is

22:07 tomoj: no swank support, right

22:10 any IDE support?

22:16 ossareh: amalloy: I'm going stick with swank

22:17 worked well last time I had to do this.

23:48 Eugene_: guys i am currently a CS student stuck between choose c# and java. Ultimately I want to end up coding in one of the lisps or at least scala c#

23:49 is it possible to get a job using functional languages?

23:49 and where can one get such a job

23:49 danlarkin: no

23:49 it is literally impossible

23:49 Eugene_: so what about c# vs java then

23:49 danlarkin: there is a worldwide ban on programming professionally using a functional language

23:49 Eugene_: come on im serrious : (

23:49 danlarkin: so am I

23:49 Eugene_: its so tough to figure it out not being in the industry

23:50 if that is true then the only real choices are c# and java

23:50 but that is hard to decide too

23:54 hiredman: I must confess to creating higher order functions to get code to format more prettily in emacs

Logging service provided by n01se.net