#clojure log - Mar 09 2010

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

0:00 technomancy: I think the string interpolation macro was <<

0:00 and there was talk of putting into contrib, but I don't know if it made it

0:00 hugod: thanks for the pointers, I'm looking for something to write system config files...

0:00 technomancy: http://muckandbrass.com/web/display/~cemerick/2009/12/04/String+Interpolation+in+Clojure

0:01 slyphon: technomancy: is there a "beginner's guide"?

0:01 technomancy: personally I'm biased against fleet since it was released like a couple weeks after fleetdb, which is entirely unrelated

0:01 but that's just me

0:02 slyphon: no, poor docs are definitely the #1 drawback for enlive

0:02 slyphon: technomancy: oh, i meant for lein

0:02 technomancy: slyphon: oh, sure

0:02 there's a screencast on vimeo

0:02 slyphon: i've never worked w/ java really professionally, so the whole "build thing" is a bit of a mystery

0:02 oh, ok

0:02 technomancy: clojurebot: the leiningen screencast is on full disclojure: http://vimeo.com/8934942

0:02 clojurebot: In Ordnung

0:03 technomancy: slyphon: it's pretty straightforward, I think

0:04 * slyphon watches

0:04 slyphon: it's odd, i can't *stand* ruby screencasts, but the clojure ones i don't mind nearly as much

0:06 mikem: rads: yep, that did the trick :) thanks!

0:10 technomancy: slyphon: if you think the leiningen readme could be improved I'd be up for suggestions there

0:11 slyphon: ok

0:11 technomancy: it depends on what you're trying to do, but basic dependencies and creating a jar should be pretty clear from those instructions

0:11 slyphon: one thing off the bat, it was a little confusing that the 'lein' script you download is the one you use

0:11 it's not an "install script"

0:11 technomancy: oh, is the wording confusing for that?

0:11 slyphon: i was a little confused

0:11 i thought i was downloading an install script

0:11 i mean

0:12 kudos!

0:12 that's really genius

0:12 but it's unique :)

0:12 technomancy: heh; yeah, having to download a separate script to install seems lame. =)

0:12 slyphon: :)

0:14 hiredman: gah, clojure-opennlp seems to not depend on the actual java nlp jar

0:15 and I can't find a maven repo with it

0:15 horrible

0:19 slyphon: technomancy: in that screencast the name of the project is org.clojars.sean_devlin/too-hot, what's with the "/too-hot"?

0:20 does it relate to the namespace of the project?

0:20 or rather, does it have to?

0:20 hiredman: it's just the project name with a namespace

0:20 slyphon: ah, mmkay

0:21 technomancy: slyphon: org.clojars.sean-devlin is the "groupId"

0:21 one bit of maven terminology that snuck in

0:21 but yeah, it functions like a namespace

0:21 so multiple people can publish their own copies of too-hot

0:21 slyphon: ahh

0:21 ok, makes sense

0:21 technomancy: like how github gems used to be prefixed by usernames

0:21 but actually as a first-class concept

0:21 slyphon: right on

0:21 technomancy: that should be explained better in the readme

0:25 hiredman: technomancy: does lein put all the jars in lib/ on the classpath or just the ones that map to dependencies from the project.clj?

0:26 slyphon: where do you look for maven deps?

0:27 * slyphon has *zero* experience here

0:28 hiredman: what do you mean look?

0:28 slyphon: well, you specify dependencies, how/where does maven then go and get those?

0:29 hiredman: so lein is not maven, it just uses some of mavens stuff

0:30 slyphon: uh, ok, more direct qustion then

0:30 hiredman: lein (and maven?) make a cached local repo of jars in ~/.m2/

0:30 slyphon: ah

0:30 hiredman: which is the first place it looks

0:30 slyphon: i'm using log4j, what do i do so that i don't have to have that checked into my git repo?

0:30 hiredman: then it goes to a online looking

0:31 technomancy: slyphon: there are centralized maven repos it checks

0:31 slyphon: mm'kay

0:31 technomancy: http://jarvana.com is a nice search for that

0:31 but it also checks clojars.org and build.clojure.org

0:31 slyphon: heh, clever

0:31 ok

0:32 hiredman: [log4j "1.1.3"] or something like it

0:32 slyphon: swank-clojure is available somewhere i take it?

0:35 _ato: http://clojars.org/swank-clojure

0:35 tomoj: it would be cool to have leiningen able to register some repositories to search

0:36 then index those locally and provide a lein task for searching

0:38 slyphon: can you specify alternate repos?

0:38 hiredman: yes

0:38 slyphon: i have a dependency on jboss' hornetq for a project i'm working on

0:38 i'm sorry that these are all probably really stupid basic questions

0:38 hiredman: I'd imagine that would be in maven central

0:38 slyphon: mm'kay

0:38 hiredman: which lein checks already

0:39 rhickey was asking about hornetq many moons ago

0:39 slyphon: it's good, not quite as fully-cooked as ActiveMQ but *way* less buggy

0:40 _ato: hmmm doesn't show up in jarvana search, but yeah you can add another repository, it's somehint like :repositories [[repo-name http://repo.url/goes/here]]]

0:41 slyphon: hrm, jarvana and mvnrepository.com both come up blank for org.hornetq

0:41 ah

0:41 hiredman: it's a map

0:41 slyphon: cool

0:41 it's a trap!

0:41 hiredman: {"repo" "url"}

0:42 gah

0:44 _ato: btw, if anyone ever wants a local copy of the clojars repo, I enabled an rsync daemon the other day: rsync -av clojars.org::clojars clojars-repo

0:47 tomoj: awesome

0:48 slyphon: wow, holy crap

0:49 technomancy: you're a genius

0:49 hiredman: whoops

0:49 hmmm

1:01 dakrone: hiredman: ping?

1:01 hiredman: dakrone: hello

1:02 dakrone: hiredman: saw your issue, the opennlp stuff doesn't exist in any maven library, do you know of the best way to get it available for for clojure jar?

1:03 hiredman: if you can make a pom.xml you can push into to clojars

1:04 grrr

1:04 dakrone: okay, I have almost 0 maven experience

1:04 is there an easy way to generate a pom.xml, or are they made by hand?

1:05 technomancy: dakrone: in leiningen you can just do lein pom

1:05 and it'll spit it out

1:05 dakrone: technomancy: I thought that was *only* for the clojure project, not for an already existing jar

1:05 technomancy: oh, right yeah

1:05 that just converts an existing project.clj into a pom.xml

1:06 hiredman: bleh

1:06 dakrone: yea, I have 3 dependencies, 2 of which aren't in maven repos

1:06 hiredman: java.lang.NoClassDefFoundError: opennlp/maxent/TObjectIndexHashMap (NO_SOURCE_FILE:0)

1:06 dakrone: that'd be the other one

1:06 maxent

1:06 hiredman: but the maxent jar on the classpath has that class in it

1:07 dakrone: weird

1:07 do you have trove.jar on the classpath?

1:07 hiredman: no

1:07 dakrone: that's the 3rd in lib, you should be able to get it from github

1:07 until I fix the dependency stuff

1:07 all 3 of the required jars are in the lib folder

1:07 hiredman: it comes in the zip for opennlp

1:08 dakrone: yea

1:08 same with maxent

1:08 hiredman: right, that's where I got the maxent jar that it doesn't seem to be able to find the class in

1:09 dakrone: adding trove.jar should fix it I think

1:09 hrmm... how to fix the dependency stuff :-/

1:10 technomancy: any way to push uberjars to clojars instead of just the library jar?

1:11 hiredman: ok, trove fixed it

1:11 wonderful

1:12 dakrone: cool

1:17 hiredman: tomorrow I'll work on creating poms for the missing libraries and push them to clojars, thanks for the heads up about missing them

1:17 I thought doing a lein jar would include everything in lib/

1:19 hiredman: dakrone: excellent

1:26 clojurebot: how much wood could a woodchuck chuck if a woodchuck could chuck wood?

1:26 clojurebot: That is the one thing Clojure can not do.

1:27 hiredman: clojurebot: you are very deep

1:27 clojurebot: Gabh mo leithscéal?

1:28 hiredman: clojurebot: what do you think of python?

1:29 clojurebot: python is ugly

1:29 hiredman: clojurebot: what about scheme?

1:29 clojurebot: Gabh mo leithscéal?

1:29 hiredman: hmmm

1:30 clojurebot: and scala?

1:30 clojurebot: Unfortunately the standard idiom of consuming an infinite/unbounded resource as a stream can be problematic unless you're really careful -- seen in #scala

1:33 zmila: the bot is capable to reason, not only calculate? :)

1:33 hiredman: clojurebot: what do you think?

1:33 clojurebot: Pardon?

1:33 hiredman: clojurebot: can you reason?

1:33 clojurebot: Reason is, and ought only to be the slave of the passions, and can never preted to any other office than to serve and obey them -- Hume

1:40 hiredman: hmmm

1:40 nlp thinks rhickey is an adverb

1:54 LauJensen: Morning team

2:07 nteon_: good morning

2:11 whats the best way to go about refactoring things in emacs with slime? I've been cutting and pasting code around, but when i recompile a buffer it gives me errors about unqualified symbols already referring to functions in other namespaces

2:15 LauJensen: If they're unqualified chances are that your source file is missing an (ns 'something) declaration

2:16 slyphon: swank-clojure-1.1.0 isn't available through lein?

2:16 technomancy: ^^?

2:17 nteon_: slyphon: I had to install lein as noted in the hacking section on github.

2:18 tomoj: I think swank-clojure 1.1.0 is available..

2:19 slyphon: yeah?

2:19 tomoj: oh, maybe I built it from source and did 'lein install'

2:19 slyphon: tomoj: how do you do that?

2:20 i have :dev-dependencies [[org.clojure/swank-clojure "1.1.0"]]

2:21 oh, duh

2:21 tomoj: well, swank-clojure's source project.clj is just [swank-clojure "1.1.0"]

2:21 so if you 'lein install' it that's what you'll have

2:21 slyphon: ah

2:21 cool

2:21 thanks

2:23 "Compiling swank.swank"

2:23 that needs another ".swank" i think

2:24 * slyphon thinks he's starting to get the hang of this

3:08 defn: so erm...am i crazy or wasn't clojure-contrib 1.2.0 supposed to switch duck-streams to .io?

3:08 clojure.contrib.duck-streams => clojure.contrib.io

3:08 because AFAICT it is still duck-streams

3:15 nteon_: defn: its io in git: http://github.com/richhickey/clojure-contrib/tree/master/src/main/clojure/clojure/contrib/

3:15 tomoj: last build was march 4

3:18 defn: ah

3:19 ive asked this in here a few times but i never really get any further:

3:19 Does anyone have any ideas on doing SSL based authentication via https

3:19 I want to scrape some secure https:// urls and I have not been able to figure out a decent way to do it

3:22 tomoj: that's a good question

3:23 maybe we can just sub in HttpsUrlConnection?

3:23 defn: I just don't know java well enough to navigate something I'd have trouble with in a language I actually feel comfortable with

3:24 neotyk: Hi *

3:24 tomoj: have you tried one of the available http options already?

3:24 defn: tomoj: such as?

3:24 tomoj: c.c.http.agent, clojure-http-client

3:24 defn: ive tried a few things but I could not figure out how to get it to use SSL

3:25 yeah i tried messing with those but I couldn't figure it out

3:25 tomoj: yes, neither of those look like they can do ssl

3:25 but, they both use HttpURLConnection

3:25 HttpsURLConnection is a subclass

3:25 so, I imagine it wouldn't be too hard to patch these libraries

3:25 neotyk: tomoj: I'm currently building async http client

3:25 defn: one thing someone suggested was apache-http

3:25 there was a port of it to clojure

3:25 neotyk: one that is not based on URLConn

3:25 tomoj: neotyk: great, is it on git yet?

3:25 defn: but again i couldnt figure it out

3:25 neotyk: will be tomorrow

3:25 tomoj: I need a good one

3:26 neotyk: and this one does not use thread per request

3:26 tomoj: how's it work, then?

3:26 defn: http://github.com/rnewman/clj-apache-http

3:26 neotyk: tomoj: I need good one to, and that's why I'm building this one

