#clojure log - Mar 24 2011

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

2:47 * raek wishes there were was a swap! that returns the value that was swapped out...

2:56 raek: (defn switcheroo! [atom newval] (let [oldval @atom] (if (compare-and-set! atom oldval newval) oldval (recur atom newval))))

2:59 scottj: (defn swap!* [a f & args] (let [ret (atom nil)] (apply swap! a (fn [x & args] (reset! ret x) (apply f x args)) args) @ret))

3:57 TobiasRaeder: morning

3:59 ephcon: morning

3:59 thorwil: morning

4:09 talios: evening

4:52 ejackson: Morning

4:52 mduerksen: greetings

4:59 angerman: xin chao

5:39 ok, now this is strange, as nice as FF4 is… it chews 33% CPU just for downloading a file.

5:39 wtf?

5:46 mduerksen: angerman: just downloading libreoffice - cpu ist almost idle

5:46 angerman: mduerksen: yes, this is very confusing. it shouldn't be a cpu intensive task to download afile.

5:46 mduerksen: maybe its the final virus check you observed?

5:47 angerman: download is maybe 25% done.

5:47 will go on for another 70 min

5:48 mduerksen: ok, so that can't be it. do you have more tabs open? with flash etc.?

5:48 angerman: no, nothing is open.

5:48 except for the download window.

5:52 mduerksen: beats me...

5:53 angerman: maybe it's the file size.

5:53 4.5gb

5:53 clgv: angerman: is it https?

5:53 angerman: clgv: hmm, that might be.

5:54 does apple serve the xcode+iso bundle from behind a https uri? … lets see

5:54 hmm no.

5:54 clgv: I guess youi would notice https in cpu usage but not that much on a modern cpu

5:55 angerman: yea, I'm simply subsum it as weird. If it doesn't persist, it's ok.

5:56 if it stays that way… FF4 has to go

5:56 clgv: oh you are an early adopter ;)

5:57 angerman: It's been FF most of the time, than for a short period of time Safari, because I simply felt faster. Until Chrome arrived, which basically just improved on Safari. But FF4 feels snappy again.

5:59 Too much of any one vendor is just not good. And I have a semi-sceptical relationship with google. But by the end of the day, what is the least hassle wins.

5:59 clgv: humm a different question: is there something like partial that also updates metadata?

6:00 I am building a configuration DSL for my algorithm and would like to check at least arity of the functions to provide an early error to the user

6:01 angerman: I don't think anyone would have ventured down that way yet.

6:02 clgv: hm I could have a look at the partial definition and hack it myself. or wrap the partial functionality in another fn or macro that keeps and updates metadata

6:09 raek: clgv: function objects do not carry metadata about the arity... or did you add it yourself?

6:10 clgv: raek: they do indirectly in the argslist when you use defn. but only if it's not overriden manually

6:11 raek: that metadata is on the var, not the function

6:11 clgv: does that distinction really matter?

6:11 I am not going to assign the same function to a different var

6:12 raek: you'd have to make your variant of partial a macro

6:12 clgv: but it would indeed fail if someone would be using fns

6:12 raek: or force the user of it to pass the var instead of the function

6:13 clgv: maybe I should define my own definition of these kind of functions

6:14 it's only intended to be at the configuration layer

6:16 angerman: jikes...

6:19 clgv: angerman: ?

6:20 angerman: somehow sandbar pukes at me.

6:20 claims that sandbar core is not found.

6:20 make zero sense.

6:27 ah. it did make sense. on a very sad level.

6:27 sandbar `uses` hiccup 0.3.0 which conflicts if you use hiccup 0.3.4

6:34 clgv: so you are doing web development in addition to your tikz rendering

6:35 angerman: web stuff is mainly a side gig.

6:35 (Research/Univ. is mostly Math / Sidestuff is Websites and iOS dev)

6:41 pyr: morning

6:41 angerman: mornig.

6:44 pyr: i'm splitting up a rather large clojure project into several files

6:45 and wondering what the best thing would be

6:45 i suppose i can't use one ns for all files

6:45 but should all independant files cross-reference the other namespaces declared ?

6:46 angerman: pyr: I usually pack them up in seperate namespaces and require them.

6:46 (:require [geometry :as g])

6:46 pyr: 'k

6:46 angerman: (g/with-geometry …)

6:48 _ato: you can actually use one ns with multiple files, use the "load" function from the main file

6:48 clojure.core uses that technique for example

6:49 pyr: that sounds nice

6:49 clgv: pyr: I guess you have a reason for splitting the project into separate files. I also guess that you will group the functions together that somehow belong together semantically. so why not take that "semantic reason" and derive an appropriate namespace from it? ;)

6:50 pyr: clgv: you're right

6:50 clgv: but i'm doing it a step at a time

6:50 since splitting up reveals toe-stepping

6:50 between semantical units

6:53 raek: a good partitioning of the namespace would be a "layered" one, since namespaces cannot have circular dependencies

6:56 pyr: ok

6:56 thanks for your pointers

6:58 raek: e.g. (ns apple) (defn make-apple ...) (ns basket) (defn make-basket ...) (defn apple-in-basket? ...) rather than (ns apple) (defn make-apple ...) (defn apple-in-basket? ...) (ns basket) (defn make-basket ...)

6:58 the rationale being that the "apple" does not have to be conserned with what might contain it

7:00 angerman: ? (case …) has no fall through?

7:01 alright. it's the last item… weird.

7:47 can I injetct a multi-method in a foreign ns?

7:48 raek: angerman: a defmulti or a defmethod?

7:48 angerman: defmethod

7:50 raek: yes you can. (ns foo) (defmulti m ...) (ns bar (:require foo)) (defmethod foo/m ...)

7:51 angerman: raek: great!

7:53 wow. library fail!

7:53 method not public.

7:55 reak is there some macro, that would allow me to go into a ns, mess with the stuff, and come back?

7:55 or would I have to write one?

7:55 clgv: angerman: there is an with-private macro I found and used for tests

7:55 angerman: I don't want to use it for tests only. It's a little bit like money patching.

7:56 Current solution is to just copy the private function into my source tree.

7:56 but that's rediculous!

7:56 Ahh well, too much complaining. It works, is ugly, who cares.

7:57 clgv: http://pastebin.com/CMKsKKeF

7:57 it is not limited to tests. I also used it with hooks

7:57 angerman: clgv: I basically want to patch functionality into a library.

7:58 clgv: just try it ;)

7:58 angerman: using defmulti was a good idea by the library author.

7:58 using a private method for essential computation inside of the multimethods was not.

7:59 clgv: "private" is only metadata that is enforced by the clojure environment though ...

7:59 but it would be better if you wouldnt have to work around

7:59 angerman: yes. It's just a mistake by the lib's author.

8:00 what the library does is great, but how it does, is not so.

8:01 clgv: but it's not only an error by 3rd party libs. this case can also be found in clojure e.g. core

8:01 angerman: I don't know I don't "privatize" my fns.

8:02 maybe put them in a different namespace, for hygenic reasons.

8:02 That reminds me.

8:02 Can I extend a Java Class's final method?

8:03 or is final enforced on a jvm level?

8:03 clgv: good question. but I guess it must be enforced on jvm+compiler level, since you often have no source ;)

8:04 angerman: do I need the source?

8:04 class X { final int do() { System.out.println("I do"); } }

8:05 (defprotocol Do (do [_] "does soemthing"))

8:05 clgv: I mean. if you only have the super class as jvm bytecode it must contain some information about final

8:05 angerman: (extend-type X Do (do [_] (println "I don't!") ))

8:05 (.do X)

8:05 clgv: that means as soon as you want to compile a class extending it, the compiler will forbid you to

8:06 angerman: but in this case, the method is final, not necessarily the class.

8:06 Even though, is it a feature of the Java Compiler, or a JVM enforcement?

8:07 clgv: I dont know if the classloader would forbid you to load the class if you somehow managed to get it compiled

8:08 angerman: sound's like it's up for an experiment.

8:08 Hmm. will do that next on my todo list

8:10 clgv: but it might be a hard assignment if the compiler doesn compile it for you and you have to generate the bytecode yourself ;)

