#clojure log - Jun 29 2010

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

1:13 itistoday: ,(map #(.toString %) (seq (.listFiles (File. ".") (reify FilenameFilter (accept [f s] (not (.startsWith s ".")))))))

1:13 clojurebot: java.lang.IllegalArgumentException: Unable to resolve classname: File

1:14 itistoday: ,(map #(.toString %) (seq (.listFiles (java.io.File. ".") (reify java.io.FilenameFilter (accept [f s] (not (.startsWith s ".")))))))

1:14 clojurebot: java.lang.IllegalArgumentException: Can't define method not in interfaces: accept

1:14 itistoday: ok, why does that happen?

1:14 it works with proxy

1:15 here's a simpler version:

1:15 ,(seq (.list (java.io.File. ".") (reify java.io.FilenameFilter (accept [f s] (not (.startsWith s "."))))))

1:15 clojurebot: java.lang.IllegalArgumentException: Can't define method not in interfaces: accept

1:15 itistoday: ,(seq (.list (java.io.File. ".") (proxy [java.io.FilenameFilter] [] (accept [f s] (not (.startsWith s "."))))))

1:15 clojurebot: java.lang.RuntimeException: java.lang.IllegalStateException: Var null/null is unbound.

1:16 itistoday: well, the proxy version works on my machine, clojurebot probably blocks file access

1:17 ,reify

1:17 clojurebot: java.lang.Exception: Can't take value of a macro: #'clojure.core/reify

1:17 itistoday: ,(doc reify)

1:17 clojurebot: "([& opts+specs]); reify is a macro with the following structure: (reify options* specs*) Currently there are no options. Each spec consists of the protocol or interface name followed by zero or more method bodies: protocol-or-interface-or-Object (methodName [args*] body)* Methods should be supplied for all methods of the desired protocol(s) and interface(s). You can also define overrides for methods of Object. Note that a

2:23 LauJensen: Morning all

2:26 ,(seq (.list (java.io.File. ".") (reify java.io.FilenameFilter (accept [_ f s] (not (.startsWith s "."))))))

2:26 clojurebot: java.security.AccessControlException: access denied (java.io.FilePermission . read)

2:26 LauJensen: $mail itistoday You forgot the explicit this argument: (seq (.list (java.io.File. ".") (reify java.io.FilenameFilter (accept [_ f s] (not (.startsWith s "."))))))

2:26 sexpbot: Message saved.

9:01 jfields: is there a way to make a function globally available? Say I want to make fnil (http://groups.google.com/group/clojure/msg/f251cfd9baab440a) available everywhere without putting a :use in every namespace, how would I do that?

9:07 chouser: jfields: patch clojure.core

9:11 lpetit: jfields: or place it in your own clojure.patch namespace, and bootstrap your clojure.patch namespace early in your project. Then from everywhere you can access it via normal fully qualified namespace resolution: clojure.patch/fnil . This will have the added benefit of being able to easily spot where you introduced such "patches".

9:12 jfields: thanks chouser and lpetit

9:12 lpetit: chouser: is it too late to make comments on early chapters of your book ?

9:12 chouser: lpetit: not at all

9:14 lpetit: chouser: I've just read chapter 2, and some things made me uneasy. I'll try to review it again (didn't take notes, was on the car during traffic jams) and share my thoughts with you.

9:14 uneasy may not be the appropriate term.

9:14 chouser: lpetit: that would be great, thanks!

9:15 lpetit: HTH

9:17 jfields: lpetit, is there a blog entry or something you can point me at that shows how to " bootstrap your clojure.patch namespace early in your project"

9:18 lpetit: jfields: :/

9:18 jfields: I'll take that as a no :)

9:19 lpetit: jfields: do you have some "entry point namespace" already ? :/

9:19 jfields: I'm not using lein, I'm just starting a simple app from ant

9:19 yes, i do

9:20 lpetit: jfields: then maybe just placing a (:refer 'clojure.patch) in the top of this "entry point namespace" should suffice

9:20 * lpetit is not totally sure what he is suggesting makes total sense

9:21 jfields: lpetit, cool, I'll look into :refer, I haven't ever seen that before. thanks.

9:22 chouser: if foo.bar/my-global is acceptible for getting to it from everywhere, you should be able to add -i foo.bar to your clojure.main command-line to get it loaded early enough

9:22 lpetit: jfields: refer is in charge of "loading" the namespace in the clojure environment, while keeping the current namespace intact (not creating any new mapping)

9:22 chouser: yes !

9:24 jfields: okay, thanks lpetit and chouser, I'll try that stuff out.

9:24 chouser: refer only bring in vars of namespaces that have already been loaded

9:26 rhickey: ,(clojure-version)

9:26 clojurebot: "1.2.0-master-SNAPSHOT"

9:26 rhickey: (doc fnil)

9:26 clojurebot: "([f x] [f x y] [f x y z]); Takes a function f, and returns a function that calls f, replacing a nil first argument to f with the supplied value x. Higher arity versions can replace arguments in the second and third positions (y, z). Note that the function f can take any number of arguments, not just the one(s) being nil-patched."

9:28 * chouser drowns in n00b thread

9:29 shoover: chouser: look at my agent thread instead. it's much easier

9:30 lpetit: jfields: my bad. As chouser pointed out, it's not refer you must just, but just plain old require

9:30 shoover: chouser: and by easier, I mean I want your opinion

9:31 lpetit: s/must just/must use/g

9:31 sexpbot: lpetit: Format is sed [-<user name>] s/<regexp>/<replacement>/ Try $help sed

9:31 lpetit: s/must just/must use/

9:31 sexpbot: s/must use/must use/g

9:31 lpetit: grmlml

9:31 chouser: shoover: shorter but stickier :-)

9:32 shoover: chouser: that's debatable, but I take your point

9:32 chouser: shoover: thanks for reminding me aobout it though. I read it but didn't have the time to look into it before.

9:33 shoover: chouser: no problem

9:34 chouser: ok, I'm thinking it's unintentional. The action has failed, so I can't think of any problem with now doing a send.

9:35 shoover: I figured. It was mentioned in the wiki, but then so was "not a promise of a feature..."

9:37 It get stickier when I realize my handler fn has the wrong number of arguments and that gets eaten too. I suppose that train has to stop somewhere, though, and I can't expect that to bubble up

9:39 chouser: yeah, unfortunately errors in error handlers have to be explicitly ignored.

9:42 ok, I think I have a fix.

9:43 shoover: that's better than an opinion! I'll take it!

9:43 chouser: rhickey: do you agree that sends should be allowed from agent error handlers?

9:43 the current behavior is to collect them as "nested" sends in the agent, and the silently throw them away.

9:44 rhickey: chouser: dunno, I'm always reluctant to see people try to use agents instead of queues

9:45 but not a real reason to prohibit

9:48 chouser: but you have to be extremely careful not to open a reentrancy hole in trying to support them

9:50 chouser: oh. ugh, you're right.

9:50 shoover: rhickey: in the queue setup you would have a queue in a ref and some other thread actively pulling from the queue?

9:50 chouser: no, wait I'm not seeing the race yet.

9:52 shoover: probably a blocking queue that the error-handler pushes on

9:53 rhickey: shoover: no, use a regular concurrent queue or message queue

9:53 chouser: shoover: and one or more threads sitting blocked on popping from the queue

9:53 shoover: right, but with just agents you don't need the sitting blocked thing

9:54 chouser: rhickey: so I've got a naive patch here, which if it has a race I'm not seeing it. May I make a ticket? Against 1.2?

9:54 dsop: hmm how to define a service in compojure 0.0.4 similar to (defservice?

9:54 rhickey: chouser: sure, thanks

9:58 yacin: how can i access a file, inside a 'lein uberjar' jar from within clojure?

10:04 pjstadig: I'm getting a OOME PermGen space

10:04 my hunch is because of a (eval (read-string "...")) that I'm doing

10:05 dsop: yacin: there is something like URL url = this.getClass().getResource("/hello.jpg"); in java, so you have to use this in clojure code I guess

10:05 pjstadig: is that an incorrect hunch?

10:06 in a cursory glance at the compiler i didn't see it generating any classes in the code path i'm taking

10:07 Chousuke: pjstadig: eval generates a class dynamically IIRC. did you enable class garbage collection?

10:07 pjstadig: Chousuke: how do i do that?

10:07 Chousuke: not sure. it's some -XX option to the JVM

10:08 pjstadig: hmm

10:08 Chousuke: or -X I suppose

10:08 hm

10:09 chouser: shoover: http://www.assembla.com/spaces/clojure/tickets/390

10:09 shoover: chouser: thanks for getting into it

10:09 Chousuke: chouser: you know more about permgen errors than I do, right? :P

10:09 pjstadig: http://bit.ly/cAdF5t made me think that PermGen shouldn't be so much an issue...but there is no mention of eval

10:10 i had assumed that eval generates classes, but like i said i couldn't see it doing that in the path i take through the compiler

10:10 chouser: Chousuke: maybe not :-/

10:11 pjstadig: eval will create at least one class, but I think it does so with a separate classloader

10:11 this means that once let go of all references to the object(s) in the eval, that class and its classloader will be GC'd

10:12 pjstadig: right

10:12 rhickey: chouser: that patch is unlikely to fly unless accompanied by a thorough analysis of its impact, else you are just putting that on the committer

10:13 chouser: rhickey: ok

10:13 pjstadig: i'm read-string'ing a call to a function, then evaling that, and i'm not holding on to any reference that i know of

10:20 rhickey: pjstadig: what does the string look like?

10:21 pjstadig: "(the-function-im-calling #=(clojure.lang.PersistentArrayMap/create {:some "keywords" :and "strings}))"

10:22 if i try to recreate it on a smaller scale I get a "GC overhead limit exceeded" OOME instead of a permgen

10:30 rhickey: pjstadig: got a gist of that?

10:31 pjstadig: https://gist.github.com/a977b8acde92665683b1

10:32 rhickey: pjstadig: not the string, the smaller scale test that gives you OOME

10:33 pjstadig: oh hehe

10:33 sure

10:33 Chousuke: pjstadig: that's not a proper string either :P you didn't escape the quotes and one is missing

10:33 pjstadig: sheesh! tough crowd :)

10:37 https://gist.github.com/9185dca57057102d765a

10:38 i'm running this on a jvm with a 20mb

10:38 so as not to take forever to fail

11:00 hugod: is the lack of a : in the ns import clause in clojure.contrib.find-namespaces deliberate?

11:01 rhickey: pjstadig: how long does it take to fail for you?

11:02 pjstadig: rhickey: hmm...i didn't time it exactly, but it feels like no more than 5-10 minutes

11:07 rhickey: pjstadig: ok, I see it here

11:24 arohner: I'm trying to daemonize a clojure process on OSX, and I'm getting this exception:

11:24 clojure.lang.Compiler$CompilerException: java.lang.InternalError: Can't start the AWT because Java was started on the first thread. Make sure StartOnFirstThread is not specified in your application's Info.plist or on the command line (core.clj:19)

11:25 does anyone have a decent explanation for what's going on?

11:36 pjstadig: rhickey: does it even make sense to think that eval is generating classes, thus leading to the PermGen? or is that a totally erroneous idea?

11:38 rhickey: pjstadig: you can be running out of memory due to another leak, not sure PermGen is driving the leakage

11:39 pjstadig: so it may not even be clojure...could be some other component?

11:40 but isn't the PermGen a fixed space that shouldn't be affected by other heap partitions? or is it more dynamic?

11:50 arohner: another clojure daemon question. The apache-commons-daemon library says to not spawn threads while the JVM has root privileges. When are the clojure thread pools created?

11:52 in Agent.java, there's a line final public static ExecutorService pooledExecutor = executors.newFixedThreadPool(...). Does that spawn new threads when it runs?

11:58 hiredman: arohner: clojure doesn't run as root unless you run the jvm as root

11:59 arohner: hiredman: right. but when starting a daemon that needs to write a pid in say, /var/run, commons daemon says start the JVM as root, then it will drop privileges

11:59 hiredman: the jvm does not have any ability to fork as a different user or switch users

11:59 arohner: but apache commons daemon does

12:00 hiredman: it does trickery

12:00 but it does not do that

12:00 arohner: hiredman: doesn't do what? drop privileges?

12:01 hiredman: http://commons.apache.org/daemon/jsvc.html#How_jsvc_works

12:02 ick

12:13 danlarkin: arohner: might just be easier to have a bash script fork/exec into you

12:13 then it's easy to trap signals, close file descriptors, etc

12:14 arohner: danlarkin: I'm already most of the way into http://github.com/arohner/lein-daemon

12:14 danlarkin: doesn't the commons daemon library handle most of that?

12:15 danlarkin: arohner: never used it... probablyy it does. But if I were going to write clojure code intended for daemonizing I'd deal with the messy bits in shell and leave java blissfully unaware

12:16 or use daemontools or something

12:17 which is time-tested rock solid

12:17 who knows about this apache commons daemonizer thing

12:35 ckirkendall: arhoner: did you try -Djava.awt.headless=true, I believe the issue has to do with AWT needing to communicate in xwindows on mac.

13:51 Licenser: fogus: you're there

13:58 arkh: defn: ping

14:12 jcromartie: pong

14:18 bhenry: if i do (with-connection db

14:18   (with-query-results rs ["select * from blogs"]

14:18     ; rs will be a sequence of maps,

14:18     ; one for each record in the result set.

14:18     (dorun (map #(println (:title %)) rs))))

14:18 from http://en.wikibooks.org/wiki/Clojure_Programming/Examples/JDBC_Examples how can i get rs into something i can use later instead of only having the side effects of println in the dorun?

14:18 clojurebot: PONG!

14:19 thorstadt: bhenry: yes, you should be able to do a doall, doseq, etc.

14:20 as long as you force the evaluation completely before you are outside of with-query-results

14:20 bhenry: nice thanks.

14:24 (doall rs) worked wonderfully

14:25 thorstadt: awesome, glad to help :-)

14:31 hugod: defrecord seems to get very confused by (require ... :reload-all)

14:38 BMeph: What do folks here use for an editor?

14:39 chouser: emacs, vim, various IDEs

14:41 mtopolnik: hi

14:42 a noob here, let me introduce myself

14:42 i work in zagreb, croatia for a firm that uses clojure in production

14:42 one of the lucky few around here :)

14:43 i would like to know if there's a way in clojure to call a java method by name that is not known in advance

14:44 lancepantz: man, i would love to go to croatia

14:44 looks like a beautiful place

14:44 mtopolnik: something like (eval (list (symbol ".setTime") (java.util.Date.) 23423424))

14:44 chouser: mtopolnik: there is

14:45 mtopolnik: lancepantz: it's lovely here, true :) at the seaside, as well as in the mountains

14:45 ckirkendall: BMeph: eclipse counterclockwise

14:45 chouser: mtopolnik: one way is to use clojure.lang.Reflector, but eval can perform better if you can cache its results

14:45 mtopolnik: the above code will fail because an object cannot be embedded in code

14:46 qbg: ,(clojure.lang.Reflector/invokeInstanceMethod "123" "length")

14:46 clojurebot: java.lang.IllegalArgumentException: No matching method: invokeInstanceMethod

14:47 chouser: that is, if the same method will be called multiple times, you can build a function on-the-fly (costing some time) that will call the method, but then subsequent calls through that generated function will be very fast.

14:47 qbg: ,(clojure.lang.Reflector/invokeInstanceMethod "123" "length" nil)

14:47 clojurebot: java.lang.NullPointerException

14:47 qbg: ,(clojure.lang.Reflector/invokeInstanceMethod "123" "length" (make-array 0))

14:47 clojurebot: java.lang.IllegalArgumentException: Wrong number of args (1) passed to: core$make-array

14:47 jkkramer: ,(clojure.lang.Reflector/invokeInstanceMember "123" "length")

14:47 clojurebot: 3

14:48 qbg: ,(clojure.lang.Reflector/invokeInstanceMethod "123" "length" (to-array nil))

14:48 clojurebot: 3

14:48 mtopolnik: i need this to transform a clojure map into java beans, so there will be no repeated calls

14:48 but speed is not a high priority here

14:48 thanks, I think this will do it for me

14:49 right now i have a solution that uses java reflection api

14:49 it's not as elegant as this

14:49 chouser: ,(let [d (java.util.Date.)] (clojure.lang.Reflector/invokeInstanceMethod d "setTime" (to-array [23423424])) d)

14:49 clojurebot: #<Date Wed Dec 31 22:30:23 PST 1969>

14:50 mtopolnik: so, Reflector needs an array of method args?

14:50 chouser: this is probably about 30 or 40 times slower than calling through a regular function

14:50 mtopolnik: just like java reflection

14:50 chouser: mtopolnik: yes

14:51 mtopolnik: so, using java reflection would probably be speedier

14:51 but i don't think this is a major factor, really

14:51 chouser: only slightly speedier, if at all.

14:51 mtopolnik: i'm calling out to axis2

14:51 chouser: that's just how slow Java reflection is in my experience.

14:52 mtopolnik: making a soap call will surely dwarf any time spent preparing the java bean for the call

14:53 chouser: :-)

14:53 mtopolnik: using Reflector is simpler because i dont' need to know the exact arg type of the method

14:53 right now i deduce that by examining the getter

14:53 obviously, that's even slower code

14:54 chouser: well, that's probably what Reflector is doing for you

14:54 mtopolnik: yes, and what i expected a form like ((symbol ".setTime") d 23234) to do

14:55 chouser: but of course that doesn't work

14:55 mtopolnik: sure

14:55 chouser: because .setTime is not a real function, it's a reader macro that expands to (. d setTime 23234), and . is a special form

14:56 mtopolnik: it cannot be made to work even with eval

14:56 Chousuke: hmm

14:56 ,'(.foo)

14:56 clojurebot: java.lang.IllegalArgumentException: Malformed member expression, expecting (.member target ...)

14:56 chouser: that's not quite true

14:56 mtopolnik: either form would be fine for me

14:56 (. method) or (.method)

14:57 but i couldn't make either work

14:57 chouser: reflection is probably faster than using eval to generate the call and then calling it.

14:57 mtopolnik: you can make eval understand the (.method) part

14:57 chouser: yes

14:57 mtopolnik: but i cannot refer to an object in a form given to eval

14:57 chouser: right, you'd have to pass that in

14:57 mtopolnik: except if it's a global symbol

14:57 Chousuke: chouser: looks like .foo is not a reader macro

14:58 pretty weird.

14:58 Licenser: chouser: are you the second JoC guy?

14:58 Chousuke: or did I just test it wrong.

14:58 chouser: ,`(.valueOf 5)

14:58 clojurebot: (.valueOf 5)

14:58 chouser: hm

14:58 Licenser: yep

14:58 Chousuke: I suppose the compiler checks for those

14:58 so clojure has an infinite number of special forms ;P

14:59 well, except java method names probably have some limits

14:59 chouser: oh right, not quite a reader macro

14:59 ,(macroexpand `(.valueOf 5))

14:59 clojurebot: (. 5 valueOf)

14:59 chouser: it's expanded after reader macros but before regular macros. :-)

14:59 or something

15:00 mtopolnik: related to this, here's what i was playing with:

15:00 Licenser: chouser: I#ve a very very big wish for you :)

15:00 mtopolnik: user> (eval (list (fn [] 1)))

15:00 1

15:00 user> (let [b 1] (eval (list (fn [] b))))

15:00 ; Evaluation aborted.

15:00 ; No matching ctor found for class user$eval__10973$fn__10975

15:00 user> (let [b (fn [] 1)] (eval (list b)))

15:00 1

15:00 user> (defn bb [] (let [b (fn [] 1)] (eval (list b))))

15:00 #'user/bb

15:00 user> (bb)

15:00 ; Evaluation aborted

15:00 ; java.lang.ClassNotFoundException: user$bb__10946$b__10948

15:00 Licenser: can you convice the pdf compiling guys to make the pdf indexed with a TOC so that I can use it on an iPad nicely?

15:01 mtopolnik: from these examples i can see that there's a problem with eval and lambdas

15:01 they don't get on eval's classpath

15:01 and i wanted to use a lambda to encapsulate my objects

15:02 chouser: (let [m ".setTime" d (java.util.Date.)] ((eval `(fn [a# b#] (~(symbol m) a# b#))) d 23423424) d)

15:03 Licenser: your MEAP doesn't have an expandable outline? I'm pretty sure mine does.

15:03 technomancy: chouser: the review copy doesn't

15:03 Licenser: *hecks on the computer*

15:04 mtopolnik: chouser: wow, that's some pretty nice code!

15:05 chouser: technomancy: :-(

15:05 Licenser: chouser: I didn't computer but not on the iPad I'm not sure what the differences are but I know it works on the iPad since i got it for other pdf's (non books)

15:05 technomancy: chouser: reviewers can tough it out. =)

15:05 mtopolnik: so you use eval only to produce the lambda!

15:05 technomancy: I got it all concatenated and loaded into my kindle easily enough.

15:06 chouser: mtopolnik: yes. Add some type hints and that lambda will call the method without any runtime reflection, making if very fast

15:06 mtopolnik: thanks, chouser, i think this is a winner!

15:06 chouser: `(fn [^java.util.Date a# b#] ...)

15:07 mtopolnik: i won't be able to do that as my code will walk through a map and generate java setter calls from that

15:07 chouser: mtopolnik: but note if you just throw away the lambda returned by eval each time, it's likely much slower (and more likely to have PermGen issues) than if you just use Reflector.

15:07 mtopolnik: so i don't know the types

15:07 hm... PermGen issues would be a problem

15:08 chouser: oh. well, then I'd probably recommend Reflector. Without type hints, the code eval generates just calls into Reflector anyway.

15:08 mtopolnik: i would create a permgen mem leak?

15:08 chouser: not necessarily

15:09 mtopolnik: reflector is a nice solution, too

15:41 bigwavejake: I want to add a lein plugin to my project, but I don't want the version from clojars. I've downloaded a forked version of the project and done a lein install. What do I need to add to my project to get the plugin to work?

15:57 arohner: bigwavejake: change the version in the forked version to be different form the clojars one

15:57 bigwavejake: then update your project.clj to point at your unique version

15:58 technomancy: I wrote http://github.com/drewr/lein-daemon , which I'm pretty happy with, except that the plugin ships with code that needs to run at runtime. I can split it into two projects, or list the dependency twice, once in :dependencies, once in :dev-dependencies (ick). Is there another way?

16:01 technomancy: arohner: I can't think of another way, sorry. =\

16:01 arohner: oh... you might be able to use classifiers for that

16:01 arohner: technomancy: classifiers?

16:01 technomancy: it's a feature that was recently added... I am not even really sure what it's for, but you could read up on them in the mvn docs.

16:02 I think it's for publishing things like test-jars as separate artifacts.

16:03 lancepantz: arohner: i ran into the same issue, ended up adding it in both deps and dev deps

16:05 arohner: hah, actually, I wrote http://github.com/arohner/lein-daemon, not http://github.com/drewr/lein-daemon

16:05 LauJensen: hehe :)

16:05 arohner: to tell them apart you could rename your repo to 'leinjure'

16:06 arohner: LauJensen: it's cool, they're the same project. drewr forked from me, I was just checking out what the diff was

16:06 LauJensen: ah ok... even still... :)

16:09 drewr: lol

16:11 arohner: no diff yet, but looks like something I'll be trying, which means I'll most likely be submitting patches ;-)

16:11 arohner: drewr: cool, bring it on :-)

16:11 drewr: I have the same feeling. I tend to patch every project I use

16:59 pjstadig: rhickey: i've figured out my problem

17:00 it's because keywords are never GC'ed

17:01 AWizzArd: pjstadig: who keeps a reference to them?

17:01 pjstadig: Keyword.table

17:01 AWizzArd: oho

17:02 pjstadig: maybe it would be good enough if it just kept the last N keywords?

17:04 pjstadig: or perhaps use weakrefs

17:04 seoushi: I'm looking for a way to use a generated vector with let. for example "(let (vec x 1 y 2) (+ x y)) => 3". is there a function I can use?

17:06 serp_: perhaps a macro could help you

17:06 seoushi: I've been trying but can't get it to work right

17:06 hiredman: speaking of keywords

17:06 http://groups.google.com/group/clojure-dev/msg/a5b527caa63ab3c0

17:07 pjstadig: cool!

17:11 kotarak: How can I reach some op of clojars?

17:14 vasily_pupkin: hi

17:14 technomancy: kotarak: I think it involves a flight to Australia at this point. =\

17:14 vasily_pupkin: i just started learning clojure (and jvm)

17:14 technomancy: next time I see _ato around I am going to have to talk him into giving someone else the keys to clojars

17:15 vasily_pupkin: i try to use java library for XMPP - smack

17:15 kotarak: technomancy: :( Someone hijacked vimclojure there. Not very nice. And _ato is going submarine...

17:15 technomancy: ouch

17:15 vasily_pupkin: some classes loaded ok - org.jivesoftware.smack.XMPPException, etc, but main XMPPConnection fails with [Thrown class java.lang.NoClassDefFoundError]

17:15

17:16 kotarak: This "everyone can push arbitrarily "fixed" (read: broken) variants" sucks.

17:16 vasily_pupkin: it placed in the same jar, and TAB key shoes it in slime repl

17:16 wtf? :]

17:16 AWizzArd: kotarak: oh :(

17:17 technomancy: kotarak: it's not bad if ops are responsive; the alternative of "wait weeks for your group-id to get approved" is much worse IMO.

17:19 kotarak: technomancy: yeah. I'm actually in favor of easily getting group-id's (with the right of prior art so-to-say for established projects). I'm just not keen of seeing 6 different vimclojure (all not from me), which are "fixed" in various ways. I somehow don't get this "fork me" stuff.

17:19 technomancy: kotarak: it does seem to be used an awful lot more than it should.

17:20 thorstadt: seoushi: a very hackish macro that will only work with basically the example you gave is: (defmacro contrived-let [vecx & body] `(let [~@(rest vecx)] ~@body))

17:20 technomancy: I don't understand why you'd push a fork unless you tried to get your fixes upstream and they were unresponsive.

17:21 thorstadt: seoushi: i can't think of a reason to use anything like this, ever, though

17:21 kotarak: technomancy: my suspicion is, that they use clojars as "local repo". I haven't provided an SNAPSHOT for 2.2, yet.

17:22 seoushi: thorstadt: thanks. I still don't understand macros all that well. Is there somewhere that describes all the special symbols? for example I don't really know what @ means, and I think ~ means use the value from the param

17:22 thorstadt: seoushi: http://clojure.org/reader

17:23 about half way down

17:23 ~@ means expand the evaluated contents of this list here

17:23 clojurebot: @ , {a b c]

17:24 seoushi: thanks

17:24 thorstadt: '~' just means evaluate (unquote)

17:25 vasily_pupkin: hm

17:25 thorstadt: if you were to modify this macro to use '~' instead of '~@' it would end up looking like (let [(x 1 y 2)] ...)

17:26 vasily_pupkin: looks like clojure couldn't load class with anonymous subclass

17:26 thorstadt: whereas ~@ 'splices' the evaluated form into your expansion

17:28 seoushi: so (defmacro my-let [vecx & body] `(let ~(vec (rest vecx)) ~@body)) would also work

17:31 seoushi: thanks much. The only thing I don't really understand is the "rest" function, I would think it would jsut chop off the first element.

17:31 thorstadt: it does

17:31 it's a terrible example

17:31 it doesn't actually evaluate the vector

17:31 the first element is 'vec'

17:33 ,(rest '(vec x 1 y 2))

17:33 clojurebot: (x 1 y 2)

17:33 seoushi: oh.. I see now, it's cutting off the first of the thing I passed in, not the evaluated version

17:33 thorstadt: correct

17:33 the problem here is that in order to evaluate (vec x 1 y 2) x and y have to have meaning

17:34 ,(vec 'x 1 'y 2)

17:34 clojurebot: java.lang.IllegalArgumentException: Wrong number of args (4) passed to: core$vec

17:34 seoushi: right

17:36 thorstadt: or rather

17:36 (vec '(x 1 y 2))

17:36 ,(vec '(x 1 y 2))

17:36 clojurebot: [x 1 y 2]

17:37 thorstadt: if you wanted to actually evaluate the form

17:37 you could do this:

17:37 (defmacro my-let [vecx & body] `(let ~(eval vecx) ~@body))

17:38 seoushi: I actually did try something like that

17:38 thorstadt: so that (my-let (vec '(x 1 y 2)) (+ x y)) would work

17:38 seoushi: but the stuff in there was unbound so it failed

17:38 ah

17:39 thorstadt: well vec takes a sequence as a parameter

17:39 you said (vec x 1 y 2)

17:39 when really its (vec '(x 1 y 2))

17:39 seoushi: I meant to say vector the first time

17:39 but yeah

17:40 thorstadt: the macro doesn't care about the variables, it sees them as symbols

17:40 that's why my-let would work

18:15 Guest63257: hello, I'm developing an application with swing and wanted to develop some component. So I started to write a function but I quickly came to the point where the parent needs to know about the current data of the component so I need a way that the parent can ask the component. But if I want to introduce a function I need something it can be called on so my original function that creates the component needs to return a map or something like

18:15 that. But from that point on I have something that looks very object oriented so I wonder if there's a more clojuresque way? I hope you understand my problem.

18:23 chouser: returning a map of data is perfectly acceptible.

18:23 though it's still worth trying to keep mutable objects separate from immutable data.

18:28 Guest63257: that would make lots of mutable objects in a larger swing application. It would result in namespaces containing one function which serves as a constructor and other functions just being normal member functions. It's not easy for me to separate the functional part then.

19:02 wolfjb: hello, been reading en.wikibooks.org/wiki/Learning_Clojure, where can I find more information about defmulti/defmethod? I'd like to know how to make defmethod accept a type rather than a value

19:02 ie generically accept a string or a specific kind of struct and perform some operation on that

19:03 (defmulti dosomething (fn [v] v))

19:03 (defmethod dosomething 'string?? ...; do something cool with the string)

19:06 Guest63257: something like (defmulti dosomething type) (defmethod dosomething java.lang.String [v] ...) ?

19:06 wolfjb: yes

19:07 does that syntax work?

19:07 Guest63257: yes.

19:07 ,(doc type)

19:07 clojurebot: "([x]); Returns the :type metadata of x, or its Class if none"

19:07 Guest63257: ,(type "some string")

19:07 clojurebot: java.lang.String

19:10 wolfjb: awesome!

19:10 thanks

21:06 rhickey: awesome: http://info.azulsystems.com/rs/azulsystems/images/zing_product_brocha4.pdf

21:12 danlarkin: awful laptop-on-clouds graphic aside, yeah that is _super_ awesome

21:12 rhickey: yet another benefit of being on the JVM

21:14 danlarkin: color me interested. I wonder how this'll integrate with existing cloud deployments

21:27 hiredman: danlarkin: it sounds like amazon would have to offer it, or at least you would need a zing ami or something

21:29 danlarkin: hrmph

21:30 hiredman: I'm seeing stuff like

21:30 Reflection warning, /Users/hiredman/amontillado/src/amontillado/core.clj:27 - call to contains can'\

21:30 t be resolved.

21:31 where 27 is a defrecord

21:31 itistoday: so i made a mistake, i did this in the repl: (def *warn-on-reflection* true)

21:31 but that refers to the user namespace

21:31 apparently i need to set clojure.core/*warn-on-reflection*

21:31 so that brings the question: how do i undefine a var?

21:31 hiredman: (ns-unmap *ns* '*warn-on-reflection*)

21:32 itistoday: hiredman: thanks!

21:32 $mail

21:32 hiredman: that does not undefine a var, but it removes the mapping from the namespace

21:32 as payment I demand that you never publicly use $mail again

21:33 itistoday: hmm.. the bot told me to

21:33 is it /$mail?

21:33 hiredman: privmsg it

21:33 or ignore it

21:33 danlarkin: ugh

21:33 the. worst.

21:34 itistoday: how do i send a mail/message to someone that's not online?

21:34 (I promise not to publicly do it :-p)

21:35 sexpbot won't respond to 'help' :-\

21:35 danlarkin: irc does not have that capability

21:35 hiredman: I suggest you send them an email

21:35 itistoday: ... i got a message that way

21:35 from sexpbot, so obviously there's a way to do it

21:37 hiredman: i don't have their email... and they didn't have mine. just got a message once i signed on from the bot saying i had mail. which is cool, only problem is i don't know how to reply

21:40 danlarkin: send them a text message

21:46 itistoday: i think i figured it out

21:46 haha, yes!

21:52 ah the power of google and opensource software. i looked up the code for sexpbot, and to send someone a message when they're offline, pm the bot with: $mail <nick> <msg>

21:53 make sure not to send anything private, as it's really fucking insecure

21:58 Raynes: itistoday: sexpbot responds to $help <command-name>

21:59 itistoday: Raynes: but it doesn't respond to $help

21:59 Raynes: Can't say the command docs are excessively helpful though.

21:59 itistoday: actually, it does, but it explicitly says it can't help you! :-p

21:59 Raynes: Indeed. I need to give it a better reply.

21:59 itistoday: how am i supposed to ask for help if i don't know the commands?

22:00 if the input is not one of the commands it should present a list of available commands.

22:00 Raynes: but really neat bot btw!

22:01 Raynes: You can get a list of commands with $dumpcmds. I actually started on some stuff to generate a list of commands I could put online with docs rather than dump a raw list of commands every time, but I haven't got around to it yet.

22:01 Thanks. :)

22:19 itistoday: where is set! defined?

22:19 i can use it but can't find it in the api docs...

22:20 hmm... found it: http://clojure.org/vars#set

22:21 * cemerick wonders whether he's doing any good pushing back at google group smugness. :-/

22:23 trptcolin: can anyone verify that scp to clojars.org is working for them right now? i'm getting "Permission denied (publickey)", but i've checked and re-checked my key several times...

22:25 itistoday: cemerick: of course you are :-)

22:25 cemerick: at least i appreciate it :-)

22:25 trptcolin: ah, nm - weird pasting issue on my part

22:26 itistoday: cemerick: then again, that might not be much comfort?but, if there's no pushback, well, you know what they say about silence being viewed as condoning

22:26 cemerick: itistoday: as long as someone is getting something out of it :-)

22:27 I'm not bothered by much, but anything approaching "go away if you're not 133t enough" irks me.

22:27 OK, just flat out pisses me off. ;-)

22:28 itistoday: cemerick: btw, i just saw your reply to cageface, nice one. i was going to reply to earlier and bring up a similar point as well, but was too tired, and i avoid writing when i'm too tired (for fear of sounding stupid :-p)

22:29 chouser: I started a similar response, but postponed it when I realized there was no way I could keep up with the pace of that thread.

22:30 cemerick: I'm really not trying to be confrontational, but some of this just has to be called.

22:32 itistoday: btw, how long does your message take on average to appear on the thread? mine have been taking a while, but recently it's speeded up from ~24 hours to about 30 minutes or so

22:32 (I respond via email)

22:33 cemerick: It varies a lot. :-/

22:33 itistoday: how google hasn't developed a solution for the spam problem boggles my mind

22:45 trptcolin: on clojars, is there a trick to getting external libraries copied up there? publishing my project jar worked fine, and scp looks like it copies all jars ok, but afterwards the external jars (org.clojars.trptcolin/*) don't appear to be there.

22:59 itistoday: Is the only difference between set! and def that def will create a var if it doesn't exist?

23:00 technomancy: itistoday: set! only works on thread-local bindings

23:00 itistoday: technomancy: ok thanks, but other than that they're the same?

23:01 (that and the fact set! doesn't create a var if it doesn't exist)

23:02 technomancy: itistoday: the main difference is that you should use def and you shouldn't use set! =)

23:02 but yeah, yours is also technically correct.

23:02 the other difference is you sholud never use def inside a function body; only at the top level.

23:02 itistoday: technomancy: well i came across it because i tried doing this in the repl: (def clojure.core/*warn-on-reflection* true)

23:03 and that gave me this error: java.lang.Exception: Can't create defs outside of current ns (NO_SOURCE_FILE:120)

23:03 technomancy: oh right; for repl usage set! is ok

23:03 yeah, you can set! fully-qualified or refered vars; that's another difference.

23:04 itistoday: technomancy: not sure what you mean by refered vars. this? (set! *warn-on-reflection* true)

23:04 cause i get: java.lang.Exception: Unable to resolve symbol: *warn-on-reflection* in this context (NO_SOURCE_FILE:121)

23:04 technomancy: itistoday: refer is the function that makes vars from other namespaces visible in the current ns

23:05 itistoday: sounds like your current namespace is screwed up

23:05 itistoday: technomancy: not screwed up i don't think, just in the repl (namespace user)

23:05 technomancy: all namespaces have all vars in clojure.core visible by default

23:06 itistoday: hmm.

23:06 you're right

23:06 it was screwed up

23:06 must be a bug in 1.2...

23:06 don't know how i caused it

23:08 technomancy: if you create a new ns with in-ns then you don't get clojure.core refered automatically

23:10 itistoday: technomancy: thanks, didn't know that. kinda odd... does a namespace created with 'ns' have them referred?

23:10 it seems too...

23:10 wonder why they did that...

23:11 (made in-ns not autoinclude them like everything else)

23:11 phenom_: thoughts on clojure vs scala ?

23:13 technomancy: itistoday: ns does auto-refer; in-ns does not

23:14 phenom_: scala is "a better Java"

23:14 itistoday: technomancy: yeah i discovered that, was wondering why though (why in-ns doesn't)

23:14 technomancy: performance?

23:14 technomancy: itistoday: in-ns is low-level

23:15 ns is a macro which expands to a bunch of calls starting with in-ns

23:15 itistoday: technomancy: ah ok.

23:15 technomancy: ,(macroexpand-1 '(ns user))

23:15 clojurebot: (do (clojure.core/in-ns (quote user)) (clojure.core/with-loading-context (clojure.core/refer (quote clojure.core))))

23:15 technomancy: there you have it

23:16 itistoday: pretty simple actually :-)

23:19 there are no type hints for primitives? only coercion?

23:19 (primitives, not primitive arrays)

23:22 why are primitives treated differently?

23:26 technomancy: itistoday: probably because they're not objects

23:26 itistoday: technomancy: ah... but primitive arrays are objects?

23:26 technomancy: itistoday: you can have a method signature that's just Object, Object, Object, etc, and it will work fine with any non-primitive you throw at it

23:27 I don't know about arrays.

Logging service provided by n01se.net