3:27 tomoj: defn: that looks cool

3:27 hadn't seen it before

3:27 defn: yeah apache-http is supposed to be the best

3:27 neotyk: defn: does it support streaming?

3:27 defn: i frankly have no idea

3:28 im just not familiar with all of the subtleties to know how to use it

3:28 tomoj: it says it can return a stream

3:28 or a Reader

3:28 neotyk: I'm building client that will call your provided function on new each new chunk

3:29 defn: neotyk: that'd be cool for twitter

3:29 the firehose and such

3:29 neotyk: so you can talk to ajax push service, like twitter stream api

3:29 defn: exactly :)

3:29 defn: ive been toying with mining the twitter firehose

3:30 and that is something ive been looking for -- you can also (per technomancy's suggestion), treat it as a lazyseq in combination with agents

3:30 tomoj: do you think the new geo-enabled stuff will see more users in the future?

3:30 wbruce: Can someone give me a quick pointer on how to filter a map? Essentially I'd like to get a map that's a subset of another (where all the keys/values pass a given predicate)

3:30 neotyk: tomoj: I hope so :)

3:31 hiredman: ,(into {} (filter (comp even? val) {:a 1 :b 2 :c 3 :d 4}))

3:31 clojurebot: {:b 2, :d 4}

3:32 hiredman: there is some other function

3:32 uh

3:32 ,(doc select-keys)

3:32 clojurebot: "([map keyseq]); Returns a map containing only those entries in map whose key is in keys"

3:32 wbruce: ah, ok

3:32 so use into for a custom predicate

3:32 and select-keys for a key match

3:32 (into + filter, obviously)

3:33 thanks!

3:33 tomoj: having to build it into a seq and then back into a map seems unfortunate

3:33 or is this optimized away somehow?

3:34 hiredman: into uses transients I believe

3:34 and seqs are not that expensive

3:34 tomoj: ok

3:34 and it's just a near constant factor more because you have to walk the entire map anyway

3:41 gko: Hello: do you use keywords only for hashs or do you use them instead of symbols in "data as code" ?

3:41 "only for hash maps"

3:43 nteon_: gko: what do you mean by 'in "data as code"'?

3:43 hiredman: #{:a :b :c} <- enum

3:44 you can user keywords for all kinds of things

3:44 gko: nteon_: example: (def protocol-encoding '( ... (:transaction-id (:integer 8)) ..)

3:44 nteon_: or :(def protocol-encoding '( ... (transaction-id (integer 8)) ..)

3:45 nteon_: gko: personally, in that case, I would use keywords. But I've only been using Clojure for a month, so I'm probably not the one to give a definitive answer :)

3:45 hiredman: and I'd use a map

3:46 gko: nteon_: OK. Thanks. I thought keywords are better too, especially as they print better (no NS).

3:47 hiredman: yes, definitively. just adapting something from CL.

3:48 By the way, how do you flatten a list in a list or vector outside of a macro ?

3:56 *smpp-fields*

4:01 Chousuke: gko: you can use flatten from contrib

4:01 neotyk: is it possible to: (let [abc {:a (lazy)}])

4:01 and have (lazy) part been executed only when needed?

4:01 Chousuke: neotyk: use a delay

4:01 (doc delay)

4:01 clojurebot: "([& body]); Takes a body of expressions and yields a Delay object that will invoke the body only the first time it is forced (with force), and will cache the result and return it on all subsequent force calls."

4:02 neotyk: (doc force)

4:02 clojurebot: "([x]); If x is a Delay, returns the (possibly cached) value of its expression, else returns x"

4:02 neotyk: Chousuke: thank you

4:02 Chousuke: deref (@) also works on delays :)

4:04 nteon_: hmm. does atom or ref matter for the 'state' of a gen-class class? Since its the only state, there shouldn't be a need to update anything else in a transaction, or am I missing something?

4:04 Chousuke: well, you might have a thread synchronously updating the states of several objects. :/

4:05 which would need a transaction

4:05 neotyk: ,(def m {:a delay (* 2 2)})

4:05 clojurebot: 3

4:05 neotyk: ,(def m {:a delay (* 2 2)})

4:05 clojurebot: 3

4:05 neotyk: how come?

4:05 Chousuke: huh

4:05 nteon_: Chousuke: good point. might as well use a ref

4:06 neotyk: I get Can't take value of a macro: #'clojure.core/delay

4:06 Chousuke: you need some parens :P

4:06 that map literal is illegal as it is, but that return value from clojurebot is weird :D

4:07 neotyk: ,(def m {:a (delay (* 2 2))})

4:07 clojurebot: DENIED

4:07 Chousuke: def doesn't work

4:07 neotyk: but works :)

4:07 Chousuke: you need to use let for stuff in clojurebot

4:09 gko: Chousuke: flatten: Thanks! Could I have found it (find-doc, ...) before requiring clojure.contrib.seq-utils from the REPL ?

4:12 Chousuke: gko: unfortunately, find-doc doesn't work like that :/

4:13 gko: Chousuke: :)

4:14 Chousuke: well, I think it's better it doesn't work like that, as find-doc wouldn't reflect what's currently available from the REPL...

4:40 neotyk: ,(let [m {:a (delay (do (println "Doing") (* 2 2)))}] (println "Before") (println @(m :a)) (println "After"))

4:40 clojurebot: Before Doing 4 After

4:40 neotyk: but

4:40 ,(let [m {:a (delay (do (println "Doing") (* 2 2)))}] (println "Before") (println (m :a)) (println "After"))

4:40 clojurebot: Before Doing #<Delay@f7d41f: 4> After

4:40 Chousuke: you need to deref the delay

4:40 it's not automatic

4:40 neotyk: so I always need to deref

4:41 Chousuke: yes.

4:42 neotyk: I was looking for a way to avoid execution of values of map until they are needed

4:42 client provides function that takes map

4:43 and was hoping to be able not force client to deref map values

4:44 hiredman: proxy or reify or something

4:45 neotyk: what is reify?

4:45 proxy is for java classes/ifaces\

4:45 hiredman: a better proxy

4:45 neotyk: hiredman: is it in 1.1?

4:46 hiredman: reify one of the map interfaces, mayne just ilookup and have it deref before passing out the value

4:46 hmm

4:46 I don't recall

4:48 neotyk: found it

4:48 http://kotka.de/projects/clojure/lazy-map.html

4:48 laz map

4:48 clojurebot: lazy map is http://kotka.de/projects/clojure/lazy-map.html

4:48 clojurebot: Roger.

5:14 nteon_: anyone have any idea on this? http://fpaste.org/XyVC/

5:15 nm

5:55 licoresse: ..