8:10 tsdh: Do I see it correctly that in order to call clojure functions from Java, I :gen-class my ns, declare the function signatures using :methods, and create wrapper defn's starting with a -?

8:10 angerman: Nah. I'm only interested if clojure allows me to.

8:13 _ato: angerman: Exception in thread "main" java.lang.VerifyError: class bar overrides final method eep.()I

8:13 at runtime

8:13 tsdh: At least, that's what's suggested in http://java.dzone.com/articles/java-clojure-interop-calling. Especially the -wrapper-functions seem a bit redundant...

8:13 angerman: _ato: ohh, thanks.

8:14 _ato: even if you could turn off the bytecode verifier it probably wouldn't work right anyway because optimisation likely depends on it, eg final methods can be inlined

8:15 angerman: _ato: good point.

8:15 Hmm life surgery on java's heart.. no thanks.

8:16 thorwil: how do i get at the contents of a #<params$wrap_params$fn__1835 ring.middleware.params$wrap_params$fn__1835@25be8e06> ?

8:17 angerman: eval it?

8:20 thorwil: can't in a way i get to see anything

8:20 angerman: maybe I'm completely wrong, but that looks like a function to me.

8:22 thorwil: i don't know what it is, but surely not what i'm after :/

8:22 _ato: heh, where did you get it from?

8:23 angerman: thorwil: what you posted looks like a method handle.

8:23 thorwil: evaluating that method will get you to it's contents.

8:23 _ato: oh it's the lambda inside this: http://clojuredocs.org/ring/ring.middleware.params/wrap-params

8:24 thorwil: hmm. my trouble seems to start elsewhere.

8:24 (app [[path not-empty] &] (submit-article (wrap-params get-form-params) path))

8:25 angerman: &] ?

8:25 sexpbot: java.lang.Exception: Unmatched delimiter: ]

8:25 thorwil: ^ it looks like get-form-params is not evaluted before submit-article

8:26 angerman: it matches urls with or without trailing /

8:26 Raynes: angerman: Congratulations! I think you're the first person ever to accidentally set off sexpbot's evaluation. I had a cookie for you, but I ate it.

8:27 angerman: Raynes: i c

8:27 thorwil: now it dawns on me. have to try (eval (wrap-params get-form-params))

8:27 Raynes: :>

8:28 angerman: thorwil: ((wrap-params get-form-params))?

8:28 _ato: er, I don't think that's going to help. I think angerman meant 'call' rather than 'eval'

8:29 angerman: thorwil: I'm not really sure what you are doing but it looks a little confused.

8:29 get-form-params sounds like a function rather than a value

8:30 thorwil: angerman: http://groups.google.com/group/clojure/browse_thread/thread/a9fa0022c9d06a93?hl=en#

8:30 angerman: there surely is a lot of confusion in my head

8:31 get-form-params is a function for getting the stuff i want out of the request map that has been added to by wrap-params

8:31 angerman: well then your calling is reverse already.

8:32 thorwil: if i just wrap my handler, i can't pass another argument

8:32 angerman: so you want something like (get-form-params (wrap-params request)))

8:32 thorwil: angerman: wrap-params takes a handler, nothing else

8:33 strike that

8:33 _ato: it takes a handler and returns a function that takes a request

8:33 thorwil: but it does not take a request, that i already implied

8:33 angerman: thorwil: the primariy idea of that line was to show that the logic is somehwat reverse.

8:34 (def wrapped-app-handler (wrap-params app-handler))

8:34 raek: thorwil: note that the form to the right of the vector should eval to a (possibly wrapped) ring handler fn

8:35 angerman: then within app-handler you can appy (get-form-params to the request)

8:35 raek: moustache has syntax for wrapping too

8:35 (app ["foo"] [wrapper1 (wrapper2 arg) handler])

8:35 * angerman goes and beats the sh*t out of sandbar.

8:37 * angerman assumes 0.4.0-SNAPSHOT is better, but the current stable 0.3.3 can be a pita.

8:38 raek: (clarification: if a form is not a vector or a map in moustache, it should usually eval to a ring handler)

8:40 thorwil: raek: it seems to me that i need either a wrapper that binds the form-params, or one that adds "path" to the request map (?)

8:41 raek: parsing form params is not done by moustache. you can use the standard ring wrap-params for that.

8:41 (basically, moustache only does routing)

8:41 thorwil: yes, that's why i use wrap-params already

8:42 the problem is passing another argument to my handler, alongside

8:42 raek: ah

8:42 angerman: doesn't wrap-params just extend the request map?

8:43 thorwil: yes

8:43 raek: I guess you can do something like (fn [req] (handler something req)) or (partial handler something)

8:44 or make a middleware fn that adds it to the reuqest map

8:44 thorwil: partial leads to fun like: results in "nth not supported on this type: PersistentHashMap"

8:44 raek: so this extra argument is not something in the form params?

8:45 clgv: raek: do you know where in clojure.core the "&" in parameter declarations of functions is handled?

8:45 _ato: partial would make path the first argument and request the escond argument

8:45 raek: that doesn't sound like something that is introduced by partial itself

8:45 thorwil: raek: no, the argument is part of the url, taken from moustach's destructuring

8:45 _ato: sounds like maybe you want: (app [[path not-empty] &] (wrap-params (fn [req] (submit-article req path))))

8:46 angerman: thorwil: maybe you should give more high-level explanation of what you are trying to archive

8:46 I still think you are stuck somewhere in the core without a clear understanding of how things are designed to work.

8:48 thorwil: trying _ato's suggestion, first :)

8:49 _ato: I'm assuming your submit-artcle is like: (defn submit-article [request path]) ; partial would assume it's like: (defn submit-article [path request])

8:49 clgv: in destructure https://github.com/clojure/clojure/blob/master/src/clj/clojure/core.clj#L3837

8:50 (= firstb '&) ...

8:50 angerman: later

8:51 clgv: sure? I dont see destructure being called in defn

8:51 Chousuke: destructure is called in fn :)

8:51 or well, no.

8:51 clgv: ah maybe-destructured is called in fn

8:52 Chousuke: fn destructuring is a bit different from let-destructuring :/

8:52 _ato: it turns it into a let doesn't it?

8:53 and let calls destructure

8:53 clgv: yep it does

8:53 maybe-destructured is building a let

8:53 thorwil: works, and i know how to take the map apart!

8:53 _ato: thank you!

8:53 raek and angerman, too :)

8:54 clgv: uuuuh! destructure is a monster

8:56 Chousuke: It is. Fortunately, it works

8:56 thorwil: _ato: to be sure, i take it the deciding thing about the anonymous function is that it takes a single argument, where the name there is just a binding?

8:58 _ato: thorwil: yeah, wrap-params expects to be given a function that takes a single request argument, which we bind to 'req'.

8:59 kjeldahlw: I'm struggling with some clr interop issues, need to figure out what classes/methods are available for a namespace etc. Any pointers on nice examples on how to "inspect" similar stuff in the java world?

8:59 (clojure jvm world I mean)

8:59 _ato: kjeldahlw: are you asking how to list the methods on a java class?

9:00 kjeldahlw: _ato: Yes, for anything inside something from the java world that one would require into the current namespace or similar.

9:01 _ato: (seq (.getMethods String)) will get you a list of all the methods on the String class

9:01 for nicely formatted output check out the 'show' function in clojure.contrib.repl-utils

9:02 thorwil: but i'm an idiot, (app [[path not-empty] &] (wrap-params (partial submit-article path))) works, too

9:03 * thorwil doesn't even know what was different when he first tried it

9:03 _ato: kjeldahlw: oh and the other half of the question (ns-imports *ns*) will list the classes imported into *ns*

9:06 clgv: kjeldahlw: seems the "ns-*" functions are of interest

9:10 saml: what's the clojure eval bot that you are using?

9:10 > (+ 1 2)

