#clojure log - Mar 29 2012

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

0:00 autodidakto: (TL;DR, get Clojure Programming and Programming Clojure 2nd when they come out within a month, then do Joy of Clojure)

0:00 mbriggs: yeah

0:00 i would agree with that

0:01 autodidakto: methodmissin: Oh! I know something you can have fun with -> https://github.com/ibdknox/live-cljs

0:02 cljs implementation of the game editor in "inventing on principle talk". git clone, and lein run it and open chrome

0:03 gotta run. was fun doodling the wednesday away in IRC :)

0:03 methodmissin: autodidakto, I love that talk! I'll check it out, thanks. For now, though, goodnight :)

0:03 muhoo: i made this thing, but it feels stupid to me: https://refheap.com/paste/1474

0:04 sure, it works, but seems... ugly

0:04 i have a feeling amalloy will show me how it could be done in one line :-)

0:08 brehaut: muhoo: how is num ever going to not be a seq?

0:09 muhoo: when it's nil

0:09 brehaut: huh. so it is

0:09 muhoo: however, (first nil) is nil

0:09 i think

0:09 ,(first nil)

0:10 clojurebot: nil

0:10 muhoo: oh, when it's a num

0:10 ,(first 1)

0:10 clojurebot: #<IllegalArgumentException java.lang.IllegalArgumentException: Don't know how to create ISeq from: java.lang.Long>

0:10 muhoo: see

0:10 so in the recur, it's sent a num

0:10 hmm, i guess i could send it [num] instead

0:11 brehaut: oh huh. i dont think ive ever recured on a vararg function

0:11 stupid java varargs

0:11 technomancy: brehaut: recur with varargs is weird even without java's weirdness

0:12 brehaut: technomancy: maybe thats why ive never tried it ;)

0:13 muhoo: well weird is my middle name

0:13 i tried it with the multiple arity form of defn, but it involved repeating code, which was even uglier

0:14 brehaut: muhoo: can you explain what this function does? (eg, inputs and outputs)

0:14 muhoo: oh, it just generates unique names

0:14 brehaut: (comp name gensym) ?

0:15 muhoo: so if i give it (gen-unique #{"fubar"} "fubar"), it gives me "fubar1"

0:15 no, unique as in, the user gives it a username, that username is taken, it gives them "username1" instead

0:16 brehaut: oh right

0:16 muhoo: very pedestrian stuff :-)

0:16 brehaut: and your using varargs for a single optional argument?

0:17 muhoo: right

0:17 is there a better way to have a single optional argument?

0:17 * muhoo has a premonition of hearing the word "destructuring"

0:18 brehaut: i tend to do (fn f ([a b] (f a b ni)) ([a b c] …))

0:18 (or some other sensible default in the n-1 args form)

0:19 muhoo: i like that approach. but when i tried it, i ended up with duplicated code in the [a b] and [a b c] bodies

0:19 brehaut: ,(or nil 0)

0:19 clojurebot: 0

0:19 muhoo: ooh, nice

0:19 brehaut: ,(or 1 0)

0:19 clojurebot: 1

0:19 brehaut: theres only two falsy values in clojure: nil and false

0:19 muhoo: right, so just dont duplicate the code ;)

0:26 ,(re-pattern (str #"^" "foo" #"(\d*)$"))

0:26 clojurebot: #"^foo(\d*)$"

0:27 brehaut: ,(map second (keep (partial re-find (re-pattern (str #"^" "foo" #"(\d*)$"))) ["a" "foo" "b" "foo23"]))

0:27 clojurebot: ("" "23")

0:35 technomancy: aperiodic: do you remember who was in the rogue vim group for the swarm coding session?

0:35 they said they were adapting the bootstrap script for vim

0:36 aperiodic: technomancy: no idea, unfortunately. i came in too late.

0:36 what does the bootstrap script do?

0:36 technomancy: just gets all the necessary dotfiles and keys set up on a fresh account

0:37 brehaut: muhoo: https://refheap.com/paste/1477

0:37 Lajla: technomancy,

0:38 brehaut: muhoo: its still a bit larger than it needs to be, but at least its a bit more declarative

0:38 Lajla: What's with the (symbol "string whose characters do not make up a valid symbol") stuff

0:38 muhoo: brehaut: now i have two problems :-)

0:38 brehaut: muhoo: (and i dont think it covers the case of the name not being in the set)

0:39 muhoo: it's very cool though, thanks

0:39 brehaut: im sure someone could come up with a cleaner way to do the keep and then map

0:42 muhoo: infact https://refheap.com/paste/1478

0:43 muhoo: now it's shorter than mine :-)

0:43 brehaut: less crashy too ;)

0:44 (than my previous attempt0

0:44 i need to sign up to this refheap thing so that i can edit these pastes

0:44 muhoo: and uses regexp instead of recur. interesting.

0:44 brehaut: ive got to cook dinner now

0:44 muhoo: thanks!

0:44 brehaut: that's a whole new way of looking at it. i learned a lot, thanks

3:07 kral: morning

3:46 Raynes: $(Character/toUpper \é)

3:46 &(Character/toUpper \é)

3:46 lazybot: java.lang.IllegalArgumentException: No matching method: toUpper

3:46 Raynes: &(Character/toUpperCase \é)

3:46 lazybot: ⇒ \É

4:31 _andrew_k: $(Character/toUpperCase \й)

4:31 $(Character/toUpperCase \ъ)

4:32 &(Character/toUpperCase \й)

4:32 lazybot: ⇒ \Й

4:32 _andrew_k: &(Character/toUpperCase \ъ)

4:32 lazybot: ⇒ \Ъ

4:33 _andrew_k: &(Character/toUpperCase \어)

4:33 lazybot: ⇒ \어

4:35 progo: oh man

5:01 stirfoo: (nth (subvec [:??? 1 2] 1) -1) ; bug?

5:03 clgv: (nth (subvec [:??? 1 2] 1) -1)&

5:03 &(nth (subvec [:??? 1 2] 1) -1)

5:03 lazybot: ⇒ :???

5:04 clgv: &(nth (subvec [:??? 1 2] 1) -10)

5:04 lazybot: java.lang.IndexOutOfBoundsException

5:04 clgv: &(nth (subvec [:??? 1 2] 1) -2)

5:04 lazybot: java.lang.IndexOutOfBoundsException

5:05 clgv: stirfoo: I'd vote for bug

5:05 stirfoo: I would say it's ok, but it's not consistent, you can access beyond the upper bound of the subvec. assoc gives funky behavior on subvec's too.

5:05 *can't access beyond the upper bound

5:06 alexyakushev: &(doc subvec)

5:06 lazybot: ⇒ "([v start] [v start end]); Returns a persistent vector of the items in vector from start (inclusive) to end (exclusive). If end is not supplied, defaults to (count vector). This operation is O(1) and very fast, as the resulting vector shares structure with the original and no trimming is done."

5:06 clgv: &(nth (subvec [:? 1 2 :??] 1 2) 2)

5:06 lazybot: java.lang.IndexOutOfBoundsException

5:06 clgv: &(nth (subvec [:? 1 2 :??] 1 2) 1)

5:06 lazybot: java.lang.IndexOutOfBoundsException

5:06 clgv: &(nth (subvec [:? 1 2 :??] 1 3) 1)

5:06 lazybot: ⇒ 2

5:06 clgv: &(nth (subvec [:? 1 2 :??] 1 3) 2)

5:06 lazybot: java.lang.IndexOutOfBoundsException

5:06 alexyakushev: clgv: "This operation is O(1) and very fast, as the resulting vector shares structure with the original and no trimming is done."

5:06 stirfoo: That's a hell of fast way to nice way to to a sub vector though.

5:06 what alexyakushev said ;)

5:07 clgv: alexyakushev: yeah but that -1 behaviour should also be avoidable in O(1) ;)

5:07 stirfoo: I'm not sure if it is a bug but I thought I'd mention it here where a few devs hang out.

5:07 clgv: stirfoo: if you can report it as a bug. It's definitely no feature ;)

5:07 alexyakushev: clgv: you mean to put additional warts on the input argument to nth?

5:08 clgv: alexyakushev: no on the class implementing the subvec

5:09 stirfoo: it's in the bounds test: if (start + i > end) throw...

5:09 it's only checking the upper bound

5:10 clgv: here: https://github.com/clojure/clojure/blob/612fba9159c6986cf875f97e086337f24a5ea3d8/src/jvm/clojure/lang/APersistentVector.java#L524

5:10 stirfoo: report it if you can. btw: can everyone create a clojure jira account for reporting?

5:11 stirfoo: clgv: I have no idea, I looked into before on another bug but gave up.

5:11 clgv: stirfoo: well there is still the google group

5:12 stirfoo: the dev group? that's invite only, no?

5:12 clgv: stirfoo: I think the normal will be sufficient

5:12 stirfoo: ah

5:18 posted

5:25 GeoffSK: has anyone used clojure to talk to riak?

5:26 clgv: stirfoo: is it already visible on the group? I dont see it yet ;)

5:26 stirfoo: has to be approved

5:27 clgv: ah ok. that list is moderated?

5:27 stirfoo: I don't use groups much at all any more, might be because it's my first post there.

5:28 I'm sure someone will handle it if it's actaully a bug.

5:41 zamaterian: geoffeg, I have

5:41 GeoffSK, I have used riak

5:42 GeoffSK, https://github.com/reiddraper/sumo

5:42 GeoffSK: does it work with the latest riak client jar?

5:46 zamaterian: GeoffSK, it uses 1.0.3,

5:47 GeoffSK: yep, it looks (so far) easier then clj-riak

5:48 zamaterian: GeoffSK, reiddraper is a basho employee - so its maintained :-)

5:49 GeoffSK: oh, nice.

5:51 rdsr: how do I fetch "test-jars" with lein. By test-jars I mean the ones we specify as "<type>test-jar<type>" under the <dependency> tag in maven...

5:53 GeoffSK: thanks zamaterian - worked well.

5:56 lytton: Check your private channnels zamaterian :)

6:05 * lytton

6:09 clgv: stirfoo: :)

6:13 _andrew_k: &(Long/toBinaryString 1)

6:13 lazybot: ⇒ "1"

6:13 _andrew_k: &(Long/toBinaryString -1)

6:13 lazybot: ⇒ "1111111111111111111111111111111111111111111111111111111111111111"

6:16 lytton: ser=> (Long/toBinaryString -5)

6:16 "1111111111111111111111111111111111111111111111111111111111111011"

6:16 user=> (Long/toBinaryString -5)

6:36 clgv: _andrew_k: lytton: what is the issue?

6:38 lytton: my guess is that it was a ex in two's complement in binary form

6:51 zamaterian: lytton, how goes

6:55 _andrew_k: i wanted to check bits and it was closest repl i had )

7:03 zamaterian: frankvilhelmsen, enjoy my day off :-)

7:08 frankvilhelmsen, :-) i'm one my out in the sun

8:08 makkalot: Hi everyone, i'm reading some stuff about refs, what is not clear to me is the reader part of the model. I understand if you have shared data to modify you put it in a transaction,but what does reader part see ?

8:10 For example suppose i have a mutual list and some threads modify it. My reader part prints the list to screen, what happens when i start printing it and in the middle of the print action some other thread changes it in some transaction ?

8:13 samaaron: makkalot: so the first thing to grok is that your vector is immutable

8:13 so it can't be changed by any threads

8:15 makkalot: samaaron, so when i do (println myvect) there is no way someone to change it implicitly ? when i get its reference i got its snapshot ?

8:15 samaaron: exactly

8:15 the only thing that changes is the ref - not the vector

8:16 once you dereference a ref, you have an immutable value that will never change

8:16 (unless of course you stored a mutable thing in there like a standard Java object)

8:17 makkalot: samaaron, ah it is clear now, thanks

8:20 samaaron: makkalot: have you seen this talk: http://www.infoq.com/presentations/Are-We-There-Yet-Rich-Hickeyhttp://www.infoq.com/presentations/Are-We-There-Yet-Rich-Hickey

8:21 if not, it's definitely worth watching

8:21 makkalot: samaaron, thanks will watch it

8:24 alexyakushev: Could anyone tell me how to call String.format function from Clojure?

8:24 ,(String/format "%s is bar" "foo")

8:24 clojurebot: #<ClassCastException java.lang.ClassCastException: java.lang.String cannot be cast to [Ljava.lang.Object;>

8:24 alexyakushev: I know that I can use format, but I'm interested in getting around the particurlar set of issues

8:26 samaaron: alexyakushev: use #'format

8:26 ,(format "%d green bottles" 10)

8:26 clojurebot: "10 green bottles"

8:27 alexyakushev: samaaron: yes, I am aware of format

8:28 samaaron: so what's the issue?

8:28 alexyakushev: I'm interested whether there is any mechanism in Clojure to force the certain overloaded method to be called

8:28 samaaron: arity

8:28 alexyakushev: And if the arity is the same for both?

8:29 take a look at the two definitions so you see what I'm talking about:

8:29 static String format(Locale l, String format, Object... args)

8:29 samaaron: can you have two methods in Java with the same arity and different signatures?

8:29 alexyakushev: static String format(String format, Object... args)

8:29 samaaron: so, they have different arities

8:30 the first takes a Local, a String and an Array

8:30 the second takes a String and an Array

8:30 alexyakushev: Well, not actually. They both have variadic arities