6:06 rrc7cz: I'm having a hard time coming up with a lazy seq of past dates. I've tried something like this: (let [cal (Calendar/getInstance)] (map #(do (.add cal (Calendar/DATE) -1) (.getTime cal)) ---)) but it seems like a kludge

6:06 nteon_: what do I use to push something onto the end of a vector?

6:07 rrc7cz: nteon_: conj

6:07 nteon_: rrc7cz: ah! thanks

6:07 rrc7cz: ,(conj [1 2] 3)

6:07 clojurebot: [1 2 3]

6:07 caljunior: is :gen-class :extends the only way to use a mixin or can I soemhow achieve this with proxy as well?

6:08 somehow

6:12 according to clojure.org: "Clojure supports the dynamic creation of objects that implement one or more interfaces and/or extend a class with the proxy macro"

6:13 I have implemented an interface now I would like to extend a class in the same proxy.

6:15 nteon_: what is the best way to debug nullpointerexceptions in clojure?

6:25 caljunior: nteon_: I just write and test all functions one by one in the REPL.

6:25 spariev: caljunior: afaik you can just add class name to the list of proxy parameters

6:26 caljunior: as simple as that?

6:26 nteon_: caljunior: thats smart. I'm not as disciplined with unit tests as I would like to be

6:26 hoeck: rrc7cz: (->> (iterate #(doto % (.add (Calendar/DATE) -1)) (Calendar/getInstance)) (map #(.getTime %)) (take 3))

6:27 rrc7cz: maybe only slightly less kludgy

6:27 spariev: caljunior: see first example (with java.io.StringReader) here - http://dishevelled.net/Tricky-uses-of-Clojure-gen-class-and-AOT-compilation.html

6:31 rrc7cz: hoeck: I like it a lot better, thanks

6:32 caljunior: thanks for the link spariev

6:33 spariev: np, it helped me a lot last week ) proxy/gen-class stuff is a bit tricky to understand

6:34 triyo: I have a list of key-val pairs (:id 123 :name "Bob" :age 29). What would be the best way to merge into a map each key-val pair? I have a set-val function that does individual key-val merger into 'nested' map so wish to call this function for each key-val pair.

6:34 spariev: triyo: try zipmap

6:35 triyo: spariev: thx I'll have a look. (First I looked at reduce and it doesn't quite fit.)

6:36 spariev: ,(apply hash-map '(:id 123 :name "Bob" :age 29))

6:36 clojurebot: {:age 29, :name "Bob", :id 123}

6:37 bsteuber: ,(zipmap '(:id :name :age) '(123 "Bob" 29))

6:37 clojurebot: {:age 29, :name "Bob", :id 123}

6:37 bsteuber: these are the two ways to go, I guess

6:38 nteon_: this is an interesting error: http://fpaste.org/4NMW/

6:39 triyo: spariev: hmm not what I was after. Sorry I don't I think I explained problem well enough.

6:39 nteon_: does anyone have any pointers?

6:42 AWizzArd: nteon_: did you put that into a source file? In that case I think Clojure can give you the line number.

6:44 spariev: triyo: ok, maybe you after something like (map #(set-val (first %) (last %)) (partition 2 [:id 123 :name "Bob" :age 29])) ?

6:44 triyo: I wish to call my function (set-val entity-inst key val) with consecutive key-value pairs that come from a list like so '(:id 123 :name "Bob" :age 29 :email "bob@xxxx.com")

6:44 nteon_: AWizzArd: I did, and it doesn't. step-fn is a function that is loaded at runtime, but I've verified it returns the correct values (a vector of 2 maps)

6:44 triyo: spariev: my result though needs to be the final map with all updated values.

6:45 so not to sure map will work

6:45 spariev: you could always wrap it with doall

6:45 AWizzArd: nteon_: If you are sure you located the problem in this function it would be best to step through it, with a debugger.

6:47 hoeck: ,(apply assoc {:a 1} '(:b 2 :c 3))

6:47 clojurebot: {:c 3, :b 2, :a 1}

6:47 hoeck: triyo: ^^

6:47 maybe you're looking for assoc?

6:47 nteon_: AWizzArd: thanks.

6:49 bsteuber: triyo: you could also use (into ...) on the stuff above

6:49 ,(into {:a 5 :d 42} (zimap [:a :b :c] [4 5 6]))

6:49 clojurebot: java.lang.Exception: Unable to resolve symbol: zimap in this context

6:49 bsteuber: ,(into {:a 5 :d 42} (zipmap [:a :b :c] [4 5 6]))

6:49 clojurebot: {:a 4, :d 42, :c 6, :b 5}

6:50 bsteuber: but yeah, if you already have a list of alternating keys and vals, assoc is your friend for updates

6:51 triyo: hoeck: my assoc / merge part is already in place in the set-val function. What I am looking for is an accumulator that will call set-val for each key-value pair and return the accumulated (updated) map

6:53 hoeck: okay, my next guess, you are looking for reduce?

6:53 triyo: so if I call first (set-val myentity :id 123) I get back {:data {:id {:val 123 :assert nil} :name {:val nil :assert}} :type person}

6:55 hoeck: yes, I tried reduce but I think I didn't feed in what its looking for correct yet.

6:56 hoeck: can you paste your code, and some expected input/output to lisppaste?

6:56 AWizzArd: triyo: either you have a map or datastructure that already supports key/value pairs, or you have a sequence that doesn't. When you don't want assoc or into, then just loop/recur over it, and use destructuring.

6:56 triyo: (reduce (fn [key val] (set-val my-entity key val)) keyvals) .. keyvals is an multi-param argument of a function so is a sequence of key-values

6:56 but that of course isnt right

6:57 hoeck: and what is my-entity?

6:57 AWizzArd: triyo: reduce will feed your fn element by element

6:57 triyo: its a data structure that holds the data-map that set-val know how to extract

6:58 hoeck: triyo: ahh, wait

6:58 AWizzArd: Destructuring won't help here if your data comes as a sequence.

6:59 hoeck: triyo: (reduce (fn [entity [key val]] (set-val entity key val)) my-entity (partition 2 keyvals))

7:00 this way, set-val is called for all key-value pairs on the updated entity consecutively

7:00 triyo: hoeck: ahh, I see this is what I had in mind a sec ago to feed in my-entity as init val

7:00 I'll give it a try

7:00 hoeck: right

7:07 nteon_: AWizzArd: my problem with that function, was that it was part of a file that was :gen-class, and the return type of the function was boolean, and ref-state was returning the updated state, which couldn't be cast to boolean

7:07 just fyi

7:08 I didn't give nearly enough context for anyone to help me figure that out

7:08 now its time for bed

7:08 night/morning

7:12 triyo: hoeck: thanks. this seems to do the job, just need to test a few more things thow. Got to go. bye.

7:58 caljunior: in follow-up to my earlier question on both implementing an interface extending a class using proxy

7:59 I use an auto-proxy macro to automatically override all interface methods.

8:00 This macro trips me up now I want to extend a class.

8:00 The macro is here: http://paste.lisp.org/+2270

8:01 I get ' java.lang.IncompatibleClassChangeError: Implementing class' exception when I simply add the extended class to the auto-proxy arguments.

8:02 I got the macro from: http://www.brool.com/index.php/snippet-automatic-proxy-creation-in-clojure

8:05 Looking for a clever way to add a mixin to this macro.

8:12 hoeck: caljunior: what do you mean with "mixin"?

8:12 if its a class you want to extend from, then you should put its name at the front of the interfaces argument of that macro

8:14 caljunior: beautiful

8:14 works like a charm. thanks. why is that?

8:15 chouser: proxy allows you to extend one concrete class and implement any number of interfaces

8:17 caljunior: right.

8:17 hoeck: because java has only single inheritance for classes, so the class arg comes first

8:18 qed: morning folks

8:19 caljunior: hoeck: thanks. wrt mixin http://en.wikipedia.org/wiki/Mixin

8:21 hoeck: caljunior: ahh, never heard the term 'mixin' in conjunction with java, now it makes more sense to me

8:32 bsteuber: ,*assert*

8:32 clojurebot: true

8:33 bsteuber: ,`*assert*

8:33 clojurebot: clojure.core/*assert*

9:03 chouser: rhickey: are you pretty sure you're going to change number handling in Clojure as you've discussed (unboxed literals, no auto-promotion)? But not til after 1.2?

9:03 Licenser_: What place do you people think clojure will take in the IT world in the future? I am curiouse what people here think, had a long discussion with a friend of mine the other day about this.

9:07 fogus: ,true

9:07 clojurebot: true

9:12 psykotic: yet another macro for "flat" keyword args that i assume everyone else has already made for themselves anyway:

9:12 http://gist.github.com/326606

9:13 * fogus drooling over http://github.com/dakrone/clojure-opennlp

9:16 psykotic: fogus: have any particular use case?

9:16 chouser: psykotic: (apply concat (map ...)) is the same as (mapcat ...)

9:17 fogus: nah, not really. Takes me back

9:17 psykotic: chouser: thanks

9:18 chouser: (apply array-map ...) is more common than (apply assoc {} ...), but I can't think of any reason yours is any worse.

9:18 psykotic: i was looking for a function like array-map, so thanks in any case

9:18 chouser: there are also hash-map, sorted-map, etc.

9:19 psykotic: (made those changes to the gist)

9:21 actually, array-map (no apply) will do

9:21 chouser: ah, right

9:21 ,(let [{:keys [a b] :or {a 1 b 2}} {:a 5}] [a b])

9:21 clojurebot: [5 2]

9:21 chouser: there's also this destructuring feature that might be helpful

9:22 psykotic: yeah, not a big fan of the repetition

9:25 actually, with more testing, neither apply array-map or array-map are correct

9:25 my assoc {} does left-to-right merging

9:25 the array-map version does it the other way, it appears

9:26 chouser: (defmacro named [kwargs defaults & body] `(let [{:keys [~@(take-nth 2 defaults)] :or ~(apply array-map defaults)} (apply array-map ~kwargs)] ~@body))

9:26 psykotic: nice. with your suggestion about map bindings, i thought you meant as a replacement for named entirely.

9:27 i don't like the 'nesting' of using maps for keyword arguments, it goes against what is otherwise clojure's preference for unnested plist-style

9:27 chouser: you're right that others have done similar things, but I've not seen the exact api you're defining. kinda nice.

9:29 I suppose the "most standard" is defnk from clojure.contrib.def ...though I don't know that I've ever used it.

9:30 psykotic: obviously my pref would be for integration with defn but this is a good stop gap and it doesn't offend my aesthetic sensibility too much

9:32 btw is there an effort underway to improve error messages, etc?

9:33 it's pretty ridiculous right now. it's gotten to the point where i'll probably get off my ass and do it myself, just to scratch my own itch.

9:33 chouser: as individual error messages are identified as egregious, patches are generally accepted.

9:35 psykotic: in this case enumerating the good rather than bad message might make for a shorter list. but i'll start keeping a list and see what i can do.

9:36 triyo: I have a seq of paramters that I need to pass on to a function as a multi param. Signature of function is (myfunc [arg1 & otherargs] ..) . How do I transform my parma list '(1 2 3 4) into 1 2 3 4 so that it can be passed on to my function as multi params?

9:36 chouser: be aware that the current compiler's implemention is on its way out, so I don't know how worth while it will be to develop patches for it for things like error messages.

9:37 tomoj: triyo: apply?

9:37 psykotic: noted

9:38 Licenser_: okay I will try if I can come up with a good sandboxing solution for clojure :) lets see if it works

9:39 * triyo is having an "of course" moment

9:39 tomoj: you can't turn '(1 2 3 4) into 1 2 3 4, but you can use apply to switch from multi-param to a single seq param

9:41 * fogus slowly breaking down the walls of Lisp-prejudice at work

9:41 tomoj: heh, me too hopefully

9:41 chouser: fogus: yay!

9:41 tomoj: my boss happened to like clojure so now he says we are a lisp shop, but no one else likes it yet

9:41 fogus: Scala is helping my cause however. ;-)

9:41 chouser: be like water. patient. gentle. relentless.

9:42 fogus: oooo. Very Zen

9:42 psykotic: except when it's stagnant pond water.

9:42 chouser: :-(

9:43 * Licenser_ likes clojur

9:43 Licenser_: ,e

9:43 clojurebot: java.lang.Exception: Unable to resolve symbol: e in this context

9:43 psykotic: chouser: an evil macro for your edification, (defmacro eager [[f & xs]] (let [syms-and-xs (zip (repeatedly gensym) xs)] `(let [~@(apply concat syms-and-xs)] (~f ~@(map first syms-and-xs)))))

9:46 triyo: I have an assertion function I need to run at macro expansion time that is passed in as a macro param. Macro of course sees this assert fn as a list data structure and not function. How do I execute the function? Eval would seem very hackish. Or am I going about this all wrong?

9:46 fogus: I have a brown-bag coming up showing one of the rhickey Vimeo vids.... any suggestions for a good start? I'm leaning towards the Clj4Java vid

9:46 tomoj: psykotic: what's the difference between that and apply?

9:47 besides the signature

9:47 psykotic: tomoj: (eager (or true (print "hello")))

9:47 tomoj: oh, I see

9:47 psykotic: it's simple shallow code walking

9:49 chouser: triyo: I think eval is the only way to get what you want, which suggest you may indeed be wanting something you shouldn't. :-)

9:50 what are the args to this assert fn that are available at macroexpand time?

9:52 defn: hi chouser i lost connection -- i was asking about irc logs earlier

9:52 chouser: any chance the #clojure irc logs are lying around in non-html format?

9:53 psykotic: is it true that the latest version of lazyseqs don't evaluate their heads until necessarily?

9:53 chouser: psykotic: you're comparing to the old lazy-cons, or something else?

9:53 psykotic: chouser: i guess the old one

9:54 ie is there no longer a 'lazyseq elements may not be forced, but at least they evaluate left to right' guarantee?

9:55 chouser: lazy-cons evaluated "rest" when you did (first s). With lazy-seq, "rest" is not evaluated until you call (rest s)

9:57 hm. is that right?

9:57 triyo: chouser: example -> (:datecreated {:init (java.util.Date.) :assert (fn [date] (instance? java.util.Date date))}) ... if the structure has the :init and :assert keys at macro expansion time, then it needs to apply the assert fn with the init value as arg.

9:58 psykotic: chouser: right now if i do (first (rest (repeatedly #(do (println "x") 42)))) i get two x's printed, so it forces first (or rather it is forced along with its containing lazy-cons-cell) on the way to the second item

9:58 but i'm not running the latest build

9:58 i was trying to reconcile that with what i read

9:59 bsteuber: user> (def x (lazy-seq (cons (do (println :hoho) 42) '())))

9:59 triyo: chouser: more accurately example of defentity macro.... (defentity person (:id) (:age {:assert (fn [id] (integer? id))}) (:datecreated {:init (java.util.Date.) :assert (fn [date] (instance? java.util.Date date))}))

9:59 bsteuber: #'user/x

9:59 user> x

9:59 chouser: oh, firsts are forced in order, if that's what you're asking.

9:59 bsteuber: (:hoho

9:59 42)

9:59 psykotic: right

9:59 good, i thought i read that they were now delayed too and only forced on 'first'

9:59 chouser: that's always been that way

9:59 psykotic: which would be a bad idea.

10:00 sorry for the dumb questions

10:01 chouser: triyo: you don't want those asserts run when real values are provided to person?

10:01 psykotic: not a problem.

10:01 triyo: ie, at runtime?

10:02 triyo: chouser: I do, you are right. However how should handle init values during the defentity step?

10:03 chouser: triyo: you want :init evaluated at runtime as well, right? You don't want the date of when that macro was expanded, but rather when the resulting code is run?

10:03 triyo: oh, you right again :)

10:04 chouser: so you're good -- no eval in sight. :-)

10:04 triyo: hmm, then it is actual runtime, no (evil)

10:04 :)

10:06 psykotic: btw, this is some code i wrote for fun after reading jshore's post about matrices to the list

10:06 http://gist.github.com/326672

10:08 the 'payoff' is the last section

10:08 chouser: btw, closures are surprisingly unprotected

10:09 psykotic: that's disturbing

10:09 chouser: hm... did it change again?

10:10 ,(.x (let [x 42] (fn [] (* x 10))))

10:10 clojurebot: 42

10:10 fogus: You mean I can't hide my trade secrets in closures?!

10:10 chouser: But that appears to be private again in master

10:11 psykotic: that's a good bit exhibitionist

10:11 chouser: I don't have 1.0 or 1.1 handy to see if they were ever public in an official release

10:12 stuartsierra: even if they were private, you could still get them out with reflection, right?

10:13 fogus: yes

10:13 psykotic: for this kind of thing, i'm not too worried

10:13 as long as it isn't flaunting itself

10:14 chouser: I was surprised the field names were so completely uncorrupted

10:14 unmunged

10:15 psykotic: munging takes work :)

10:15 even if it's as simple as prepending a few characters

10:15 heh

10:23 chouser: ,(resolve foo)

10:23 clojurebot: java.lang.Exception: Unable to resolve symbol: foo in this context

10:24 chouser: ,(resolve 'foo)

10:24 clojurebot: nil

10:24 chouser: ,(resolve 'foo.bar)

10:24 clojurebot: java.lang.ClassNotFoundException: foo.bar

10:24 chouser: should that last case really throw an exception instead of just returning nil?

10:29 stuartsierra: probably not

10:29 hoeck: the ns-resolve doc says "... ,else nil"

10:31 so I would consider the current behaviour a bug

10:34 chouser: yeah, thanks.

11:25 * defn forgets how to use lazy-seq

11:27 defn: i dont think i can use a lazy-seq due to my side effects

11:28 i have something like (def foo (file-seq (java.io.File. "path")))

11:29 (defn parser [arg] (remove (or nil? "") (map #(second (re-split #"regex" %)) (read-lines (str arg)))))

11:29 (def parsed (map parser (rest foo)))

11:29 is it possible to turn that into a lazy-seq

11:34 S11001001: defn: if you're really careful about the side-effects you can still have lazy-seqs

11:35 also, it is already a lazy seq

11:35 defn: heh yes i just realized that

11:35 methinks i got lucky with map

11:39 duncanm: hmm, when i try to use WITH-OUT-APPEND-WRITER in clojure.contrib.io, i keep on getting the "Cannot change an open stream to append mode." exception

11:40 i'm doing this (with-out-append-writer (append-writer f) (pprint ....)) - is that wrong?

11:43 stuartsierra: yes

11:43 you don't need the extra append-writer

11:44 duncanm: ahh

11:51 cljneo: hi, question about lein on windows. "lein swank" throws an exception IllegalArgumentException: no matching field found: getCommandLine for class org.apache.tools.ant.taskdefs.Java

12:14 dakrone: technomancy: ping

12:14 hah

12:59 chouser: ugh. I've got macros that expand into forms that contain macro usages, nested fairly deep.

12:59 one of the inner ones is throwing an exception.

13:00 oh, worse -- they're not real macros, but :inline fns

13:07 brandonw: is there a preference of when to use (.split "1;2;3" ";") vs (. "1;2;3" split ";") ?

13:07 cemerick: brandonw: always use (.methodname obj args) forms

13:07 that's just idiomatic -- no difference in the functionality

13:08 brandonw: so tend towards (.methodname over (. symbol methodname) just because it is closer to clojure's syntax

13:09 excellent, that is what i had already (inadvertently) started doing

13:11 cemerick: yeah, it puts the name of the thing you think you're calling in function position

13:12 adriancole_: hi clojures

13:13 I'm the jclouds guy, and I'm putting together a blog on backends that are written in clojure

13:13 if anyone has thoughts to share motivation or otherwise, please email me adrian@jclouds.org

13:13 I'll cite you in the blog and quote if you are ok with it

13:25 cemerick: adriancole_: not public yet, but will be very soon :-)

13:28 adriancole_: cemerick: cool... well love to hear your story when you can talk about it :)

13:28 cemerick: adriancole_: people generally can't shut me up once I start blabbing :-)

13:28 tomsw: I want to perform some actions in sequence, but I only know when an action has finished via an event or a callback - is there a good way to do this in clojure?

13:29 adriancole_: adriancole_: heh.. I'll keep that in mind, then :p

13:29 chouser: you can either nest the operaions inside the callbacks, each step getting deeper...

13:30 or you can use promise/deliver to block the original thread at each call.

13:31 tomsw: chouser: that sounds er promising, I'll check it out (thanks!)

13:41 chouser: btw, I'd recommend the former unless you have specific reasons it won't work.

13:48 tomsw: oh. Why? But I'm not doing anything very demanding - mainly waiting to be sure that other threads have finished doing things and fetching bits of information from them, eg an id, some content

13:50 chouser: I guess it doesn't matter too much. It's just I've occasionally had to refactor code from using promise/deliver to using nested callbacks much more often than the other way around.

13:52 hiredman: maybe you aren't promising enough

13:52 tomsw: the nesting avoids needing to mutate anything I suppose, thanks to scoping


13:52 hiredman: (repeatedly promise)

13:53 ^- why repeatedly shouldn't be deprecable

13:54 rads: what is definline used for?

13:55 chouser: repeatedly shouldn't be deprecated. replicate should.

13:55 rads: convenience macro to define a single thing that can behave either as a macro or a fn, depending on how its used.

13:56 rads: when would you need that?

13:56 hiredman: chouser: are you sure?

13:57 (that definline defined things can be used as a function)

13:57 chouser: ,(map + [1 2] [3 4])

13:57 clojurebot: (4 6)

13:57 chouser: yup

13:57 hiredman: is + defined with definline, or is the inline stuff added to the function metadata?

13:57 chouser: oh. that doesn't actually use definline does it.

13:58 hiredman: anyway, you are right

13:58 chouser: (definline plus [a b] `(+ ~a ~b))

13:58 rads: so it's like a macro that you can pass around like a function?

13:59 hiredman: chouser: in my test I called it "add"

13:59 chouser: hiredman: "add" is a better name. :-)

13:59 stuartsierra: No, it should be "plusify"

14:00 hiredman: rads: in the right circumstance it will expand the body of the function inline, sort of like a macro, instead of just emiting code to call the function

14:01 chouser: definline is pretty rarely useful in my experience. however I manually do :inline stuff rather often.

14:01 more often than I should, no doubt.

14:02 rads: what do you gain from it?

14:02 performance?

14:02 clojurebot: http://clojure.org/java_interop#toc46

14:02 chouser: yeah

14:02 hiredman: ~botsnack

14:02 clojurebot: thanks; that was delicious. (nom nom nom)

14:03 chouser: I've got some fns here that can run as much as 100x faster by doing work at compile time instead of runtime.

14:03 rads: so I guess it's not something I should worry about unless I'm optimizing

14:03 Raynes: Why was doseq named doseq?

14:03 hiredman: chouser: neat

14:03 chouser: but by using :inline instead of a macro, they can transparenly fall back to the slower code and so users can still map, apply, etc. as needed.

14:04 hiredman: Raynes: it does stuff to a seq

14:04 chouser: I'd be happy to have it renamed to something like dofor

14:04 rads: chouser: would you say it's in the same category as transients? something you don't use until you need the performance?

14:05 Raynes: I'm in a bit of an argument with a couple of people who are saying Clojure has unclear naming and are using that as an example.

14:05 chouser: rads: definitely

14:05 Raynes: I'm not sure I can argue with them at this point. :\

14:05 chouser: Raynes: 'do' takes a block of code and does it wonce

14:05 once

14:05 'doseq' takes a block of code and does it once for each item in the seq

14:06 technomancy: "do" also indicates side-effects

14:07 though I agree "dofor" might be clearer

14:07 alson_kemp: is clojure-contrib considered stable-ish? I was working on learning clojure yesterday and bumped into a number of broken bits in clojure-contrib...

14:07 "a number" -> 2 or 3 or so

14:07 stuartsierra: But "do" doesn't support all the extra options of "for"

14:07 hiredman: if that is their only example, they are just arguing with you for arguments sake, since any language you care to name as an odd name or two

14:07 stuartsierra: alson_kemp: *parts* of it are stable, most aren't

14:07 brandonw: dofor would only be clearer if you come from a background with heavy use of for loops

14:07 it is externally consistent but not internally

14:08 you can't say dofor 'does something to a for loop'

14:08 it would have to be just called 'for'

14:08 chouser: doseq supports a minilanguage nearly identical to for, so having them named similarly would be good I think

14:08 cemerick: alson_kemp: what specifically did you run into?

14:09 alson_kemp: stuartsierra : are there any docs about which parts are stable or should I expect to get VerifyErrors?

14:09 technomancy: hiredman: like "static". what on _earth_ posessed them to use that word?

14:09 static in Java, I should say. it may be used reasonably in other languages.

14:09 chouser: At times I get confused which of dorun, doseq, and doall does which and have to think of all three before I can get it straight.

14:09 stuartsierra: alson_kemp: You should never get VerifyErrors

14:09 alson_kemp: cemerik:

14:09 user=> (require 'clojure.contrib.string)

14:09 java.lang.VerifyError: class clojure.contrib.string$loading__4925__auto____106 overrides final method meta.()Lclojure/lang/IPersistentMap; (NO_SOURCE_FILE:0)

14:09 (eww... pidgin broke up that line...)

14:09 stuartsierra: alson_kemp: You've got mismatched versions.

14:10 If you're using a Clojure release, use a matching contrib release.

14:10 Raynes: What are the chances of something like that being renamed at this stage in the game? Nil, I suppose.

14:10 Would break pretty much all existing code.

14:10 Momentarily, anyways. :p

14:10 chouser: could have both names for a while, with a deprecation warning at compile-time on doseq

14:11 dunno if rhickey is at all interested in this particular one though

14:11 alson_kemp: stuartsierra: so I should use git & git versions? I'd prefer to stay closer to the bleeding edge while I'm learning (???)

14:11 brandonw: couldn't you use for or doseq, if they both have many similarities?

14:11 stuartsierra: alson_kemp: Clojure master => contrib master; Clojure 1.1 => contrib 1.1

14:12 Raynes: chouser: Oh, I'm not asking that it be renamed, I was just curious as to how something being renamed would be handled at this point.

14:12 alson_kemp: stuartsierra: got that, but would recommend staying away from head and sticking with 1.1?

14:13 stuartsierra: alson_kemp: unless you want to play with deftype/defprotocol, yes

14:13 Raynes: 'doseq' /is/ consistent, if not very clear, so I doubt rhickey would want to change it.

14:13 rads: Raynes: the read metadata macro (^) is being repurposed as the set metadata macro starting in 1.1

14:14 you just get a warning in 1.1, but in the future it will change

14:14 brandonw: i'm still not sure there is even a problem. i came from a background in procedural oop and heavy use of for, and doseq made sense when i first read it

14:14 i read about the do function first, then read the name of the doseq function, and it was pretty clear what it did

14:17 Raynes: I'm not saying it's a 'problem'.

14:17 But I can see how it might be a little unclear to the uninitiated.

14:41 hugod: is there some way of dynamically determining if &env is available in macos?

14:44 dakrone: technomancy: congrats on the new job! :)

14:44 chouser: hugod: hm, interesting.

14:45 hugod: all I can think of is to define &env in an outer scope (var or let) to a well-known value like :unavailable

14:45 hugod: then in the macro if (= &env :unavailble), you know you don't have it.

14:45 hugod: chouser: i'll give it a try, thanks

14:46 technomancy: dakrone: oh, I just got added to the commit list; it's not a job. thanks though.

14:56 Licenser: ,(def a)

14:56 clojurebot: DENIED

14:56 hugod: chouser: seems to work

14:56 rickmode: Let's say I have an in memory cache and a persistent data store in a multi-threaded application. The cache should be guarded using refs (probably one for the overall table and one for each item). How can we keep the in-memory cache consistent with the data store given that side effects such as I/O should not be done dosync? Is the best we can do saving the value of a ref and persisting after the STM transaction?

14:56 Licenser: ,(let [a (def x 1)] 1)

14:56 clojurebot: 1

14:56 Licenser: ,x

14:56 clojurebot: 1

14:57 Licenser: hiredman: I found a hole in clojurebot

14:59 rickmode: Is there another way to use thread-safe data and persistence in idiomatic Clojure?

15:01 sproust: Hi; clj newbie here, trying to setup compiling, having slightly frustrating problems.

15:01 How do I set *compile-path*?

15:01 I tried (set! *compile-path* "/a/b/v//d")

15:01 hiredman: Licenser: I am not surprised

15:01 Licenser: hiredman: I also have a fix I think :)

15:02 sproust: I cannot seem to alter the value of *compile-path*, it evaluates to the same afterwards.

15:02 cemerick: rickmode: you have to think of your refs within a transaction as a separate database -- from there, the question becomes, how do you keep two databases synchronized.

15:02 ?

15:02 sproust: (I actually use a path that exists, and the path I use _is_ in my classpath)

15:02 Any idea?

15:02 Also, this is eval'ed using slime from Emacs.

15:03 rickmode: cemerick: yes exactly. How do we keep in-memory and persistent state in sync while each has it's own transactions

15:03 wbruce: Looking to write a macro that defines a function with a given name; running into issues since defn won't work with a keyword or symbol [please forgive the contrived example]: (defmacro makefn [name] `(defn ~name [x] x))

15:03 sproust: 'compile is not happy with a "could not locate" error.

15:03 cemerick: rickmode: watches are what you fundamentally want.

15:03 hiredman: Licenser: feel free to bounce a pm off me about it

15:03 Licenser: kk

15:03 sproust: (If this is not a good place for newbie question, please let me know.)

15:04 neotyk: Hi *

15:04 dnolen: sproust: it's a great place for newbie question. *compile-path* is usually set with binding i think.

15:04 (binding [*compile-path* ...] ( ... some code ... ))

15:04 wbruce: obviously (makefn :foo) and (makefn 'foo) don't work here

15:06 sproust: Thx dnolen

15:06 The binding form works.

15:07 However I still cannot compile; I have a difficult time to diagnose why.

15:07 The directory exists.

15:07 'compile still fails with the same error: "Could not locate ..../.../ClassName__init.class on classpath

15:08 Maybe I'm not getting how this is supposed to work--searched online a lot, digged through SHalloway's book, still can't find.

15:08 cemerick: sproust: I'd strongly recommend using a build tool like clojure-maven-plugin or lein instead of compiling at the REPL

15:08 sproust: I have a (ns ... ) directory right above;

15:08 I eval that.

15:08 Then I try to compile.

15:09 If the code isn't compiled yet, how is it meant to find the files?

15:09 dnolen: sproust: you need your source directory and your classes directory on your classpath, "java -cp src:classes:clojure.jar ...". I agree with cemerick tho.

15:09 sproust: Do I really have to place the (ns ... :gen-class) in the file in the classpath?

15:09 dnolen: I'm doing everything from within Emacs, this is prototyping... I'd like to be able to eval everything.

15:10 hoeck: wbruce: but (makefn foo) will work

15:10 dnolen: sproust: dynamically changing your classpath is not supported so you can't really do that.

15:10 sproust: Setting up ant/maven just to create a class (I need to, need to override the constructor) sounds like a lot of effort for such a small thing.

15:10 dnolen: sproust: the otherway around sadly :)

15:10 sproust: Oh I don't want to change it--just want to execute my gen-class.

15:10 cemerick: sproust: well, if you're going to do it more than once, then, nope, it's not :-)

15:11 hoeck: wbruce: try (macroexpand-1 '(makefn foo)) to see what your macro does

15:11 rickmode: cemerick: looking at agent watchers... with this is is possible to build a write-behind cache, which may work in most cases. But what happens if the persistence fails? (Perhaps I am not seeing the whole picture here...)

15:11 sproust: So... wait a second; if you're just fiddling around with an idea, you can't do it with only eval from emacs?

15:11 dnolen: sproust: you can, but you want to do something special, AOT

15:11 sproust: AOT?

15:11 cemerick: sproust: you don't need to AOT-compile stuff if you're just fiddling

15:11 clojurebot: AOT genclass is http://paste.lisp.org/display/70665 and http://clojure-log.n01se.net/date/2008-11-18.html#14:19

15:12 dnolen: sproust: Ahead-Of-Time compilation. Clojure is always compiled.

15:12 cemerick: sproust: clojure code is *always* compiled. The only question is whether stably-named classfiles are generated

15:12 dnolen: I'll get out of your way now. :-)

15:12 dnolen: cemerick: no, the more the merrier :)

15:12 wbruce: hoeck: ah, true ;-)