9:10 hsbot: No instance for (GHC.Show.Show (a -> a)) arising from a use of `M43891536.show_M43891536' at <interactive>:(2,0)-(4,32) Possible fix: add an instance declaration for (GHC.Show.Show (a -> a))No instance for (GHC.Num.Num (...

9:10 _ato: ,(+ 1 2)

9:10 clojurebot: 3

9:10 _ato: &(+ 1 2)

9:10 sexpbot: ⟹ 3

9:11 saml: is it open source?

9:11 _ato: saml: https://github.com/cognitivedissonance/sexpbot https://github.com/hiredman/clojurebot

9:11 saml: ,source

9:11 clojurebot: java.lang.Exception: Unable to resolve symbol: source in this context

9:12 _ato: ~source

9:12 clojurebot: source is http://github.com/hiredman/clojurebot/tree/master

9:12 saml: what's the difference?

9:13 _ato: the , means eval clojure code, ~ means run a bot command

9:13 saml: sexpbot vs clojurebot

9:13 clgv: sexpbot is way cooler ;)

9:13 $source map

9:13 sexpbot: map is http://is.gd/Fd9Ag4

9:14 saml: sexpbot, is web scale

9:14 it is mongodb

9:15 kjeldahlw: Excellent. (ns-imports *ns*) shows the stuff I was looking for. And given a key from that map, how do I list all symbols in the namespace?

9:16 saml: why clojure no new release?

9:16 is it abandoned?

9:16 clgv: kjeldahlw: there is also ns-map.

9:17 joly: saml: not abandoned

9:17 clgv: just do a ##(find-doc "ns-")

9:17 sexpbot: ⟹ ------------------------- clojure.contrib.logging/commons-logging ([]) Defines the commons-logging-based implementations of the core logging functions. End-users should never need to call this. ------------------------- clojure.core/ns-aliases ([ns]) Returns a ... http://gist.github.com/885030

9:17 _ato: saml: releases are here: https://github.com/clojure/clojure/downloads

9:18 saml: it's alpha

9:18 joly: saml: still means there is active development

9:18 clgv: 1.2.0 is not alpha ;)

9:18 raek: nor is 1.2.1...

9:18 clgv: raek: 1.2.1?

9:18 saml: will stuff change a lot on 1.3?

9:18 should i use 1.3 or 1.2?

9:19 in production

9:19 raek: I think it was released this week

9:19 clgv: for real?

9:20 kjeldahlw: clgv: Thanks, but how do I use it? If I put in as parameter anything from the (ns-imports *ns*) (keys or values) I get "no namespace" errors. Feel free to give an example from the jvm world..

9:20 raek: maybe it hasn't been announced yet, but leiningen 1.5.0 (also released this week?) uses it as the default now

9:20 clgv: raek: dont see it on clojure.org

9:20 _ato: 1.3 changes are shown here: https://github.com/clojure/clojure/blob/master/changes.txt there are breaking changes, I think mostly it's just adding :dynamic when you want to rebind stuff

9:20 raek: http://build.clojure.org/releases/org/clojure/clojure/1.2.1/

9:21 clgv: kjeldahlw: I just meant you can lookup functions with it. ns-map sounds promising

9:21 raek: changelist?

9:21 raek: or better update notes?

9:22 raek: saml: there has been discussions of changing the version from 1.3 to 2.0, so there might be some breaking changes

9:23 though, I know that there are people who use 1.3 in production already

9:24 kjeldahlw: clgv: Sounds easy, maybe I'm just being dense. If I do (ns-imports *ns*), the first pair I get in the map is UriBuilder System.UriBuilder. Trying (ns-map UriBuilder), (ns-map System.UriBuilder), and also with the quote symbol in front, I still get errors. Do I need to "look up" the namespace some other function before passing it to ns-map?

9:24 raek: clgv: http://groups.google.com/group/clojure-dev/browse_thread/thread/f1b1fbfd2a6c1a9f

9:24 saml: raek, ah thanks

9:24 clgv: ,(ns-map *ns*)

9:24 raek: ,(ns-publics 'clojure.core)

9:24 clojurebot: {sorted-map #'clojure.core/sorted-map, read-line #'clojure.core/read-line, re-pattern #'clojure.core/re-pattern, keyword? #'clojure.core/keyword?, val #'clojure.core/val, ProcessBuilder java.lang.ProcessBuilder, chunked-seq? #'clojure.core/chunked-seq?, Enum java.lang.Enum, find-protocol-impl #'clojure.core/find-protocol-impl, SuppressWarnings java.lang.SuppressWarnings, ...}

9:24 {sorted-map #'clojure.core/sorted-map, read-line #'clojure.core/read-line, re-pattern #'clojure.core/re-pattern, keyword? #'clojure.core/keyword?, val #'clojure.core/val, chunked-seq? #'clojure.core/chunked-seq?, find-protocol-impl #'clojure.core/find-protocol-impl, vector-of #'clojure.core/vector-of, object-array #'clojure.core/object-array, *compile-path* #'clojure.core/*compile-path*, ...}

9:25 clgv: raek: thx

9:26 kjeldahlw: raek: How about anything that is not from the clojure namespace, but java?

9:27 _ato: kjeldahlw: Java classes aren't clojure namespaces, so you need to use Java reflection to list their methods. AFAIK there's no Clojure functions for doing it (in core), you just use: (.getMethods SomeClass)

9:27 kjeldahlw: _ato: Ah, ok. Similarly for clr then. Ok, I'll keep digging. Thanks.

9:28 _ato: maybe (.GetMethods System.UriBuilder)

9:29 for CLR

9:29 clgv: kjeldahlw: how does clojure CLR work for you so far?

9:29 _ato: just guessing from some example C# code

9:46 tsdh: What's the right way to coerce a ratio into a double with proper rounding?

9:46 (double (/ 1001876 11)) ==> 91079.63636363635, which is wrong.

9:47 Correct would be 91079.63636363636.

9:48 Hm, doing the same in Java gives 91079.63636363637, which is wrong, too. :-)

9:50 amalloy: tsdh: wtf, that doesn't look wrong to me

9:51 er, yes it does

9:51 tsdh: The correct result is 91079.[period 63].

9:51 amalloy: but doubles are pretty vague. if you care about precision in the 20th digit you shouldn't really use doubles

9:52 &(/ 1001876. 11)

9:52 sexpbot: ⟹ 91079.63636363637

9:53 tsdh: amalloy: I don't care too much, but that forces me to using a custom comparison function in my tests, where I compare Java results with Clojure results.

9:53 amalloy: tsdh: you should be doing that anyway for doubles. never compare doubles for equality

9:54 the way you compute something can cause rounding errors to appear in different places, so that results which "should" be the same will differ

9:56 tsdh: In the concrete case, I really compare "1001876 / 11.0" with (double (/ 1001876 11)), so it's really only the coercion that makes the difference.

9:58 And in this case, the Java result is about twice as near at the exact value.

9:59 Or better, the Clojure error is twice as big as the java error.

10:38 devn: morning gents

10:39 Raynes: devn: Morning.

10:39 fliebel: I saw dnolen inherit Object in a deftype and overwrite equals and hashCode for speed. Why? Any deftype inherits those from Object already, doesn't it?

10:40 Raynes: devn: You know, it's impossible to tab complete your name because of Derander and devhost. (sorry for the pings)

10:40 Not that it's difficult to type out. Just an observation.

10:40 dnolen: fliebel: for improving the speed of putting LVars into a collection (PersistentHashMap/Set)

10:41 fliebel: Raynes: depends on your client and how many chars you type before completing.

10:41 amalloy: fliebel: i saw that too and was puzzled

10:41 dnolen: did your original version use defrecord instead?

10:41 fliebel: dnolen: Sure, but why are your methiods better than those on Object?

10:41 dnolen: amalloy: no

10:42 tsdh: My leiningen project depends on a foo.jar contained in lib/. How can I teach leiningen not to add that into the uberjar, because now I want to use my project in the foo project (which of course contains its own classes anyway)?

10:42 amalloy: defrecord comes with value-based versions of = and hash, but i had the same thought as fliebel: this looks just like the built-in

10:42 Raynes: fliebel: Not really. In this case, if you type d, you get a list of everyone with d in the name. de, you get Derander; dev, you get devhost. The only way around that is to set it to prefer the people who have spoken last.

10:42 amalloy: tsdh: circular dependencies are not cool

10:43 Raynes: Or get a client that doesn't understand the order of the alphabet. But I digress.

10:43 amalloy: Raynes: or get privs and boot anyone whose name gets in the way of your tab completion

10:44 Raynes: :)

10:44 tsdh: amalloy: Well, I agree. What I really want is to use my clj project in another Eclipse Java project that depends on the Eclipse Java foo project.

10:46 fliebel: dnolen: equals of Object is really identical, and uses == ultimately. hashCode does call some other function that may take some time.

10:46 VMMemoryManager.getIdentityHashCode

10:47 amalloy: i rule my filesystem with an iron fist. it messes up tab completion of something more important, it gets the whip

10:47 fliebel, Raynes: you could also find a client that uses fuzzy completion like emacs. then dvn would probably complete to devn

10:48 tsdh: then don't build an uberjar

10:48 thorwil: i wonder why (ds/save! (flatten `(Article. ~(vals form-params) timestamp)))