8:32 samaaron: alexyakushev: that's probably only in the Java syntax, not the JVM semantics

8:33 just take a look at the implementation of #'format and you'll see what I mean

8:33 :-)

8:34 Rick Ceme!

8:37 Sid Eriss!

8:37 Due Yjim!

8:38 alexyakushev: samaaron: Thank you. Type hints are the answer, I supposed something like that

8:38 But...

8:38 ,(let [^String formstr "%s is bar"] (String/format formstr "foo"))

8:38 clojurebot: #<ClassCastException java.lang.ClassCastException: java.lang.String cannot be cast to [Ljava.lang.Object;>

8:39 samaaron: ,(String/format "%d green bottles" (to-array [10]))

8:39 clojurebot: "10 green bottles"

8:40 samaaron: it's not a type hint thing

8:40 alexyakushev: ah, the to-array thing

8:40 samaaron: the method signature is String, Array

8:40 at least from the Clojure side

8:41 alexyakushev: Thanks again for help

8:41 Sorry, my bad

8:41 fdaoud: Aron Sama!

8:43 samaaron: fdaoud: your vowels and consonants aren't evenly distributed

8:43 Da Oudf!

8:44 fdaoud: :-)

8:44 samaaron: alexyakushev: you're very welcome :-)

8:44 fdaoud: ,(sort "fdaoud")

8:44 clojurebot: (\a \d \d \f \o ...)

8:45 fdaoud: ,(apply str (sort "fdaoud"))

8:45 clojurebot: "addfou"

8:45 samaaron: :-)

8:45 fdaoud: ,(apply str (sort "samaaron"))

8:45 clojurebot: "aaamnors"

8:45 ssideris_: almost "add foo"

8:45 samaaron: Da Food!

8:45 fdaoud: ssideris_: yeh :D

8:45 jimduey: samaaron: How goes The Reasoned Schemer?

8:46 samaaron: jimduey: I'm only on page 20

8:46 but it's been amazing so far

8:46 fdaoud: ah I still have to read the Seasoned

8:46 samaaron: jimduey: dnolen pointed me to your recent blog post - looks like crazy cool work

8:46 jimduey: Thanks.

8:47 fdaoud: this one? http://www.clojure.net/2012/03/24/Continuation-monad/

8:47 jimduey: TRS is pretty mind bending. I couldn't understand it until I actually implemented it.

8:47 fdaoud: The next one.

8:47 samaaron: I must say, I still haven't managed to get my head around monads

8:48 That "aha" moment is waiting for me in the future

8:48 jimduey: samaaron: Feel free to ping me if you're stuck on anything in particular.

8:48 fdaoud: jimduey: I see, thanks.

8:48 ssideris_: my main question about monads is: what's the benefit?

8:48 samaaron: jimduey: that might be helpful - I'll try working through your posts again

8:49 jimduey: Once you get the "aha" you'll be like "Is that all there is?" :)

8:49 samaaron: ssideris_: from what I can perceive, making code more readable for DSLs is a big benefit in Clojure

8:49 fdaoud: jimduey: so far almost everything I've read that you have written has made my brain hurt.

8:50 jimduey: ssideris_: Because they're cool! Actually, my last post tells how thinking in DSL's helped me make core.logic multi-threaded.

8:50 samaaron: Also, jimduey's latest post implied that monads helped him reason about something super complex

8:50 sthuebner: a friend told me, Clojure is not the right language to learn Monads. Haskells types would help the beginner to understand easier, what Monads are.

8:50 jimduey: fdaoud: :) That was how I felt when I was trying to get a handle on monads the first time.

8:51 sthuebner: Probably true. But I didn't want to have to learn the Haskell syntax, so I learned just enough to read papers.

8:51 fdaoud: jimduey: right. I'm still trying to "get" monads. I know there is something very cool in there, but I haven't "aha"'d yet.

8:51 ssideris_: ok, thanks. I started reading about monads, but I couldn't see the motivation (the motivation for making my brain hurt, as fdaoud mentioned)

8:51 ferd: sorry to interrupt the monad philosophy talk... Anybody managed to make Cobertura (code-coverage tool) work with Clojure?

8:52 sthuebner: yeah, learning Haskell would too much, I think, just to get my head around Monads

8:52 ssideris_: jimduey: in fact, I was reading *your* blog posts last night

8:53 ferd: jimduey: I'm feel I'm getting closer to the "aha" moment thanks to your posts

8:53 bulters: `w

8:53 jimduey: ferd: Good to hear.

8:53 bulters: whu, there goes my lurking

8:53 ssideris_: thanks, they're great, but it's a very tricky subject anyway

8:54 fdaoud: jimduey: Ideally I need to see a piece of code in its "before" state, probably something with an ugly bunch of if's and so on, and then in its "after" state, all cleaned up and much nicer looking thanks to monads.

8:54 jimduey: ssideris_: Let me know if you need a hand getting over a particular hump.

8:55 fdaoud: That's kind of what I was trying to do in showing how DSL's can often be written easily using monads.

8:55 ssideris_: jimduey: thanks, much appreciated

8:55 samaaron: jimduey: sorry to be an apostrophe-fiend but it's DSLs not DSL's :-)

8:56 jimduey: To me, the core.logic fork/join work was pretty compelling.

8:56 samaaron: although i understand it's me that should stop whincing with misplaced apostrophes rather than people misplacing them

8:56 jimduey: samaaron: :) I'll correct my usage immediately.

8:57 samaaron: unless you're talking about the properties of a specific DSL, then it's this DSL's properties

8:57 jimduey: So you can save your whincing for other things.

8:57 samaaron: :-)

8:57 fdaoud: samaaron: I understand how you feel. Its something that let's me get upset sometimes as well ;)

8:57 samaaron: haha - you just did it too!

8:58 it's lets not let's

8:58 :-)

8:58 fdaoud: um, both were on purpose :)

8:58 samaaron: argh!

8:58 Da Food!

8:59 Da Foud!

8:59 fdaoud: the Its was wrong too

8:59 samaaron: yeah, i noticed on a re-look

8:59 it always got me when people were talking about Rails

8:59 ssideris_: samaaron: there is something way more annoying

9:00 fdaoud: don't "loose" your mind over it-- there's another mistake that keeps coming up.

9:00 [[ssideris]: <- this

9:01 fdaoud: samaaron: don't "loose" your mind over it-- there's another mistake that keeps coming up.

9:01 samaaron: haha, i just this moment got some recruitment spam:

9:01 "I have a position in Central London that I think may interest you. It would be heading up a team of RoR Developer’s with the view..."

9:01 fdaoud: haha

9:02 let's the good time rolls!

9:02 samaaron: :-)

9:24 tacoman: I installed leiningen via the bootstrap script on Ubuntu 11.10, but I'm getting a "could not find the main class: clojure.main" error on attempts to run lein swank (full trace at http://pastebin.com/DSiUxdS9); is it not finding Clojure itself? I have 1.1, 1.2, and 1.3 all installed

9:25 1.1 and 1.2 through the package manager, 1.3 by downloading it and placing it where it would go if it had been installed via package manager (not the best approach I now realize, but this install only has another month to live anyway)

9:36 alexyakushev: Do you have swank plugin installed?

9:36 z

11:10 lynaghk`: ping: jonasen

11:21 jonasen: lynaghk`: yes?

11:22 lynaghk`: jonasen: what's the story with the new rules format?

11:23 jonasen: what do you mean? If we're going to use it in kibit?

11:23 lynaghk`: jonasen: do you think that will be integrated into kibit? What needs to be done before that can happen, and what (if anything) would you like my help on?

11:23 jonasen: does it do what you want?

11:23 lynaghk`: Yes, I think it's the most general solution that's appropriate for Kibit

11:24 since you can throw around anything that'll work with core.logic; not just forms that can be unified-with.

11:24 jonasen: I think so too. I've been working on some macros to get the rules to look nicer...

11:25 lynaghk`: jonasen: ok, great. I was thinking about doing the same thing.

11:26 jonasen: lynaghk`: I'd be very interested in what you could come up with.

11:26 lynaghk`: jonasen: for basic matching what is the most appropriate core.logic goal that I should be using? E.g., to match (symbol ?x . ?rest) you'd expand into...matche?

11:27 jonasen: I'll give it a shot this weekend; I'm actually sitting down to start porting big pieces of C2 to "cljx" this morning.

11:28 jonasen: lynaghk`: I saw you struggled with metadata and core.logic

11:28 lynaghk`: jonasen: but won = )

11:28 jonasen: I think the struggle continues with clojure.walk :(

11:28 lynaghk`: that it was silently eating metadata didn't help build my learning-logic-programming confidence though.

11:29 jonasen: ohhhh. I'm only dealing with toplevel forms right now, but I wouldn't be surprised if core.walk was using some fn that didn't preserve metadata.

11:30 jonasen: lynaghk`: But if it turns out to be a problem we can always write our own prewalk. It's just a few lines anyway

11:32 lynaghk`: jonasen: yep. Okay, well I'm going to dig into translating C2, which is a decently sized codebase. That should inform any more modifications to kibit (which I don't anticipate) and the kind of rules that could use tidying up via macros.

11:34 jonasen: I think you can count on the new rule system. I'll include it in master when I've got some macros I'm happy with, but it should alway be possible to fall back on "raw" rules.

