#clojure log - Dec 17 2011

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

0:00 amalloy: jcromartie: (proxy [Foo] [] (someMethod [] (.redraw this)))

0:00 jcromartie: this!

0:00 of course

0:00 thanks

0:01 TimMc: OK, turns out the CLJS compiler will not write to an existing file. >_<

0:09 but now there is a sort of cljs REPL on k.timmc.org:7013

0:10 no client support yet -- but (+ 1 2) works

0:16 davekong: The clojure spec says that when Integers becomes to large they will automaticall be converted to BigNums but (use 'clojure.contrib.math) (expt 999 999) and I get an overflow error?

0:33 clojurebot expt

0:39 notostraca2: &(doc expt)

0:39 lazybot: java.lang.RuntimeException: Unable to resolve var: expt in this context

0:39 notostraca2: ,(doc expt)

0:39 clojurebot: Gabh mo leithscéal?

2:05 mrevil: i don't understand the purpose behind the necessity of deftest, why not just testing "…"?

7:46 Borkdude: What is the most idiomatic way to get true or false out of (some pred coll) instead of nil?

7:59 raek: Borkdude: run it through 'boolean': (some (comp boolean f) coll)

8:01 or if 'pred' is a set, you can use 'contains?' as the function instead of 'get' or the set itself

8:03 Borkdude: raek: ah ok

8:45 Vinzent: Hello. I'm trying to use clojure.core.cache, but (cache/fifo-cache-factory 10 []) gives me "Assert failed: (map? base)". Why? I don't want a map, I want just a collection of values. Can somebody please explain me how to use this library?

8:51 janissary: Xjk

9:02 jasperla: anyone here used xmpp-clj? it doesn't seem there's a way to initiate a chat, right?

9:57 Vinzent: what's with clojureql.org?

9:58 tscheibl: seems like it's standing still... isn't it?

10:01 Vinzent: hm, I can't open it (unknown host)

10:01 tscheibl: I can... but maybe it's cached in my DNS

10:02 you are right...

10:02 it was only cached in my browser

10:05 Vinzent: looks like it isn't mainained now at all... well, looking at korma

10:06 tscheibl: I had a look at Korma, too... but stayed with clojureql... improving it by myself

10:07 Korma is a bit too much ORM for my taste....

10:08 Vinzent: have you considered forking it?

10:08 tscheibl: I've cloned it locally

10:09 when I find some time I will eventually push my changes to a github fork

10:10 ... I've integrated a slightly modified version of bendlas' "with recursive" improvements

10:11 and added the possibility to use non parameterized (inline) predicates... which is usefull with the "with recursive" construct.. at leas with H2 DB

10:13 ..yes.. and I can use sql functions now with update queries... useful for example to increment a revision count within an update query

10:14 btw, clojureql is still online on github

10:15 Vinzent: yeah, I agree it feels like orm, and for my case clojureql would be a better fit, but you know, docs and all that stuff - probably it'd be easier and faster with korma...

10:15 accel: is there a simple way in clojure ot get a dump of all threads in the current jvm?

10:17 Vinzent: that's cool! you should definitely push it to the main repo

10:21 tscheibl: @accel: not in core ... I'v used Java interop utilizing the Thread and ThreadGroup classes to implement this

10:21 accel: tscheibl: do you have a short snipplet of code you can paste bin?

10:22 tscheibl: accel: let me see...

10:22 accel: awesome :-)

10:26 tscheibl: accel: damnit .. didn't commit it into the repo...

10:27 but basically you have to get your current thread using (Thread/currentThread)

10:27 accel: is it like: http://stackoverflow.com/questions/1323408/get-a-list-of-all-threads-currently-running-in-java ?

10:27 tscheibl: yep

10:28 accel: noted; thanks

11:10 can someone point me at a guide for doing blind, stupid line by line trannslation of java into clojure?

11:10 [I'll fiure out how to clojure-ify it after I get it working]

11:12 nickik: accel, there is no guild. You'll have to look at the clojure-java interop stuff.

11:12 Vinzent: new Class() becomes (Class.), obj.method becomes (.method obj), cls.static() becomes (cls/static), that's all

11:12 nickik: You will find lots of examples in the internet

11:13 accel: how about new Class (foo)

11:13 does it beomce (new Class foo) ?

11:13 nickik: (Class. foo)

11:13 Vinzent: yes, or (Class. foo)

11:13 accel: cls.static(foo, bar) -> (. cls static foo bar) ?

11:13 Vinzent: (cls/static foo bar)

11:14 accel: Vinzent: nice; thanks

11:14 does clojure have osmethig like lisp's let* ?

11:16 TimMc: accel: let

11:17 amusingly, let* is like lisp's let

11:17 because it is the more basic form that let uses.

11:18 &(let [x 5, x (+ x 2)] x)

11:18 lazybot: ⇒ 7

11:18 accel: lol; clojure does not give a damn about lisp specs

11:18 TimMc: accel: That confused the hell out of me until I re-read http://clojure.org/lisps

11:19 Clojure is a Lisp, but it is not Common Lisp.

11:19 &((fn [x x x] x) 1 2 3)

11:19 lazybot: ⇒ 3

11:19 TimMc: ^ fn binds sequentially as well

11:22 tscheibl: accel:

11:22 (defn root-thread-group []

11:22 (loop [thread-group (.getThreadGroup (Thread/currentThread))]

11:22 (let [parent-group (.getParent thread-group)]

11:23 (if parent-group

11:23 (recur parent-group)

11:23 thread-group))))

11:23 this gives you the root thread group in clojure

11:23 TimMc: tscheibl: *cough* gist *cough*

11:23 tscheibl: sry

11:24 accel: tscheibl: nice; thanks :-)