10:48 is not equivalent to (ds/save! (Article. path (form-params "title") (form-params "body") timestamp))

10:49 dnolen: amalloy: fliebel: all I know is that (.hashCode x) is ~2X faster when I've defined it myself.

10:49 amalloy: thorwil: um, because the former has a list where the latter has a function call

10:49 dnolen: that i can believe, for reasons fliebel gives. but is = faster?

10:50 fliebel: dnolen: Yea, I can imagine, the hashCode of Object goes deep down into native code.

10:50 amalloy: fliebel: all the native code really does is return the object's memory address, so it seems like it should be trivially fast, but not as fast as returning a number you cached at ctor time

10:51 tsdh: amalloy: Oh, you are totally right. I had the impression that uberjar is needed to make :gen-class work. But that is a false assumption.

10:51 fliebel: amalloy: I see. What about… the speed of lookup of local vs class vs superclass?

10:52 kjeldahlw: clgv: Re: CLR, just getting started. Struggling with getting assemblies loaded and figuring out the CLR interop stuff (obviously).

10:52 fliebel: I imagine Java tries them in that order, so for a really fast function, it might be faster to have it on the class, rather than have Java go up the chain. But otn the other hand, this might be optimized away anyway.

10:53 dnolen: amalloy: yeah, defining equals like that doesn't make it any faster/slower.

10:53 amalloy: fliebel: java doesn't have to try them in any order - it's doing a dynamic dispatch on type anyway

10:54 fliebel: Oh, right.

10:54 * fliebel has trouble choosing which conj video to watch next.

10:54 clgv: kjeldahlw: ah ok. you could let me know whether it went well when you did some progress

10:57 kjeldahlw: clgv: It seems to be working. I've managed a Windows "hello world" style app importing the System.Windows.Forms namespace and instantiating a MessageBox instance with the text hello world in it. But if I want to use WPF and similar, I need more access to classes and methods, which is what I'm struggling with.

11:04 dnolen: amalloy_: thx for the point about equals, updated my code and blog post.

11:09 saml: , 1 + 2

11:09 clojurebot: 1

11:09 clgv: ,(+ 1 2)

11:09 clojurebot: 3

11:10 scottj: ,1 + 2

11:10 clojurebot: 1

11:10 scottj: oh it only evals the first form?

11:10 angerman: lol, what? IndexOutOfBounds exception?!

11:29 fliebel: It'd be useful if this page mentioned which ones where lightning talks: http://clojure.com/blog/2011/03/23/conj-talks-all-up.html

11:32 hv: Assume I have made the JVM load a class from a SomeFile.class in CLASSPATH (file is directly there, not in a .jar). After SomeFile.class is regenerated, can I make the JVM reload it, at least for new uses of that class?

11:39 Fossi: hv: afaik there are some hacks to do that, but normally you can't

11:40 jrebel and the like use proxy classes and javaagent privileges to reload some stuff

11:41 but even then some things can't be replaced like enums or anonymous inner classes

11:44 cemerick: I seem to recall there being another library released recently (not scriptjure) that emits javascript for a subset of Clojure code. Does anyone have the name handy?

11:44 nm, got it: https://github.com/kriyative/clojurejs

11:46 angerman: &(keyword? (symbol ":foo"))

11:46 sexpbot: ⟹ false

11:47 angerman: hm.

11:47 clgv: a symbol is not a keyword

11:47 &(keyword? (resolve (symbol ":foo")))

11:47 sexpbot: java.lang.SecurityException: You tripped the alarm! resolve is bad!

11:48 angerman: clgv: i'll just go with :: :D

11:48 &(keyword ":foo")

11:48 sexpbot: ⟹ ::foo

11:48 clgv: &::foo

11:48 sexpbot: ⟹ :clojure.core/foo

11:49 clgv: &:::foo

11:49 sexpbot: java.lang.Exception: Invalid token: :::foo

11:49 angerman: &::::foo

11:49 sexpbot: java.lang.Exception: Invalid token: ::::foo

11:49 angerman: too bad :D

11:49 hv: Fossi: thanks. that's unfortunate that JRebel is not open source :(

11:49 angerman: &::-::foo

11:49 sexpbot: java.lang.Exception: Invalid token: ::-::foo

11:49 clgv: angerman: I guess you violate conventions with (keyword ":foo")

11:51 angerman: clgv: I assume I can live with that for now.

11:51 clgv: why do you need the extra ":"?

11:51 angerman: I get the :… stuff from the database.

11:51 don't really want to strip the first character prior to converting it to a keyword.

12:05 saml: how can I install clojure?

12:05 angerman: saml: define "install"

12:06 saml: i downloaded clojure jar and contrib jar and put it on ~/opt/clojure/

12:06 I'm trying to run sexpbot .