11:36 lynaghk`: jonasen: okay, rad. Have a great day.

12:35 dnolen: CLJS PersistentVectors are looking good

12:36 bobzhang1988: hi all, just read the source, what does fn* mean? I googled, but found nothing

12:37 jimduey: dnolen: Realized last night how I could aggregate fork/join tasks to reduce the overhead in core.logic.

12:38 dnolen: jimduey: excellent! I was pondering that myself today :)

12:38 bobzhang1988: it's a special form - the primitive function constructor

12:39 bobzhang1988: dnolen: can you give me a link? Yes, I guess it's a special form

12:39 jimduey: Pretty simple really, just don't fork at every level of the search tree. Only fork every other, every third or somethig.

12:39 Also, don't fork on every clause in a conde. Group them in pairs or triples.

12:39 dnolen: jimduey: have you given this a go yet?

12:40 jimduey: Nah, I've kind of moved on to something else. Looking at arrows and also writing a java bytecode->x86 compiler in Clojure.

12:40 dnolen: jimduey: nice :)

12:41 jimduey: And maybe a state machine DSL for writing distributed apps sparked by this: http://blog.incubaid.com/2012/03/28/the-game-of-distributed-systems-programming-which-level-are-you/

12:41 Overwhelmed by too many interesting things to work on. :)

12:43 dnolen: jimduey: definitely. Thanks for doing the the fork-join core.logic - definitely a good starting point for taking it further.

12:46 jimduey: Another interesting thing to look at would be distributing core.logic programs over a cluster. Should be pretty easy to do.

12:47 Then you could have a database sharded and do some cool queries, I think. For example.

12:47 dnolen: jimduey: definitely! I also like the generality of your solution. There's talk of task parallelism in the browser - would be easy to make your mods work in CLJS if/when that happens.

12:48 jimduey: Yeah, that would be cool. In the back of my mind I'm curious if I didn't miss something that makes the whole approach unusable. I'm too close to the code now to see it if there was.

12:48 dnolen: jimduey: how do you mean?

12:49 jimduey: Don't know. It's those dang unknowns that bite you. :)

12:49 dnolen: jimduey: you said most of the tests pass right? :)

12:49 jimduey: Yeah. :) So I'm not too worried about it.

12:59 dsabanin: hi guys

12:59 I have a possibly stupid java+clojure question

12:59 I never used java for anything real

13:00 my problem is: I call a factory and get back an instance of the Blah class. That class is a subclass of an abstract class Meh (Blah extends Meh). However, instance of class Blah is missing the methods from class Meh

13:01 I'm using highly popular java library so I think there's something wrong with my code or I'm doing clojure/java interop incorrectly

13:02 fdaoud: dsabanin: which library, if you may tell?

13:02 dsabanin: svnkit.com

13:03 fdaoud: dsabanin: so how are you trying to invoke a method on a Blah object?

13:05 dsabanin: here's some code: http://pastie.org/3692894

13:05 actually, that's my whole code :)

13:05 dnolen: nice, CLJS PersistentVectors are nearly 100X faster to use then Vector

13:06 TimMc: than which Vector? Java's Vector?

13:06 the old CLJS impl?

13:07 dnolen: TimMc: old CLJS impl

13:07 TimMc: (I guess that's the only one it makes sense to compare against...)

13:08 fdaoud: dsabanin: it looks like it's the other way around. You're getting a Meh class back and are trying to call a method only defined in Blah.

13:09 dsabanin: fdaoud, but if "FSRepository extends SVNRepository", that means that FSRepository should have SVNRepository's methods, right?

13:10 sattvik: dsabanin: Actually, I think it's just a matter of the arguments being wrong…

13:10 dsabanin: I checked the list of methods on the FSRepository instance I get, and it's missing "log" method at all

13:10 it has logImpl (which is used in log method implementation in SVNRepository)

13:11 sattvik, or are you talking about some other arguments?

13:11 fdaoud: dsabanin: that's right. but SVNRepository does not have a log method. And, from what I can tell from the Javadocs, it doesn't look like FSRepository has a log method, either. Where do you see this log method?

13:11 dsabanin: I'm looking here http://svn.svnkit.com/repos/svnkit/tags/1.3.7/svnkit/src/main/java/org/tmatesoft/svn/core/io/SVNRepository.java

13:11 search by "public long log"

13:12 also here: http://svnkit.com/javadoc/org/tmatesoft/svn/core/io/SVNRepository.html#log(java.lang.String[],%20java.util.Collection,%20long,%20long,%20boolean,%20boolean)

13:13 and I checked the source java code for the version of svnkit I'm using, and it has that method too

13:14 fdaoud: dsabanin: if you don't see the log method by inspection at runtime, maybe it's a classpath issue? you have a different version on the classpath?

13:15 dsabanin: I use leiningen, and I see jar with proper version in the lib/

13:16 I don't use any custom classpaths (don't know how yet :)

13:16 technomancy: best to keep it that way

13:16 sattvik: dsabanin: Have you tried into-arry instead of to-array. The latter gets an Object[], not a String[].

13:16 gtrak: cemerick, what is this I hear about emacs-ifying eclipse?

13:17 cemerick: gtrak: just noodling on some things

13:17 dsabanin: sattvik, you did it!!

13:17 thank you :)

13:17 fdaoud: dsabanin: just trying to think of what it could possibly be,the problem.. probably sattvik is right, it has to do with types of args

13:18 dsabanin: so is it possible to not see the method in the list and yet the method will still be there?

13:18 does it not show you the methods of ancestors?

13:18 sattvik: dsabanin: No problem.

13:18 gtrak: cemerick, it sure sounds really exciting :-)

13:18 I use the emacs+ plugin myself for java work

13:22 dsabanin: fdaoud, thanks for your help too!

13:23 fdaoud: dsabanin: you're very welcome

13:25 dnolen: CLJS PersistentVectors have landed, https://github.com/clojure/clojurescript/commit/e615f4cd326e7c608050272c64c4dfaff9a34689

13:26 RickInGA: very cool

13:27 ibdknox: dnolen: what were the numbers on that?

13:27 dnolen: ibdknox: insanely faster all around, http://jsperf.com/persistentvector-norecur-js/11

13:27 ibdknox: those tiny bars are Vector

13:28 ibdknox: nice! :D

13:29 dnolen: ibdknox: notice how fast the handwritten PersistentVector.js is on Chrome, something to look forward to when we get more compiler optimizations in :D

13:30 ibdknox: dnolen: yeah, what a big difference :) definitely room for awesomeness there.

13:30 dnolen: ibdknox: I think in 6-7 months we can look forward to all around good performance from CLJS.

13:31 ibdknox: PersistentHashMap is another big one to do.

13:31 ibdknox: I like that outlook.

13:31 hehe

13:32 gfredericks: where's the hippest library with a -?>> macro?

13:32 ibdknox: core.incubator might have that one

13:33 gfredericks: ibdknox: looks like it does; thx

13:38 cemerick: gtrak: that's probably just keybindings though?

13:39 gtrak: cemerick, keybindings, and it does M-x stuff as well, but not the full experience of course

13:39 cemerick: right; I'm not concerned with UI

13:39 IMO, that's solidly part of "the rest" of emacs :-)

13:40 gtrak: so, like an emacs backend for eclipse? could you hook up emacs to it?

13:40 cemerick: It's far more important to be able to interactively extend and modify the environment from userland, and do it in Clojure

13:40 no, no unholy unions ;-)

13:41 gtrak: neat though, I suppose if you're writing clojure you may be in emacs anyway, so there's that :-)

13:41 repl-driven java refactoring?

13:43 cemerick: I'm never in emacs; I was talking more about adding the easy runtime-modifiability of emacs to eclipse / counterclockwise.

13:43 gtrak: very cool

13:43 jimduey: I would love an editor I could program in Clojure that had VIM keybindings and a repl that understood more than just text.

13:44 Iceland_jack: jimduey: viper?

13:44 jimduey: Bonus points if it ran in a browser and multiple people could connect to the same session.

13:44 Iceland_jack: Editor in a browser?

13:44 cemerick: jimduey: vimclipse + ccw + future magic sauce, perhaps.

13:44 Iceland_jack: You can use one of many terminal multiplexers that support shared sessions

13:44 jimduey: Iceland_jack: I might have to look at viper in the future.

13:45 cemerick: yet another thing on my todo list. :)

13:45 Iceland_jack: I believe Emacs offers some multi-user support but I just use GNU Screen

13:45 cemerick: bah, it's eclim, not vimclipse :-P

13:45 jimduey: Iceland_jack: Yeah, I've used tmux and emacs to great effect when pairing.

13:46 technomancy: multi-user emacs doesn't work unless you have nearly zero latency

13:46 concurrency =(

13:46 gtrak: ideally, you would want to share buffers but not keyboard control, right?

13:46 Iceland_jack: gtrak: yes

13:46 cemerick: jimduey: BTW, I really appreciate the work you've been doing with monads, as well as the f/j core.logic stuff.

13:46 Iceland_jack: create an Emacs server, connect to it using two Emacs clients from different screen sessions

13:47 jimduey: cemerick: thanks. It's been fun to have something to talk about.

13:47 ibdknox: jimduey: GSOC might start to get you exactly that this summer

13:47 RickInGA: technomancy: you talked about emacs and vim for swarm coding. do you think it is feasable to do swarm coding with eclipse?

13:47 jimduey: ibdknox: Cool!

13:47 technomancy: RickInGA: if you have a very fast local network and/or a high tolerance for latency, maybe

13:48 RickInGA: technomancy: translation, don't count on it :)

13:48 TimMc: I've seen multi-user Eclipse.

13:48 It communicates over XMPP.

13:48 technomancy: well, I don't think swarm-coding would work nearly as well if you had to install a bunch of stuff on every machine

13:49 it works because all you need is a terminal emulator and an SSH client; otherwise you've got That Guy holding up the whole group because he's got the wrong version of something or other

13:50 at least for a user group. maybe in other contexts (inside a company or during a workshop session where folks are prepped) it wouldn't be as big of a deal.

13:51 simard: I read in JoC that you shouldn't use clojure.lang.PersistentQueue accross threads, why ?

13:55 raek: simard: it works perfectly fine with multiple threads (since it's persistent), but there are more effecient ways of implementing work queues

13:55 simard: persistent == immutable ?

13:55 Bronsa: no

13:55 mk: simard: sort of, and a few other things

13:56 simard: so, no, and sort of :)

13:56 mk: like same-performance guarantees

13:56 Bronsa: well, it was a "not only" :)

13:56 gtrak: I thought persistent is just about performance

13:56 raek: simard: normally you'd use something like this for work queues: http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/BlockingQueue.html

13:56 Bronsa: it means also that they do structural sharing

13:57 gtrak: ah, I suppose I was wrong, then it's redundant to say persistent immutable data structures as folks do

13:57 raek: my assumption was that persistent implies immutable

13:57 TimMc: it does

13:57 Bronsa: i guess so

13:58 mk: I guess it's just extra-immutable, in that the performance isn't supposed to change either

13:59 wasn't there a structure in clojure that works as a blockingqueue?

13:59 eggsby: Hola #clojure, I had a quick question about load-file vs. (eval (read-string ..)). If I were to use the read-string method, Assuming what I'm reading is a clojure data structure, how would I read in more than one def from a file?

14:00 Bronsa: clojure.lang.PersistentQueue maybe?

14:00 ibdknox: eggsby: wrap it in (do .. )

14:00 simard: as for the BlockingQueue, why is it more efficient than PersistentQueue ?

14:01 eggsby: ibdknox: I'm new to clojure, I understand the do construct, but how would I loop over each def in the file?

14:02 ibdknox: you wouldn't have to if you did (eval (read-string (str "(do " some-str ")")))

14:02 you're turning it into one form that way

14:02 mk: simard: it's not immutable, but it's not broken when it comes to threading

14:03 (is my guess)

14:03 raek: simard: you can't really compare their performance because they do different things

14:04 mk: I was thinking of something more like what seque uses?

14:04 eggsby: oh interesting ibdknox

14:04 raek: a BlockingQueue does thread synchronization (so that threads can wat for each other) and maintains state

14:05 eggsby: thank you, I will try that

14:05 raek: a persistent queue is stateless, so to have something that changes over time you need a reference primitive too

14:06 simard: Ok, I have two threads, I want to send immutable objects (say strings) between them (bidirectionaly), and asynchronously. What's the best data structure in that case ?

14:06 raek: maybe you could say that a persistent queue wrapped in an atom is comparable to a blocking queue

14:06 simard: raek: that's what I use at the moment

14:06 raek: but the atom lacks blocking features

14:06 mk: raek: well, it abstracts much of that away, since you can treat it as a simple function (since it blocks), and to add things to the queue is a lot like using an agent

14:07 simard: and I don't need to block.

14:07 mk: simard: could you explain the bidirectionality?

14:07 simard: so I guess a persistent queue wrapped in an atom is what I needed after all.

14:07 raek: simard: what do you want to do when you try to pop when the queue is empty?

14:07 simard: mk: well, I'll just use two queues.

14:08 basically, one thread reads, the other writes, and I'll have two such queues, one each way.

14:08 mk: simard: are you talking about return values? do you want two server-like things?

14:08 simard: raek: go on doing something else, and peek later.

14:08 raek: I guess you could use both approaches

14:08 clojurebot: Excuse me?

14:09 raek: if any of the threads need to way for a value, then blocking queue is a better fit

14:09 simard: mk: hum no there would not be request/reply, but I guess it COULD happen sometimes (that would be an exception)

14:10 mk: simard: it might help if you give a bit of a broader picture

14:10 raek: or if you are thinking of implementing an infinite loop that polls for values

14:10 autodidakto: ibdknox: thanks for noir, btw. I'm messing with it now, trying to get my head around it (coming from a sinatra/padrino/rails perspective)

14:11 raek: the biggest difference between the approaches is how the reading end behaves, I think

14:11 simard: ok I have an opengl rendering loop (thread 1), and some clojure sandbox (thread 2). thread 1 sends commands to thread 2, thread 2 sends results back. Note that thread 1 could send events to thread 2 (that do not require a reply from thread 2).

14:12 the opengl thread must not be blocked by a long operation of thread 2.

14:12 mk: do you mean that the sandboxT2 sends commands to the renderT1?

14:12 raek: what does thread 2 do while the queue is empty?

14:13 you can also use thread pools through executors

14:13 mk: I'd guess that it renders more frames

14:13 simard: raek: sleep ?

14:13 raek: so it's blockgin, then?

14:14 ibdknox: autodidakto: you're quite welcome :)

14:14 raek: or do you alternate between pop and Thread/sleep?

14:14 simard: raek: hum actually no it doesn't sleep, it could do some other jobs.

14:14 eggsby: thank you ibdknox I was able to solve my problem :)

14:14 simard: but I guess the thread could be awoken by some message from that queue.

14:14 raek: re. executors: http://blog.raek.se/2011/01/24/executors-in-clojure/

14:15 fdaoud: ibdknox: so much for hiding from the fans ;)

14:15 ibdknox: srsly

14:15 haha

14:16 mk: simard: what does the sandbox do?

14:17 gtrak: anyone, any thoughts on what's useful to say about clojure(script) to normal js/ruby who haven't heard or considered clojure?

14:18 simard: basically the idea is to allow the player to script his own actions, and perform some tasks based on timers etc.

14:18 gtrak: normal js/ruby web dev guys*

14:19 simard: mk: you could, say (defn jump-twice [] (jump) (jump)) in the sandbox, then bind that function to a keypress. thread1 (UI/GL) would send keypress events to the sandbox, sandbox would reply asynchronously by sending two strings "jump" "jump".

14:19 gtrak: "it's a lisp on the jvm" is not persuasive :-)

14:19 mk: gtrak: you can recite the usual 4 things, which are immutability, lispyness, functions?, and... something else

14:20 lynaghk: gtrak: tell them Clojure is expressive and fun like Ruby, but without all of the magic. That should appeal to anyone who has had to go into a Rails project he/she didn't write.

14:20 gtrak: ah, yea

14:20 ibdknox: on the JS side, reasonable semantics

14:20 lol

14:20 mk: gtrak: one big pull might be that it's really set up for multi-processor computing

14:20 autodidakto: gtrak: as a way to convince them to check out clojure in general? or try to replace their ruby/js frameworks?

14:20 technomancy: "metaprogramming you can still understand next week"

14:20 lynaghk: technomancy: hells yes.

14:20 autodidakto: technomancy: lol. nice

14:20 fdaoud: no more "what the hell 'this' is this?"

14:20 Bronsa: lol

14:20 Wild_Cat: lynaghk: I wouldn't so much say "without the magic". I mean, macros *are* pretty magical.

14:21 gtrak: those guys don't really get shared memory, php/ruby/python is all about launching a process per your request

14:21 so concurrency means 'add another box'

14:21 lynaghk: Wild_Cat: yes, but people in the community are wary of them much more than Ruby folks are wary, of, well, everything they do.

14:21 ibdknox: Wild_Cat: not really, they're just functions that take in a form and spit out a new one

14:22 Wild_Cat: gtrak: IMO the awesome thing about Clojure is that it's a Lisp with more syntax, which makes it saner, and it has kickass STM support.

14:22 ibdknox: I think the real argument is the level of abstraction you can achieve in Clojure

14:22 fdaoud: as RH put it, if you want syntactic sugar, clojure macros give you your own personal chocolate fudge machine!

14:22 mk: simard: I see. And both sides have other things to do when not waiting for the other side to do something?

14:23 Wild_Cat: ibdknox: you can also halt/resume form evaluation in macros, and rebind surrounding vars, which as a Python dev I find weird.

14:23 lynaghk: wild_cat: this is the best critique of ruby programming style I have ever seen: https://www.destroyallsoftware.com/blog/2011/one-base-class-to-rule-them-all

14:23 simard: mk: the GL side, definitely, the sandbox side, yes, maybe.

14:23 Wild_Cat: lynaghk: note that I'm not defending Ruby programming style. I hate it because it appears to rely so much on monkeypatching.

14:24 simard: unless timers are dealt with from thread1 and sent as events to the sandbox

14:24 gtrak: well, the main issue I found is immutability, concurrency, lisp metaprogramming are both core motivations of clojure and totally unrelatable to those guys, the 'fun like ruby but less magic' is a great one though

14:24 simard: in which case the sandbox could be blocking

14:24 lynaghk: Wild_Cat: yeah, I hear you. I think I've still written more Ruby code than I have Clojure code at this point. You can probably bend Clojure to do terrible things too, but I love that the community is very much against that kind of thing.

14:24 fdaoud: aot straight JS, definitely that in ClojureScript I don't worry about JS weirdness lurking and just waiting to ruin my day.

14:24 mk: simard: on the gl side, you don't need to block. If you want to block on the sandbox side, you can have it block on a blockingqueue

14:24 Wild_Cat: lynaghk: and I agree with that paper, although Ruby isn't my thing much. I'm a hardcore Python guy currently learning Clojure (and liking it)

14:25 gtrak: Wild_Cat, python was my schtick before clojure, too, I haven't looked back really

14:25 ibdknox: gtrak: the old you write the language you write your program in is also interesting to those folks

14:25 lynaghk: Wild_Cat: glad to hear you're liking Clojure thus far.

14:25 fdaoud: Wild_Cat, gtrak: Django too?

14:25 Wild_Cat: gtrak: Python is kinda like my job, so... :p

14:25 fdaoud: no, Pyramid.

14:25 gtrak: i tried django to learn web dev, and got really bogged down :-)

14:25 mk: I've been wondering about opengl actually, because it's hard to map on to clojure's persistent collections...

14:26 autodidakto: Matz: "Some may say Ruby is a bad rip-off of Lisp or Smalltalk, and I admit that. But it is nicer to ordinary people." :)

14:26 Wild_Cat: fdaoud: although that's a recent development. I used to do embedded work with Python

14:26 gtrak: ibdknox, i think you typo'd there?

14:26 simard: mk: so basicaly, two queues, both blocking, t1->t2 and t2->t1. t2 blocks on t1->t2 and sends results on t2->t1, t1 peeks t2->t1 and never blocks on it.

14:26 ibdknox: left off the quotes

14:27 gtrak: the old "you write the language you write your program in" is also interesting to those folks

14:27 gtrak: ah, got it

14:27 eggsby: django is fun, pyramid is better

14:27 :p

14:27 I'm playing with a coworker using noir right now

14:27 Wild_Cat: Django is kind of a PITA if you're not using its ORM, which I strongly dislike.

14:27 mk: simard: one of them would be non-blocking (the one that gl reads). Presumably you'd use an atom for that

14:27 autodidakto: one last quote: "Ruby is the love child of Lisp and Smalltalk, raised by Perl the eccentric nanny"

14:27 fdaoud: just asking out of curiosity, because my publisher has a django book in the works now.

14:27 Wild_Cat: (plus, since I'm working with DynamoDB these days, I couldn't use Django's ORM even if I wanted to)

14:27 eggsby: Wild_Cat: it's not so different than sqlalchemy declarative, but.. ~wrong channel~

14:28 Wild_Cat: eggsby: fair enough, let's drop that :p

14:28 eggsby: So, what are peoples thoughts on enlive vs hiccup?

14:28 gtrak: fdaoud, I went to pycon to try to get better at all that stuff, including django, but my style is to understand things thoroughly, which is harder than it looks there

14:28 autodidakto: eggsby: coming from haml, both scare me.

14:29 eggsby: lol

14:29 ibdknox: hiccup is not far from haml

14:29 why does it scare you?

14:29 eggsby: Do you have a reason why you prefer hiccup over enlive ibdknox ?

14:29 mk: simard: does the sandbox simulate the environment?

14:29 technomancy: enlive is more elegant, hiccup is more straightforward.

14:29 ibdknox: enlive is probably the single most complicated library I've seen, which is somewhat ridiculous given what it does :)

14:30 autodidakto: ibdknox: going through the noir examples now... just feels really weird to see the html defined inline, i guess

14:30 ibdknox: I don't necessarily prefer hiccup to anything really.

14:30 eggsby: autodidakto: it makes sense if you just think of it in terms of the dom structure

14:30 ah ibdknox sorry for the assumption :p

14:30 ibdknox: In talking to people these days, I usually list 3 solid solutions to templating:

14:30 eggsby: dom structure is just a tree, easy to represent in clojure

14:30 ibdknox: hiccup, comb (erb-like), and stencil (mustache)

14:31 icey: autodidakto: I felt the same way initially, but give it a go in a project or two… it ends up being really nice once you start thinking about your UI in terms of pieces that are disconnected from styling

14:31 autodidakto: then use CSS to push stuff around on the page / style

14:31 mk: simard: it sounds like you're dealing with proper-object or actor (?) communication / message passing

14:31 autodidakto: icey: Thanks, I'll keep that in mind

14:31 technomancy: hiccup has a cooler namesake: http://tinyurl.com/y7ncrur

14:31 icey: autodidakto: being able to treat your markup like everything else in clojure (data) ends up being really powerful feeling

14:32 ibdknox: yeah, true composability is really nice. That coupled with the simplicity of hiccup are its main values

14:32 autodidakto: ibdknox: second-ing your enlive comment, i like how enlive is a templating language... and a web scraper!.... and a cold-press coffee brewer!

14:32 icey: ibdknox: btw, I'm checking out Korma for the first time today. It's nice, I like it :)

14:32 technomancy: from a tooling perspective, erb-like tools are a mess

14:32 fdaoud: icey: +1

14:33 technomancy: I tried to write Emacs support for ERB and had to abandon it; it is simply not worth the trouble.

14:33 ibdknox: technomancy: sure, but some people want them *shrug*

14:33 mk: "also makes chili and fries"

14:33 fdaoud: I hate writing an app and need to switch mindsets just because I'm working on the template part

14:33 technomancy: ibdknox: people want for loops too.

14:33 ibdknox: there are times when you need that level of complexity

14:33 technomancy: ibdknox: times when you don't have time to do it the right way, I guess

14:33 ferd: fdaoud: +1 ?! come on!... it's (inc %) here ;-)

14:33 autodidakto: icey: haha yeah, I was checking out noir, then korma, then live-cljs and i was like "hey wait this is that one guy in irc"

14:34 ibdknox: technomancy: haha :p

14:34 fdaoud: ferd: :)

14:34 ibdknox: icey: glad you like it :)

14:34 icey: autodidakto: afaik ibdknox is actually quadruplets who all happen to hack

14:34 ibdknox: technomancy: in any case, I think those three cover all the bases

14:34 fdaoud: git clone https://github.com/ibdknox/*everything*

14:35 autodidakto: fdaoud: about switching mindsets: that's how i got use to things in sinatra/rails... You program controller, you structure in html, you design in css...

14:35 ibdknox: lol

14:35 mk: shouldn't it be (inc! username)?

14:35 technomancy: ibdknox: I think stencil gets you the familiarity of looking erb-like without opening the door to doing stupid things you'll regret later.

14:35 fdaoud: {ibdnox,technomancy,weavejester,mmcgrana}

14:36 ibdknox: I think the place hiccup *really* shines is on the client

14:36 using hiccup (via crate) in CLJS is awesome

14:36 technomancy: I agree, it's my first suggestion for those looking to write html in html

14:36 technomancy: it's like having pure functions; it's not really about adding restrictions, it's about being able to offer guarantees about a function/template.

14:36 autodidakto: ibdknox: ahh, makes sense. one reason i've stayed around from client side javascript mvc stuff is the hideous templating/views..

14:37 ibdknox: yeah

14:37 they're terrible

14:37 autodidakto: not that i know what i'm talking about, but it all kind of looks like a hack the browser/javascript was never ment to do

14:37 *meant

14:38 cljs is a tempting promise of better days

14:38 fdaoud: autodidakto: yeah it gets a bit crazy. I'm mainly a Java guy and JSP just drives me nuts.

14:39 lynaghk: autodidakto: I feel the same way. I just do all of my dynamic templating with hiccup / C2.

14:40 Seeing all of the {{ }} in JS just makes me long for a better Clojure set literal synatax, anyway.

14:41 autodidakto: fdaoud: I don't know much about jsp. What is it that drives you nuts?

14:42 lynaghk: what's C2?

14:42 ibdknox: lynaghk: lol

14:42 lynaghk: autodidakto: http://keminglabs.com/c2/

14:43 ibdknox: (lil' kevin's first troll!)

14:43 ibdknox: haha, like I said, I think we should switch the syntax for maps ;)

14:43 fdaoud: autodidakto: essentially what I hinted at earlier, that you work with a solid full-featured language (Java,Clojure,whatever), then you get to the template side (which in Javaland usually means JSP) and then it's a whole different syntax, watered down features, and a ton of "oh but in JSP you can't do that.."

14:44 lynaghk: ibdknox: actually, I do all of my clojure programming with inline JSON literals = P

14:44 autodidakto: lynaghk: cool thanks

14:45 scriptor: hey guys, so I'm tinkering with a clojure->php thing right now

14:45 ibdknox: oh god

14:45 lol

14:45 that's scary :p

14:45 autodidakto: fdaoud: well said. It's like you leave the power and world of the language, and enter into a not-quite-right dsl-disconnect

14:45 scriptor: got a question on how you guys suggest how to tag whether an expression should be used as an expression or a statement

14:46 autodidakto: fdaoud: or at least that's how I feel when I do rails stuff

14:46 chouser: scriptor: are you trying to generate idiomatic php? or something that has clojure symantics?

14:46 scriptor: (for example, an if expression that's just by itself is compiled as a statement, one embedded in a function call needs to be an expression)

14:46 chouser: clojure semantics, preferably

14:47 at best the php should be readable, but doesn't have to be idiomatic

14:47 chouser: scriptor: ah. Well, the Clojure analyzer (but not the cljs one) figures this out

14:47 ibdknox: scriptor: are you starting from the ClojureScript ocmpiler?

14:47 scriptor: ibdknox: nope

14:47 I looked through the cljs compiler a bit

14:47 simard: mk: sorry someone passed by my office, yes, I use actors

14:47 mk: elsewhere in the app anyway

14:47 scriptor: it seems to package sexprs into...hashes? lemme check again

14:47 simard: not from clojure code right now, I was considering using queues instead

14:48 technomancy: I don't think it's possible to have a clojure implementation on a runtime that has mutable strings

14:48 hiredman: scriptor: it is easy, everything is an expression unless it is not the last expression in a do

14:48 simard: mk: the sandbox doesn't simulate anything, there is another (a third) thread for that running jbullet

14:48 technomancy: you would have to call seq on every string before you compare it for equality, which is just horrible

14:48 chouser: scriptor: The Clojure analyzer keeps track of "context", whether an expression is in return, expression, or statement position

14:48 scriptor: right, context

14:49 dnolen: chouser: I thought CLJS analyzer did that as well

14:49 technomancy: you would have to choose between broken equality semantics (in which case it's not really Clojure anymore) and losing host interop for strings.

14:49 scriptor: technomancy: as long as strings are never actually mutated, would there still be a problem?

14:49 chouser: dnolen: It may. I meant to say that I didn't *think* the cljs one did. I wasn't trying to claim knowledge there.

14:49 dnolen: and now that you mention it, I think I do recall that.

14:50 dnolen: chouser: k, it does :) I was deferring to you're generally deeper knowledge about these things :)

14:50 scriptor: ah, if other php code mutates the strong

14:50 *string

14:50 chouser: dnolen: ha!

14:50 technomancy: scriptor: you simply cannot make the kind of guarantees you need

14:50 I recommend reading http://home.pipeline.com/~hbaker1/ObjectIdentity.html before you sink too much time into the project =)

14:50 mk: simard: hmm. Since you're sending keystrokes to the sandbox, if the sandbox is a single thread, and it might be busy, you might end up with something very unresponsive

14:50 technomancy: I've thought about this for elisp as a compilation target, and I can't see any way around the problem.

14:51 chouser: clojure deals with mutable platform things all the time that it just pretends are immutable.

14:51 it would be a shame if strings were in that category, but I think not a deal breaker.

14:51 scriptor: technomancy: so the issue is if, say, you call a function in some external code, pass it a string, and that function mutates the string?

14:51 dnolen: scriptor: just use the CLJS analyzer, it should be easy to modify ClojureScript to emit PHP, save yourself a lot of time.

14:51 scriptor: chouser: that's what I was thinking

14:51 fdaoud: autodidakto: I agree, and that's why I like hiccup

14:51 technomancy: ,(= (into-array [0]) (into-array [0]))

14:51 clojurebot: false

14:51 technomancy: chouser: ^

14:52 chouser: hmm

14:52 that's an excellent point

14:52 dnolen: scriptor: a CLJS->PHP would be kind of awesome - all the work has pretty much been done for you in ClojureScript, it wouldn't even be difficult I think.

14:52 scriptor: dnolen: true, I'll have to look at it closer, but one issue is that js can do some things that you can't do in php

14:52 * chouser has to show up in IRC every once in a while to be wrong a few times in a row, and then slink back offline.

14:52 dnolen: scriptor: CLJS relies on lowest common denominator JS, what specifically are you thinking of?

14:53 scriptor: for example, if you want to compile a do block as an expression, it wraps the resulting code of that into: (function(){...})()

14:53 with the result of the do block inside the function

14:53 fdaoud: chouser: because in person you are always right, so coming here keeps you honest? :D

14:53 simard: mk: yeah, there's a timeout in the sandbox, but of course the user could make it rather unresponsive if he wished to. Did you have something on your mind about that ?

14:54 chouser: fdaoud: I didn't say that. Not out loud.

14:54 fdaoud: chouser: ok. I didn't hear you say that, either.

14:54 technomancy: it bothers me because this is the argument I use against CLers who loudly proclaim how CL is so great because it can be made to do anything with macros

14:54 dnolen: scriptor: seems like that wouldn't be hard to work around.

14:54 technomancy: and it's a really good argument against CL

14:54 ibdknox: php has lambdas now

14:54 technomancy: but unfortunately it's also a really good argument against a bunch of otherwise-interesting runtimes

14:54 hiredman: you don't need lambdas

14:55 chouser: you could use non-host strings. :-P

14:55 pjstadig: technomancy: i don't get why mutable strings matters

14:55 hiredman: https://github.com/hiredman/php.lisp/blob/master/compiler.php

14:55 pjstadig: even immutable strings are compared char for char for equality

14:55 technomancy: pjstadig: because you can't define meaningful equality predicates against mutable objects

14:55 ,(= (into-array [0]) (into-array [0]))

14:55 clojurebot: false

14:56 technomancy: ,(= (seq (into-array [0])) (seq (into-array [0]))) ; you have to seq it first

14:56 clojurebot: true

14:56 pjstadig: so

14:56 chouser: pjstadig: the problem is if two strings are mutable, you should *always* say they are unequal, even if they happen to have the same contents at any given moment

14:56 technomancy: pjstadig: you can implement it, but it's going to be very annoying to use in practice

14:57 chouser: but having strings always be unequal ruins their usefulness (I was going to say "value" haha) as map keys

14:57 scriptor: so in clojure equality for arrays is based on identity, not contents?

14:57 chouser: scriptor: exactly

14:57 pjstadig: i don't follow the argument

14:57 there are all kinds of mutable objects that are compared for equality all the time

14:57 chouser: for pretty much anything mutable, equality is based on identity

14:57 pjstadig: sure it isn't as nice as immutable objects

14:57 mk: simard: I think mostly I'm just trying to think through how I would end up doing this in clojure... the way gl handles state is ugly (if you want it to be efficient)

14:58 pjstadig: and you can argue that they should rightly be considered unequal (or at the least only equal at that moment)

14:58 but practically people compare mutable objects

14:58 scriptor: technomancy: so we only treat strings as if they were immutable, is the problem then that the strings *can* be mutated by outside code?

14:59 mk: simard: I guess there should just be the simulation code, which needs a dropbox for incoming keystrokes/input (though these could be converted into specific :right :left :jump keywords)

14:59 technomancy: pjstadig: right; the point is that clojure.core/= makes a certain set of guarantees, and if you want to compare the current value of two strings, you will have to use something else.

14:59 chouser: technomancy: what about a combination of a str= function, an immutable non-host string type, and not using host strings as map keys?

14:59 a bit of a mess, but maybe not too bad in practice?

14:59 scriptor: interop could be a pain

15:00 chouser: yeah. as would two different string types.

15:00 technomancy: chouser: yeah, the map keys issue is moot in elisp since you would be using symbols for that anyway. it might not be too horrid in practice; I don't know.

15:00 scriptor: yep, and PHP doesn't let you extend the string class in any meaningful way

15:00 chouser: maybe just str= and then use keywords not strings as map keys

15:01 technomancy: chouser: funnily enough, elisp case actually refuses to consider strings as equal, which I hated until I read the Baker paper.

15:02 dnolen: scriptor: nor does Java, Clojure implementation will need to work around those kinds of host details in various ways.

15:02 technomancy: anyway, everyone should read http://home.pipeline.com/~hbaker1/ObjectIdentity.html and keep a copy on hand in case you are accosted by a CLer.

15:02 mk: simard: if you're not using the advanced gl stuff which caches collections on the gpu, then maybe the gl thread can just run on its own, and occasionally read the "worldstate" atom or whatever, and then render it

15:03 autodidakto: technomancy: Here's that link in Reability: http://www.readability.com/articles/nme17i9w :)

15:03 scriptor: technomancy: can you explain what the problem is with just treating strings as if they were immutable, interop?

15:03 mk: simard: (I'm just thinking out loud here - the way you seem to have it set up with a pair of atoms, or an atom+blockingqueue, will probably work out just fine)

15:03 dnolen: scriptor: CLJS is immutable by convention as well

15:03 technomancy: hmm; it could be possible to make strings in clojure-in-elisp read as symbols

15:03 chouser: oh I forgot js strings are mutable

15:04 scriptor: wait, they are?

15:04 dnolen: scriptor: anybody could take a CLJS PersistentVector and mess things up if they want to.

15:04 technomancy: what

15:04 dnolen: chouser: they are not

15:04 technomancy: ok, whew

15:04 scriptor: the problem is that clojure.core/= makes a very specific set of guarantees; you either have to break those guarantees or always return false.

15:04 simard: mk: actually, the rendering (scala) and the simulation (java) both work at the moment and communicate with each other using actors (sending force application to objects) and locks (setting objects position by physics engine)

15:04 scriptor: any place where those guarantees are documented? :)

15:04 chouser: seriously, I need to keep my mouth shut. I wonder if there's something about today I can blame it on.

15:05 technomancy: scriptor: yeah, the paper I just linked to =)

15:05 clojure.core/= is an implementation of egal

15:05 simard: mk: the sandbox (clojure) is something else, that must communicate with the GL thread (same thread as UI)

15:05 scriptor: ah, got it

15:05 mk: simard: I see - though I thought that the sandbox was a sort of secondary simulation

15:06 simard: mk: no, however if the user wants to do some calculation there (say AI), he could.

15:06 dnolen: chouser: haha, no way :) easy to forget what can be changed in a language as loose as JS

15:08 technomancy: the baker paper on equality will help you appreciate the huge mountain of crap that Clojure neatly lets you totally avoid.

15:08 it's up there with Out of the Tarpit IMO

15:08 scriptor: so, even if strings are never actually mutated, it'll break the set of guarantees core/= has?

15:09 autodidakto: technomancy: "crap clojure neatly lets you totally avoid" makes me think of design patterns

15:09 chouser: scriptor: yes

15:09 Wild_Cat: technomancy: what paper is that, I'm afraid to ask?

15:09 technomancy: clojurebot: equal rights for functional objects

15:09 clojurebot: Equal Rights for Functional Objects is Baker's paper on equality and why it's impossible to define sensible equality in the presence of mutable data structures: http://www.pipeline.com/~hbaker1/ObjectIdentity.html

15:09 technomancy: Wild_Cat: there ya go

15:10 autodidakto: clojurebot: Out of the Tarpit

15:10 clojurebot: Out of the Tarpit is a short, accessible paper on FP and reducing complexity by identifying and minimising state: http://ben.moseley.name/frp/paper-v1_01.pdf

15:10 technomancy: clojurebot: botsnack

15:10 clojurebot: Thanks! Can I have chocolate next time

15:10 Wild_Cat: technomancy: it's appropriate to break out the "mother of god" memeface.

15:10 chouser: scriptor: imagine (let [a {"foo" "bar"}] (baz a) (get a "foo")). I clojure, I promise that returns "bar". I don't have to look at baz

15:10 autodidakto: technomancy: the link for out of the tarpit is way behind wrong

15:11 technomancy: clojurebot: forget Out of the Tarpit |is| a short, accessible paper on FP and reducing complexity by identifying and minimising state: http://ben.moseley.name/frp/paper-v1_01.pdf

15:11 clojurebot: I forgot that Out of the Tarpit is a short, accessible paper on FP and reducing complexity by identifying and minimising state: http://ben.moseley.name/frp/paper-v1_01.pdf

15:12 gtrak: aikido is pretty awesome though

15:12 chouser: scriptor: but if strings are mutable and = compares their contents, then the definition of baz could reach into a and change the contents of the the string "foo" or "baz"

15:12 technomancy: clojurebot: Out of the Tarpit is a short, accessible paper on FP and reducing complexity by identifying and minimising state: http://web.mac.com/ben_moseley/frp/paper-v1_01.pdf

15:12 clojurebot: Ok.

15:12 technomancy: autodidakto: thanks

15:12 autodidakto: gtrak: hehe

15:12 technomancy: no prob

15:13 chouser: scriptor: if "foo" changes, the map is then completely broken with hashs leading to the wrong branches of the tree.

15:13 gtrak: immutability, use your mutable-state's energy against itself in a circle-like motion

15:13 chouser: just an example of what happens when you break the guarantees provided by =

15:14 technomancy: "even if strings are never actually mutated, it'll break the set of guarantees core/= has?" is a bit like "if a tree falls in the forest and no one is around, does it make a sound?"

15:14 if you can guarantee that strings are never mutated, then you don't have mutable strings anymore =)

15:16 mk: simard: I see - I don't think I'll be able to come up with something better than suggesting blockingqueue for cases when the thread has nothing else to do (ie, it sleeps then polls), and agent/persistentqueue communication otherwise

15:17 pjstadig: look i'm not saying that mutable strings are better than immutable strings

15:17 i'm just saying it's not impossible to use mutable strings

15:17 it's just very, very precarious and fragile

15:17 simard: mk: well thanks for your time, the discussion itself was worth it :)

15:18 pjstadig: the java.util.Map javadoc gives you a stern warning about using mutable objects as keys, because it most definitely can be disastrous if a key changes after being put into a map

15:18 gtrak: that's what you have to do in C, but they're already ok with precarious/fragile

15:18 mk: simard: :)

15:18 technomancy: pjstadig: yeah, it's just a question of whether the hassle would be enough to render the runtime impractical

15:19 HaakonKL: Why would you want to use mutable keys in the first place?

15:19 technomancy: certainly it's possible

15:21 amalloy: HaakonKL: presumably because you're in a language where everything is mutable by default, and it's just easiest

15:21 sritchie: technomancy: trying out leiningen 2, finally!

15:21 For some reason I'm getting no output from lein2 deps

15:22 Exception in thread "main" java.lang.IllegalArgumentException: array element type mismatch

15:22 lein2 compile is silent as well, strange

15:22 technomancy: no output is what you should expect from lein deps, right. where are you getting the exception?

15:25 scriptor: technomancy: right, so even though php's strings may be implemted to be mutable, clojure semantics would still hold if you could guarantee that it is never actually mutated

15:25 *they are never

15:25 cemerick: interesting bits on the ML today…dum de dum…trademark law?! o.0

15:25 dnolen: scriptor: hmm can't you copy PHP strings?

15:25 autodidakto: ibdknox: It's huge shock to the system to be reading the html tutorial on the beautiful noir site, then clicking on the "StringTemplate" link.

15:25 technomancy: scriptor: if you could guarantee that it's never mutated then it's immutable.

15:25 scriptor: dnolen: I think it uses copy-on-write, so probably

15:25 ibdknox: autodidakto: lol

15:26 scriptor: technomancy: yes! that's what I was thinking

15:26 now to guarantee that in a language so friendly to things like this

15:26 technomancy: but you can't guarantee that without rewriting the interpreter

15:27 sritchie: technomancy: exception's on lein swank --

15:27 technomancy: lein2 deps doesn't populate a lib folder either, though

15:27 technomancy: sritchie: yes, that's by design

15:27 scriptor: off the top of my head I can't think of too many functions that change a string as a side-effect

15:27 technomancy: the lib/ dir was an accident of history

15:27 emezeske: technomancy: Would it not be sufficient (although perhaps inefficient) to implement an immutable string class in the host language, and use that?

15:27 sritchie: ah, interesting

15:27 technomancy: scriptor: that's a far cry from a guarantee though

15:27 sritchie: lein2 repl is throwing the exception

15:27 scriptor: technomancy: true, but a start

15:28 technomancy: emezeske: depends on the runtime I guess

15:28 you can never entirely avoid hosty strings

15:29 sritchie: technomancy: here's what I've got: https://gist.github.com/2242587

15:29 that's my initial stab at conversion

15:29 technomancy: emezeske: "no wrapper classes" is very central to the design of Clojure

15:29 basically you'd end up doing (into "" (hosty-function)) all over the place

15:30 sritchie: there's currently a bug in :javac-options handling; lemme find the issue

15:30 I think the workaround is easy

15:30 scriptor: yea, it wouldn't be worth it

15:30 sritchie: technomancy: fixed, it was my javac-options

15:30 cool

15:30 technomancy: sritchie: https://github.com/technomancy/leiningen/issues/450 for the record

15:31 emezeske: technomancy: Ahh, I see, that does make sense. You'd have to also make sure all the hosty-functions were wrapped so as to return immutable strings, which might not be tenable

15:32 scriptor: emezeske: yep, or have all string handlling functions call my-stringify in some way

15:32 emezeske: Yeah, that does get pretty ugly

15:33 scriptor: on the other hand, that's pretty much what I do with pharen's sequences

15:33 technomancy: not saying you shouldn't try it; just be mindful of the pitfalls

15:33 even if it's a bit of a mess, it'll be much more pleasant than using PHP =)

15:33 cemerick: weavejester: Q: what was the rationale for lower-casing HTTP header names?

15:34 eh, I withdraw the question. :-)

15:34 scriptor: it's easy with strings, since a lot of it boils down to first/rest

15:34 *with seqs

15:34 ferd: technomancy: I'd like for slime's macroexpand to show me metadata (like when setting *print-meta* on the REPL). Is it possible?

15:36 technomancy: If it needs changes on swank-clojure, I can look into it (some pointers welcomed ;-))

15:38 Frozenlock: Hmm... lein asks me for javac.exe. Do I need to install another java package? (Development Kit?)

15:40 TimMc: JDK, not JRE

15:41 weavejester: cemerick: You'd have to ask Mark, but I suspect it was because HTTP headers are case insensitive, and keys in a map are case sensitive.

15:41 cemerick: So you need some normalization, and lower-casing it probably the easiest.

15:43 cemerick: weavejester: Sure; I was mostly asking in frustration after not grokking why my (headers "Some-Header-Name") refused to work for a bit. :-)

15:44 Frozenlock: TimMc: Thanks, downloading now :)

15:46 samaaron: does lein handle plugin and support dirs in a special way?

15:47 weavejester: samaaron: What do you mean by plugin and support dirs?

15:48 samaaron: weavejester: i'm trying to figure out how the lein-cljsbuild plugin works

15:48 it seems to have two internal 'projects' - one in a dir called plugin, and another in a dir called support

15:48 when you do a `lein deps` lein seems to know to pull the deps for both

15:48 emezeske: samaaron: That's not handled by lein specially, they are literally two separate projects

15:49 ibdknox: samaaron: emezeske separated the primary library from the leiningen plugin

15:49 samaaron: so lein knows to look for subprojects?

15:49 emezeske: samaaron: 'lein deps' doesn't pull deps for both; it pulls only the plugin. Then, when the plugin executes, it uses eval-in-project, at which point the dependencies for that subproject are pulled.

15:49 samaaron: oh, interesting

15:50 emezeske: So technically the plugin/ doesn't depend on the support/, in it's project.clj file

15:51 It's the subproject that the plugin creates that depends on it.

15:51 BTW, I wouldn't use lein-cljsbuild as an example of how to do things -- I have no idea what I'm doing! ^_^

15:52 samaaron: emezeske: :-)

15:52 emezeske: it just seems like magic to me

15:53 in fact, most of lein seems like magic

15:53 perhaps that's the point?

15:53 weavejester: samaaron: Lein's not that magical, honestly :)

15:53 samaaron: The command "lein foo" just runs leiningen.foo/foo

15:53 samaaron: weavejester: oh, i'm sure - when you understand it thoroughly enough

15:54 Raynes: I can attest that there is very little magic in Leiningen.

15:54 samaaron: weavejester: yeah, i grok that simple usecase

15:54 weavejester: samaaron: And then the eval-in-project macro evaluates a Clojure form with all the project's dependencies

15:54 Raynes: It only looks like magic because Clojure is like magic.

15:54 weavejester: samaaron: That's really all you need to know

15:55 samaaron: The way people make dependencies is they assoc them into the project map before calling eval-in-project

15:55 samaaron: oh ok

15:55 so `lein deps` calls eval-in-project with an empty form?

15:56 weavejester: So instead of: (eval-in-project project `(foo.core/foo "foo") `(require 'foo.core))

15:56 Raynes: eval-in-project isn't even magic. All it does is spin off a separate JVM with the classpath set up for the project. It then sends the code to that JVM for evaluation.

15:56 Now classloaders (which we haven't quite gotten right yet) are a bit like magic.

15:56 weavejester: You'd first update the project like: (update-in project [:dependencies] conj ['foo "1.0.0"])

15:56 HaakonKL: Classloaders: Because otherwise you could get viruses from the internet...

15:57 weavejester: What was that add-classpath project called...

15:58 samaaron: ok, so let me try and get this straight...

15:58 weavejester: Ah, pomegranate

15:59 samaaron: when i call `lein deps` in a new project that i'm using cljsbuild in

15:59 it creates me a .lein-plugins dir with a bunch of dependencies in

15:59 is that lein doing that or cljsbuild?

15:59 and how would I know?

16:00 emezeske: samaaron: That's lein. You know that because you haven't typed 'lein cljsbuild' yet :)

16:00 samaaron: ah ok

16:00 weavejester: samaaron: Lein loads the plugin. When you run the plugin, it will update the project map with its own dependencies.

16:00 emezeske: samaaron: (Technically lein cljsbuild could hook into deps and do it's own thing, but it doesn't)

16:00 weavejester: samaaron: Leiningen automatically downloads any deps needed, so there's no need for "lein deps" strictly speaking

16:01 You could just go "lein cljbuild" straight off

16:01 And Lein would make sure its deps were up to date before trying to resolve the command.

16:01 samaaron: that makes sense

16:02 weavejester: There's an implicit "lein deps" before every command, and before any "eval-in-project"s

16:02 samaaron: :-)

16:03 so when i do `lein cljsbuild` i don't see any new deps downloaded

16:04 weavejester: samaaron: In new versions of Leiningen it doesn't bother creating a "lib" or "classes" directory

16:04 Raynes: Yeah, it doesn't copy deps to your project anymore.

16:04 weavejester: samaaron: I believe it just downloads the deps into your $HOME/.m2 folder and adds them to the classpath directly.

16:04 Raynes: It uses them from where they sit in ~/.m2

16:05 sparkleshy: why are some "special forms", like fn, implemented with just ordinary clojure code? Isn't that against the definition of "special form"?

16:05 weavejester: sparkleshy: Implementation detail :) - don't look behind the curtain

16:05 sparkleshy: In future, they might be "real" special forms, so it makes sense to treat them that way.

16:08 samaaron: so how do i get access to the the google closure libs?

16:08 Raynes: Call google and ask for permission.

16:08 samaaron: haha

16:08 emezeske: samaaron: The base google closure library is a dependency of the clojurescript compiler

16:08 samaaron: but if they're in a jar in my ~/.m2 directory...

16:09 emezeske: samaaron: So you can just (:require ...) and you're good. They will always be on the classpath.

16:09 samaaron: oh, cool

16:09 emezeske: samaaron: Note that the base library doesn't include any third party stuff (soy templates, etc)

16:10 * emezeske goes to lunch.

16:17 benDos: Would this be the channel for clojurescript questions?

16:17 lynaghk: benDos: it would.

16:17 Raynes: Yep.

16:18 benDos: Ah cool, was going to start with it this weekend and wanted to make sure i could find an irc :)

16:19 Raynes: $max

16:19 lazybot: The most users ever in #clojure is 420

16:19 Raynes: He lies.

16:19 amalloy: Fix that plugin.

16:19 scriptor: make it say 69

16:19 benDos: Out of curiosity, do I still get access to browser native js libs like JSON?

16:20 scriptor: JSON isn't a lib, as far as I know

16:20 TimMc: ~max

16:20 clojurebot: Most users ever in #clojure: 404

16:20 Raynes: At least clojurebot is closer.

16:20 Er, lazybot.

16:20 TimMc: a broken clock...

16:20 scriptor: benDos: you'll have access to anything the browser provides

16:20 benDos: I've tested in chrome firefox and opera, they all seem to recognize JSON.stringify etc

16:21 scriptor: ah, didn't know they had that now

16:21 benDos: Cause of the super loose typing the compiler is able to not care about that type of run time stuff?

16:21 solussd: is defstruct/create-struct actually going away sometime? I think I'd prefer using them in some cases- e.g. when I'm threading a datastructure through several functions that conj data onto a map

16:21 benDos: I mostly work in java and c, but need javascript for a new project

16:22 Having not used clojure in a few years maybe less, seems like clojurescript will be a little nicer to work in

16:22 scriptor: I don't see why it wouldn't be able to use JSON.stringify

16:23 hiredman: ls

16:23 dnolen: benDos: (.stringify js/JSON ...) is what you want

16:23 benDos: in generally if you want to access global JS functionality you need to prefix with js/...

16:24 benDos: Forgive me, I don't remember clojure syntax v lisp'n'friends but the cadr looks like part of the function call there?

16:24 dnolen: benDos: cadr?

16:25 benDos: second element in the list :x

16:25 scriptor: (car (cdr ...)) ?

16:25 ah, yes

16:25 it's (.method-name object ...)

16:25 Bronsa: ,(macroexpand '(a/b))

16:25 clojurebot: (a/b)

16:26 Bronsa: no wait.

16:26 benDos: Maybe I'll start with some clojure docs before getting into clojure script clearly i thought i remembered more than I do

16:26 Bronsa: oh.,

16:26 ,(macroexpand '(Math/pow))

16:26 clojurebot: (. Math pow)

16:27 dnolen: benDos: someone needs to write a good ClojureScript book - I heard perhaps one was in the works?

16:27 benDos: From the readme, clojurescript is clojure less the jre?

16:27 but compiles to js etc

16:28 dnolen: benDos: it's an implementation of Clojure that compiles to JS yes.

16:28 technomancy: less the JRE and less eval

16:28 benDos: cool

16:29 hiredman: less vars

16:30 amalloy: dnolen: won't a good clojurescript book be out of date by the time it's published?

16:30 ibdknox: dnolen: isn't it a bit early for that?

16:30 pjstadig: less the stm

16:30 ibdknox: it will certainly be out of date by the time it is published

16:30 dnolen: pjstadig: anything JVM concurrency related really

16:31 cemerick: something is underway

16:31 pjstadig: isn't clojurescript still alpha?

16:31 benDos: clojure's stm uses the jre?

16:31 dnolen: amalloy: ibdknox: well I don't forsee the language changing dramatically. Many things going forward is optimization oriented.

16:31 cemerick: pjstadig: very, but the process of nailing down a book will be a decent forcing function for that

16:32 dnolen: are

16:32 autodidakto: I heard cemerick has the ear of tim oreilly himself

16:32 eggsby: What is the difference between binding and let?

16:32 ibdknox: dnolen: but any book on the subject will need to talk about libs and ways to do things..

16:32 eggsby: It seems to me that they do the same thing...

16:32 cemerick: hah

16:32 Raynes: Oh man.

16:32 Am I obligated to have a chapter on clojurescript in my book now?

16:32 amalloy: i think you're more obligated to have a book that's finished

16:32 cemerick: autodidakto: keep spreading that; enough of a whisper campaign might end up making it so :-P

16:33 Raynes: goodness no

16:33 * Raynes wipes sweat from how brow.

16:33 Raynes: his*

16:33 dnolen: ibdknox: I think a good book could cover libs and tooling in an appendix with caveats about change

16:33 scriptor: eggsby: binding rebinds already existing vars, then when it's finished executing it reassigns those vars to their previous values

16:33 dnolen: I think there are many people who might use ClojureScript who are thoroughly unfamiliar w/ Clojure.

16:34 eggsby: scriptor: but effectually, that is the same as let? Is it just the implementation that is different?

16:34 benDos: dnolen, google is throwing a shitton of money at dart maybe that'll end up working out

16:34 technomancy: eggsby: the two differences are that binding is "deep" and that let only applies to locals.

16:34 scriptor: eggsby: let doesn't assume that the vars exist, nor does it try to return them to their previous values

16:35 technomancy: vars and locals look sort of alike, but are very very different

16:35 dnolen: I also think ClojureScript might appeal to advanced JS devs who've been doing JS long enough to be interested in other approaches.

16:35 who don't really care about the JVM at all.

16:35 scriptor: how much production use does cljs see, if any?

16:36 dnolen: scriptor: I think there's stuff happening tho perhaps under the radar, and I think in the next 6 months could pretty quick.

16:37 eggsby: Thank you scriptor and technomancy

16:37 benDos: I understand that concurrency with imperative languages is hard but do so many feel to claim it just doesn't work :/

16:37 Was reading http://clojure.org/state

16:37 eggsby: I'm not sure I understand the use cases, but at least I understand the difference :)

16:37 flazz: is there a way to have stack traces be in terms of clojure?

16:38 pjstadig: binding and vars are a concurrency mechanism and a way of managing mutable state

16:38 technomancy: flazz: look at clj-stacktrace

16:38 pjstadig: a binding is mutable and can be set within the same thread

16:38 locals are immutable

16:38 Chousuke: eggsby: binding alters *dynamic* scope

16:38 dnolen: benDos: note that's written by someone who's done C++/Java/C# concurrent programs for 20 odd years.

16:39 Chousuke: eggsby: ie. the binding is changed for all code that runs while the binding is in effect.

16:39 eggsby: even if it's not in the current visible lexical scope.

16:39 autodidakto: technomancy: btw, why do stacktraces have the error at the top and not the bottom? everybody is constantly scrolling up.

16:40 technomancy: dunno

16:40 Chousuke: eggsby: let, on the other hand, just binds names (not vars) and creates a new lexical scope.

16:40 dnolen: flazz: 1.3 has very Clojure-y stacktraces, but I think few tools expose it.

16:41 flazz: dnolen: does emacs with swank/slime expose it?

16:42 dnolen: benDos: even w/ Gilad Bracha's involvement, I find Dart insanely boring. But I believe it also pushing the multi-lang browser support we're seeing now.

16:42 flazz: nope

16:42 technomancy: swank uses clj-stacktrace, which is a lot more readable

16:43 eggsby: thank you Chousuke and pjstadig

16:43 that clears it up, but wouldn't it be better to explicitly change state via a ref using the STM ?

16:44 autodidakto: ibdknox: it seems noir begins to embrace MVC with it's directory structure, but then mixes views and controlers routers?

16:44 Chousuke: not always

16:44 technomancy: eggsby: each of the four reference types is useful in different contexts

16:44 Chousuke: eggsby: dynamic vars are often used for a "context" sort of thing.

16:44 sritchie: autodidakto: that's kind of like saying you embrace bisexuality by dating girls, then losing steam

16:44 Chousuke: eggsby: ie, you have a bunch of functions using some global var, then you rebind that var to a value to provide a context for the functions, and proceed to use the functions while the binding is in effect.

16:45 ibdknox: autodidakto: https://groups.google.com/d/msg/clj-noir/FxipsTEhVtM/nDH3JH48LFAJ

16:45 autodidakto: sritchie: hehe, ibdknox: ok i'll check that out

16:46 eggsby: ah Chousuke

16:46 technomancy: ibdknox: does the default noir skeleton still spit out files that have non-def forms in the top-level?

16:46 ibdknox: it has one

16:47 which is sugar over require

16:47 Chousuke: eggsby: dynamic vars should be used sparingly though. After all, when you rebind a var you are affecting something that you can't see.

16:47 technomancy: I don't like it, but I'm stumped to come up with an alternative =\

16:48 Chousuke: that can get you in trouble.

16:48 ibdknox: technomancy: yeah, I'm not sure what else I could do

16:48 one line isn't so bad

16:49 given what it does

16:49 technomancy: sometimes I wonder what life would be like if ns were extensible

16:50 ibdknox: lol

16:50 if it had wildcards everything would be fine ;0

16:50 ;)

16:50 (:require [my-views.*])

16:50 technomancy: (ns my.noir.app (:require [noir.server]) (:noir-views [my.noir.app]))

16:50 ibdknox: ooo

16:50 that would be neat

16:50 didn't think about that

16:50 technomancy: but there's no way to namespace them

16:51 so you'd run into nasty collisions

16:51 ibdknox: yeah

16:51 technomancy: ns+ is pretty sweet; I would love to see something like :like in core

16:51 doesn't help here though

16:53 ibdknox: technomancy: what does :like do?

16:53 technomancy: it defines a template ns form

16:53 http://code.google.com/p/clj-nstools/

16:53 ibdknox: have you considered using bultitude to load views?

16:54 ibdknox: I don't know what that is :)

16:54 Raynes: He does something similar and probably terribly.

16:54 ibdknox: https://github.com/Raynes/bultitude

16:54 technomancy: ~bultitude is for finding namespaces on the classpath https://github.com/Raynes/bultitude

16:54 clojurebot: Ik begrijp

16:55 ibdknox: ooo

16:55 do you know if that works in a war?

16:55 technomancy: anything on the classpath

16:55 should be fair game

16:55 autodidakto: ibdknox: I was looking at noir from a sinatra/padrino perspective, hence both familiarity and confusion. But I read the link and I like what you have to say. I'll give it a try (side note: i might be helpful to lots of people to have this rational on the website)

16:56 ibdknox: autodidakto: yeah, I need to update the noir site sometime soon.

16:57 technomancy: I use clojure.tools.namespace right now

16:57 unfortunately it doesn't work in wars which has been the source of a fair amount of confusion

16:57 technomancy: ditch it!

17:02 sritchie: ibdknox: it fails w/ clojure 1.2 if you have any lein-newnew templates on the classpath

17:03 ibdknox: say what?

17:04 technomancy: ibdknox: bug in clojure.tools.namespace

17:04 ibdknox: wow

17:04 weird

17:04 ok

17:04 I'll switch it over

17:04 Raynes: ibdknox: A bug that stuartsierra says he wont fix.

17:04 ibdknox: unless Raynes gets to it before I do

17:04 Raynes: Just FYI.

17:05 Is that a hint?

17:05 :p

17:05 ibdknox: fixing wars will eliminate what I think has been the largest source of questions on Noir lol

17:05 scriptor: also world peace

17:05 ibdknox: I looked into it at one point but didn't understand how classloaders worked in that context well enough to know how to fix it

17:06 I'm woefully uninformed on the ridiculousness of loading things into the JVM :)

17:06 technomancy: well double-check for yourself; I have never used a war file before and could be gravely mistaken

17:06 Bronsa: what's the bug?

17:07 benDos: dnolen, sorry had to run earlier i'll bbiab

17:08 ibdknox: Raynes: no I don't mind either way

17:08 Raynes: ibdknox: But yeah, it might actually not work in wars, but I don't really see why it wouldn't. It's pretty thorough.

17:08 hiredman: the thing is, all these "load namespaces" things are based on the classpath, when really the way you find resources and load code is via classloaders, there is really only one classloader that uses the classpath

17:09 Raynes: bultitude iterates through every classloader.

17:09 ibdknox: ah

17:09 TimMc: crazy talk

17:09 ibdknox: that should fix it then

17:09 technomancy: hiredman: isn't it more like there's one classpath per classloader?

17:10 and thus there's only one classloader with the classpath provided at boot?

17:10 cemerick: ibdknox: fixing wars?

17:10 hiredman: technomancy: but other classloaders don't have a classpath

17:10 technomancy: they can have an internal path by which they load classes though

17:11 hiredman: they can, but is not required at all

17:11 and in most cases they don't

17:11 technomancy: right; ok, that's a bit different I guess

17:11 Raynes: Java is a giant horror show.

17:11 technomancy: still, only one classpath seems like an oversimplification given clojure.lang.DynamicClassLoader

17:11 hiredman: and classloaders don't give you a way to list the resources available

17:12 technomancy: clojure.lang.DynamicClassLoader is an example of a classloader with no classpath

17:12 it loads classes right from memory

17:13 the classpath is just a bootstrapping mechanism used by the system classloader

17:13 technomancy: http://docs.oracle.com/javase/1.5.0/docs/api/java/net/URLClassLoader.html#getURLs() <- what does this return then?

17:14 hiredman: technomancy: that is only for a particular subclass of classloader

17:14 technomancy: sure

17:14 hiredman: http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/ClassLoader.html

17:15 what you really want is, given a classloader, find on the namespaces available through it, which is hard

17:16 of course that also precludes dynamicly created namespaces

17:17 technomancy: it's not terribly difficult given an URLClassLoader, but it can be slow

17:17 ibdknox: cemerick: dynamically loading view ns's doesn't work in wars

17:18 cemerick: ibdknox: unless they're exploded, I wouldn't expect so, no

17:18 or, do you mean via the REPL?

17:25 aperiodic: how do folks usually use swank when working with multiple projects in parallel?

17:26 i'm starting a standalone swank server with lein-swank and connecting to it from multiple editor instances, but only one of my projects is on its classpath

17:26 i suppose i could just make a fake project that has all of the projects i want to use as dependencies, and start the server there

17:28 cemerick: aperiodic: lein checkout deps + clojure-jack-in should handle that, I think

17:29 lynaghk: Is there a way to get clojure-jack-in working with Lein2 projects? My src-paths [... ...] doesn't get picked up when I try it.

17:34 aperiodic: cemerick: putting all the checkout deps into a catch-all project, then? the projects themselves actually don't have much to do with eachother, i'm just a bit ADD.

17:34 cemerick: Yeah, that world work, though it seems like an odd thing to do if they're unrelated.

17:35 aperiodic: yeah, i felt that way, too. but it seems like the alternative is killing and starting swank servers whenever i switched between the two

17:35 scriptor: ooh, non-copy-on-write persistent vectors

17:35 lynaghk: aperiodic: can't you just start swank servers on different ports?

17:37 aperiodic: lynaghk: as far is a can tell, the swank server port for slimv is configured globally, so that would mean juggling a few different vimrcs

17:37 lynaghk: aperiodic: sounds like you're using an inferior editor.

17:37 aperiodic: :P

17:37 lynaghk: =P

17:38 pandeiro: ibdknox: iyo is there any advantage to using fetch if i'm just serving predefined clojure maps, not running remote functions?

17:39 ibdknox: what's the disadvantage?

17:39 pandeiro: dep i guess?

17:39 ibdknox: the lazy-store stuff would cache the result locally

17:39 but that's about it

17:40 aperiodic: ooh, there's a "localvimrc" plugin for project-specific vimrcs. sweet.

17:47 amalloy: seancorfield: is there an easy way to get c.j.jdbc to show the query it's running? i'm trying to switch from clojureql, and it had this handy feature where you could ask for any query's sql (with ? replaced with actual values)

17:48 we were only using it for logging, of course

17:49 ibdknox: I couldn't find a way

17:49 cemerick: Perhaps of interest to some here: Drawbridge, an HTTP nREPL transport, implemented as a Ring handler. http://groups.google.com/group/clojure/browse_frm/thread/2c78990f8a49188c

17:49 * arohner would really love if clojurescript implemented (delay)

17:50 weavejester: cemerick: I noticed you working on that. I've been meaning on writing something similar, but I'm glad you beat me to it!

17:50 amalloy: arohner: it should be pretty simple to implement yourself, right?

17:50 arohner: amalloy: how?

17:51 dnolen: arohner: huh, I'm not sure why CLJS doesn't have delay - would take a patch for that. That's an easy one.

17:51 arohner: I must be missing something simple. Why is that easy to implement?

17:51 dnolen: arohner: delay is just thunking

17:51 amalloy: arohner: it's just a macro wrapped around an "is it done yet" atom

17:52 ibdknox: cemerick_away: are you storing serializable things in the session?

17:52 arohner: dnolen: oh right. I was thinking of promise

17:52 ibdknox: cemerick_away: er, *only* printable things I guess

17:52 arohner: I want promise as well :-)

17:52 amalloy: promise is just about as easy

17:53 arohner: but if you block waiting for a result, when does the other 'thread' run?

17:53 dnolen: amalloy: not really

17:53 amalloy: oh right, threading

17:53 ibdknox: yeah, that one is hard

17:53 dnolen: arohner: promise is hard, and I'm personally not convinced it makes much sense, tho others might disagree

17:53 arohner: I'm seeing a race in knockout.js that would be trivially solved w/ promise

17:54 pandeiro: arohner: are you doing interop with knockout.js?

17:54 ibdknox: dnolen: why doesn't it make sense?

17:54 arohner: pandeiro: I'm using knockout, but not interop yet

17:55 dnolen: ibdknox: promise, at least in my mind, thread semantics - blocking on read

17:55 pandeiro: just curious because i know knockout uses custom attributes, and it's a little bit painful manipulating them from cljs imo

17:55 amalloy: (defmacro delay* [& body] `(let [value# (atom nil)] (reify clojure.lang.IDeref (deref [this#] (:value (swap! value# (fn [{done# :done :as curr#}] (if done# curr#, {:done true, :value (do ~@body)}))))))))

17:56 ibdknox: dnolen: I guess the real solution is async from F#/C#

17:56 amalloy: except you'd want delay instead of delay*, and whatever cljs's protocol is called

17:56 ibdknox: where while that is blocking the thread yields

17:56 amalloy: dnolen: i can send that as a patch if you want?

17:57 dnolen: ibdknox: yes inside an async construct it could make sense - and that could be done via a lib

17:57 amalloy: sure! but it should just be delay, not delay* right?

17:58 amalloy: yes, i mentioned that. i copy/pasted my clj-jvm version, where i was avoiding overwriting

17:58 arohner: btw, knockout seems like a great lib for clojurescript. it's essentially clojure cells for web UI

17:59 dnolen: amalloy: actually there's a broken looking implementation of delay in core.cljs now

17:59 amalloy: for some reason delay is a fn instead of a macro.

17:59 amalloy: haha weird

17:59 i do prefer their approach though, of deftyping for it, rather than my atom/reify

18:00 so i'll just patch the existing impl

18:00 dnolen: amalloy: cool, thx

18:01 amalloy: dnolen: how do i make a macro in cljs?

18:02 dnolen: amalloy: inside of core.clj, the same folder as complier.clj

18:02 in the same folder as compiler.clj I mean

18:02 amalloy: yeah, just found that

18:02 dnolen: amalloy: I'm assuming you're going to remove broken fn too :)

18:02 amalloy: yeah

18:03 it's a bit weird, because i want the macro in clj to depend on the deftype in cljs. is that not a problem?

18:03 i guess it's not; lazy-seq does the same thing

18:04 Raynes: amalloy: What are you using cljs for?

18:05 amalloy: Raynes: i'm not

18:14 dnolen: how do the macros in core.clj get "imported" into core.cljs? i don't see any require-macros calls for me to add delay to

18:15 dnolen: amalloy: core.clj is required in compiler.clj

18:21 cemerick: weavejester: :-) hopefully it stands up to scrutiny