11:25 do I need to import something to be able to say (foo/bar) instead of (. foo bar) ?

11:25 tscheibl: (foo/bar) denotes a static method call

11:27 but you could use the (.bar foo) sugar to abbreviate calls to instance methods

11:28 Vinzent: accel, you need to import to be able to say e.g. Baz/static instead of foo.bar.Baz/static, this is just like in java

11:28 accel: noted

11:28 fixing things up :-)

11:31 woot; I think it kinda worked

11:31 thanks everyone

11:32 tscheibl: accel: you could even replace the let and if lines with (if-let [parent-group (.getParent thread-group)] ...) to gain one line of code :)

11:32 I mena... to save one line...

11:32 mean

11:35 accel: is there a good documentation of "all the things clojure changed from standard lisp/scheme?"

11:36 tscheibl: accel: http://clojure.org/lisps

11:36 accel: tscheibl: awesome; thanks!

11:39 cgray: is there a version of with-open that can handle being read from lazily?

11:40 sorry, that's not too clear... i want to put a java.io/reader in a with-open, and then read from the reader lazily

12:11 accel: I have a basic cojure GUI (basically http://clojure.org/jvm_hosted). I have another piece of clojure code that renders to a graphics 2d environment. Question: How do I create a graphics 2d environment?

12:11 I have a basic cojure GUI (basically http://clojure.org/jvm_hosted). I have another piece of clojure code that renders to a graphics 2d environment. Question: How do I create a graphics 2d environment (within the GUI I have; i.e. what gui element do I want? i.e. something of the type JLabel, JButton, ... but not quite, maybe somethging like JGraphics2D)

12:13 hmm, JPanel followed by a getGraphics

12:13 ?

12:13 surely there is a less hackish way

12:23 tscheibl: accel: why don't u use something like https://github.com/daveray/seesaw for GUI development? ... there is another one on github.. I forgot the name...

12:24 ahh yeah.. that one: https://github.com/stathissideris/clarity

12:24 clojurebot: eg, https://github.com/clojure/tools.logging is the new version of clojure.contrib.logging

12:27 accel: as it turns out

12:27 all I literally need

12:27 is a graphics 2d environment

12:27 to render graphics stuff to

12:33 TimMc: accel:Something like this? https://github.com/timmc/CS4300-HW3/blob/master/src/timmcHW3/gui.clj#L179

12:35 accel: TimMc: not sure yet

12:35 I just threw in a JPanel; now trying to get stuff to render to it

12:36 TimMc: accel: Just proxy a JComponent.

12:36 override the paint method.

12:36 cgray: accel: if you don't need buttons and stuff, you might want to look at clj-processing

12:38 accel: muhahaha

12:38 got it working :-)

12:38 clj-processing soudns cool though :-)

12:38 TimMc: ended up I think, doing the equiv of proxing a jpanel

12:39 TimMc: cool

12:39 "you think"? :-P

12:39 accel: i'm famliar with neither java nor clojure

12:39 I have noi dea what I've done, but it works :-)

12:39 TimMc: haha

12:39 accel: You'll want to read up on the Swing event loop at some point.

12:40 accel: this is the "learn a programming language by picking a project + trying to make it work" approach

12:40 TimMc: It's not too complicated, and it's important to know.

12:40 accel: yeah; I need to understand how the separte GUI thread

12:40 and what I'm allowed to do in what thread

12:40 TimMc: accel: https://github.com/timmc/CS4300-HW3/blob/master/src/timmcHW3/core.clj#L557 Check out what launch does and how it is invoked from -main.

12:41 accel: what is this

12:41 and how are you taknng a CS class

12:41 where the HW is done in clojure

12:41 and why is your CS HW publically abailable on github? :-)

12:42 TimMc: Ignore all the ref-set stuff, just note that the frame is created from an invokeLater.

12:42 accel: Computer Graphics course at Northeastern University. The prof said any language was fine. :-)

12:43 He also OK'd putting the stuff on GitHub -- I don't remember if I put it up after the assignment was over, or because it's an honor system, or what.

12:49 accel: I also managed to get permission to use Clojure for my Computer Architecture course.

12:51 In the REPL, how do I switch over to another namespace and have all the defs refer'd?

12:54 tscheibl: refer to the previous namespace?

12:55 TimMc: No, refer all the new defs, as if I had started the REPL there.