12:06 java -cp lib/*:src/:resource clojure.main -e "(use 'sexpbot.run) (-main)"

12:06 angerman: ahh ok.

12:07 amalloy: cemerick: clojurescript too, right?

12:07 angerman: well you need $ java -cp ~/opt/clojure/clojure.jar:~/opt/clojure/clojure-contrib.jar:lib/*:src/:resources clojure.main -e "(use 'sexpbot.run) (-main)" then.

12:08 jlf: technomancy: nathanmarz resolved the previous missing dependency issue with the cascalog package, but the next issue is a "org/apache/hadoop/conf/Configuration [Thrown class java.lang.NoClassDefFoundError]" exception when i do (use 'cascalog.api). is this another package issue, or do i need to manually add the location of my local hadoop installation to my classpath in package.clj?

12:08 angerman: (e.g. clojure and clojure-contrib should be in you classpath)

12:08 amalloy: saml: cake deps will download sexpbot's dependencies, including clojure

12:08 jlf: or anyone... :)

12:08 saml: ah i see

12:08 chouser: amalloy: clojurescript is something else. Clojure semantics, not JS semantics.

12:08 saml: is cake recommended over lein?

12:09 clgv: how can I access the meta-data of a function that I passed into another function?

12:09 amalloy: saml: by cake users, yes. by lein users, no

12:09 it's pretty split

12:09 saml: how about by clojure users?

12:09 * angerman is with lein. Had no reason to switch so far… what am I missing?

12:09 amalloy: for specifically sexpbot i'd suggest cake

12:09 i doubt it matters, but that's what all the sexpbot devs use

12:09 saml: is cake ruby?

12:10 amalloy: cake is clojure with a thin layer of ruby, like lein is clojure with a thin layer of bash

12:13 technomancy: jlf: I'd be surprised if you were meant to manually tweak things around like that, especially if the readme doesn't make it clear. I suspect it's another case of misdeclared dependencies.

12:13 odd that cascalog would be so delinquent in this regard; I've heard good things about it. =\

12:14 amalloy: jlf: i had a similar problem using cascalog, and added hadoop to my deps

12:14 i think the reason is so that it will work with whatever version of hadoop you want, rather than depending on version x

12:15 technomancy: then again, these kinds of problems do remind me of the brief time I spent investigating the hadoop ecosystem. =\

12:15 saml: Caused by: java.security.AccessControlException: access denied (java.lang.RuntimePermission createClassLoader)

12:15 when I run sexpbot

12:15 jlf: is there no way to express version ranges in lein dependencies?

12:15 amalloy: saml: did you read the readme?

12:15 [clojure "[1.2.0,1.3.0)"]\

12:16 saml: amalloy, do you think it's mongodb?

12:16 i thought i removed all plugins that use mongodb

12:16 jlf: amalloy, technomancy: thanks, i'll try adding the hadoop dependency manually for the moment and report to nathanmarz as well

12:17 Raynes: saml, amalloy: #sexpbot

12:17 amalloy: saml: no, it's the jvm sandbox

12:23 jlf: technomancy: hmm, i noticed that running deps from lein interactive doesn't seem to check for updated dependencies in project.clj

12:24 technomancy: jlf: deps doesn't auto-trigger unless lib/ is empty

12:24 though there's code to turn that on in the latest version; disabled by default since it's fairly untested

12:25 jlf: i'd expect deps to rescan project.clj dependencies if its mtime has changed since last invoked

12:26 technomancy: jlf: it checksums the value of the :dependencies map if you turn this option on

12:26 jlf: ah ok

12:27 technomancy: :checksum-deps true in project.clj; will probably be default in 2.0

12:28 jlf: nice, ty

12:29 angerman: yikes.

12:29 Sandbar is _very_ strange.

12:30 ev4l: good morning everyone

12:30 anyone know an easy way to perform the following operation:

12:31 i'd like to merge to seqs ("aaa" "bbb" "ccc") and ("111" "222" "333") into a vector of vectors: [["Aaa" "111"] ["bbb" "222"] ["ccc" "333"]]

12:31 is there some sort of "vector-interleave" function for it?

12:31 amalloy: $google transpose in clojure

12:31 sexpbot: First out of 243 results is: Matrix transposition - Rosetta Code

12:31 http://rosettacode.org/wiki/Matrix_transposition

12:31 amalloy: ev4l: ^

12:32 &(vec (map vector '[a b c] [1 2 3]))

12:32 sexpbot: ⟹ [[a 1] [b 2] [c 3]]

12:33 ev4l: amalloy: thanks! i need to get some speed with this seq transformations

12:49 angerman: we'll get rain… the local rainman is drumming again...

12:49 grr.

12:50 amalloy: ev4l: do you mean, the seq transformation needs to be fast; or, you need to get familiar with seq transformations so you can write them quickly?

12:50 ev4l: amalloy: the latter one. :)

12:51 amalloy: pretty ambiguous statement..haha

12:54 Derander: Raynes: sorry :-(.

12:54 Raynes: Derander: I don't mind. Like I said, it was just an observation. :p

12:55 saml: is there a collection of good clojure snippets? to show off people

12:57 dakrone: saml: clojuredocs.org has short snippets for examples for functions, if that's what you're looking for

12:58 amalloy: rosettacode has some, of highly variable quality

12:58 $google rosettacode clojure fibonacci

12:58 sexpbot: First out of 39 results is: Fibonacci sequence - Rosetta Code

12:58 http://rosettacode.org/wiki/Fibonacci_sequence

12:59 saml: thanks dakrone and amalloy

13:18 clojure-luddite: ok, I haven't touched clojure for a while now. turns out clojure development moved from svn to git, development sites went through google code, assembla, jira, and what not. in github the repositories were changed for clojure and contrib, and the old ones are still what google returns on the top. the docs are totally out of date everywhere, including the very nice clojuredocs. it seems there...

13:18 ...are multiple schemes for fetching jars and building projects, and every project adheres to only one of those schemes. contrib has been split, rearranged, moved, and some of it imported into core (docs not included). sure, I like it that clojure is innovative and cutting edge, but right now it's a moving target I'm sure even the best of us can't hit. simple file utils went from duck-streams to s

13:18 omething else to contrib.io to java.io to who knows where, and I can't find the freaking latest read/write-lines functions. can anybody help find them before I lose it?

13:18 sorry /rant

13:20 so, anyone knows where I can find the latest read/write-lines?

13:20 technomancy: read-lines was dropped because it's a common cause of resource leaks

13:21 clojure-luddite: so what's the up to date idiomatic way to lazily read lines from a file?

13:22 dakrone: ,(doc line-seq)

13:22 clojurebot: "([rdr]); Returns the lines of text from rdr as a lazy sequence of strings. rdr must implement java.io.BufferedReader."

13:22 technomancy: need to use with-open+reader to manage the scope of the file opening yourself

13:23 clojure-luddite: was the reader fn that automatically sets up the reader also dropped?

13:23 ampleyfly: technomancy: are you aware of any problems with running "lein plugin install swank-clojure 1.3.0" on windows? yesterday, I got the message that the jar could not be found in any of the places tried (like clojars, I presume)

13:24 dakrone: clojure-luddite: (with-open [r (clojure.java.io/reader "/tmp/foo")] (doall (map println (line-seq r))))

13:25 drewr: dakrone: doseq println please :-)

13:25 dakrone: drewr: right, my mistake :-/

13:25 clojure-luddite: dakrone: wasn't the all purpose of the read-lines to do just that?

13:25 technomancy: ampleyfly: weird, my push didn't seem to go through last night; re-pushed

13:25 thanks for the heads-up

13:26 ampleyfly: that explains it =)

13:27 dakrone: clojure-luddite: you're welcome to do (.split (slurp "/tmp/foo") "\n") if you need something simpler

13:28 technomancy: clojure-luddite: the difference is that read-lines closes the file non-deterministically

13:29 whereas with-open makes the scope explicit

13:29 * devn imagines what a clojure-luddite is

13:30 devn: someone who writes clojure, but only with pen and paper, not none of them newfangled computar(sic) contraptions

13:33 alpheus: That's honestly the way I learned C. Had a book, couldn't afford a computer.

13:36 sritchie: alpheus: that's the way I went through The Little Schemer

13:37 I've been working my way through the exercises in SICP, too -- I do them all by hand, and type them in later, when checking answers

13:46 Lulu58e2: sritchie: by "hand"? Is that a new language?

13:46 devn: *nod* yeah I'm not making fun of that approach -- i've used it as well, but i find the REPL feedback loop to be really instructive

13:46 * devn checks esolang

13:46 Lulu58e2: ;)

13:46 sritchie: Lulu58e2: haha, felt like it at first

13:47 devn: definitely! The repl's been amazing, switching to clojure. we can't all be don knuth

13:49 Lulu58e2: I feel more like Don Knotts most of the time

13:52 angerman: &(case (keyword ":foo") ::foo "Hi" "Ho")

13:52 sexpbot: java.lang.ClassCastException: clojure.lang.PersistentVector cannot be cast to clojure.lang.MapEntry

13:56 amalloy: ,(case (keyword ":foo") ::foo "Hi" "Ho")

13:56 clojurebot: "Ho"

13:57 amalloy: angerman: there's something wrong with sexpbot's macroexpansions in certain cases; i'm still not sure why

13:58 hiredman: ,::foo

13:58 clojurebot: :sandbox/foo

13:58 hiredman: ,(keyword ":foo")

13:58 clojurebot: ::foo

13:58 angerman: amalloy: hehe :)

13:59 still sad that (keyword ":foo") != ::foo

13:59 amalloy: angerman: that is not sad at all

13:59 angerman: amalloy: sad for me :)

14:08 amalloy: angerman: sad only if you are crazy. (keyword ":foo") properly "should" throw an exception, but its error handling is minimal

14:10 ataggart: amalloy: it's not clear to me why a keyword's name should be constrained to only those which can be literally represented.

14:19 kumarshantanu: hi, is it possible to access `this` object in (proxy ...) ?

14:19 hiredman: ,(doc proxy)

14:19 clojurebot: "([class-and-interfaces args & fs]); class-and-interfaces - a vector of class names args - a (possibly empty) vector of arguments to the superclass constructor. f => (name [params*] body) or (name ([params*] body) ([params+] body) ...) Expands to code which creates a instance of a proxy class that implements the named class/interface(s) by calling the supplied fns. A single class, if provided, mu...

14:21 dnolen: ,(keyword (str *ns*) "foo")

14:21 clojurebot: :sandbox/foo

14:21 dnolen: ,(doc keyword)

14:21 clojurebot: "([name] [ns name]); Returns a Keyword with the given namespace and name. Do not use : in the keyword strings, it will be added automatically."

14:22 dnolen: angerman: ^, that doesn't work for you?

14:33 I don't suppose anyone here's read the Dybvig Subcontinuations paper.

14:37 devn: amalloy: the more i look through your utils the happier i am -- im looking through my projects and adding to a devn/utils.clj || devn/utils/macros.clj

14:38 in a fork

14:38 amalloy: devn: glad to hear you have your own utils. what do you mean by "in a fork"?

14:39 devn: i forked the project and am adding mine in a devn.utils ns -- not sure if you'll want to pull them back in, but i figure it could be neat to generalize the project and make it a mix of different clojurians' utils

14:39 so i could do dnolen.utils, amalloy.utils, etc.

14:39 amalloy: interesting

14:40 i hadn't thought of that, and i think it would wind up with somewhat too much bloat if it caught on, but as long as it's unpopular it's pretty clever :)

14:40 devn: haha yes i was just thinking the same thing

14:41 however, with judicious pull requests it could mean that duplicated effort is not cool

14:41 i phrased that wrong: what i mean to say is, generalizing the project to make it less specific to one person and making it sort of a swiss army knife of things that aren't in contrib, could be cool

14:42 dnolen: wow, Simon Peyton Jones, Amr Sabry, Dybvig: A Monadic Framework for Subcontinuations (2005).

14:42 devn: even if it was a giant project, if it was well-organized by category, it could be a really useful set of things which dont fit in contrib

14:42 technomancy: isn't contrib just a set of things that don't fit anywhere else? that didn't work out so well.

14:43 jlf: amalloy: btw adding the hadoop dependency resolved the issue, cheers

14:44 devn: technomancy: how did contrib not work out?

14:46 amalloy: devn: it's being modularized for 1.3

14:47 devn: wow...someone is out of the loop

14:48 amalloy: no kidding

14:48 devn: ouch

14:51 technomancy: well, im not acting like it's revolutionary -- but it would mean a bit less ceremony for people to just drop a nice resuable function in here and there

15:21 i think i killed chat

15:32 * TimMc sidesteps a tumbleweed

15:33 amalloy: devn: looks like you deleted the fork and created a separate repo?

15:34 not-timmc: Watching from over here in my don't-hide-even-JOINs-and-PARTs account, I now see that empty conversational space is in fact filled with virtual users popping into and out of existence.

15:39 devn: amalloy: i did

15:39 going to roll my own amalloy

15:40 amalloy: very well...only know, you can never equal the true amalloy!

15:40 devn: i have like 50-60 mini toy projects that have snippets here and there, just spending the rest of the day walking through them and compiling what I like

15:40 amalloy: :D

16:03 mec: Any thoughts on making this implementation of life a bit faster? Currently it takes about 1/4 of a second to iterate https://gist.github.com/885740

16:05 raek: you are dereferencing the world a lot (not a very expensive operation, maybe). any reason why you don't swap! instead?

16:07 amalloy: reset! is crazy when the new state depends on the old state, even if it won't improve performance to change to swap!

16:08 mec: I checked and dereferencing once vs for each cell makes no difference.

16:08 I suppose I could switch to swap! but then i'd have to pass world to all the functions

16:08 raek: (using reset! that way is unideomatic, that's all)

16:09 amalloy: the horror. those functions all depend on the world; you're just pretending they don't by making the world a global

16:09 dnolen: mec: you should expect any game of life implementation written that way to be slow.

16:09 mec: https://gist.github.com/420036, similar and can do 2000x2000 in 480ms.

16:09 mec: dnolen: thanks i'll have a look

16:11 brehaut: dnolen: thats 1.3 code?

16:11 dnolen: brehaut: pretty sure 1.2

16:12 brehaut: so it is

16:12 raek: protocols supported primitives, but not functions?

16:12 hrml, that makes sense, though

16:13 dnolen: raek: protocol don't support primitives.

16:13 raek: ah, definterface, I see

16:14 brehaut: ah right. thats where i went wrong too

16:14 mec: is this better? https://gist.github.com/885740

16:18 amalloy: mec: next-world isn't passing along the world arg

16:19 mec: ya i fixed those

16:21 i was hoping i could get next-world faster with pmap, but it was actually slower

16:21 amalloy: so this is not at all a performance issue, and really kinda questionable style advice too, but you could avoid repetition by defining update-cell as (apply alive? (map #(% world x y) [cell neighbors]))

16:25 errr, ends with [count-neighbors get-cell]

16:25 mec: dnolen: how come cells is defined as ^longs ^longs but only ever used as a plain array

16:25 amalloy: or the other way round, whatever. you see what i mean, i hope

16:26 mec: amalloy: less repetition but harder to comprehend i think

16:26 amalloy: up t'you

16:26 actually that map is a little more verbose than necessary: ((juxt get-cell count-neighbors) world x y)

16:27 which is basically what juxt is for

16:27 mec: now thats not bad

16:28 amalloy: technomancy, raek: we have another juxt fan

16:28 raek: amalloy: :)

16:28 nice fit

16:33 dnolen: mec: what do you mean used as 'plain array' ?

16:34 mec: (aget cells n)

16:36 dnolen: mec: that's how Clojure array support works. i.e. aget-long would be wrong and slow.

16:36 mec: Is there any difference using ^longs ^longs cells over ^longs cells?

16:37 dnolen: mec: multidimensional array access is slow.

16:37 brehaut: dnolen: i think mec is talking about your type hint on line 12

16:38 dnolen: heh, typo

16:38 fixed

16:38 mec: ah

16:39 I couldnt figure out why it was hinted as a 2 dimensional array but built and accessed as one dimensional

16:39 dnolen: mec: yeah sorry about that.

16:40 while I'm at it: defrecord -> deftype.

16:40 no need for defrecord here.

16:41 brehaut: dnolen: can you explain that distinction a bit more?

16:42 dnolen: brehaut: between deftype and defrecord?

16:42 mec: yes please

16:42 brehaut: yeah, in particular in this context

16:43 Licenser: aloa

16:44 dnolen: defrecord creates fields for metadata and an extension map, not required here. It also declares a lot of unnecessary methods.

16:44 brehaut: thanks

16:47 mec: Now some UI code, be gentle its my first time ;p https://gist.github.com/885740

16:50 Although it is somewhat copied from the ants demo

16:56 brehaut: mec, you've copied an old style meta hint for Graphics

16:56 just use a hat, you dont need the hash any more

16:57 mec (line 53)

16:57 mec: thanks

16:58 was thinking that was in 1.3 for some reason

16:58 brehaut: my memory of these things is shaky, but i think its 1.2

16:59 mec: ya it works fine

16:59 amalloy: brehaut: i think that's correct, but i've never written any 1.1 code

17:00 brehaut: mec asside from being a giant bag of globals your swing code is as decent as swing code normally gets :P

17:01 mec: Hows the bottom there? I was using agents like in the original ants, and I just kind of guessed at how to correctly do this

17:01 with futures

17:01 brehaut: looks fine

17:01 amalloy: augh dorun/for. plz use doseq

17:03 mec: thanks I can never remember which combination that is

17:03 amalloy: re: globals, this code seems pretty easy to wrap up into a big let instead

17:04 brehaut: i think that (dorun (for is another artifact of the ants demo being such old code

17:04 mec: is there a shortcut for doall/for

17:05 brehaut: i think that would also be doseq

17:06 it just makes you be explicit that its side effecting (because it doesnt return the head)

17:06 Caffeine: I'm writing my first potentially big enough Clojure program and I'm wondering if there is a commenting convention for documentation production, like what is JavaDoc to Java.. ??

17:07 mec: I think the autodoc for like http://clojure.github.com/clojure/clojure.core-api.html is just the function comments

17:08 _ato: Caffeine: do you mean like /** ... */ ? Clojure has explicit docstrings, eg (defn foo "Docs go here" [])