18:22 ibdknox: yeah, the session holds the nREPL transport (in this case, just a pair of queues) that the backend drops response messages into

18:22 nothing says the responses must be printable though; I've yet to address nontextual REPL interactions in drawbridge

18:23 ibdknox: cemerick: I'm thinking about times when you can use the memory session store

18:23 can't*

18:23 cemerick: ah

18:24 that would get very dicey very fast

18:24 ibdknox: the backend is necessarily single-host; when would memory sessions not work?

18:25 ibdknox: basically anytime you have more than one box and can't do sticky sessions :(

18:25 i.e. heroku

18:26 cemerick: technomancy may have a more useful response to that

18:26 anyway, for textual REPL interactions, using a persistent session store would work fine

18:27 ibdknox: cool

18:27 hiredman: why use in memory queues? why not rabbit or similar?

18:27 ibdknox: I just know a fair amount of people are using alternate session stores and that might cause some very weird errors if what's being added to the session can't be printed

18:28 cemerick: that was my only concern ^

18:28 Raynes: ibdknox: refheap uses a mongodb session store.

18:28 hiredman: if you use a message bus, do you need sessions at all?

18:28 cemerick: hiredman: a rabbitmq transport would be quite trivial.

18:29 hiredman: I am aware

18:29 cemerick: Well, I don't use it, and the extra dep would be a PITA for most people, so…