12:55 tscheibl: the defs you did before switching?

12:56 TimMc: No, the defs in the new namespace.

12:56 I mean, I could (use 'other.namespace)...

12:59 tscheibl: sounds good

13:00 (in-ns 'namespace-name) should also work if the namespace is already loaded

13:01 TimMc: oops, in-ns takes away core...

13:01 I think I'll stick with use.


13:02 tscheibl: ^^

13:02 TimMc: "Assert failed: Can't recur here" -- and then the next time I call it, no problemo

13:03 tscheibl: lol

13:05 .. just catch the first exception and retry :D

13:10 TimMc: ugh, seriously.

13:10 I think I'm going to add that to the startup code. >_<

14:19 duck1123: what projects would anyone recommend to look at that are extensively tested in Midje? (aside from midje itself)

14:40 accel: is there a program where I can feed it a collection of *.Java files

14:41 and it'll pull out all the constructors for me?

14:41 I have a huge java library and I need to interface with clojure

14:55 qbg: accel: Maybe using reflection on the classes themselves might be better

15:29 blakesmith: If I have a sequence of integers that represent a right single quote in UTF-8 (http://www.fileformat.info/info/unicode/char/2019/index.htm), what's the easiest way to convert that to a string?

15:30 Trying with no success. https://gist.github.com/1491274

15:30 I think I'm missing something obvious. :-(

15:36 qbg: blakesmith: Try using String(byte[], Charset) instead

15:36 tomoj`: have to get bytes somehow

15:37 but they're signed..

15:37 blakesmith: I found out Java doesn't support unsigned bytes. :-(

15:37 qbg: Doesn't matter

15:37 You need to cast them to byte

15:38 tomoj`: .. manually? :)

15:38 qbg: clojure.lang.RT has a method for the cast

15:38 tomoj`: &(byte 0xE2)

15:38 lazybot: java.lang.IllegalArgumentException: Value out of range for byte: 226

15:38 blakesmith: &(byte 0x99)

15:38 lazybot: java.lang.IllegalArgumentException: Value out of range for byte: 153

15:38 tomoj`: oh, nice

15:38 qbg: Yeah, byte doesn't work

15:38 tomoj`: hmm

15:38 you mean byteCast?

15:38 qbg: There is an unchecked byte cast method on clojure.lang.RT

15:38 I forget the name of it though

15:39 tomoj`: I get the same error

15:39 ah, uncheckedByteCast

15:39 qbg: ,(clojure.lang.RT/uncheckedByteCast 226)

15:39 clojurebot: -30

15:39 qbg: Yep

15:39 There we go

15:39 tomoj`: excellent

15:39 blakesmith: Nice. Thanks guys!

15:39 I'll give it a shot.

15:45 qbg: Hrm, I'm getting java.lang.IllegalArgumentException: No matching method: uncheckedByteCast (NO_SOURCE_FILE:104)

15:45 user=> (clojure.lang.RT/uncheckedByteCast 226)

15:45 qbg: What version of clojure are you using?

15:45 blakesmith: 1.2.1

15:47 qbg: ,(.byteValue 226)

15:47 clojurebot: -30

15:47 qbg: Try that

15:48 blakesmith: Cool, got it.

15:50 ,(String. (into-array Byte/TYPE (map #(.byteValue %) [0xE2 0x80 0x99])) "UTF-8")

15:50 clojurebot: "’"

15:50 blakesmith: Awesome, must be my terminal.

16:04 tomoj`: oh.. ##(unchecked-byte 0xE2)

16:04 lazybot: ⇒ -30

16:14 raek: blakesmith: if you use Mac OS X, java is configured to use the wrong default encoding

16:15 blakesmith: but (String. bytes charset) and (.getBytes string charset) is the correct way

16:38 compmstr: When setting up a macro (defmacro def-func [name] `(defn ~name [attribs] ... why does it turn attribs into user/attribs and not set it up as the argument to the defined function?

16:40 I end up getting the error: "Can't use qualified name as parameter: user/attribs" when I attempt to use the macro

16:40 Bronsa: this is because syntax-quote automatically namespace-qualifies vars

16:41 what you need to do is to replace attribs with attribs#

16:41 TimMc: Bronsa: Thank you for saying that, Bronsa, for you have saved me from making a stupid suggestion.

16:41 (but not saved me from writing awkward sentences)

16:42 Bronsa: TimMc: haha you're welcome

16:42 compmstr: Thank you, so that makes it so that a symbol stays a local symbol instead of expanding to a namespace?

16:42 er...

16:42 Bronsa: ,`(a)

16:42 clojurebot: (sandbox/a)

16:42 Bronsa: ,`(a#)

16:42 clojurebot: (a__106__auto__)

16:42 TimMc: compmstr: foo# is a gensym -- a symbol will be created for you.

16:42 Bronsa: that ^

16:42 compmstr: Ah, ok

16:43 TimMc: &`(fn [x#] x#)

16:43 lazybot: ⇒ (clojure.core/fn [x__15392__auto__] x__15392__auto__)

16:43 compmstr: I was starting to get around it using (symbol ...), but I thought there had to be a better way

16:43 TimMc: compmstr: and it will be the same symbol for all instances of foo# in the syntax-quote.

16:43 compmstr: Is that documented anywhere?

16:44 TimMc: It's probably in clojure.org/reader

16:44 (The URL, not a namespace)

16:44 Bronsa: http://clojure.org/reader under "Syntax-quote"

16:44 gfredericks: &`(#foo #foo ~(list `#foo))

16:44 lazybot: java.lang.ClassNotFoundException: foo

16:44 gfredericks: hmm

16:45 compmstr: Thank you very much :)

16:45 * gfredericks can't figure out what went wrong there

16:45 compmstr: I've been mainly using the cheatsheet

16:45 TimMc: gfredericks: foo# not #foo

16:45 gfredericks: oh ha

16:45 Bronsa: gfredericks: did you mean foo#?

16:45 gfredericks: just saw that

16:45 &`(foo# foo# ~(list `foo#))

16:45 lazybot: ⇒ (foo__15401__auto__ foo__15401__auto__ (foo__15400__auto__))

16:54 TimMc: Ugh, I just want to give up on this try-cljs thing.

16:55 CLJS is so awkward to work with.

16:55 budu: talking of CLJS, anybody got the browser REPL working through lein repl?

16:56 TimMc: 1) I can't just make an API call and get compiled code back -- it has to write it to the filesystem, and then I have to read it back in.

16:56 2) The GClosure system has its own notions of where dependencies live, and it isn't very clear what those are.

16:56 alexbaranosky: TimMc: I see your commit. Cool.

16:57 really busy now, hopefully I can get to TryCljs at some point

16:57 TimMc: 3) I have to jump through hoops to compile all the cljs client libs to JS first.

16:57 blakesmith: raek: Thanks, what's the easiest way to change it? (I'm on OS X)