17:09 semperos: you can use marginalia and include comments in markdown format, both in your function docs and throughout your code base

17:10 https://github.com/fogus/marginalia

17:10 technomancy: _ato: thanks for the thorough reply re: clojars ops =)

17:11 Caffeine: _ato: ahh I think that's what I'm looking for

17:12 _ato: technomancy: no worries. I'm not too good at documenting things until someone asks me :p

17:13 Caffeine: _ato: semperos: I know how to make comments, but I want the standard Clojure way of documenting, so that it's conform and that I could eventually generate documentation .. kindof javadoc but not necessarily that.. dunno how that would be called for clojure... ClojureDoc?

17:13 semperos: marginalia generates documentation

17:13 tsdh: If I have a seq of 1-ary predicates, how can I combine them using AND into one function?

17:13 semperos: it's not formatted like javadoc, but it's worth a look to see if it suits your needs

17:13 Caffeine: semperos: ok good, thanks!!

17:14 semperos: np

17:14 _ato: Caffeine: also have a look at http://tomfaulhaber.github.com/autodoc/

17:14 Caffeine: yeah it should be okay, I don't need any particular format, just good looking.. better looking than through code, that is

17:14 _ato: ok thanks

17:14 semperos: autodoc is what is used for the official api docs, whereas marginalia is like read through your code with help; you probably want autodoc