15:12 cemerick: rickmode: If the persistence fails, then you'll have data in memory that won't make it to disk. *shrug*

15:13 sproust: Thx guys.

15:13 cemerick: STM is a database, but it's *not* durable.

15:13 wbruce: hoeck: Fromthis contrived example, I do get the following error, though (due to the parameter): java.lang.Exception: Can't use qualified name as parameter: user/x

15:13 sproust: I guess I need to find a minimal example somewhere.

15:13 hoeck: wbruce: right, then just change the x's in your macro to x#

15:13 sproust: BTW this is one of the few things that isn't explained well anywhere.

15:13 cemerick: sproust: um... http://clojure.org/compilation :-)

15:14 hoeck: wbruce: and then they expand to symbols with a unique name and without a namespace

15:14 sproust: Thx cemerick; I had seen that page, am just getting enough context now.

15:14 Tell me, is it possible to use gen-class without compiling?

15:14 rickmode: cemerick: ya... I think in the end there is an equivalent issue even with raw concurrency and persistence (as with plain java). I could simply invalidate that cache entry upon failure. Further it looks like I can use "await" so a user interface will know of the failure. Thanks!

15:14 cemerick: sproust: to do what?

15:14 sproust: I was using (proxy) but I need to override the ctor, and it seems impossible.