16:58 TimMc: alexbaranosky: I sort of almost have the CLJS client libs loading...

16:58 alexbaranosky: nice!

16:59 TimMc: non-technical question - do you think TryClojureScript is a better name, considering the site is targeted at beginners, who will probably have no idea what cljs is?

16:59 TimMc: alexbaranosky: The first compilation almost always fails with an AssertionError, and then succeeds for every subsequent try.

17:00 alexbaranosky: Sounds good.

17:00 alexbaranosky: TimMc: strange... what's the assertion error?

17:00 TimMc: I don't have it on hand, let me start it back up.

17:00 alexbaranosky: TimMc: I'll add the cljs -> ClojureScript idea to the TODO file, and get to it when I have time to play

17:03 TimMc: alexbaranosky: "recur not allowed here" or something.

17:05 it's in the cljs compiler

17:05 alexbaranosky: TimMc: strange. My first thought when you said it failed the first time but not afterward, was maybe that there was some weird timing or ordering issue ----- doesn't seem likely though if the error is coming from the compiler

17:06 TimMc: It only happens on the first call, and almost always.

17:06 totally weird

17:06 alexbaranosky: are the inputs to the first and second call preceisely the same?

17:07 maybe one is html encoded and the second one is decoded - shot in the dark

17:07 I have to go though, ciao

17:07 TimMc: precisely

17:07 cya

17:08 alexbaranosky: TimMc: bug in compiler?

17:09 djhworld: w

17:11 gfredericks: djhworld: x

17:17 budu: is there a way to get the cljs repl working with slime?

17:18 TimMc: at least (js* "alert(5)") :-P

17:18 *works

17:30 technomancy: budu: no; it would be tons of work to get that working.

17:38 devn: good way to convert 500 to [5 0 0] without a lot of intermediate nonsense?

17:41 weavejester: devn: Are you asking for a good way to do that?

17:41 devn: weavejester: i am

17:41 TimMc: devn: Depends on what you mean by "intermediate nonsense".

17:41 devn: TimMc: I'm thinking about str -> char -> int, etc.