17:15 *like reading

17:15 Caffeine: ahh probably then

17:15 mec: tsdh: #(apply and (apply juxt predicates) %)

17:16 tsdh: mec: I've thought it would be something with juxt. :)

17:16 brehaut: on #clojure its always something with juxt

17:17 mec: hmm that doesnt quite work because and is a macro

17:17 brehaut: #(and %&)

17:18 amalloy: mec: http://groups.google.com/group/clojure-dev/browse_thread/thread/899349c6a9b526e0/41f1a8012f861309?show_docid=41f1a8012f861309

17:18 brehaut: that function is equivalent to identity

17:18 oh, and tsdh also, ^

17:18 brehaut: oh so it is

17:19 tsdh: I've just got aware of that...

17:19 * amalloy wonders if those made it into 1.2.1

17:19 mec: identity would work, it doesnt handle varargs

17:20 r/would/wouldnt

17:20 brehaut: mec, amalloy is pointing out that due to the magic of macros etc, that function i wrote is just an identity

17:20 amalloy: mec: my point is that brehaut's implementation doesn't work. it's not *exactly* like identity, but it's close

17:20 brehaut: it doesnt actually apply and

17:20 amalloy: it's more like (complement (comp zero? (comp count list)))

17:20 brehaut: (or more correctly, it applies and but its not what you think)

17:20 amalloy: ie, "true iff you pass at least one arg"

17:21 not sure why i used two comps, there

17:21 (comp pos? count list)

17:21 tsdh: mec: Then I'll use this AND: #(if %1 %2 false)

17:22 amalloy: tsdh: #(when %1 %2)