15:15 I'm having to derive from a class and override some methods (typical Java thing) but the ctor needs to be overridden.

15:15 That's it, basically, ; I could not do it, so I tried to use the :gen-class form and now I'm in compilation dilemma state :-)

15:16 rickmode: cemerick: ah... it's all here in "Programming Clojure" pg. 189 to 191...

15:16 cemerick: sproust: Yeah, I think gen-class is the only option for constructor requirements.

15:17 sproust: cemerick: great, but does that imply it _must_ get compiled?

15:17 (I meant: compiled to files?)

15:17 cemerick: rickmode: yeah, you've got it about right. STM is by no means a silver bullet for everything, and it does not address durability at all, so all the usual tricks, caveats, and tools apply when you need that.

15:17 wbruce: hoeck: ah, the gensym thing. thanks

15:17 sproust: In other words, is it possible to use (ns ... :gen-class) and then to instantiate that class without compiling?

15:17 wbruce: I wonder why that's necessary, since x is local

15:17 cemerick: sproust: no, gen-class is a purely AOT-compiled thing.

15:17 wbruce: (more to learn)

15:18 hoeck: wbruce: np :)

15:18 mabes: cemerick: I just read your post about using jetty + maven + compojure.. very nice. I'm wondering if you have crossed the production deployment bridge yet.. I've been looking into the options (embedded jetty, glassfish, cargo plugin, etc..) but I'm wondering if you could share any lessons learned

15:18 sproust: AWESOME. Thanks. I'll put the file in my classpath and try that.

15:18 rickmode: cemerick: We could also persist first then use STM to update the in-memory store (depends on if write-ahead or write-behind is more appropriate). I suppose an online payment might use write-ahead, while a blog could use write-behand.

15:18 hoeck: wbruce: its not, you can also use ~'x in this case

15:18 cemerick: mabes: not quite, but getting very close. I actually don't use that approach anymore -- once we added an enclojure repl server into our webapp, we just load up new code that way instead of having jetty reload.

15:19 hoeck: wbruce: but you can't have a namespace-qualified symbol as a local

15:19 wbruce: hoeck: ok, I think that makes sense to me

15:19 cemerick: rickmode: yup, your degree of durability and consistency can vary depending upon the application.

15:19 hoeck: wbruce: and `x expands to user/x by default to prevent aliasing

15:19 ,`x

15:19 clojurebot: sandbox/x

15:20 hoeck: or whatever namespace your macro is in

15:20 wbruce: right

15:20 sproust: cemerick: So now the file is found.

15:20 But I want to do interactive development, e.g. C-M-x and rerun, within Emacs.

15:21 I suppose you _do_ use (compile) to do this, no?

15:21 What's your workflow like?

15:21 hiredman: dakrone: sweet

15:21 sproust: (i.e. the most "interactive" workflow, for working with :gen-class)

15:21 dakrone: hiredman: just see I fixed the deps thing?

15:21 hiredman: dakrone: yeah

15:21 wbruce: Does anyone have any experience with benchmarking a clojure daemon's footprint on a system? Just looking for any basic idea on the minimum resource consumption I can expect (thinking about writing some system tools)

15:22 dakrone: hiredman: you mentioned using it for clojurebot, what sort of stuff are you planning on doing with it?

15:22 hiredman: I'd like clojurebot to be a better conversationalist

15:23 cemerick: sproust: once the generated classfile has been loaded into an environment, you can load the clojure bits that back it up again and again however you like.

15:23 through a repl, that is

15:24 hiredman: previously if you asked clojurebot something and it did not have a direct match it would just sort of jumble up the sentence and try to do matches on random combinations of words from the sentence

15:24 dakrone: hmm, that sounds like a cool thing to work on

15:24 hiredman: right now I have clojurebot using nlp to pull out nouns

15:25 but nlp things rhickey is an adverb :/

15:25 thinks

15:25 sproust: Hmm I see; I'm reading that you mean I could just go to the file with the :gen-class in it and C-M-x there and the values will override the ones from the class. Nice. Thanks cemerick.

15:25 dakrone: yea, unfortunately it isn't trained for things like usernames

15:26 cemerick: sproust: yes, the AOT-compiled class just delegates to whatever is defined in the (dynamically-reloadable) vars in the associated namespace.

15:28 Licenser: hmm we talked yesterday about sandboxing, so I took some effort in starting a library, so far it looks quite niceish (for a start of cause) so I ran into a not so nice situation if I 'extract' the funections from '(fn [b] (+ b 1)) I get (fn* b + b) - any idas how I can distinguish between fn*, + (which are actual funections) and b which is not?

15:28 hoeck: wbruce: jvisualvm is a good tool to measure the memory footprint of a java/clojure program

15:29 wbruce: and it is included in the sun jdk

15:29 wbruce: hoeck: thanks (again) :-)

15:29 hoeck: wbruce: np again, just sharing some experience :)

15:30 hiredman: dakrone: I don't know much (anything) about opennlp or really nlp at all, do you have any adivce for a starting point?

15:31 duncanm: can someone teach me how to use clojure.contrib.probabilities.random-number?

15:32 dakrone: hiredman: unfortunately, the documentation is really poor for a lot of it, http://alias-i.com/lingpipe/demos/tutorial/read-me.html has a lot of tutorials on the sort of stuff you can do with it, but it's for a different library altogether

15:32 if you are interested in the kinds of things you can do with NLP

15:33 hiredman: it's a start

15:33 StartsWithK: ,(loop [a 1] (case a 1 (recur 2)))

15:33 clojurebot: java.lang.Exception: Unable to resolve symbol: case in this context

15:34 hiredman: Licenser: it's like writing an interpreter, you have a set of special forms, fn* being one of them

15:34 chouser: StartsWithK: yeah, there's a thing with recur in case at the moment

15:34 StartsWithK: http://www.assembla.com/spaces/clojure/tickets/258

15:35 StartsWithK: chouser, then i can only wait :)

15:36 Licenser: hiredman: I know, fn* and + are note an issue

15:36 the issue is the 'b' since in the list it does not distinguise from + or fn*

15:38 sproust: I'm having troubles with the cwd.

15:38 hiredman: welcome to java

15:38 sproust: Is there a way to change the slime cwd from within Emacs?

15:38 I tried changing the user.dir system property.

15:38 Doesn't work.

15:38 dnolen: sproust: there's no way to do it.

15:38 hiredman: java doesn't really have the concept of a cwd

15:38 The-Kenny: sproust: I think the JVM doesn't allows this

15:38 sproust: I mean, the property gets changed, but the effect is not there.

15:39 java doesn't have a concept of cwd? It runs in a UNIX process, doesn't it?

15:39 You gotta be kidding me...

15:39 Licenser: what is cwd?

15:39 The-Kenny: Licenser: current working directory

15:39 sproust: Licenser: current working directory

15:39 Licenser: cookie weilding demons?

15:39 ah okay

15:39 raek: hmm, slime does not recognize my ns declaration (it has doc and author metadata)... how to fix?

15:39 hiredman: sproust: the jvm doesn't expose that though

15:39 sproust: hiredman: that's brilliant.

15:40 hiredman: *shrug*

15:40 sproust: So... forget relative pathnames?

15:40 How do Java programmers do?

15:40 chouser: they're just relative to where the jvm was started

15:40 sproust: Allright, I guess I'm veering off topic, I'll go dig in Google.

15:40 hoeck: Licenser: if its the first element of a list, then its a function

15:40 hiredman: you have a working directory

15:40 Licenser: hmm not nessesarily

15:40 dnolen: sproust: nope. this is why things like lein and maven are popular. cwd works if you start the REPL in _that_ directory. you can't change it tho.

15:40 hiredman: it's just not the "current" working directory because it doesn't change

15:40 Licenser: well yes but not only

15:40 hoeck: Licenser: if its the second element in a list where the first one is apply, its a function

15:41 yes, that gets complicated soon

15:41 hiredman: hoeck: but then you need to know every higher order function in advance