18:29 hiredman: infact, just hooking clojure.main/repl up to queues instead of io streams is trivial

18:30 cemerick: I just mean it could actually make drawbridge work on heroku (if the session thing is a problem)

18:31 https://github.com/hiredman/vespa-crabro/blob/master/test/vespa_crabro/test/core.clj#L57

18:31 cemerick: ibdknox: Sure; I don't think there'll be any problem given the publicly-available nREPL middlewares that are around so far.

18:32 hrm, actually, it's more complicated than that. The REPL session's dynamic scope would need to be persisted as well.

18:32 hiredman: :|

18:33 arohner: I'm starting to think everything should be serializable. Even fns and infinite seqs

18:33 maybe *especially* fns

18:34 TimMc: $google serializable fn

18:34 lazybot: [technomancy/serializable-fn · GitHub] https://github.com/technomancy/serializable-fn

18:34 arohner: TimMc: yes, I'm aware. I mean production-ready serializable

18:34 TimMc: :-P

18:34 aperiodic: how do you serialize the lexical scope?

18:35 arohner: aperiodic: the same way it's in the compiler, as a stack of maps of immutable values

18:35 * TimMc writes a serializeable-pointer library

18:35 cemerick: ibdknox: I'll lay in wait for problem reports and science done by technomancy et al. before thinking too hard about it.