17:23 mec: (fn [arg] (reduce #(and %1 %2) ((apply juxt predicates) arg)))

17:23 (fn [& predicates] (fn [arg] (reduce #(and %1 %2) ((apply juxt predicates) arg))))

17:24 tsdh: Oh, that's nice.

17:24 mec: lol i just opened that page amalloy linked, its almost exactly that

17:25 (defn conjoin [& preds] (fn [& args] (every? (fn [arg] (every? #(% arg) preds)) args)))

17:25 brehaut: &(apply every? identity ((juxt (constantly true) pos?) 1))

17:25 sexpbot: java.lang.IllegalArgumentException: Wrong number of args (3) passed to: core$every-QMARK-

17:26 brehaut: &(every? identity ((juxt (constantly true) pos?) 1))

17:26 sexpbot: ⟹ true

17:26 brehaut: &(every? identity ((juxt (constantly false) pos?) 1))

17:26 sexpbot: ⟹ false

17:31 amalloy: i've finally figured out a way to use paredit-convolute-sexps!

17:32 it makes it easier to turn (if test (f a1 a2 special-value) (f a1 a2 other-value)) into (f a1 a2 (if test special-value other-value))

17:33 brehaut: thats cool

17:34 mec: all I can do is move parens around, i havnt figured out how to move sexprs

17:34 amalloy: mec: with paredit mode, you're not allowed to move parens anymore :P

17:34 mec: what do you mean? thats all I use paredit for

17:35 amalloy: i mean, all of the paredit functions operate on sexps. that happens to cause parens to move around in some cases, but you're always working with sexps

17:36 maybe it's just a spiritual thing, i dunno

17:37 mec: lol all i have interned is C-<left> and C-<right>

17:37 pauldoo: when inside a transaction, is there a way to 'deref' but without without the guarantees of the transaction? I.e. I want to get some value out the ref, but don't want it to cause my transaction to fail on commit

17:37 brehaut: mec learn M-s and C-k next

17:38 amalloy: eg paredit-forward-slurp-sexp doesn't "move a paren forward", it "modifies current sexp to include next sexp, then deletes next sexp"

17:38 brehaut: i rarely use M-s

17:38 TimMc: mec: C-M-k kills the next form. Very useful.

17:38 amalloy: M-<UP> ftw

17:38 mec: oo how do you kill previous

17:38 pauldoo: I guess I can deref before entering the transaction and grab the last comitted value, and then use that inside the transaction

17:39 just wondering if I can do that from inside the transaction

17:39 mec: you can deref inside a transaction to grab the latest if you're retried

17:39 amalloy: mec: i don't think paredit has a command for that. you don't really need it

17:40 mec: amalloy: right M-<UP> is what i wanted

17:43 amalloy: mec: M-<DOWN> and M-r are similar to that, if you want to do something slightly different

17:44 mec: my m-l and m-r just move the cursor a word

17:45 amalloy: M-r, really?

17:45 brehaut: my problem with paredit is that ive interned enough of it to be useful (and so that i dont have to reference the cheat sheet) but ive forgotten what i havent interned

17:45 ejackson: brehaut: I even have the damned cheatsheet on my desk, and fail to look at it.

17:45 amalloy: try C-h k m-r, or C-h f paredit-raise-sexp

17:46 mec: i gave up trying to remember too much, it takes more time to look it up than just do something by hand

17:46 amalloy: those two should be bound to each other

17:46 mec: a ya m-r does

17:52 amalloy: brehaut: if you find yourself wondering whether paredit can do X for you, try C-h f paredit-<TAB>, maybe?

17:52 brehaut: amalloy: its not that i wonder, its that i dont wonder. im using it to half efficiency but its so much more efficent than not that i never stop to learn more

17:53 amalloy: feh. always wonder. improve your tools. various curmudgeonly unhelpful advice

17:54 brehaut: im sure ive mentioned my non-tool-using monkey ways before. i spent my time wondering about my code and not about the tools.

17:54 and despite trying a lot, i cant seem to rewire my brain to think about both

17:55 Licenser: clojure is pretty darn sweet for sysadmin tasks :D

17:56 ejackson: Licenser: despite the startup time ?

17:56 Licenser: ejackson: yap doesn't matter

17:56 ejackson: i guess if its cron, who cares ?

17:57 Licenser: It's a data collection task

17:57 so even 1m startup won't be trouble

17:58 I've a program to ssh to multople hosts, run commands collect the results and evaluate the output

17:59 mec: Do I still use proxy for an abstract class?

18:01 Licenser: https://gist.github.com/51d43bff9d076d36f4f3 < reads ifconfig -a and parses the interface details

18:01 darn easy :)

18:07 amalloy: mec: reify

18:07 (that is, you *can* use proxy, but reify is much lighter-weight and usually suffices)

18:08 mec: reify doesnt allow abstract classes

18:11 amalloy: really?

18:11 &(doc reify)

18:11 sexpbot: ⟹ "Macro ([& 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 [a... http://gist.github.com/886009

18:12 mec: deftype is the same way

18:12 amalloy: clojure's big "screw you" to implementation inheritance i guess

18:13 mec: They throw an exception if you call a method from an interface that isnt explicitly defined right?

18:13 TimMc: amalloy: Rich was pretty clear on that in one of his talks.

18:14 amalloy: TimMc: sure, and i'm happy to not be allowed to define abstract classes

18:14 but it seems like the definition of reify (both in english and in clojure) is compatible with an abstract class

18:15 mec: well for swing I either proxy WindowAdapter or reify WindowListener and have to specify all the methods myself

18:17 TimMc: I haven't done much work in Clojure that requires a bunch of functions to all operation on the same custom data structure, but namespaces seem to work fine.

18:19 amalloy: TimMc: it seems to me that you are arguing against a point nobody is making

18:20 TimMc: haha

18:33 amalloy: you have to wonder how anyone could write the WindowAdapter class and not ask themselves "is my language so lame that i really have to do this?"

18:42 ossareh: morning

19:00 amalloy: wow, immutability has gotten really deep in my head. i saw the following PHP (no, no idea what the code is actually for) and was sure it could never terminate: while (isset($PROFS[$desc]['end'])) {$desc .= '*';}

19:01 dnolen: finally something worth using clj-cont for, nestable engines / coroutining.

19:11 TimMc: amalloy: Well, it was an issue I ran into with Javascript, for instance.

19:11 I'm delighted that I haven't had the same problem yet in Clojure.

19:11 amalloy: what issue/problem?

19:14 TimMc: Not having a good way of organizing a group of functions that all operate on the same custom data structure.

19:14 None of the techniques I tried in JS was very satisfying.

19:26 lucian: TimMc: uh, classes?

19:26 TimMc: lucian: In JS?

19:26 lucian: TimMc: sure. they're just more verbose to write

19:27 look at CoffeeScript's classes

19:27 note what they compile to http://jashkenas.github.com/coffee-script/

19:27 TimMc: Well, that's not raw JS.

19:27 lucian: doesn't matter, you can write the raw js if you want

19:27 or you can use one of the many (and tiny) libraries that can do that for you

19:28 but really, there's no reason not to use CoffeeScript if you like

19:28 TimMc: My experience with JS predates CoffeeScript. :-)

19:29 I may investigate it.

19:59 Anyway, I now find it convenient to represent a "class" as a namespace full of constructors, accessors, and other methods. Then I (:require [class :as c]) so can do (c/constructor ...) etc. Seems to be a useful and natural pattern.

20:09 amalloy: TimMc: why are you doing this kind of oop in clojure? interop or something?

20:09 TimMc: Nah, it just seemed natural a couple of times.

20:10 amalloy: i'd like to take your word for it, but criticism and evangelism are so much more fun :)

20:10 TimMc: :-)

20:12 To use a weak but close at hand example, I had a representation for triangles in my 3D rendering program. I wanted to keep implemenation details from leaking to the rest of the program, so I kept them in one namespace: https://github.com/timmc/CS4300-HW4/blob/master/src/timmcHW4/tri.clj

20:13 As it turns out, I'll probably need to redo the implemenation drastically for HW5, so this abstraction barrier may have to fall anyway.

20:15 amalloy: i'm not against this sort of separation of concerns. i thought you actually meant (defn constructor) and other gross OO stuff like mutators

20:16 and +1 for the unicode. i intend to configure emacs to let me type in that crap more easily sometime

20:16 (good idea or no)

20:17 Frozenlock: Greetings gentlemen, I'm currently trying to install clojure with swank and slime. I downloaded swank with the ELPA, but now that I'm trying to M-x slime, I'm unable to get the swank-clojure jar file. "byte-code: Failed to download Clojure jars." I would be very grateful if one of you could give me a hint on how to proceed.

20:18 technomancy: Frozenlock: the swank-clojure readme should have you covered; short version is instead of M-x slime you use lein swank plus M-x slime-connect

20:20 Frozenlock: Oh thank you, I'll read that right away

20:20 no_mind: is there a way to have dynamic routes in compojure instead of hardcoding the routes in a function ?

20:21 brehaut: no_mind: what do you mean by 'dynamic' ?

20:22 no_mind: brehaut, I want to define a ogic in which based on the url, the application should dispatch the request to suitable module. for eg. a url abc.com/home/add should call add function in a module called home

20:23 brehaut: ogic ?

20:23 amalloy: logic, smartypants

20:23 brehaut: oh right :)

20:23 i thought it was an abbreviation i didnt know

20:24 amalloy: sometimes i wonder if "logic" is something i don't know about

20:24 hiredman: no_mind: https://github.com/hiredman/graft

20:26 https://github.com/hiredman/place-for-things

20:27 technomancy: hiredman: ITYM "utils"

20:27 oh wait, nm

20:27 hiredman: I know what you meant

20:27 technomancy: I thought "place-for-things" was your "bucket-o-stuff" repo

20:29 brehaut: do you attach an arbitrary ring handler into a compojure app?

20:30 can you just put it in place of the (GET whatever) ?

20:30 hiredman: I donno

20:30 dunno

20:30 brehaut: no matter

20:30 hiredman: I haven't done any compojure in maybe a year or more

20:31 brehaut: neither. i switched to moustache and never looked back

20:39 ossareh: brehaut: what are the key differences between moustache and compojure? I took your advice on the enlive vs hiccup and chose enlive and <3 it a lot.

20:39 brehaut: ossareh: much smaller than between enlive and hiccup

20:39 ossareh: you mean the reasons are?

20:40 brehaut: the difference sorry

20:40 they both achieve very similar things

20:40 and through quite similar mechanisms

20:41 ossareh: i've been butting heads with compojure in a few ways recently - most notably I want email addresses in my routes and I need to supply a regexp to clout to get that to work.

20:42 brehaut: the biggest differences as far as i can see is that moustache's RHS of a route basically has to be a ring handler function, whereas compojure has a lot more flexibility there

20:42 i think in terms of actually routing facilities the two are about equal

20:43 biggest difference is that moustache requires a vector of rules to match, whereas clout has some sugar to let you use a string

20:44 personally i have a preference for moustache's simplier apps; its very clearly glue for ring handlers

20:45 ossareh: heres a very simple example https://github.com/LauJensen/SocialSite/blob/master/src/socialsite/core.clj#L83-96

20:53 technomancy: is compojure mostly just routing?

20:54 brehaut: technomancy: give or take yeah

20:54 all the non-routey stuff got extracted out into other libraries (including the routing engine 'clout')

20:55 it knows how to take a bunch of different types of things and turn them into responses, and has some utilities for applying middleware too

20:58 TimMc: amalloy: In Ubuntu (probably thanks to GNOME) I just use C-S-u and type the hex code for Unicode -- works in Emacs and everything. In this case, I used copy and paste. :-P

20:59 amalloy: that's control-super-u?

21:00 doesn't do anything for me

21:00 TimMc: Ctrl-Shift-u

21:00 C-U, sorry

21:00 technomancy: M-x ucs-insert if you want to use the code-point's name

21:01 ‽ is especially handy for functions that are destructive but also happen to be predicates

21:01 amalloy: *laugh*

21:01 hiredman: wow

21:02 growl rendered that as an alpha and an omega

21:02 technomancy: you and your ridiculous MacRoman.

21:02 amalloy: (defn was-eaten‽ [atom] (reset! atom nil) true)

21:03 aw, i forgot to write "eat it" in there, whatever

21:09 ossareh: I kinda sorta hate AOT.

23:27 * devn wonders what it would take to put every single core function into a single program

23:27 devn: *goal*

23:44 amalloy: devn: you could probably list all existing namespaces and require them all

23:46 _ato: devn: if you write a program that uses every core function purposely (like it actually achieves something useful with each) I will be extremely impressed :D

23:46 for the ultimate challenge use every core function exactly once

23:47 devn: _ato: I was thinking I might start with the cheat sheet

23:47 and then work my way out

23:47 How many core functions (that are usable) are there?

23:47 and by usable I mean "regular" and "occur in regular programs"

23:47 I think it's somewhere around 4-600?

23:55 amalloy: devn: heh. 4 <= x <= 600? surely you can manage a smaller window than that

Logging service provided by n01se.net