17:41 weavejester: (->> 500 str (map #(Integer. %)))

17:42 ,(->> 500 str (map #(Integer. %)))

17:42 clojurebot: #<ExecutionException java.util.concurrent.ExecutionException: java.lang.IllegalArgumentException: No matching ctor found for class java.lang.Integer>

17:42 TimMc: &(map #(Integer/parseInt (str %)) (Integer/toString 500 10))

17:42 lazybot: ⇒ (5 0 0)

17:42 weavejester: Oh, oops

17:43 Somelauw: ##(Integer/toString 500) vs ##(str 500)

17:43 lazybot: (Integer/toString 500) ⇒ "500"

17:43 (str 500) ⇒ "500"

17:43 technomancy: it's too bad there's no memfn equivalent for static methods and constructors

17:43 weavejester: Yeah...

17:43 technomancy: ,((memfn Integer.) "30")

17:43 clojurebot: #<IllegalArgumentException java.lang.IllegalArgumentException: No matching method found: Integer. for class java.lang.String>

17:43 technomancy: (just checking)

17:44 weavejester: &(->> 500 str (map #(Integer. (str %))))

17:44 lazybot: ⇒ (5 0 0)

17:44 weavejester: I'd kinda like a "coerce" multimethod in Clojure core

17:45 TimMc: I guess we don't need to worry about bases here -- not likely to get octal by accident.

17:45 &(Integer. "050")

17:45 lazybot: ⇒ 50

17:45 weavejester: Like: (coerce 1 String) (coerce "1" Integer)

17:45 devn: what about using mod?

17:45 TimMc: &(Integer/parseInt "050")

17:45 lazybot: ⇒ 50

17:45 devn: ,(mod 500 10)

17:45 clojurebot: 0

17:45 devn: ,(mod 500 100)

17:45 clojurebot: 0

17:45 devn: ,(mod 500 1000)

17:45 clojurebot: 500

17:45 TimMc: Maybe something with iterate.

17:46 devn: hm, yeah

17:46 Somelauw: ,(take-while #(> % 1)(iterate 500 #(/ % 10)))

17:46 clojurebot: #<ExecutionException java.util.concurrent.ExecutionException: java.lang.ClassCastException: sandbox$eval486$fn__489 cannot be cast to java.lang.Number>

17:47 Somelauw: Nevermind, that won't work

17:49 Raynes: &(->> 500 str (map (comp read-string str)))

17:49 lazybot: ⇒ (5 0 0)

17:49 Raynes: Close enough.

17:53 devn: that's pretty

17:56 ,(#(for [c (str (* % %2))] (- (int c) 48)) 500)

17:56 clojurebot: #<ArityException clojure.lang.ArityException: Wrong number of args (1) passed to: sandbox$eval136$fn>

17:57 devn: ,(#(for [c (str (* % %2))] (- (int c) 48)) 5 100)

17:57 clojurebot: (5 0 0)

17:57 TimMc: Raynes: I'm writing this Leiningen deps hook that does a bunch of filesystem manipulation and I find myself wishing for a nice macro that allows me to represent a directory tree and bind names to certain nodes.

17:58 Raynes: TimMc: That sounds interesting.

17:58 devn: TimMc: what kind of criteria do you have to work with for the nodes? Could you use some combination of file-seq and info about each node?

17:58 like modified time, etc.

17:59 TimMc: devn: Just paths.

18:00 Let me show you an example of what is making me want this... https://gist.github.com/1491709

18:00 Look at the defs around line 37 and the let bindings in the fetch-cljs fn.

18:01 devn: TimMc: ahhh, i see

18:01 TimMc: I haven't decided what the input form would look like, but I imagine something like match.

18:01 well, I don't know

18:06 Raynes: TimMc: I don't know if I'll have time anytime soon to write something like that, but if you end up with something, I'd love to include it in fs.

18:07 TimMc: Raynes: I plan on writing something, but I wanted to put the idea out there in case anyone else had any thoughts on it.

18:07 I'll let you know if I build something.

18:11 OK, pushed changes, so I can delete the gist. Here's the example: https://github.com/baznex/trycljs/blob/efb14d492b29a9afa60a6dd841eed2500c81cbc7/src/leiningen/fetch_cljs.clj

18:13 Raynes: TimMc: In case you were wondering why I had that little task for grabbing JS deps, it's because I got sick of tryclojure being listed as a JavaScript project.

18:13 TimMc: haha

18:13 devn: Raynes: i found that if you place them under a dir called vendor it seems to ignore them

18:13 fwiw

18:14 Raynes: Yeah, I know, but meh.

18:14 TimMc: I think that's what amalloy does.

18:14 Raynes: I totally likes my way too.

18:14 TimMc: Raynes: CLJS moves so fast that I want to be able to rebuild it. :-/

18:14 devn: it's kind of nice when you consider the amount of clojure required is a tiny fraction of the JS in most web projects

18:15 even for medium-sized clojure web projects

18:15 Raynes: devn: That's mostly not true though.

18:15 devn: Raynes: which part? :)

18:16 Raynes: devn: The reason there is such an insane amount of JS is because people include what is essentially a standard library in their project (jquery) and other dependencies.

18:16 tryclj's actual application js is fairly small.

18:16 If you included 4clojure's dependencies in the repo...

18:18 devn: Raynes: it would be interesting to compare a couple of full clojure libs with a project as well as the js libs it needs and see how they stack up

18:21 how big is an unminified version of jquery lately?

18:22 9,266 uncompressed

18:28 Raynes: amalloy: OHai!

19:02 mrevil: If I fork a clojure library, is there a way I can pull it in as a lein dependency without pushing it to a maven repo?

19:05 ihodes: is there a nice way of changing how toString works on clojure.lang.PersistentQueue?

19:05 Raynes: mrevil: Check out Leiningen's subproject dependencies.

19:06 You can also just do 'lein install' to install it in your local maven repo, where it will be usable from other projects like normal dependencies but only on your machine. You don't have to push it to an remote maven repo.

19:06 TimMc: and there are checkout-deps

19:06 for a tight development loop

19:06 Raynes: TimMc: I think that's what I meant by subproject dependencies.

19:07 I've still got cake on the brain.

19:07 TimMc: Oh good, I thought I had missed a mechanism.

19:09 mrevil: checkout dependencies may work, I can add the library that I'm hacking on as a git sub-module

19:09 thanks!

19:09 amalloy: ihodes: no

19:10 Raynes: ihodes: You can write your own print method that will make Clojure print it prettily.

19:11 TimMc: or convert it into a pretty-printing data type

19:11 ihodes: Raynes, amalloy: yeah, that's not ideal though. i wonder what i was thinking... i could have sworn there was something i could do so calling str on a queue would work nicely...

19:11 TimMc: what do you mean?

19:12 TimMc: Man, how do you even make them?

19:13 &(into clojure.lang.PersistentQueue/EMPTY [1 2 3])

19:13 lazybot: ⇒ #<PersistentQueue clojure.lang.PersistentQueue@6b58d153>

19:13 TimMc: &(vec (into clojure.lang.PersistentQueue/EMPTY [1 2 3]))

19:13 lazybot: ⇒ [1 2 3]

19:14 ihodes: TimMc: ah that's what yo mean, haha. yeah, that's not ideal

19:15 amalloy: vec is expensive

19:15 &(seq (into clojure.lang.PersistentQueue/EMPTY [1 2 3]))

19:15 lazybot: ⇒ (1 2 3)

19:15 ihodes: &(time (seq (into clojure.lang.PersistentQueue/EMPTY [1 2 3])))

19:15 lazybot: ⇒ "Elapsed time: 0.7737 msecs" (1 2 3)

19:15 ihodes: &(time (vec (into clojure.lang.PersistentQueue/EMPTY [1 2 3])))

19:15 lazybot: ⇒ "Elapsed time: 0.462153 msecs" [1 2 3]

19:16 TimMc: ihodes: You're not going to get a meaningful benchmark that way.

19:16 Raynes: It's meaningful to him. Let him be.

19:16 :p

19:16 devn: +1 :)

19:16 ihodes: TimMc: i know, just curious if there was an order of magnitude difference :) it wont' work for me anyway.

19:17 TimMc: 1) Run it 10000 times to get HotSpot going, 2) make sure to walk both colls, 3) man, lazybot is like the worst benchmark platform.

19:17 ihodes: If there is an order of magnitude difference, you're not going to see it that way.

19:17 ihodes: oh #2 is something i forget all too often.

19:17 TimMc: same here

19:18 "Oh man, I can compute an infinite sequence of values in .003 seconds! Clojure ROCKS!"

19:18 ihodes: either way... there's no way to ... use something like `proxy` and improve on PersistentQueue.... hmmm damn

19:18 Raynes: TimMc, ihodes: He is very correct about lazybot not being a good benchmarking platform. clojail molests the the code and such.

19:19 amalloy: TimMc: but the point here is *not* to walk both colls. calling vec is eager and copies the whole thing even though you don't need to; seq is O(1) and gives you a sequential view from which to create your string

19:19 TimMc: Also, lazybot (and its computer) has other concurrent tasks.

19:20 amalloy: I guess you have to ask it for the number of results you would in a real situation.

19:20 ihodes: Forget everything that's been said -- if you need to know, benchmark the difference *in place* in your application. :-)

19:21 ihodes: haha, i really don't need to either way--I think i'm good

19:22 TimMc: amalloy: Hey, maybe you know the answer to this -- why is the CLJS compiler file-oriented?

19:22 amalloy: TimMc: fwiw, just timed calling str on (vec q) and (seq q) on a 1M-element queue. vec is about 33% slower (in what is still not a very good benchmark)

19:22 man i don't know anything about cljs

19:22 TimMc: You were a recent committer, so I bugged you.

19:23 amalloy: but it's my impression that you can get it to output javascript to the repl. i saw chouser doing something like that at the conj

19:23 TimMc: You see what happens?

19:23 Yeah, but can *I*? He's a wizard or something.

19:25 amalloy: TimMc: fwiw i just committed an impl of subvec, which really only required converting java to clojure - the cljs aspect was pretty minimal

21:14 TimMc: OK, found it: analyze and emits.

21:18 Thinking back on the binding vs. lazy-seq thing... I guess that even if a lazy-seq call could capture the current bindings for later (and there weren't any other concerns), you wouldn't necessarily want to hold onto those objects.

21:33 accel: is ther esomething like ";" but coments out an entire region instead of a single line?

21:34 TimMc: There's #_ for entire forms

21:34 accel: http://stackoverflow.com/questions/1191628/block-comments-in-clojure

21:34 wtf

21:34 does that really work?

21:35 ah, #_ is a reader macro?

21:35 nice

21:35 guns: accel: I've got a vim macro that wraps current form with (comment)

21:35 works nice

21:42 sirvaliance: Does lein have any sort of hot code reloading type features? For doing web dev, if would be nice not to have to restart the server everytime.

21:43 accel: err

21:43 I have a confession to make

21:43 I think I have fallen in love with the repl

21:44 technomancy: sirvaliance: you can either work with a swank/nailgun/nrepl server and reload from your editor or use the wrap-reload middleware (which is ring-specific)

21:45 sirvaliance: technomancy: Checking out wrap-reload now. Thanks

21:45 accel: dumb question: how can I attach an action listener to a JFrame?

21:45 i.e. anytime when a key is pressed inside this JFrame,

21:45 I want an event triggered

21:50 amalloy: $google java keylistener jframe

21:50 lazybot: [swing - Java KeyListener for JFrame is being unresponsive? - Stack ...] http://stackoverflow.com/questions/286727/java-keylistener-for-jframe-is-being-unresponsive

21:53 weavejester: sirvaliance: If you're using lein-ring, it should automatically reload modified files.

21:54 Same for Noir, if memory serves.

21:55 sirvaliance: weavejester: Hi! I was just running lein run -m appname.web. First day actually building something with clojure. I will checkout lein-ring. Thanks

21:59 weavejester: sirvaliance: There's a page on the Ring wiki about different ways of doing interactive development in Ring

21:59 sirvaliance: https://github.com/mmcgrana/ring/wiki/Interactive-Development

21:59 sirvaliance: weavejester: Oh awesome, I missed that :)

22:00 What do you all recommend for template rendering? I am fond of pythons django/jinja style templating (inheritance, simple html files, etc).

22:02 Also, what would be the best way to open files to render them, (some-template-render (slurp "some-template.html"))?

22:02 Or is there a better way to manage template directories. None of the tutorials or examples seem to go there.

22:04 TimMc: sirvaliance: Enlive is one approach to templating, although I'm not exactly thrilled with the paucity of API docs.

22:04 sirvaliance: I like clostache, and I don't know how I feel about hiccup

22:04 TimMc: Enlive as well, not to interesting...

22:06 s/to/too

22:07 weavejester: Clostache looks most like Django's templates...

22:07 TimMc: I like the theory behind Enlive, but it's a bit hard to use.

22:07 Once you have working Enlive code, though, it's pretty easy to read.

22:07 weavejester: I also have comb, which is essentially a Ruby erb clone.

22:08 I've been meaning to use it for creating project skeletons.

22:10 duck1123: are there any good clojure libs for modifying clojure source files?

22:10 TimMc: I think I'm going to have to abandon work on try-clojurescript for now -- I just don't understand some of the compilations I'm getting back.

22:11 scottj: duck1123: I'm guessing the fs lib by Raynes has an rm command :)

22:11 TimMc: There's some real impedance mismatch between GClosure and the REPL model. :-/

22:12 tmciver: TimMc: I just start getting into the trycljs code and now you're going to abandon it? :(

22:12 TimMc: tmciver: For now, at least.

22:12 CLJS is pretty fast-moving though, so it may not be very long until I'm back in it.

22:12 Raynes: scottj: Indeed, it does.

22:13 TimMc: tmciver: And other folks may continue hacking on it.

22:13 duck1123: scottj: I'm looking to make a code generator. adding requires to namespaces, adding lines in a form, adding functions to the end, etc

22:13 TimMc: tmciver: (comp/emits (comp/analyze {} '(def x 1))) gives me ".x = 1;\n"

22:13 tmciver: TimMc: well, I'm going to continue to look at it, for a little while anyway. I know almost nothing about cljs.

22:13 TimMc: Well, same here!

22:14 tmciver: TimMc: you're so modest!

22:14 TimMc: tmciver: But I'll keep the site running and updated: http://k.timmc.org:7013/

22:14 scottj: duck1123: no clue, maybe slamhound has something that might help an itsy bit

22:14 tmciver: TimMc: already there.

22:14 sirvaliance: I am going with clostache for now. I am rewriting an app from django to clojure. Don't want to rewrite all of the html

22:16 TimMc: duck1123: The tricky thing is to preserve the surface syntax, like #(foo).

22:18 duck1123: mostly I'm looking to append new functions and create files if they don't exist, nothing too heavy

22:18 sirvaliance: Back to rendering templates from files, what would be the best way to do it? Is slurp appropriate?

22:18 technomancy_: sirvaliance: slurp on clojure.java.io/resource

22:19 that way it doesn't matter whether you're running from a project checkout or a jar/war file in deployment

22:20 sirvaliance: technomancy_: Ahh, ok

22:22 TimMc: Oh hey, that's good to know.

22:23 Raynes: sirvaliance: Don't use clostache.

22:23 Use stencil.

22:23 Clostache is terribly broken and non-spec compliant.

22:24 http://github.com/davidsantiago/stencil

22:24 weavejester: There's a spec?

22:24 Raynes: weavejester: Yesterjester.

22:25 weavejester: Clostache breaks on basic examples.

22:25 weavejester: Ahh

22:25 Raynes: https://github.com/mustache/spec

22:25 sirvaliance: Raynes: Will do, thanks!

22:26 Raynes: It caches and loads templates :)

22:27 TimMc: Oh man, I'm so excited -- for the first time, I actually have a *reason* to benchmark one of my programs and tweak the performance.

22:28 Unfortunately, it's in Python, and I have a lot to learn about performance stuff in that language.

22:49 YES! 40x speedup.

22:58 accel: Vars makes sense to me. Refs = trnsactions, I think. Why do I ever want Agents/Atoms?

22:59 technomancy_: accel: atoms are just less fancy

22:59 they're your vanilla reference type

23:00 TimMc: Non-coordinated single-writer, yeah?

23:00 (That's probably a terrible way of characterizing it, sorry.)

23:00 Raynes: I wish it was clearer what that meant to the uninitiated.

23:03 TimMc: accel: atoms are thread-safe boxes you can hammer on, but they don't provide for coordination of multiple bits of state. refs give you true transactional capabilities -- you can hammer on more than one at a time and have guaranteed coordination of updates.

23:03 amalloy: accel: if you think vars make sense but you don't understand atoms, you're probably wrong about vars too

23:04 atoms are really a lot simpler than vars: a single mutable pointer to an immutable value. you can change what value they point to in a thread-safe way, but not in a "transaction-y" way

23:07 TimMc: amalloy: What happens if you swap! an atom while in a dosync that has to be retried?

23:07 amalloy: then you'll swap! it a few more times

23:07 changing it every time: no transaction safety

23:08 TimMc: OK, so it's a "side-effect" sensu dosync.

23:08 amalloy: $dict sensu

23:08 lazybot: amalloy: Word not found.

23:08 TimMc: but agents are safe to hammer on in a dosync, yeah?

23:08 amalloy: "in the sense of"

23:08 amalloy: yes, send doesn't actually do anything until the current transaction (if any) completes

23:10 okay, finally understood what you meant by "in the sense of" here. yes: swap! should be treated with as much care as any side effects, when inside a transaction

23:11 accel: is there a way to just read the value of a ref

23:11 without using a dosync?

23:11 amalloy: @

23:11 accel: oh

23:11 I'km an idiot

23:12 can I also simplify the following 3 lines?

23:12 (dosync

23:12 (let [o @curline]

23:12 (ref-set curline (str o (.getKeyChar e)))))

23:12 basically I'm saying "append this one char to this ref"

23:13 TimMc: &(doc alter)

23:13 lazybot: ⇒ "([ref fun & args]); Must be called in a transaction. Sets the in-transaction-value of ref to: (apply fun in-transaction-value-of-ref args) and returns the in-transaction-value of ref."

23:13 hiredman: ~alter

23:13 clojurebot: alter is always correct

23:13 TimMc: amalloy: Do you know of a more idiomatic way of getting a snapshot of multiple refs than (let [[x y] (dosync [@x @y])] ...)?

23:14 amalloy: (dosycn (alter curline str (.getKeyChar e)))

23:14 no, i don't. i don't really use refs that often, but that looks like the best solution, TimMc

23:15 TimMc: I guess one could make a macro (with-snapshot [x y] ...)

23:15 amalloy: wait, except yours might not work, TimMc

23:16 you might need to use [(ensure x) (ensure y)]? i'm not really clear on the difference between ensure and @

23:16 hiredman can probably tell us if i'm totally wrong

23:16 TimMc: I think I don't need ensure since I'm not modifying anything.

23:18 &(doc ensure)

23:18 lazybot: ⇒ "([ref]); Must be called in a transaction. Protects the ref from modification by other transactions. Returns the in-transaction-value of ref. Allows for more concurrency than (ref-set ref @ref)"

23:18 accel: cool cool cool

23:18 I am happy with this

23:18 very very good

23:18 now, for even better

23:19 is there a way in java graphics to render high quality vector graphics/

23:19 is this done with the graphics 2d api, or something else?

23:19 by high quality, I want anti aliasiing, and all that neat stuff

23:19 TimMc: Ensure is to prevent "write skew", IIRC.

23:19 accel: For anti-aliasing you can turn on some Graphics2D options.

23:20 amalloy: yeah, it's like setRenderingHint or something

23:21 TimMc: amalloy: Here's a great explanation of where ensure is needed: http://clojure.higher-order.net/?p=50

23:23 amalloy: yeah, i've read it. i just use refs so rarely, and ensure never, that it doesn't really click/stick

23:23 and then i go around recommending cargo-cult ensures, apparently, just in case

23:27 accel: are these objects: (svgGraphics2D) http://xmlgraphics.apache.org/batik/using/svg-generator.html viewable as GUI elemnts?

23:29 cool cool i'm almost there

23:29 so I need a blinking timer

23:29 I'm using awt/swing

23:29 what is the right way to do this?

23:29 should I set a timer

23:29 and constantly flip the value of a string?

23:32 TimMc: accel: Use a timer from util or whatever.

23:33 amalloy: seems like changing the value of a string is crazy, just change the color of something

Logging service provided by n01se.net