18:35 hiredman: lexical scope is just fields in a class

18:35 aperiodic: ah right, immutability rocks

18:35 hiredman: TimMc: you mean vars?

18:36 arohner: TimMc: obviously many Java things won't be serializable, but I'd be happy with a solution that worked on pure clojure

18:36 ibdknox: cemerick: oh, I wasn't interested in a solution so much as a warning :)

18:36 cemerick: ibdknox: Good thing! ;-)

18:36 hiredman: to make fns serializable you would have to ship the fn's class around too

18:37 cemerick: I'm a Heroku noob myself, so I'm far from knowing where all the bodies are buried.

18:37 ibdknox: also no free variables

18:37 hiredman: and clojure's gensym (used a lot for naming classes) isn't safe between vms

18:37 ibdknox: in these functions to be serialized

18:38 arohner: ibdknox: free variables?

18:38 hiredman: ibdknox: not a problem

18:38 ibdknox: hiredman: hm, resolve them before?

18:38 hiredman: when a fn object is created, the values it closes over are passed to the constructr and stored as fields

18:38 ibdknox: ah

18:39 hiredman: top level values are resolved to vars at compile time

18:39 (before the class is generated)

18:40 arohner: hiredman: do you need the classname to be unique? why not just hash the input clojure source of the fn?