15:41 Licenser: can'T go by that for example: (let [good-fn bad-fn] (good-fn "rm -rf /"))

15:41 hoeck: like looking for (.invoke (fn ...))

15:41 hiredman: Licenser: if it's in the whitelist, it's a function

15:41 hoeck: Licenser: do not put bad-fn on the whitelist?

15:42 Licenser: hoeck: then I'd had to put any (not yet used symbol) on the whitenod

15:42 hoeck: and write wrapper-functions for the semi-bad ones like symbol, in-ns ..

15:42 Licenser: (let [a b] ...) b and a has to be in the white list

15:43 that is a real problem for whitelists

15:43 * triyo feeling stupid. (first my-lazy-seq) works. The take and doall, don't realize all the seq elements. Recursing the seq would work but surely there is a simple clojure way.

15:43 Licenser: whitelists are a real problem it seems

15:44 since either I've to be able to distinguise between things that are functions and things that are not or I'll have trouble with bindings

15:44 of cause I could let out let, but then there's the problem that you can't let stuff

15:45 sproust: dnolen: do you know how to tell SLIME to start from a specific dir?

15:45 dnolen: never mind if it's not at the TOYH, I'll dig.

15:45 dnolen: sproust: I use lein. You can also use maven. If you use lein you can do with this "lein swank".

15:45 Licenser: hmm one way would be to filter out things that are removed but that's trickyish

15:46 dnolen: this starts a REPL on 4005, you can connect from Emacs with M-x slime-connect, and use the defaults.

15:46 hiredman: Licenser: you have to replace let to a call to my-let

15:47 Licenser: hmm I don't quite understand hiredman o.O

15:47 hoeck: Licenser: but if there is no reference to bad-fn( because its not on the whitelist), then you don't have to find all function calls and filter them with (not bad-fn?)

15:47 or am I wrong, did I miss something?

15:47 Licenser: well whitelist as in everything in there is OK, everything not not. so if bad-fn isn't in there it fails

15:48 rickmode: dnolen: I have the same directory issue using swank-clojure-project. The current directory seems to be a bit random. Sometimes its the directory of the project, and sometimes not (I haven't figured out why). Using lein swank works solidly though.

15:49 hiredman: you replace any calls to things you want to allow, but can't trust you replace with calls to wrappers

15:49 hoeck: Licenser: right, the whitelist would be probably 75% of clojure.core, and some wrappers to maybe-bad but necessary functions

15:49 hiredman: and some special forms

15:50 sproust: dnolen: thanks. Sounds like a lot of technology. I like it simple. I killed all my inferior/superior repl's, M-x cd MYDIRECTORY, then M-x slime, and it worked.

15:50 hiredman: swaping out special forms may get tricky

15:50 sproust: I guess SLIME inherits the directory of its parent process, in this case Emacs.

15:50 I hope this is recorded somewhere, will be useful to others!

15:50 dnolen: sproust: nice! good to now.

15:51 hoeck: hiredman: which special forms have to be swapped out?

15:51 sproust: "How to change the slime current working directory (cwd)." There. That should get Google hooked up.

15:51 hiredman: hoeck: well we were talking about let

15:51 bsteuber: hiredman: didn't you recently try to have M-x slime use the new clojure version?

15:51 Licenser: hiredman: I am note exactly sure why I should wrap anything it does not interfeers with problems like a not being defined

15:51 hoeck: def?

15:51 sproust: :-)

15:51 clojurebot: deftype is see datatype

15:51 neotyk: is lazy map the way to do lazy maps and why it is not in clojars?

15:51 hiredman: bsteuber: sorry I wasn't paying attention to your thread, whats going on?

15:52 sproust: IT WORKS. I'm so excited. I'm going to liberate a large codebase of questionable java with Clojure! Yeah!!

15:52 bsteuber: hiredman: don't worry, that's been the start of it =)

15:52 hiredman: I grapped the swank-clojure src, and jared it up without compiling it

15:52 and then makde the jars in .swank-clojure symbolic links to whatever

15:53 sproust: Whoah... it generates _many_ .class files...

15:53 hiredman: sure

15:53 bsteuber: hiredman: thx, I'll try that

15:53 neotyk: clojurebot: lazy map

15:53 clojurebot: lazy map is http://kotka.de/projects/clojure/lazy-map.html

15:53 Scriptor: is there any advantage to having the & and the parameter following it be separate in the params vector? why not just do &other_params ?

15:53 neotyk: is that lazy map a way to do lazy maps?

15:54 The-Kenny: Looks like this page is a bit outdated, as it mentions lazy-cons

15:54 hiredman: yeah

15:54 it's old

15:55 neotyk: you can just use proxy or similar

15:55 hoeck: neotyk: it is, though its not really 1.2-ish, it was written in the ancient clojure-1.0 days, or even before

15:56 Licenser: *hrm*

15:57 hiredman: Licenser: it may just be easier to write an actually interpreter

15:57 Licenser: hiredman: I fear you might be right, which is scaryish

15:58 hiredman: a lisp interpreter in lisp is not hard

15:59 Licenser__: gnaw disconnect

15:59 hiredman: a lisp interpreter in lisp is not hard

15:59 it's maybe a single multimethod?

15:59 Licenser__: +c :Waves

16:00 sproust: Is there a way to access the 'this' pointer from within a constructor?

16:00 (Using gen-class)

16:01 hiredman: I didn't think you could generate a constructor using gen-class

16:02 neotyk: hiredman, hoeck would using proxy be more 1.2-ish?

16:02 sproust: hiredman: isn't it just the :init optional arg?

16:02 That's what I'm using; it calls it.

16:02 cemerick: hiredman: I believe the ctor is fixed; the :init is a post-ctor init hook.

16:02 hiredman: neotyk: 1.2 ish would be reify or deftype

16:03 hoeck: neotyk: deftype would be the #1 option for implementing it

16:03 nowadays

16:03 hiredman: sproust: have you looked at post-init?

16:03 sproust: hiredman: will do right away.

16:04 (frantically juggling google, emacs and xchat)

16:04 hoeck: neotyk: but its safe to use, its in no-way deprecated and you use it mostly through the normal map interfaces (it inherits from APersistentMap)

16:04 neotyk: is it known that if in java you have package local class with public methods and you use class that is public that subclasses previous one you have problems in clojure 1.1 with accessing public method of packege local class?

16:05 triyo: can it be that a LazySeq elements cannot be fully realized using something like doall? But for example first and last functions work?

16:05 neotyk: hoeck: and that is exaclty hat i want, normal map interface, only lazy

16:05 s/hat/what/

16:05 hiredman: neotyk: if you put a hint in the right place it should work

16:06 neotyk: hiredman: do tell

16:06 hoeck: right, you won't even notize if lazymap changed its implementation from gen-class to deftype except for the build-process :)

16:06 hiredman: well, as long has you have an interface you can hint with

16:07 neotyk: I forget exactly, but this (or similar arising from the same issue) has come up

16:07 sproust: hiredman: :post-init works, but I had to kill and restart my slime.

16:07 No amount of evaluation or compiling made a difference.

16:08 Kill process, restart, and voila.

16:08 hiredman: sproust: you will have to restart the jvm anytime you compile

16:08 sproust: Oh...