18:40 i.e. rather than (gensym foo), store (sha1 (str (quote (fn foo [x] (inc (bar x)))

18:41 hiredman: arohner: it doesn't actually have to be uniqueue, but your stack traces become much harder to read

18:41 amalloy: dnolen: http://dev.clojure.org/jira/browse/CLJS-173 opened, patch and test attached, marked as waiting on you

18:42 arohner: hiredman: that seems like a minor problem compared to getting this to work at all :-)

18:43 sritchie: technomancy, have you seen "error in opening zip file" at all?

18:43 w/ leiningen 2

18:43 or any idea how to debug it?

18:43 error's at at leiningen.core.classpath$extract_native_deps$fn__255.invoke(classpath.clj:42)

18:45 amalloy: sritchie: probably a corrupt jar file on your classpath somewhere

18:45 sritchie: amalloy: this is that same issue as before, I think, where someone references a dependency that's just a pom, but doesn't mark it as such

18:45 maven doesn't choke on those, but leiningen does

18:45 I'll see if I can track it down

18:47 amalloy: lein 1 is fine

18:47 lein 2 chokes on this particular dep

18:55 technomancy: sritchie: oh yeah, I think there was a bug reported with pom dependencies

18:55 are you on master or preview2

18:55 ?

18:55 sritchie: preview2

18:58 technomancy: do you have a :type :pom that I could test on?

18:58 oh, and is your stack trace the same as https://github.com/technomancy/leiningen/issues/481 ?

19:02 kurtharriger: Is it possible to turn this into a leiningen plugin https://gist.github.com/2244645, what step would I need to hook to get it to run for any command?

19:35 TimMc: hiredman: No, it was a joke about serializing C-style pointers

19:47 sritchie: technomancy: sorry, I need to turn my alerts back on

19:47 this one's private, but yeah, that's the exception

19:47 funny, that's the exact jar I was using

19:47 perfect

19:47 gotta start reading issues :)

19:49 technomancy: so ... with dependencies that aren't jars, does it make more sense to keep them off the classpath via a blacklist or a whitelist?

19:49 thinking maybe only allowing dependency jars/zips to be on the classpath would make sense, but I've never worked with non-jar dependencies

19:51 if only cemerick were here

19:53 aperiodic: is it just jaring that chokes on non-jar deps?

19:54 technomancy: it's the search for native deps

19:54 also screws up eclipse though https://github.com/technomancy/leiningen/issues/330

19:55 mebaran151: I'm trying to play with Apache Pivot, but I'm having a tiny bit of a hard time getting it to see clojure's classes. It is using the wrong classloader

19:55 how can I get the awt thread (threads?) to reference the clojure classloader?

19:55 kurtharriger: technomancy: hadoop usually adds the configuration directory is added to the classpath so that configuration files can be accessed as resources

19:56 I currently do this with extra-classpath-dirs

19:56 technomancy: kurtharriger: oh sure; I mean classpath entries that come in via dependencies

19:56 gotta have directories on the classpath

19:57 kurtharriger: I guess I wasn't following the question well enough, getting dependencies that aren't jars or folders?

20:00 mebaran151: or change the classloader to default to clojure (right now Class/forName is failing to find classes created with defrecord / deftype)

20:00 technomancy: kurtharriger: yeah, you can have dependencies that are just bare pom files

20:01 sander: I think I have a (non-empty) solution to the 4clojure quine problem, but it says "Empty input is not allowed"

20:01 xeqi: technomancy: I ran into this with 457 as well, and decided a .pom in the classpath didn't make sense

20:01 amalloy: sander: care to share?

20:01 xeqi: I thought a whitelist to just zip/jar would work

20:01 sander: if i am not ruining it for anyone here, sure

20:01 its probably not a very elegant one..

20:02 amalloy: *shrug* gist it then, and if someone doesn't want spoilers they won't click

20:02 sander: right. didn't think about that one

20:02 technomancy: xeqi: yeah, I think I'll go with that

20:04 amalloy: oh whoa. something is wrong with 4clojure now, apparently, sander. it thinks every input is empty

20:04 aperiodic: mebaran151: i've never had to screw around with classloaders to get hadoop to find my classes, but they're all AOT'd so that might not be relevant

20:04 amalloy: it was working fine this morning, and i haven't touched anything since then

20:05 sander: amalloy: uups

20:05 aperiodic: mebaran151: as long as .class files are being generated and placed on the classpath, i don't think you should have to resort to using the clojure classloader

20:06 sander: amalloy: here it goes anyway: https://gist.github.com/2245072

20:07 amalloy: good luck for finding the problem, I'll go to sleep now

20:08 amalloy: sander: fixed it

20:08 if you want to submit your thing

20:08 i didn't find the problem, but a restart fixed it :P

20:08 sander: ammalloy: thanks

20:08 amalloy: what was the problem?

20:08 amalloy: dunno. didn't find it

20:09 mebaran151: aperiodic: not running havoc: trying to play with Apache Pivot (neat looking gui toolkit)

20:09 stepping through the source it's failing with a Class not found exception at Class/forName

20:09 sander: amalloy: restart?

20:09 :-)

20:09 amalloy: yep

20:09 mebaran151: I'm pretty sure aot would solve a lot of my problems, to be sure

20:10 but I'd like to play dynamically at the repl :)

20:10 aperiodic: that shouldn't be an issue, as long as you're not changing the class interfaces

20:11 mebaran151: so I'd have to restart my repl first right?

20:13 aperiodic: yeah, but i think you'll be able to play around in the repl as long as the interfaces don't change

20:13 mebaran151: how do I AOT?

20:13 aperiodic: lein compile

20:13 mebaran151: cool I'll try that next

20:13 thanks

20:14 (I'm willing to bet I'm going to run into resource problems next actually

20:14 aperiodic: heh, don't thank me until it actually works ;)

20:17 mebaran151: oh, firstt you'll need to set the :aot key in your project.clj to a list of namespaces (or a regex) that you want to be AOT'd

20:32 mebaran151: aperiodic: that mostly worked!

20:33 now I just have to figure out a way to get it to find my resources

20:38 aperiodic: mebaran151: cool! for the resources, try the :extra-classpath-dirs key in project.clj (see https://github.com/technomancy/leiningen/blob/master/sample.project.clj)

20:38 mebaran151: I was just dropping it resources

20:42 actually it isn't lying to me, getResource is returning nil

20:42 where am I supposed to put things like xml gui descriptions, etc

20:42 (i.e. what do the best practices say; resources seems like a slightly poor fit)

20:44 aperiodic: why is resources a poor fit? they sound like resources to me.

20:45 mebaran151: maybe, they seem to have a code fit too. I put them in resources at first just because I didn't know if there was a better place

20:49 hey it's working now! Though I have to recompile my app every time I make a change

20:53 aperiodic: what happens if you remove all the .clj files from the classes directory?

20:53 mebaran151: there are none there

20:53 I think the main thing is that Pivot is looking to load a class file (and now it can find my ApplicationRecord)

20:59 aperiodic: oh, the application record is coming out of defrecord?

21:01 that might have a different behavior than classes created using gen-class. such classes dynamically seek the implementation in .clj files, which is why you only need to AOT them when you add/remove functions, or change their signatures

21:01 mebaran151: ah yeah

21:01 I was using defrecord

21:02 seems like in this case gen-class might be a stronger fit

21:02 aperiodic: i'd agree

21:08 mebaran151: I also have a minor quibble: when I ctrl-c lein on windows, it doesn't close and I have to use taskmgr to reset it

21:10 ihodes: so, i want to finally give clojurescript a try. i'm wondering what the best workflow/environment is? i'm using ring/moustache for my backend stuff, but i'm wondering what's the best way to update the javascript in the browser from my cljs repl and not refresh?

21:13 aperiodic: mebaran151: seems to be a known issue https://github.com/technomancy/leiningen/issues/319

21:36 technomancy: mebaran151: according to someone on the mailing list it's an intrinsic problem with cygwin

21:53 matt444: Wow, Himera is a game-changer

21:53 ihodes: hmmm, anyone? (previous question asking about a setting up a good workflow for developing in clojurescript; i'm going to be doing graphics programming, so i don't want to be refreshing the page each time)

21:56 mebaran151: technomancy: I'm not running lein in cygwin: I'm running lein in Powershell

21:57 technomancy: hm; I don't know then.

21:58 mebaran151: I see the lein process die, but not its child swank

21:58 technomancy: matt444: still trying to figure out what game exactly it is that's been changed

21:58 mebaran151: btw, has there been a lein release that fixed clojure-jack-in for windows?

21:59 technomancy: mebaran151: 1.7.1 is the latest release; I don't know if jack-in works on it

21:59 mebaran151: ah I'm there

22:00 technomancy: it's unlikely to get fixed unless some enterprising windows user dives in and tries to fix it

22:00 * technomancy heads to seajure

22:02 oakwise: ihodes: run a browser connected repl and have your editor send code to it

22:03 are you using emacs?

22:04 ihodes: oakwise: i am

22:05 oakwise: ihodes: great. I just M-x shell and start a repl with `lein trampoline cljsbuild repl-listen` and then do something like this to send forms to that repl: https://github.com/brentonashworth/one/wiki/Emacs

22:06 ihodes: oakwise: oh nice--thanks!

22:07 oakwise: np

22:07 Zoka: technomancy: This is far fetched, but are you by any chance running some incarnation

22:07 of webrepl-client against ringMon demo site at http://noirmon.herokuapp.com/ringmon/monview.html ?

Logging service provided by n01se.net