16:08 hiredman: (so don't)

16:08 sproust: I see.

16:08 This is VERY useful information.

16:08 Someone, somewhere, should write a compendium of this. Maybe I'll start a text file.

16:09 hiredman: because compilation generates a stable classname, and java doesn't have built in class reloading

16:09 sproust: you can change implementations of methods on the fly though

16:09 sproust: Great.

16:09 hiredman: but changes to :gen-class options, and additional methods, that kind of stuff will need a recompile

16:10 neotyk: hiredman: thanks, so I will not bother with reporting it

16:10 hiredman: I forget what the resolution was, I think it might have just been a limitation of reflection

16:11 sproust: Allright, another one: -init does not take a this ptr; -post-init does. I have another method, it doesn't. How do I access the this ptr from that method?

16:11 The "implicitness of this" seems very different between proxy and gen-class.

16:12 chouser: -init doesn't take a this because the object doesn't exist yet at that point.

16:13 hiredman: sproust: the first argument to the functions implementing a method is this

16:13 sproust: Aaaah never mind I got it.

16:13 (My bad; I happened to have a single arg.)

16:13 hiredman: I wouldn't go hog wiled on gen-class though

16:13 wild

16:15 sproust: (println) invokes .toString() automatiaclly; is there another function to avoid this, e.g. like __repr__ in Python?

16:15 hiredman: gen-class is the most painful corner of clojure you can wedge yourself into without much benefit

16:15 sproust: what do you want to be printed?

16:15 neotyk: don't know how to hint it

16:16 (let [rb (RequestBuilder. RequestType/GET)] (.setUrl rb "url"))

16:16 sproust: I'm asking, because I noticed that getting one of the base Java class' properties when I print them I get an empty string, and was expecting it would expose them as atoms.

16:16 ... which it does: I can (set!) on them, but then I expected #<Atom: ... >

16:16 neotyk: RequestBuilder inherits from RequestBuilderBase that is package local

16:16 hiredman: sproust: you have to wrap it in an atom

16:16 set! does not work on atoms

16:16 neotyk: and I get Can't call public method of non-public class: public com.ning.http.client.RequestBuilderBase com.ning.http.client.RequestBuilderBase.setUrl(java.lang.String)

16:17 duncanm: i have a list like this [[x1 y1] [x2 y2] ....] and i want to make that into a double [][], what's the right call?

16:17 neotyk: how do I hint it?

16:17 hiredman: neotyk: you have to find a suitable interface or superclass with that method

16:17 sproust: What's the proper method of modifying the base class' property?

16:17 (set!) ?

16:17 it's a var I guess...

16:17 hiredman: no

16:17 it's a field

16:18 neotyk: RequestBuilder extends RequestBuilderBase

16:18 RB i spublic

16:18 RBB is package local

16:18 what is suitable superclass?

16:18 hiredman: anything above RequestBuilderBase?

16:19 neotyk: like (let [rb (RequestBuilder. RequestType/GET)]

16:19 RB is above

16:19 hiredman: no, I mean in the class hierarchy

16:20 neotyk: why clojure tries to access RBB.setUrl directly ?

16:20 public class RequestBuilder extends RequestBuilderBase

16:20 abstract class RequestBuilderBase

16:21 has setUrl method

16:21 abstract class RequestBuilderBase has public setUrl method

16:23 hiredman: uh

16:23 sproust: hiredman: I'm looking everywhere for a field... set! seems to work, but SH's book says it's evil; I print the type, says it's a java.lang.String (when I access it via (.fieldName this)). Is there a guide somewhere for accessing java properties?

16:23 hiredman: whoever wrote RequestBuilderBase doesn't understand genercs

16:24 sproust: if you look at the gen-class examples they usually put an atom in the field

16:24 that type is the runtime type of the field

16:24 the field can hold any Object

16:25 triyo: I have (throw (AssertionError. (str "errors: " errors))) which outputs errors: clojure.lang.LazySeq@79be0545. If I print errors seq outside of the throw call, it prints fine.Do I have to do something special here?

16:26 sproust: hiredman: but if I replace the field, won't the java code that uses this barf out when it tries to use the java.lang.String interface?

16:26 hiredman: triyo: the .toString method on lazy-seqs returns a string like that, and str calls t.toString

16:26 sproust: that depends on the field

16:27 neotyk: hiredman: very unlikely, but still my problem stands as it was

16:27 hiredman: I was assuming you were talking about the .state field

16:27 neotyk: the code is full of "(T)this" with @SuppressWarnings("unchecked")

16:28 triyo: hiredman: ahh, so its the str thats calling .toString on each param. Thanks.

16:28 hiredman: you can't cast wtih java generics

16:28 triyo: you need to use pr-str

16:28 neotyk: hiredman: ok, how about my error :)

16:28 triyo: ,(doc pr-str)

16:28 clojurebot: "([& xs]); pr to a string, returning it"

16:29 hiredman: neotyk: very sketchy (I know this doesn't help, but I noticed while trying to find the javadocs)

16:30 neotyk: clojurebot: where do you keep history?

16:30 clojurebot: Pardon?

16:30 neotyk: clojurebot: what is brain?

16:30 clojurebot: brain dump is http://clj.thelastcitadel.com/clojurebot

16:30 hiredman: clojurebot: please give us logs

16:30 clojurebot: logs is http://clojure-log.n01se.net/

16:30 neotyk: thans

16:30 thanks

16:31 sproust: Is there a way to invoke the superclass' method from a method in a gen-class?

16:31 bsteuber: hiredman: I updated slime's clojure in a different way

16:31 I've used (setq swank-clojure-classpath (list "path/to/clojure.jar" ...)) in my .emacs

16:31 that seems to do the job

16:33 hiredman: bsteuber: I would watch out because your AOT compiled swank might not be binary compatible with version of clojure other than what it was built with

16:33 sproust: :expose or maybe :expose-methods

16:33 sproust: checkout the api docs for gen-class

16:34 sproust: hiredman: thanks; I'll print that, a lot of the secrets seem to be in there.

16:35 bsteuber: hiredman: thx for the warning, I have to watch out when things go wrong

16:36 but also with non-compiled jar's you might prefer swank-clojure-classpath over symlinks I guess

16:37 raek: anyone have a solution for slime not understanding ns declarations with metadata?

16:37 hiredman: bsteuber: well the issue is the clojure part of swank

16:37 raek: what do you mean?

16:38 technomancy: raek: hugod just committed a fix for that a few days ago; try the latest git version

16:38 raek: if i write the ns decl as (ns #^{...} foo), slime still does not change namespace when evaluating the file

16:38 technomancy: ah, thanks! I will check it out

16:39 technomancy: raek: also be aware that you don't need to use that syntax just to add a docstring

16:39 just putting a string after the ns name will make it a docstring

16:39 raek: ah, ok

16:39 technomancy: you only need that syntax if you want arbitrary metadata

16:39 little-known fact!

16:39 raek: that would solve my current problem

16:40 bsteuber: technomancy: is this a new feature? because I think I've tried it before without success

16:40 raek: I added author info, but that is not crucial now, since i'm the only one working on it

16:40 technomancy: bsteuber: quite new

16:40 bsteuber: i see

16:40 technomancy: yeah, author metadata can be gotten from git

16:40 raek: is it in slime or in swank-clojure?

16:41 technomancy: raek: swank-clojure.el

16:41 hugod: i didn't realise either, until after fixing swank-clojure

16:41 bsteuber: btw. is there a reason why def doesn't allow docstrings?

16:42 tomsw: sorry, more newbie questions - what is the best way to poll something until it changes? At the moment I'm using a separate thread that repeatedly sleeps until the has changed, then calls a callback. But I think it sucks

16:42 arohner: bsteuber: check out clojure.contrib.def

16:43 chouser: tomsw: polling in general kinda sucks. are you sure you need to?

16:43 bsteuber: arohner: I know about that, but I dislike defvar's docstring are after the value

16:43 hiredman: neotyk: actually there is some skepticism in ##java that the code in question will actually compile

16:43 bsteuber: I already hated this in CL :)

16:44 Licenser: hmm nicer

16:44 neotyk: hiredman: not only it does compile it also runs

16:44 bsteuber: but still I wonder why it can't be added to core/def

16:44 hiredman: (def #^{:doc "foo"} a 1)

16:45 bsteuber: hiredman: sure, but I'd prefer (def a "foo" 1)

16:46 tomsw: chouser: i'm scripting a Java (Eclipse RCP) application, a lot of things I'm waiting for are closed boxes

16:48 StartsWithK: case can't match a value of enum?

16:48 bsteuber: so if noone has a good reason why simple docstring can't be added to def, I'll file a ticket

16:48 miltondsilva: isn't there a fn to return the diff between seqs?

16:49 hiredman: StartsWithK: has to be a literal

16:49 miltondsilva: I know there is one for sets.. but why not for all seqs?

16:49 chouser: StartsWithK: I've seen that, yes.

16:49 Licenser: what is the best way to say 'every second element from an seq'?

16:50 chouser: ,(take-nth 2 (range 10))

16:50 clojurebot: (0 2 4 6 8)

16:50 Licenser: weeh!

16:50 thanks

16:50 tomsw: chouser: so to cut a long story short the most reliable way I have of knowing if my automation script can start performing actions on something is to check the cursor. So maybe my problem isn't not knowing how to poll...

16:51 hiredman: :(

16:51 busy loops

16:52 ,(doc while)

16:52 clojurebot: "([test & body]); Repeatedly executes body while test expression is true. Presumes some side-effect will cause test to become false/nil. Returns nil"

16:52 chouser: or a thread-pool-scheduling thing

16:53 dakrone: is there a 2-way map data structure where I can do something like (:foo {:foo "blah"}) => "blah" *and* (get {:foo "blah"} "blah") => :foo ?

16:53 alson_kemp: is clojurescript dead? Or just lying fallow?

16:54 chouser: alson_kemp: hibernating until clojure-in-clojure is done

16:58 triyo: in emacs my clojure-mode tabbed-indentation are looking huge. How do you guys deal with this, if at all?

16:58 some that is

17:02 bsteuber: triyo: while some things could be nicer, I'm quite happy with clojure-mode as it is - especially toghether with paredit

17:02 oh, it is about tabs? I use spaces everywhere

17:03 triyo: I see, I'll need to experiment a bit.

17:04 bsteuber: so does clojure-mode insert tabs? or do you have code from other editors?

17:05 powr-toc: miltondsilva: Just turn your seq into a set... (intersection (set seq-a) (set seq-b))

17:05 triyo: I actually think its spaces its just I guess where I'm braking lines and my lists are getting deep so it goes quite far to the right with a massive whitespace on the left.

17:06 miltondsilva: powr-toc: but what if they are nested?

17:06 triyo: its starting to look silly

17:06 bsteuber: you mean like

17:06 (some-long-name x

17:06 y)

17:06 ?

17:06 powr-toc: miltondsilva: then use tree-seq

17:07 bsteuber: miltondsilva: what kind of diff algorithm do you want? something tricky for versioning?

17:08 miltondsilva: no I have something like ((6 8) (2 8) ...) and then something like ((1 2) (6 8)...) and want to return ((2 8) (1 2) ..)

17:09 triyo: bsteuber: yes, exactly

17:09 hiredman: miltondsilva: you can't do that lazily

17:09 speak of the devil

17:09 bsteuber: :)

17:11 miltondsilva: hiredman: hmmm... I'm extremely inexperienced with the lazy-seq concept.. but how did you reached such a conclusion so quickly?

17:12 powr-toc: miltondsilva: are they nested at the same depth, or is it a tree?

17:12 hiredman: miltondsilva: you'd have to walk all of sequence a before you could determine that an element of sequence b was in it

17:12 miltondsilva: powr-toc: nested at the same level

17:12 Licenser: woohoo!

17:12 I think I got it!

17:12 bsteuber: ,(clojure.set/difference (set '((6 8) (2 8))) (set '((1 2) (6 8))))

17:12 clojurebot: #{(2 8)}

17:12 bsteuber: you could start from here

17:13 powr-toc: miltondsilva: then just map ehash-set over the sequence and intersect

17:14 bsteuber: triyo: I played with my line-breaking style and now I'm quite okay

17:14 Licenser: bsteuber, hiredman if you'd like to take a peak here is what I came up with for the problem of extracting functions

17:15 miltondsilva: bsteuber: ohh... thanks, I was having some troubles doing that.. they werent at the same level and I hadn't noticed

17:15 triyo: bsteuber: think I'm gonna have to do some playing around too.

17:16 bsteuber: licenser: nice, I'm studying your code right now

17:16 Licenser: :)

17:18 hmm little bugs still in there :(

17:20 there we go, fixed

17:21 bsteuber: licenser:I guess fn-seq should also skip maps, not just vectors - right?

17:22 Licenser: hmm hmm?

17:22 fn-seq?

17:22 but on a nother note, you're quite right, I forgot to handle maps and vectros

17:23 bsteuber: line 15:

17:23 (filter #(and (ifn? %) (not (vector? %))) (s-seq form)))

17:24 so you skip vectors but not maps - but I guess it doesn't matter as they are never equal to your functions :)

17:25 hiredman: ,(doc fn?)

17:25 clojurebot: "([x]); Returns true if x implements Fn, i.e. is an object created via fn."

17:25 bsteuber: oh, ic

17:25 so why is there a check to vector? then?

17:25 hiredman: ifn? and fn? are no the same

17:26 bsteuber: oh, now I get it

17:26 so it's (filter ifn? (s-seq form))

17:28 Licenser: hiredman, bsteuber http://gist.github.com/327199 <-is the new code

17:28 the tree-seq does not work, you don't have enough controle over the matter

17:30 ,{1 1}

17:30 clojurebot: {1 1}

17:30 Licenser: ,{1 (def y 1)}

17:30 clojurebot: DENIED

17:31 Licenser: ah nice :)

18:07 neotyk: how do I comment on issue in assembla?

18:09 hiredman: I believe you have to send in a CA

18:10 neotyk: even to comment?

18:10 boy oh boy

18:11 hiredman: from what I understand you have to be a member of the space comment

18:11 to

18:11 and to be a member you need a CA

18:11 neotyk: will have to sign another CA than

18:11 hiredman: I could be wrong, I haven't used assembla much

18:12 neotyk: #259 should be linked with #126 as example

18:15 hiredman: done

18:15 mabes: what is the recommended way to have/use custom exceptions? I created one with gen-class but according to this, now year old, post that may not be the best route: http://groups.google.com/group/clojure/browse_thread/thread/fae67b5494578baf/006579290248352c?lnk=gst&q=custom+exception#006579290248352c

18:15 would deftype be a better way of dealing with custom exceptions now?

18:15 Chousuke: If assembla doesn't allow watchers to comment, then I suppose you need to bring it up on the group.

18:16 S11001001: mabes: I'm a fan of clojure.contrib.condition

18:16 Chousuke: mabes: I don't think deftype even allows defining exceptions. :/

18:16 mabes: I think the most clojurey solution would simply be not to throw any custom exceptions :P

18:17 mabes: Chousuke: as long as you implement Throwable I would think you would be okay (I haven't done anything with deftype though so I don't know what I'm talking about)

18:17 Chousuke: mabes: is Throwable an interface though? :/

18:17 _ato: it's a class

18:17 mabes: ah

18:17 * mabes looks up clojure.contrib.condition

18:19 mabes: Chousuke: what would the clojurey solution be like exactly? I started down the path of having hash maps returned with the key :errors but the control flow was becoming unruly

18:20 hiredman: mabes: why do you need to throw a custom exception though?

18:22 mabes: hiredman: it may not be the best solution so I'm open to alternatives.. right now I have something that validates some data (coming from a web API), transforms it, and the processes it. If anything goes wrong in the validating or transforming I want to give back helpful messages to the client.

18:23 hiredman: ok, and why does that need custom exceptions?

18:23 ,(.getMessage (Exception. "such and such failed"))

18:23 clojurebot: "such and such failed"

18:23 neotyk: hiredman: thank you

18:24 mabes: sure, but what if I want to have more custom data that doesn't make sense to stuff it in the string.. i.e. the HTTP response code

18:25 hiredman: mabes: well that is sepperate from the concern of showing a message to users

18:25 Chousuke: I don't like the proliferation of exception types. hm...

18:26 hiredman: getting different http responses is hardly an exceptional situation

18:26 Chousuke: There should be a ClojureException which can hold a map of arbitrary data :P

18:26 mabes: Also, the issue with doing a blanket catch of just Exception is that I may be catching unintended errors. I prefer that any unexpected exceptions bubble up where I have another middleware catching those and handling them appropriately (logging and sending alerts)

18:26 Licenser: good night my lispy friends!

18:27 hiredman: *shrug*

18:27 Chousuke: returning a map of {:error foo} from the functions is not necessarily a bad approach if you manage to structure the error checking in a way that makes sense.

18:27 dakrone: good evening Licenser

18:27 mabes: hiredman: agreed WRT it not being an exceptional situation.. I have been going back and forth. When I try using normal flow control it just seems messier.

18:28 hiredman: mabes: use trampolines and pass and error handling function

18:28 an

18:28 Licenser: hiredman: and thank you for all your advice :)

18:28 hiredman: Licenser: thank you for catching that hole in de-fang

18:29 Licenser: ^^

18:29 hiredman: pass an error

18:29 Chousuke: maybe instead of explicit error checking you could simply code up some monadic structure that allows you compose functions so that error cases are handled properly :P

18:29 mabes: do you know of some code (i.e. on github) that uses that approach so I can get a better idea of how that would work?

18:30 hiredman: not really, trampoline doesn't seem to be used often

18:30 mabes: ok, so it seems like the best/standrd approach would be to have the functions return a map with :error in it then.. correct?

18:30 hiredman: are you familiar with trampolines?

18:30 :/

18:31 mabes: no, I remember reading about them in stuart's book but I haven't used them

18:32 hiredman: clojurebot: tco is <reply>yes please

18:32 clojurebot: Ack. Ack.

18:32 hiredman: clojurebot: do you want tco?

18:32 clojurebot: yes please

18:32 Chousuke: mabes: in a way, a parse error is a valid result from a parser so I think yes :P

18:34 mabes: Chousuke: I guess the angst I'm feeling is that in Java that parse error would be in the form of an exception. That may be more of a result of it's static typing though..

18:42 zkim: Quick question: In the following snippet: http://clojure.pastebin.com/uQf5JnsE I'm trying to get the varargs passed through to my-func-1 without being wrapped in a list a second time. Can anybody help me out on how to accomplish this?

18:50 jsanders: zkim: You can do it with a macro http://clojure.pastebin.com/EVfnT3pQ - might be a better way, but that way works

18:51 zkim: jsanders: thanks, will do

18:59 jsanders: question: what is a good way to define a function with a dynamic name, in a string for instance

18:59 I have this macro - #

18:59 (defmacro defn-with-str [name args & body] `(defn ~(symbol name) ~args ~@body))

19:00 which works, if the first argument is a literal string

19:00 but not if it is a symbol that is defined to be a string

19:00 http://clojure.pastebin.com/YKwTGpph

19:21 arohner: jsanders: you'll have to control evaluation in your macro

19:24 jsanders: right, but I can't seem to figure out how to do so

19:24 arohner: you'll probably want something like (defmacro defn-with-expr [expr args & body] (let [val expr] `(defn ~val ~args ~@body))

19:24 note that the let is before the `, so the part inside the let is evaluated at compile time

19:24 and then the output is stuck in the defn call

19:25 if you want it to be evaluated at run time, you'll have to generate a let statement:

19:27 jsanders: yeah i went down the let route a bit, but it gives the same results, although i must say i don't understand why

19:27 ,(defmacro defn-with-expr [expr args & body] (let [val expr] `(defn ~val ~args ~@body)))

19:27 clojurebot: DENIED

19:28 jsanders: oh, oops

19:29 it seems that the let should evaluate expr first, but it does not seem to

19:30 arohner: oh right, the macro doesn't evaluate its arguments. so the let has to be generated

19:32 jsanders: right but then it is too late - because I need the the value of (symbol expr) at expansion time, so the let can't be generated

19:35 arohner: this works, but it's icky:

19:35 (let [val (eval expr)] (assert (symbol? val)) `(defn ~val ~args ~@body))

19:36 jsanders: it's not *so* icky

19:37 and it does have the whole "working" thing going for it

19:37 is there no better way for macros to force evaluation of their arguments than a direct call to eval

19:40 arohner: putting the arguments in a let is the typical way to do it

19:40 I have another idea, one sec

19:41 jsanders: ok - btw, that failed in the case of a string - but this works for what i was going for

19:41 (defmacro defn-with-expr [expr args & body] (let [val (symbol (eval expr))] (assert (symbol? val)) `(defn ~val ~args ~@body)))

22:32 slyphon: anyone used "cascade"?

22:56 nteon: so lein is broken for me, and google pointed me at this (identical) paste: http://pastebin.com/HN9HJ0Aq

22:56 tomoj: nteon: I saw that the other day

22:56 or something like it

22:57 what's in your project.clj?

22:57 and have you tried 'lein clean && lein deps'

22:57 nteon: tomoj: doesn't seem to matter; happens in my home directory and my lein project clone just typing 'lein'

22:57 tomoj: ^

22:58 tomoj: ah, I think cleaning out maven fixed something similar for me the other day, I will try that

22:58 tomoj: oh, hmm

22:58 that is odd

22:59 nteon: tomoj: yea, that fixed it

22:59 tomoj: what'd you do exactly?

22:59 remove stuff from your ~/.m2 ?

22:59 nteon: tomoj: cd ~/.m2/repository; rm -rf *

23:00 then

23:00 lein-stable self-install

23:00 tomoj: odd, wonder what the problem was

23:02 nteon: tomoj: lein for me is symlinked to the bin/lein in my clone of the lein repo, that lein is suppose to pull all its deps from its lib folder. having that work after deleting the jars in the m2 repo suggests it was pulling stuff from the maven repository and clashing, somehow

23:02 thats my best guess

23:04 ah ha!

23:04 I can reproduce.

23:05 tomoj: is that a bug, then?

23:07 nteon: having clojure 1.1.0 in maven (but not 1.1.0-master-SNAPSHOT) causes lein to break

23:08 tomoj: hmm

23:08 only on edge lein?

23:09 I just removed 1.1.0-master-SNAPSHOT, now I have 1.1.0 and 1.2.0-master-SNAPSHOT, but 'lein help' from my homedir works fine

23:09 but I'm using stable lein

23:16 nteon: tomoj: maybe it was having both 1.1.0 and 1.1.0-master-SNAPSHOT

23:17 kylesmith: is anyone successfully using leiningen for native dependencies?

23:17 tomoj: but, that was working too :)

23:18 kylesmith: there's a plugin for that

23:18 schizm: gr

23:18 tomoj: kylesmith: see for example http://wiki.github.com/ztellman/penumbra/getting-started

23:18 schizm: [20:17:51][wf:.../projects/vimclojure]> java -cp ../clojure/clojure-1.1.0/clojure.jar:../clojure/clojure-contrib-1.1.0/clojure-contrib.jar:build/vimclojure.jar com.martiansoftwar

23:18 e.NGServer

23:18 kylesmith: yes, I have the plugin, and it downloaded all the files perfectly, but it didn't put them on java.library.path

23:18 schizm: it can never find the com/martiansoftware/NGServer with that

23:18 yet all of those jars are there

23:19 tomoj: kylesmith: ah, hmm

23:19 nteon: tomoj: doesn't work with 1.1.0 and not -master-SNAPSHOT. so whatever reason, my setup is dieffferent from yours :)

23:19 tomoj: kylesmith: you ran lein native-deps?

23:19 kylesmith: tomoj: yep

23:19 tomoj: it seemed to work fine for me for penumbra, with lein swank. dunno anything about it, really, though, sorry

23:20 psykotic: does the #(... % ...) syntax support varargs? i.e. i want the equivalent of (fn [& args] ...)

23:21 schizm: woah, trippy...if I just include the vimclojure.jar it works, if I include any of the clojure.jars it fails

23:21 'works' as in I assume it won't when firing it up in VIM

23:21 anyone have vimclojure in cygwin/windows working?

23:22 tomoj: that sounds like fun

23:22 schizm: :)

23:22 tomoj: psykotic: I don't think so.. how would you refer to them?

23:22 #(... %args ...) ?

23:22 psykotic: tomoj: or some other % symbol

23:22 tomoj: interesting idea

23:23 aha

23:23 ,'#(%&)

23:23 clojurebot: (fn* [& rest__4221] (rest__4221))

23:24 tomoj: never knew that

23:24 psykotic: nice

23:24 kylesmith: tomoj: I figured it out. I had [[native-deps "1.0.0"]] under the regular dependencies, rather than dev dependencies. Perhaps that should give an error message?

23:24 tomoj: kylesmith: perhaps :)

23:24 I have no idea how it works

23:24 psykotic: ,(#(+ %&) 1 2 3)

23:24 clojurebot: java.lang.ClassCastException

23:24 psykotic: ,(#(apply + %&) 1 2 3)

23:24 clojurebot: 6

23:24 psykotic: there we go

23:25 ,(#(do [%1 %&]) 1 2 3)

23:25 clojurebot: [1 (2 3)]

23:25 kylesmith: okay, next library: does clojuratica work with leiningen yet?

23:25 tomoj: oh wow

23:25 that do trick is neat

23:25 not sure whether I like it

23:26 I usually resort to fn at that point

23:26 psykotic: well, the alternative is fn. you can't do "bare" #

23:26 tomoj: yeah, it's neat

23:27 psykotic: even with this, i think i still prefer my $ alias for partial, since i don't have to spell out apply when i'm partial-ing with multiple arguments remaining

23:28 e.g. ($ + 2 3) vs #(apply + [2 3] %&)

23:29 i'm doing some things where i'm using -> for a pipeline, and all the functions in the pipeline are partially applied, so spelling out 'partial' constantly is making the code extremely ugly

23:30 tomoj: that sounds strange

23:30 psykotic: it's for monads

23:30 schizm: so noone has done vimclojure in windows?

23:30 that makes me sad

23:30 tomoj: you mean like (-> foo (partial x y z)) ?

23:30 psykotic: maybe i'll find a better way to write it, but i'd rather not build special syntax

23:30 schizm: I just want to try clojure out :(

23:30 clojurebot: Clojure ranked #21 on 8/14/2009

23:30 tomoj: that looks weird

23:30 psykotic: tomoj: yes, except the pipeline is generally much longer, etc

23:31 using the $ makes the name of the function that does the work more visible

23:31 tomoj: so, the partially applied functions return more functions?

23:31 psykotic: also, it's reminiscent of haskell's $

23:31 no

23:31 savanni: schizm: I have done vimclojure, but not anything advanced and not on Windows.

23:31 psykotic: a partially applied function is itself a function awaiting the remaining arguments before it invokes the original

23:31 tomoj: psykotic: my confusion is that, in (-> foo (partial x y z)), it seems to me that this is not (x y z foo), but (foo x y z)

23:31 schizm: savanni: tks

23:32 can't get the damn vim leader to fire anything off, just fails

23:32 sigh

23:32 tomoj: er, (partial foo x y z) I suppose

23:33 savanni: schizm: "fire anything off"? Are you referring to the Nailgun system?

23:33 tomoj: so in (-> foo (partial x y z) (partial a b c)), you've got (partial (partial foo x y z) a b c)

23:33 which looks... strange to me

23:33 schizm: savanni: the leader simply takes me into the mode s puts me in, (leader-sr)

23:33 psykotic: yeah i think you're right

23:33 schizm: ie. nothing happens

23:33 psykotic: anyway, thanks for the %& tip, looks like you learned about that too :)

23:33 schizm: it's unfortunate this has to be so difficult :/

23:34 tomoj: schizm: yep :(

23:34 psykotic: tomoj: btw, i think what i wanted was ->>

23:34 tomoj: but, the reason it's easy for me is because people have put in work making it easy for my platform :)

23:34 psykotic: ah, that makes more sense to me

23:34 psykotic: this why i won't need partial application

23:34 *way

23:34 ->> is SO close to being like haskell's do notation

23:35 savanni: huh... I actually don't know what the leader is. But I only have syntax hilighting, rainbow parenthesis, and indent working.

23:35 psykotic: all it needs is support for :let for binding intermediate function call results to names

23:35 savanni: And all of that is on Linux.

23:35 schizm: savanni: the vim leader, for special modes

23:35 usually \, mine is remapped to ,

23:35 savanni: *OH*

23:35 schizm: ala: Open a REPL within Vim by typing \sr (or <local-leader>sr; the default local leader is the back slash )

23:38 savanni: rainbow matching, etc all works

23:38 it's the REPL within VIM That I kinda wanted

23:40 savanni: Yeah, I can't help with that. I never actually tried to make it work.

23:58 psykotic: is there a good reason for why the seq function isn't a multimethod that defaults to the current behavior for collections but otherwise allows, say, class-based dispatching, so you don't have to called all those class-specific *-seq functions for java classes?

Logging service provided by n01se.net