#clojure log - Dec 10 2012

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

0:03 tomoj: is one called "one" to taunt people who only want _one_ piece of it?

0:11 I guess the plan is for those pieces to graduate to libraries eventually

0:14 seangrove: I thought of it as a PoC right now

0:14 It's a bit large, was definitely difficult for me to wrap my head around when I was getting started with cljs

0:15 But maybe that's my fault for thinking it'd be a good way of starting

0:15 tomoj: isn't that exactly what it's supposed to be?

0:16 I wonder why one.test hasn't been broken out

0:16 would feel weird copying it and releasing it, but neither do I really want to copy it into every one of my projects

0:19 muhoo: private repo then?

0:20 tomoj: good idea for now, but I want to release my library too :)

0:21 muhoo: oh, well, hmm. there's nothing wrong with ripping guts out of an open source project and forking it as a separate thing, it is open source. maybe ask the one people if they'd accept a patch to split it up tho?

0:21 who knows, they may have been waiting for someone to volunteer to do it.

0:35 michaelr`: good morning

1:48 tomoj: wonder how the ring spec would look for ajax

1:49 seems to make sense for :server-port, :server-name, and :scheme to be optional

1:49 and maybe for :uri to be possibly relative?

1:53 but if you supply :server-name and a relative :uri..

1:54 on the other hand, if you require :uri to be absolute, and, like clj-http, have a middleware that accepts a :url, it would be rather odd for :url to be a uri

1:59 nightfly_: Are the protected/private java access modifiers respected while doing Java interop?

1:59 tomoj: yes

2:05 Lajjla: THEY'RE MAD


2:05 I was at #wordpress-dev


2:06 They consider echo '<h3>' . $title . '</h3>'; good coding practce


2:06 They thought the established way of something like $page->addElement('h' . $page->currentLevel, $page->title); was bad


2:21 p_l: Lajjla: welcome to PHP world

2:22 though your established practice looks bad as well. Again, welcome to PHP :P

2:26 bbloom: https://github.com/brandonbloom/dispatch-map :-)

2:38 seangrove: Well, hard to argue with their success

2:39 nightfly_: tomoj: Thanks. Of course I was hoping they wouldn't be in this instance, but for the greater good...

2:39 seangrove: bbloom: No idea what this is for, but curious

2:39 bbloom: seangrove: i'll probably write a blog post to motivate it

2:40 so basically, i'm working on some GUI experiments and i have a scene graph -like tree structure

2:41 Lajjla: p_l, they were like



2:41 bbloom: and i wanted to be able to have a sort of list-view thing that renders a template for each element in the list, but the template dispatch was a simple map of class -> template


2:41 bbloom: templates aren't functions, they are data structures

2:41 Lajjla: And that it's known to be very bad at identifying bugs for you.


2:42 I must go to the source and inspect

2:42 seangrove: Ah, I see

2:42 bbloom: seangrove: i wanted a map that would let me render the "best" template for a datatype

2:42 Lajjla: I raised the issue that if you mistyped a variabvle name in PHP, it didn't bleep and said the variable was not in scope but it created a new one for you with the value set to null.

2:42 They never even considered the fact that it would be better to catch bugs if you made a type error that it then bleeped.

2:42 bbloom: seangrove: it also means you could redefine multi methods in terms of a dispatch-map and an atom

2:43 seangrove: Yeah, that's the inverse of what I was thinking

2:43 Where you would dispatch based off of deep keys in a map

2:44 Very cool stuff

2:44 bbloom: seangrove: what would that be for?

2:44 seangrove: I also wasn't sure of that, but was just curious ;)

2:45 bbloom: well that's the short version: i wanted to treat a multimethod like data

2:45 er, i mean, like a "value"

2:55 SegFaultAX: Man, datomic is pretty pricey for a virtually unproven database.

2:56 bbloom: SegFaultAX: it's pretty cheap (and simple) when compared to a virtually DISproven database: http://www.oracle.com/us/corporate/pricing/price-lists/index.html :-P

2:56 i kid, i kid

3:08 michaelr`: i wonder how excel's grid is stored in memory

3:08 tomoj: SegFaultAX: free to try at least :/

3:09 nightfly_: Slightly related, how useful is datomic's free version in a "production" environment?

3:10 typeclassy: is cljs.core.IFn a protocol in clojurescript? the compiler claims it isn't, but google is only showing me https://gist.github.com/2346866

3:12 plain "IFn" gives a massive gibberish java stack trace

3:16 seangrove: nightfly_: Been using datomic free along with wei_ for Jida (a dideproject), seems reasonably good, haven't run too many problems yet so far

3:16 Main problem is that we don't have enough money for a vps to run a transactor

3:17 typeclassy: does datomic free store all of its data on the filesystem?

3:19 wei_: typeclassy: I believe so, yes

3:20 typeclassy: i suppose it doesn't really matter if you're not a gigantic app. hacker news runs off the filesystem as well iirc

3:20 wei_: another problem was that we ran into the max peer limit pretty quickly with one worker and one web server

3:31 bbloom: seangrove: i packed up my motivation in a blog post http://blog.brandonbloom.name/2012/12/clojures-multimethod-dispatch-as-library.html

3:31 seangrove: let me know if that makes sense :-)

3:50 andrewmcveigh|wo: bbloom: I was thinking about something somewhat related to that the other day. I wanted a multimethod where the dispatch value could be a core.match pattern. Didn't have time to try it though.

4:01 tomoj: seangrove: hmm, for what?

4:02 oh, I see someone else already asked

4:05 I've considered writing multimethods for deep keys for dealing with document-ish maps

4:06 Lajjla: p_l, MADNESS


4:42 no7hing: good morning everybody

4:43 seems like i have some problems wrapping my head around protocols

4:44 ucb: no7hing: morning! what's up?

4:44 no7hing: i thought i had a nice case for using protocols to abstract the used datastore behind a registry

4:44 https://gist.github.com/4249604

4:45 ucb: no7hing: what's wrong with that?

4:45 no7hing: but what was a self-contained service before that could be called like (registry/register 123) now needs the actual instance passed in too

4:46 my problem is that i don't know where to put my actual instance

4:46 ucb: how was registry/register defined before?

4:46 no7hing: and if it's really true that i have to implement another layer in front of it to store the actual instance in

4:47 just a function in the namespace and f.e. the zookeeper connection as a ref

4:47 ucb: a global ref then?

4:47 no7hing: yes

4:47 global in the ns

4:49 ucb: right, so that's where protocols might be an interesting alternative

4:49 you'd have no global shared anything

4:49 amalloy: no7hing: how could ZKR work without an instance, though? you need to store a connection *somewhere*, and making it global to your namespace is really unpleasant

4:49 ucb: thanks for putting it succinctly amalloy

4:51 no7hing: then i'am actually not getting a vital part of idiomatic clojure

4:52 because i have no idea where i should put my connection other than the namespace that serves as my zookeeper facade

4:53 amalloy: no7hing: if you did that, one of the problems you'd have is that you could never have two different registries in the same program

4:53 no7hing: that's what i actually want

4:54 amalloy: make the person who's calling register and deregister responsible for tracking their registry. they probably have some other larger object that it's convenient to put it into

4:54 no7hing: but isn't that a global var again?

4:54 amalloy: only if you imagine, for whatever reason, that their larger object is global

4:55 no7hing: as this is in the context of a stateful server i need to store state *somewhere*

4:55 amalloy: (there's nothing disastrously bad about having a global var for this sort of thing, for convenience, but definitely don't tie it in at the lowest level, which would force everyone to use the same model)

4:56 no7hing: the way i built it so far is that the ns store the state they're responsible for

4:57 amalloy: then your whole app is just singletons. you can't ever use a namespace twice

4:58 no7hing: a registry holds a map of registered (=currently online) users either in memory or in ZK, the session store holds the actual user sessions, etc

4:58 i think there's a lot of erlang thinking in the way i built my app

4:58 my clojure exercise: https://github.com/mhaemmerle/grimoire

4:59 Sgeo|web_: I need to learn how to stop using global variables

4:59 Ironic, since I love Haskell and it practically prevents usage of global variables

4:59 amalloy: no7hing: all of that is fine, but the example.registry namespace isn't a registry: it is code for building and using a registry. it shouldn't also be responsible for maintaining a reference to one particular "blessed" instance of a registry

4:59 Sgeo|web_: (There are tricks around it, but they're noticable and annoying)

5:00 no7hing: ok, so i need another ns to actually implement it - even if it's more or less just doubling the protocol and passing the actual registry instance in

5:00 back to the drawing board :)

5:01 and thanks a lot for the help!

5:02 amalloy: you're welcome! apologies if i'm overly zealous this late at night: it's bedtime

5:02 no7hing: no apologies needed!

5:02 clojurebot: Gabh mo leithscéal?

5:03 no7hing: i want to learn it the proper way

6:23 AWizzArd: Is there a list that tells me what Interfaces/Protocols I have to add to my defrecord/deftype, when I want it to do X. For example, I want to be able to deref instances ==> this list would point me to clojure.lang.IDeref. I want to (count it) ==> list would point me to?

6:24 Sgeo|web_: Reading the source?

6:24 (source count)

6:24 ,(source count)

6:24 clojurebot: Source not found

6:24 Sgeo|web_: Although actually, actual documentation would be better

6:24 AWizzArd: Currently I read the sources at https://github.com/clojure/clojure/tree/master/src/jvm/clojure/lang

6:25 I just thought having such a list might save some time.

6:25 Sgeo|web_: Would also make it less implementation-detail-y

6:26 AWizzArd: Now I really would like to know: what does my deftype have to implement/extend when I want to use count?

6:27 Sgeo|web_: What time complexity is your count?

6:27 AWizzArd: ISeq?

6:27 linear

6:27 Sgeo|web_: Looking at the source, it looks like Counted would work for ... oh, Counted implies O(1) I think

6:27 Um, I think ISeq would work, but not sure

6:28 countFrom mentions Collection and IPersistentCollection

6:29 AWizzArd: Sgeo|web_: thanks, Counted is fine.

6:29 Works.

6:29 Sgeo|web_: :/ pretty sure Counted is intended to imply O(1) time complexity

6:29 bbloom: AWizzArd: you shouldn't implement Counted unless you have O(1) counts

6:29 AWizzArd: Yes, I now have o1

6:30 bbloom: ,(source counted?)

6:30 clojurebot: Source not found

6:30 bbloom: blah.

6:30 (doc counted?)

6:30 clojurebot: "([coll]); Returns true if coll implements count in constant time"

6:30 bbloom: the source is: [coll] (instance? clojure.lang.Counted coll)

6:30 anyway, bed time

6:32 AWizzArd: That other bot maybe supports “source”?

6:33 Sgeo|web_: &(source counted?)

6:33 lazybot: java.lang.RuntimeException: Unable to resolve symbol: source in this context

6:33 Sgeo|web_: lazybot is Clojailed :( (not relevent, but it's a source of a flaw)

6:34 ,(let [-> inc] (-> 5)) ; ##(let [-> inc] (-> 5)

6:34 clojurebot: 6

6:34 Sgeo|web_: ,(let [-> inc] (-> 5)) ; ##(let [-> inc] (-> 5))

6:34 lazybot: ⇒ 5

6:34 clojurebot: 6

7:23 hcumberdale: Hi ;)

7:24 ucb: hello hubert :)

7:27 ivaraasen: considering buying a ThinkPad T430. does anyone here own one?

7:32 hcumberdale: ivaraasen: Thought about it. But at the moment I consider the Samsung S9 and Apple Mac Book.

7:34 ivaraasen: hcumberdale: definitely considering the S9.

7:35 hcumberdale: It's only 4GB ram on board. FEB 2013 are the new release dates.

7:35 So I think there will be 8GB+ and the new WQHD display.

7:36 ivaraasen: thing is, a T430 over here (with IPS and a 180 GB SSD) is the same price as a low-end MacBook Air, given that I buy an extra two years of guarantee for the latter. (the T430 comes with a three year guarantee)

7:37 hcumberdale: ivaraasen: yes. Gurantee @Apple is bad

7:37 remebering the defect displays...

7:37 ivaraasen: and defective logic boards in my case

7:37 like, three times

7:37 hcumberdale: Nealy everyone was affected. Display inverter must be replaced in all old mac books

7:37 ivaraasen: and two dead power supplies, because they break so easily

7:37 hcumberdale: here too ;)

7:38 ivaraasen: almost blew my speakers due to the logic board problems

7:38 hcumberdale: Have a TP X300

7:38 That notebook is years old but super awesome.

7:38 ivaraasen: how are ThinkPad power supplies? way sturdier?

7:38 hcumberdale: nearly indistructible

7:39 But,... the real "ThinkPad" is gone ;(

7:39 ivaraasen: nice. small detail, but it's really important for me as a journalist.

7:39 hcumberdale: The new keyboards are horrible, thx to background leds

7:39 ivaraasen: which is why I'm going with a matt screen as well

7:40 hcumberdale: me2 I really dislike the "mirrored" screens ;)

7:40 My experience: The X series are robust and good

7:41 A lot T series (@ my company) broke after ~2 years.

7:41 Defect screen, only power-on with power supply

7:41 They tried to fix it two times. Errors occured again

7:41 The new keyboards are horrible

7:42 The X1 has a different power adapter. I thought everybody is buying thinkpads because there is everywhere power for it ;)

7:42 ivaraasen: hcumberdale: regular or IPS screen?

7:43 hcumberdale: regardless of technology it should be non-reflecting and ~400nit

7:44 ivaraasen: I'm guess I'm not going to worry that much with a three year guarantee, at least.

7:44 hcumberdale: traveling with notebooks <350nit and reflecting screen is the worst ;(

7:44 Yes, one year is pretty bad @Apple

7:45 2 Years for the S9 is okay

7:45 The S9 power jack is really bad designed ;( And the 4GB ram... Will wait to FEB

7:45 until FEB 2013

7:46 mpenet: 2x8g ram = $80 for T4**

7:46 ivaraasen: I'm probably upgrading to 8 GB myself. I only have 2 GB on this poor old Unibody

7:46 mpenet: you can upgrade it yourself, something not possible with apple laptops I think

7:46 hcumberdale: ivaraasen: the S9 mem is onboard. If you are familiar with reflow soldering it's possible I think ;)

7:47 mpenet: not possible for apple & samsung

7:50 ivaraasen: hcumberdale: when I solder things myself, angels cry

7:54 hcumberdale: ivaraasen: the odds are 1:100 that it'll work

7:55 multilayer board

7:55 PGGB: anyone here using set with clojure?

7:56 *swt

7:56 mpenet: ~anyone

7:56 clojurebot: anyone is anybody

7:56 mpenet: :(

7:57 * hcumberdale does not work with swt

7:57 * hcumberdale thinks web technologies are "the future"

7:57 hcumberdale: better move over to javascript ;)

7:57 Sgeo|web: Why do I keep typing analyze as analyse

7:58 mpenet: I make that mistake very often

7:58 clgv: Sgeo: your british side fights your american side? :P

7:58 mpenet: that is how it's written in my first language tho

7:58 Bergle_1: you have been eposed to proper english.. it is 's'

7:59 PGGB: swt is actually quite nice

7:59 but it requires functions to run in the main thread

7:59 so I can't seem to call them from the repl

8:00 clgv: PGGB: there probably is some "invoke in main thread" function

8:00 * Bergle_1 finds it funny analyze is accepted, but analyzis isnt :P

8:00 Sgeo|web: I shouldn't have a British side. I have only left the US once in my life, when I was a little kid

8:01 But I'm in an IRC channel with a bunch of Brits, so maybe I should blame them

8:01 "Brits" isn't offensive, is it?

8:01 PGGB: clgv: yeah that'd be nice, haven't found anything thus far

8:01 clgv: Sgeo|web: seems your subconsciousness has a british side then... ;)

8:02 Sgeo|web: I do have an intense hatred for doing the American thing with quotes, the whole punctuation on the inside even if you're not quoting the punctuation thing

8:03 * Bergle_1 is from ozz ;)

8:03 * hcumberdale is from germany

8:04 clgv: hcumberdale: :O and you are not in #clojure.de ? tsktsktsk

8:04 Sgeo|web: Hmm

8:05 It doesn't look like it should be too difficult to write a correct macroexpander, if I just look for which part of each special form Compiler.java uses analyze on, and copy that

8:05 How often would that stuff change though

8:06 I'd need to change it with each version of Clojure, potentially, and also have a convenient way to write code that works in several versions

8:06 clgv: PGGB: display.syncExec(new Runnable() ... ); (http://www.eclipse.org/swt/faq.php#uithread)

8:06 Sgeo|web: Also, what if there's some complication that I'm overlooking?

8:07 hcumberdale: clgv: never heard from it

8:07 clgv: hcumberdale: now you have ;)

8:07 Sgeo|web: I know that I need to handle &env and special forms which don't macroexpand their arguments

8:07 But I might be forgetting stuff

8:08 hcumberdale: clgv from .de too ?!

8:08 clgv: hcumberdale: yes

8:10 PGGB: clgv: I need to create a display first though

8:11 and it still needs the main thread for that

8:11 clgv: PGGB: maybe there is something similar as static method... I have almost zero experience with SWT ;)

8:12 PGGB: hm

8:12 it'd be nice if you could lein run with a repl attached

8:12 clgv: PGGB: Display.getDefault().syncExec( ... )

8:13 Sgeo|web: Looking at the FnExpr parsing code, I don't see any calls to analyze

8:13 wtf

8:17 kmicu: ac 0 set status "Fajka, jajka i Jamajka!"

8:20 * kmicu hate buffor errors x]

8:21 kmicu: and muscle memory

9:04 fureddo: Anyone could explain why in case 1 (let [r (range 1e9)] [(first r) (last r)]), it runs ok but in case 2 (let [r (range 1e9)] [(last r) (first r)]), I got a OutOfMemoryException?

9:05 Chousuke: fureddo: in the latter case, the program can't free the elements in the sequence before you run (first r)

9:06 whereas in the first case it'll just throw out each element while realising (last r) since there's no longer anything that needs a reference to r.

9:09 fureddo: Chousuke, I don't get it. :-(

9:11 andrewmcveigh|wo: fureddo: http://stackoverflow.com/questions/5698122/explanation-of-lose-your-head-in-lazy-sequences

9:11 kmicu: fureddo: range is lazy

9:11 andrewmcveigh|wo: fureddo: Maybe that will help?

9:11 kmicu: , (class (range 1e9))

9:11 clojurebot: clojure.lang.LazySeq

9:12 kmicu: If you'll keep reference to first element, then whole seq must fit into memory.

9:12 @google clojure lazy seq

9:15 fureddo: andrewmcveigh|wo, Interesting link. Thanks.

9:25 cemerick: tpope: I'm around, if you want to nail down this :out and :err issue.

9:25 tpope: cemerick: I've got about 10 minutes, sure

9:26 cemerick: so, you've got a session id from clone, ands still no :out?

9:26 tpope: cemerick: correct

9:26 cemerick: can you replicate in Clojure, or is this solely in vimscript?

9:27 tpope: cemerick: I can replicate in clojure

9:27 cemerick: tpope: please, do paste somewhere

9:28 Sgeo|web: I seem to actually be singing "a special symbol at the head of a list always means a special form"

9:28 ...that's wrong, just realized

9:28 Only when that form is treated as code

9:28 tpope: cemerick: https://www.refheap.com/paste/7470

9:37 cemerick: tpope: OK; what are you seeing as the result of the (client ...) call?

9:39 tpope: cemerick: ({:ns "user", :session "20bd7b37-aa50-4c23-b61b-326976436fc8", :value "nil"} {:session "20bd7b37-aa50-4c23-b61b-326976436fc8", :status ["done"]})

9:40 so it gets the result but does not capture the output

9:46 cemerick: tpope: Yeah, something's screwy, despite a dozen-plus testcases verifying :err and :out. What if you send {"op" "eval" "code" "(println :foo)"}? (i.e. no sid)

9:46 tpope: cemerick: works fine

9:47 cemerick: yesh

9:47 yeah*

9:47 that's what I'm seeing too

9:47 tpope: on it :-P

10:11 tpope: OK, so: I can verify what you're seeing in a REPL, but not when running the same code as part of an automated test.

10:11 I need to take off for a while, but will return with a solution this afternoon. :-P

10:18 Sgeo|school: Should I keep my whining in the comments, or is whining ok in examples?

10:19 http://clojuredocs.org/clojure_core/clojure.walk/macroexpand-all#example_1001

10:21 clgv: Sgeo|school: write a better macroexpand-all ;) just kidding

10:21 Sgeo|school: I think frenchy64 is doing that

10:22 I should play with it

10:22 clgv: ambrosebs does?

10:23 Sgeo|school: The analyzer should be usable for that purpose, I think

10:23 clgv: ah ok

10:27 Sgeo|school: Hah!

10:28 https://www.refheap.com/paste/7471

10:28 I do object to ast being a macro though :(

10:29 Oh, it's just a wrapper around an analyze-form function

10:29 hrm, crud

10:34 Looks like it handles &env properly

10:34 Although I wish it could actually take an &env as input

10:34 ambrosebs thank you thank you!

10:35 @tell ambrosebs THANK YOU

10:35 @mail ambrosebs THANK YOU

10:35 ?

10:35 %mail ambrosebs THANK YOU

10:35 nDuff: Sgeo|school: /msg memoserv send ambrosebs THANK YOU

10:35 Sgeo|school: $mail ambrosebs THANK YOU

10:35 lazybot: Message saved.

10:35 nDuff: Sgeo|school: ...or that. :)

10:36 * nDuff is a little unclear on why one would bother with channel-local facilities that strictly duplicate network-wide ones, but... *shrug*.

10:37 Sgeo|school: Too lazy to sign in to Freenode, and recipient might not sign into freenode

10:37 scriptor: and $mail is much shorter to type, anyway

10:39 nDuff: Sgeo|school: I was too lazy to sign into freenode, and then someone stole my preferred nick

10:39 Sgeo|school: ...which is why I'm now nDuff, zDuff or znDuff as opposed to Duff.

10:39 ...anyhow -- lessons learned.

10:40 Sgeo|school: I'm registered on Freenode at least

10:40 * nDuff really ought to set up his work client to do automated signin via client certificate authentication, now that the network supports taht.

10:40 nDuff: ...err, that.

10:40 Sgeo|school: And usually have XChat sign me in automatically

10:40 But computer being weird

10:42 Does Clojail use a macroexpander?

10:43 AWizzArd: Is there a way how I can implement my own count on a defrecord? Currently when trying to do so I get a ClassFormatError: Duplicate method name&signature in class file

10:44 mdeboard: is there a recommended AWS S3 lib for Clojure? I'm looking at weavejester's repo but it doesn't appear to use connection pooling, so if I need to GET multiple objects, it's going to open a new connection for each (get-item) invocation.

10:48 Sgeo|school: Hah. Clojail's macroexpand-most is strictly better than macroexpand-all, but it's still wrong

10:51 Would Raynes likely to be willing to depend on analyze?

10:52 mdeboard: weavejester: Any input on connection pooling for multiple GET requests to S3 using your lib?

10:53 Sgeo|school: ,(seq? [1 2 3])

10:53 clojurebot: false

10:53 Sgeo|school: ,(coll? [1 2 3])

10:53 clojurebot: true

10:53 Sgeo|school: ,[-> 1 2]

10:53 clojurebot: #<CompilerException java.lang.RuntimeException: Can't take value of a macro: #'clojure.core/->, compiling:(NO_SOURCE_PATH:0)>

10:53 Sgeo|school: &[-> 1 2]

10:53 lazybot: java.lang.RuntimeException: Can't take value of a macro: #'clojure.core/->

10:54 Sgeo|school: Darn

10:56 ,(let [(-> a) 5] a)

10:56 clojurebot: #<ExecutionException java.util.concurrent.ExecutionException: java.lang.RuntimeException: java.lang.Exception: Unsupported binding form: (-> a)>

10:56 Sgeo|school: &(let [(-> a) 5] a)

10:56 lazybot: java.lang.Exception: Unsupported binding form: (-> a)

10:56 Sgeo|school: &[(-> 5)]

10:56 lazybot: ⇒ [5]

11:07 * gfredericks is going to try magit for the first time

11:08 technomancy: gfredericks: it will change your life

11:09 I don't know how people get by with git on the command line; it's so awful

11:09 * nDuff wouldn't describe git's CLI as "awful" as much as "demanding"

11:10 hyPiRion: technomancy: In what way is it better than the git CLI?

11:10 scriptor: it's a bit painful to learn, but after that it starts making sense

11:10 nDuff: ...expects the user to put in time and effort to learn abstractions unique to it, rather than following conventions set by other SCMs.

11:10 hyPiRion: I've not looked at magit, so feel free to pitch it.

11:10 ohpauleez: cognitively taxing, mostly. Otherwise pretty solid

11:12 daimrod: hyPiRion: it's easy to browse the log and to do partial commit

11:12 gfredericks: okay. it is loaded. now I need to figure out how to use it.

11:13 daimrod: gfredericks: C-h i m magit RET

11:13 hyPiRion: daimrod: partial commit as in part of a file, or part of files?

11:13 daimrod: part of file

11:14 like git add --interactive

11:14 scriptor: equivalent of add -p I'm guessing?

11:14 daimrod: or -p

11:14 I don't know

11:14 -p

11:15 hyPiRion: Well, I'm not in dire need of that as of right now, but I guess I'll have a look at it later.

11:15 scriptor: that's the only feature I'd like to have editor support for, staging specific lines

11:17 daimrod: hyPiRion: not having to open a terminal (even within emacs) is a big plus for me.

11:20 gfredericks: daimrod: my C-h don't work

11:20 gotta have da backspaces

11:23 chronno: gfredericks: then try f1 i m magit RET

11:24 gfredericks: omg I just made a commit

11:24 TimMc: M-x info I think

11:24 gfredericks: chronno: f1 opens the gnome terminal help; I am forever cut off from emacs help

11:25 chronno: gfredericks: lol, I'm on KDE so never tought of that...

11:31 gfredericks: Do as TimMc says, M-x info m magit RET

11:31 technomancy: scriptor: magit lets you just select a region and stage it with a single keystroke

11:32 scriptor: hmm, how does it define regions in non-sexpr languages?

11:32 technomancy: scriptor: I mean "the region"

11:32 the area between mark and point

11:33 scriptor: ah

11:33 technomancy: a screencast on it: http://vimeo.com/2871241

11:33 daimrod: you can add/revert a file/thunk/region

11:33 technomancy: bit dated but it gets the idea apart

11:35 TimMc: I've been pretty happy with git-gui and gitk.

11:43 What benefits does magit provide, other than being part of an editor?

11:44 S11001001: TimMc: does there need to be more of a reason than that?

11:48 TimMc: Yes.

11:49 And no. But I'm mostly curious about feature/workflow differences.

11:50 weavejester: mdeboard: Still around?

11:51 gfredericks: technomancy: I decided to switch when I realized that my workflow was A) open a terminal for emacs, use emacs for everything except B) open a terminal for git because eshell sucks for that

11:51 I'm not a git-cli hater. I'm just tired of that second window.

11:53 (I do realize the git-cli is crazy, I'm just already acclimated so it doesn't bother me)

11:53 TimMc: screen

11:53 (now you have two problems)

11:54 * nDuff 's workflow has emacs on one monitor, tmux on another... and it suits him very well.

11:54 nDuff: (screen? bah!)

11:56 weavejester: mdeboard: clj-aws-s3 is just a wrapper around the Java SDK library, so whether or not it uses connection pooling depends on the library provided by AWS

11:58 egghead: are there any good writeups on wrapping a clj library in java?

11:59 thorwil: TimMc: magit will notify you, if you bring it up and have unsaved files belonging to the repo open in any buffer

11:59 gfredericks: egghead: you want to take a clj library and write a java wrapper for it?

11:59 nDuff: egghead: How do you want to do it? There are two basic approaches -- interacting with clojure.lang.RT from your Java code, or exporting a Java-friendly interface from your Clojure via gen-class or such.

12:00 gfredericks: egghead: nDuff: lib-2367 gives you a one-liner for exporting a namespace into a class with static methods

12:04 hokay so if I'm using compojure and planning on returning all-json all-the-time what is the easiest way to let the routes return data that gets encoded transparently?

12:04 write a handler-wrapper myself?

12:08 egghead: nDuff: I saw some snippets of datomic which uses RT.invoke in it's private methods, it looked very nice but I think I'd like to understand it better

12:09 thorwil: gfredericks: i did that recently, for now for a single case of doing a async PUT via javascript: https://github.com/thorwil/tlog/blob/master/src/tlog/dispatch/route.clj#L19

12:12 technomancy: gfredericks: what's wrong with git in eshell?

12:12 lack of a pager?

12:12 gfredericks: well it uses LESS I think

12:12 I suppose you can configure it not to?

12:12 technomancy: export GIT_PAGER=cat

12:12 gfredericks: then git will suck outside of emacs

12:13 technomancy: (export "GIT_PAGER" "cat")

12:13 gfredericks: this good tip.

12:14 * technomancy falls prey to the "you just need to put more parens on it" problem

12:19 Sgeo|school: map->form emits fn.

12:19 Wait, hold on

12:19 Yeah, it does

12:19 But fn is not a special form, fn* is

12:20 fn is a macro

12:20 So why is map->form emitting fn?

12:29 duck1123: I have a ns that is AOT compiled into a gen-class. The methods of this class need to call into my application, but if I require those namespaces then it ends up AOT-ing almost my entire application. Can anyone point to any resources to see how best to keep the compile time requires to a minimum? Would it be a huge hit to require the namespace, intern the var and call it in each of these methods? Or is there a better way?

12:30 Sgeo|school: $mail ambrosebs Considering that fn is not a special form, while fn* is, why does map->form emit fn and not fn* ?

12:30 lazybot: Message saved.

12:30 Sgeo|school: Is ambrosebs the correct nick?

12:31 Looks oit

12:31 it

12:33 melipone: hi! it's me again

12:35 How can I have a for loop with a counter? I wanted to do (for [x [:a :b :c] n (iterate inc 0)] (println x n)) but the counter "n" does not stop when "x" stops

12:37 Sgeo|school: zip?

12:37 clojurebot: zip is not necessary in clojure, because map can walk over multiple sequences, acting as a zipWith. For example, (map list '(1 2 3) '(a b c)) yields ((1 a) (2 b) (3 c))

12:38 duck1123: ,(doall (map str [:a :b :c] (range)))

12:38 clojurebot: (":a0" ":b1" ":c2")

12:38 Sgeo|school: ,(for [[x n] (map vector [:a :b :c] (iterate inc 0))] (println x n))

12:38 clojurebot: (:a 0

12:38 :b 1

12:38 nil :c 2

12:38 nil nil)

12:38 melipone: duck1123: thanks!

12:38 Sgeo|school: I don'

12:38 I doubt that that's the best way to do that though

12:39 uvtc: melipone: `for` is for creating seqs. For printing out stuff, I think you want `doseq`.

12:40 duck1123: (doc map-indexed)

12:40 clojurebot: "([f coll]); Returns a lazy sequence consisting of the result of applying f to 0 and the first item of coll, followed by applying f to 1 and the second item in coll, etc, until coll is exhausted. Thus function f should accept 2 arguments, index and item."

12:40 melipone: uvtc: thanks!

12:41 Sgeo|school: ,(map-indexed identity [:a :b :c])

12:41 clojurebot: #<ExecutionException java.util.concurrent.ExecutionException: clojure.lang.ArityException: Wrong number of args (2) passed to: core$identity>

12:42 Sgeo|school: ,(map-indexed vector [:a :b :c])

12:42 clojurebot: ([0 :a] [1 :b] [2 :c])

12:42 Sgeo|school: In that context, what function makes more sense to use, list or vector?

12:44 melipone: Sgeo: thanks!

12:45 Sgeo|school: melipone: erm, you're welcome, but I think the others in this channel were more helpful

12:46 uvtc: Aw, I like all the thank-yous. :)

12:47 duck1123: he thanked everyone in turn. No one got left out

12:47 technomancy: http://nedroid.com/2010/11/thanks-for-reading-my-comics/

12:47 uvtc: Yes. One of my fears: thanking profusely but leaving someone out.

12:48 technomancy: thanks for that link!

12:48 technomancy: thanks for following it

12:53 melipone: quit

12:58 TimMc: duck1123: Does your ns need to expose anything besides -main?

12:58 duck1123: TimMc: My ns has a load of methods that it needs to implement. https://github.com/duck1123/jiksnu/blob/master/src/jiksnu/xmpp/user_repository.clj

13:00 I've tried to use channels and promises to work around it, but I don't like that solution

13:00 TimMc: *and* you have a shitload of requires

13:00 Oh hey, tigase -- I use their free host.

13:02 duck1123: Maybe there's a solution where you first pull all the implementations into a different ns.

13:02 duck1123: The requires in this file used to be a whole lot worse. I want to keep it as small as possible

13:02 clj_newb_234: is http://skillsmatter.com/podcast/scala/the-refined-clojurist available in non-video format?

13:02 like maybe words + diagrams on a page?

13:52 alexnixon: where I can read up about the implementation of local variable and argument nulling in clojure (i.e. the compiler making it harder for you to unwittingly hold on to your head)?

13:56 hiredman: ,(doc dorun)

13:56 clojurebot: "([coll] [n coll]); When lazy sequences are produced via functions that have side effects, any effects other than those needed to produce the first element in the seq do not occur until the seq is consumed. dorun can be used to force any effects. Walks through the successive nexts of the seq, does not retain the head and returns nil."

14:04 borkdude: what's the current status of counterclockwise + leiningen 2, do I still need a beta or can I use a stable version?

14:06 Sgeo|school: Apparently I'm in a writing mood, yet instead of writing my ethics paper I'm writing on Clojure vs Common Lisp

14:06 And I think I sort of went off the rails a bit

14:08 AimHere: Maybe you could write a paper on the ethical implications of your choice of Lisp

14:09 If you're going to go off the rails, might as well do it properly

14:09 borkdude: what's Common Lisp?

14:10 Sgeo|school: http://sgeo.tumblr.com/post/37650151853/common-lisp-symbols-vs-clojure-symbols

14:11 I don't think this post is entirely clear to be honest

14:11 oops, wrote Common Lisp when I meant Clojure

14:18 TimMc: alexnixon: A useful search term would be "locals clearing".

14:30 gfredericks: why was rhickey's go talk not taped? :(

14:30 ivaraasen: gfredericks: schadenfreude

14:31 gfredericks: that's the worst kind of freude

14:31 ivaraasen: it's the only kind

14:31 gfredericks: ah so the term is redundant then

14:33 Sgeo|school: Go talk?

14:34 gfredericks: from SL2011 I think

14:34 it's been long enough now that I can assume it won't ever exist :)

14:35 Sgeo|school: Is it rhickey talking about the Go language? Or something else

14:35 gfredericks: no the board game

14:35 ^ no sarcasm there in case that occurred to you

14:36 "Rich hickey discusses the english language's shortest verb."

14:36 Sgeo|school: I'm just not sure why he'd give a talk on a non-Clojure language

14:37 gfredericks: right. he didn't. it was the board game.

14:37 ivaraasen: Sgeo|school: masochism

14:37 * gfredericks has no way to convince a skeptic that he isn't being sarcastic

14:37 gfredericks: no wait I can use the link

14:37 $google rich hickey learn to play go

14:37 lazybot: [Learn to Play Go - Strange Loop] https://thestrangeloop.com/sessions/learn-to-play-go

14:37 gfredericks: there now you know I'm not kidding

14:38 Sgeo|school: ...I thought your "no sarcasm there in case that occured to you" was sarcastic

14:38 Just Googled...

14:38 ivaraasen: god damn it gfredericks. there goes my reading hour

14:38 gfredericks: I thought you might but it seemed futile to make meta-assertions

14:38 ivaraasen: why? there's no video. You're just going to start learning go independently?

14:39 g_s_g_s: newb question, the expression:

14:39 (set (map #( [ (:name %) (:type %) ] ) nodes)

14:39 ivaraasen: g_s_g_s: yes

14:39 g_s_g_s: barfs, what am I missing?

14:39 gfredericks: fails with wrong number of args passed to a vector

14:40 g_s_g_s: am trying to return a 2-elt containing those extracted fields

14:40 gfredericks: try (fn [%] [(:name %) (:type %)])

14:40 the #() form is a bit awkward for returning vectors

14:40 g_s_g_s: aha thx

14:40 gfredericks: the way you have it you're calling the vector as a function and trying to return that

14:41 TimMc: Ergh, don't use % as a normal symbol.

14:41 gfredericks: g_s_g_s: also good options are (fn [{:keys [name type]}] [name type]) and (juxt :name :type)

14:41 g_s_g_s: if I wanted to return a 2-elt list would it be easier?

14:41 don't care particulalry

14:41 gfredericks: g_s_g_s: you could say #(list (:name %) (:type %)), yeah

14:41 juxt is the bestest option though if it doesn't weird you out

14:42 amalloy: clojurebot: juxt is the bestest option though if it doesn't weird you out

14:42 clojurebot: Roger.

14:45 amalloy: gfredericks: my goal is to someday cause clojurebot to have more juxt quotes from you than from me

14:46 TimMc: &(nth (iterate (juxt first second) '[first second]) 1000)

14:46 lazybot: ⇒ [first second]

14:46 gfredericks: amalloy: that's juxt nonsense!

14:47 g_s_g_s: juxt it is, thx :)

14:49 TimMc: ,(nth (iterate (juxt first rest) '[first rest]) 10)

14:49 clojurebot: [first (((((((((#)))))))))]

14:50 amalloy: whaaaaat

14:51 Sgeo|school: Ugh, webchat seems to be rather unstable

14:51 amalloy: fyi in any reasonable repl that results in [first ((((((((((rest))))))))))], which makes total sense. i don't get this # nonsense clojurebot is saying

14:52 Sgeo|school: I missed it, what did clojurebot say?

14:52 gfredericks: [first (((((((((#)))))))))]

14:52 Sgeo|school: What was the thing?

14:52 gfredericks: eh just some code

14:52 ,(nth (iterate (juxt first rest) '[first rest]) 10)

14:52 clojurebot: [first (((((((((#)))))))))]

14:52 TimMc: amalloy: print-depth indicator

14:52 I once spent like an hour trying to debug my repl because of that.

14:52 Sgeo|school: So, there are no perfect Clojure REPL bots in here

14:52 :(

14:53 TimMc: &(nth (iterate (juxt first rest) '[first rest]) 10)

14:53 lazybot: ⇒ [first ((((((((((rest))))))))))]

14:53 TimMc: Sgeo|school: lazybot is better at printing (and not flooding, too)

14:53 Sgeo|school: clojurebot is better at not using a broken recursive macroexpander

14:54 gfredericks: lazybot is better at having feature X

14:54 TimMc: Sgeo|school: Ah, do tell?

14:54 Sgeo|school: I'm way too fond of this example

14:54 mattmoss: &::xyz

14:54 lazybot: ⇒ :clojure.core/xyz

14:54 amalloy: TimMc: he's pointed it out like a hundred times but isn't interested in trying to fix it

14:55 Sgeo|school: ,(let [-> inc] (-> 5)) ; (##(let [-> inc] (-> 5))

14:55 lazybot: ⇒ 5

14:55 clojurebot: 6

14:55 amalloy: lazybot's macroexpander is definitely awful; i know, because i wrote it :P

14:55 Sgeo|school: ../me wats at the extra parens he put for the lazybot one

14:55 mattmoss: &(do (in-ns 'foo) ::bar)

14:55 lazybot: java.lang.SecurityException: You tripped the alarm! in-ns is bad!

14:56 Sgeo|school: amalloy: I think a good fix would be to replace it with ambrosebs's analyze

14:56 mattmoss: Doh.

14:56 amalloy: Sgeo|school: no, a good fix would be to replace it with clojure.tools.macro. analyze is probably hugely overkill

14:56 TimMc: Ah, it applies macros even where locals should shadow them?

14:56 Sgeo|school: amalloy: in terms of speed issues?

14:56 TimMc: Good to know, I guess.

14:57 amalloy: no, in terms of being too hard to figure out

14:57 Sgeo|school: If the output is different from expected but equivalent, would that cause any issues?

14:57 Because a macroexpander from analyze is just a composition of two functions that it has

14:58 Was playing with it earlier

15:00 ARTWORKS: www.artworks.lt is waiting for a new artists, and people who like art.

15:03 Sgeo|school: Does lazybot expose any libraries that have macros that use &env?

15:03 Because mexpand-all doesn't process &env correctly, iirc

15:06 hcumberdale: How to get a key=>value pair from a map?

15:06 Sgeo|school: ,(find :a {:a 1})

15:06 clojurebot: #<ClassCastException java.lang.ClassCastException: clojure.lang.Keyword cannot be cast to java.util.Map>

15:06 Sgeo|school: ,(find {:a 1} :a)

15:06 clojurebot: [:a 1]

15:06 Sgeo|school: ,(find {:a 1} :b)

15:06 clojurebot: nil

15:06 hcumberdale: thx Sgeo|school

15:06 Sgeo|school: yw

15:07 hcumberdale: is it possible to return it as map again?

15:07 Sgeo|school: ,(into {} (find {:a 1} :b))

15:07 clojurebot: {}

15:08 Sgeo|school: ,(into {} (find {:a 1} :a))

15:08 clojurebot: #<IllegalArgumentException java.lang.IllegalArgumentException: Don't know how to create ISeq from: clojure.lang.Keyword>

15:08 gfredericks: ,(conj {} (find {:a 1} :a))

15:08 clojurebot: {:a 1}

15:08 gfredericks: ,(conj {} (find {:a 1 :b "BEEES"} :a))

15:08 clojurebot: {:a 1}

15:08 TimMc: &(into {} [(find {:a 1 :b 2} :a)])

15:08 lazybot: ⇒ {:a 1}

15:09 Sgeo|school_: qwebirc sucks :(

15:09 scriptor: school lab computer?

15:10 Sgeo|school_: Yes

15:11 hcumberdale: what is the difference between binding and let in macros?

15:12 nDuff: hcumberdale: binding creates thread-local values for dynamic vars.

15:12 mr_rm: ,()

15:12 clojurebot: ()

15:12 mr_rm: ,((fn [] "a"))

15:12 clojurebot: "a"

15:12 nDuff: hcumberdale: ...those local values are visible from anything that can see that dynamic var, not just within the textual scope.

15:13 mr_rm: ,(#("a"))

15:13 clojurebot: #<ClassCastException java.lang.ClassCastException: java.lang.String cannot be cast to clojure.lang.IFn>

15:13 TimMc: hcumberdale: If the (binding ...) and (let ...) in question are inside a syntax-quoted form, then nothing.

15:13 (As in, it won't matter that it's in a macro.)

15:13 mr_rm: can someone tell me what the difference is between calling anon functions is here: ((fn [] "a")) and (#("a"))

15:14 TimMc: mr_rm: Instead, ask hy this does what you expect: #(+ 1 2)

15:14 ,(#(+))

15:14 clojurebot: 0

15:14 mr_rm: TimMc: in this case i want a simple function that just returns a string

15:15 why doesn't the second case work? i thought those two syntax examples should be identical but they aren't

15:15 TimMc: That's why I posed that question to you.

15:15 nightfly_: mr_rm: (#("a")) is the same as ((fn [] ("a")))

15:16 TimMc: ,'#("a")

15:16 clojurebot: (fn* [] ("a"))

15:16 nightfly_: #(do "a") should work

15:16 TimMc: (constantly "a")

15:16 mr_rm: ahh

15:16 <slaps forehead>

15:16 yeah ok

15:22 ipostelnik: in lein, can you make a task automatically select a profile?

15:23 technomancy: ipostelnik: you can alias the task to ["with-profile" "my-profile" "mytask"]

15:24 nDuff: Heh.

15:24 ipostelnik: Howdy!

15:24 ipostelnik: technomancy, that's what I did, but it appears I can't use the same task as alias name

15:24 e.g. :alias ["uberjar" ["with-profile" "foo" "uberjar"]]

15:24 nDuff, hey

15:24 technomancy: ipostelnik: it's definitely possible; that's been explicitly supported for a while

15:25 ipostelnik: technomancy, I get stack overflow using 2.0.0-preview10

15:25 hcumberdale: I have a lot routes looking like: (GET "/url" request (render-in-admin-template (page-content-as-string) request)). Is it possible to write it cleaner? maybe using macros? render-in-admin-template extracts :context from request and provides it as additional argument to the rendering map (mustache template)

15:26 technomancy: ipostelnik: hrm; maybe there's a regression

15:26 if you can repro on a fresh project feel free to open an issue

15:33 brehaut: hcumberdale: im no expert, but i think you are bumping up against the division between macros (GET) and functions (ring handlers). the presence of a macro makes me thing you may need macros to create anything that will simplify it

15:35 weavejester: hcumberdale: In general it's not always a great idea to pass the entire request object to your functions.

15:36 hcumberdale: But you don't need a macro to simplify it. Just a function will do.

15:36 Bracki: Where did clojure/contrib/socket-server go?

15:36 Trying to refurbish a 4 yr old fun project...

15:36 amalloy: clojurebot: where did clojure contrib go?

15:36 clojurebot: contribute is http://clojure.org/contributing

15:36 amalloy: ~contrib

15:36 clojurebot: contrib is contribs

15:36 amalloy: sigh

15:36 Bracki: exactly

15:37 bbloom: ~contribs

15:37 clojurebot: Monolithic clojure.contrib has been split up in favor of smaller, actually-maintained libs. Transition notes here: http://dev.clojure.org/display/design/Where+Did+Clojure.Contrib+Go

15:37 TimMc: clojurebot: forget contribs |is| contrib

15:37 clojurebot: I forgot that contribs is contrib

15:37 amalloy: clojurebot: forget contrib |is| contribs

15:37 clojurebot: I forgot that contrib is contribs

15:37 Bracki: server-socket did not seem to go anywhere or vanished in thin air...

15:37 amalloy: Bracki: that wouldn't be too surprising to me; it doesn't do very much iirc

15:37 TimMc: amalloy: contribs -> contrib was taught; the reverse direction was inferred.

15:37 weavejester: Bracki: I had that problem a couple of years ago, and wrote: https://github.com/weavejester/tcp-server

15:39 TimMc: hiredman: The symmetric relation in clojurebot's inference engine is making the factoid module pretty hard to use.

15:39 technomancy: weavejester: "Copyright (C) 2011 FIXME" <- oops =)

15:40 amalloy: TimMc: is that really a thing he does implicitly? that's pretty surprising

15:40 weavejester: technomancy: I didn't say it was very polished :)

15:40 technomancy: weavejester: not even a © symbol

15:40 brehaut: technomancy, weavejester: at least it has Usage

15:41 bbloom: I think I taught him contrib is contribs b/c it game some nonsensical error

15:41 TimMc: bbloom: Other way around.

15:41 amalloy: technomancy: Foundation for Imagining Xanth, by Malloy Enterprises. he attributes copyright to meeeeeeee

15:42 TimMc: I've always wondered what that stood for!

15:43 bbloom: "Usage: see test/*"

15:44 borkdude: if I want to try Scala (to find out if it's worth educating to students), what book and IDE do you recommend? I know it's cursing in here, but Clojure people seem to have good taste :P

15:45 amalloy: i bet eclipse has a pretty good scala plugin

15:45 hcumberdale: weavejester: a function will do? how?

15:45 weavejester: hcumberdale: Well, the GET etc. macros are just fancy ways of creating anonymous functions

15:45 hcumberdale: So you can treat them like a closure

15:46 hcumberdale: When I like to call them in the following syntax:

15:46 weavejester: hcumberdale: e.g. (defn template-get [route template] (GET route request (render-template template request)))

15:46 hcumberdale: (GET "/abc" [] (admin-template (other logic)))

15:47 How do i pass the :context parameter to admin-template ?

15:47 weavejester: hcumberdale: Do you just want to wrap a set of routes in a template?

15:48 If so, you could use middleware

15:48 hcumberdale: yes weavejester. But only a few, not all

15:48 some are POST JSON/REST stuff

15:48 weavejester: hcumberdale: Middleware can be applied selectively to some routes, and not to others

15:48 hcumberdale: others are GET adminui-view stuff

15:49 weavejester: Unless you're using Noir

15:49 hcumberdale: currently I'm doing: (defmacro S_GET [path args & body] `(GET ~path ~args (atmpl ~@body {:context (:context ~args)})))

15:50 but it isn't nice because I need the full request to be there!

15:50 weavejester: hcumberdale: That could be a function, depending on what ~@body is.

15:50 It's generally a bad idea to pass a function directly through the routes

15:50 hcumberdale: body differs for each adminui route

15:50 weavejester: One of the purposes of the routes is to filter relevant information out of the request

15:51 callen: weavejester: how does ragtime store applied migrations?

15:51 weavejester: callen: It depends on the adapter

15:51 callen: weavejester: is "in the database defined by the adapter" a fair summary?

15:51 weavejester: callen: The default SQL adapter stores them in a table called ragtime_migrations

15:51 callen: weavejester: precisely what I wanted to know. tyvm.

15:52 weavejester: callen: You're welcome

15:52 callen: weavejester: I'm evaluating lobos, ragtime, migratus, etc.

15:52 weavejester: hcumberdale: Could you give me an example of what ~@body might be?

15:53 hcumberdale: (render-file "templates/dashboard" {}) << 'inner template' rendering

15:53 results in a string

15:53 => evaluates to a string

15:53 callen: hcumberdale: what are you doing for templates?

15:53 hcumberdale: stencil

15:54 weavejester: hcumberdale: So ~@body always evaluates to a string?

15:54 hcumberdale: Logicless Mustache templates for Clojure

15:54 yes weavejester

15:54 callen: hcumberdale: da. just wondering, thank you.

15:54 weavejester: So you could have some middleware that does something like…

15:55 hcumberdale: In the case that a adminui page is rendered,... not for all GET/POST requests

15:56 ohpauleez: is there anyway to visual the tree/trie of a data structure?

15:56 I thought the inspector would do it (never used it before), but it doesn't seem to be the case

15:57 weavejester: hcumberdale: https://gist.github.com/4253294

15:57 So you return the body that isn't wrapped in the outer template

15:57 And then use middleware to add it.

15:59 hcumberdale: weavejester: it feels some kind of wrong to use middleware. It should take effect only on specific routes and how they differ is configured in the defroutes part

15:59 brehaut: hcumberdale: middleware is used more aggressively in clojure/ring/compojure than other languages / frameworks

16:00 weavejester: hcumberdale: Why is it wrong? Middleware is about applying a common set of behaviour to a subset of routes.

16:00 brehaut: hcumberdale: its the secret sauce that makes it so great

16:01 hcumberdale: How can I mask to routes where the middleware should be applied?

16:01 ohpauleez: nvm, found: https://groups.google.com/forum/?fromgroups=#!topic/clojure/HmsyuhLzico

16:02 weavejester: hcumberdale: You just apply the middleware directly to a subset of routes

16:02 Bracki: https://github.com/technomancy/server-socket/ I found this

16:02 weavejester: hcumberdale: So (wrap-foo (GET "/bar" [] …)) will work

16:02 Bracki: But now I get a Could not locate server_socket__init.class or server_socket.clj on classpath

16:02 weavejester: hcumberdale: As will (wrap-foo (routes (GET "/foo" [] …) (GET "/bar" [] …)))

16:03 Bracki: Given project.clj how do I figure out what the actual namespace is?

16:03 amalloy: Bracki: not possible

16:04 hcumberdale: like (defroutes admin-routes (wrap-template (GET "/" [] nil) (GET "/x" [] nil)) (GET "/other" [] nil))

16:04 ?!

16:04 Bracki: amalloy: What is not possible?

16:04 amalloy: Bracki: Given project.clj how do I figure out what the actual namespace is?

16:04 weavejester: hcumberdale: More like...

16:04 (def admin-routes (wrap-template (routes (GET "/" [] nil) (GET "/x" [] nil)) (GET "/other" [] nil)))

16:05 Bracki: So leiningen just downloads useless stuff?

16:05 amalloy: cannot be done. the project.clj has no bearing on the namespace, except that frequently the namespace is related somehow to the project name

16:05 weavejester: I kinda regret putting "defroutes" in Compojure

16:05 S11001001: Bracki: no

16:05 weavejester: Because it's just short for (def … (routes …))

16:05 But people treat it as more magical than it is.

16:05 hcumberdale: ;)

16:05 amalloy: weavejester: kinda inclined to agree. my mind was blown when i found out routes was its own entity

16:06 brehaut: weavejester: i imagine people would have treated routes as just as magical

16:06 weavejester: I think "routes" was a poor name, too. It should have been something like "combine" or "cascade"

16:06 TimMc: Bracki: A project called "org.timmc/sparkles" might have a main namespace called "unicorn.rainbows.core".

16:06 S11001001: weavejester: then the RoR refugees wouldn't have been able to find it

16:06 hcumberdale: weavejester: no second routes for "other" ?

16:06 weavejester: Since all it does is combine multiple routing functions into one

16:06 amalloy: i also imagined, for quite some time, that routes was a macro that looked at all the GET/POST clauses and compiled something special

16:06 weavejester: hcumberdale: Oh, right, yeah, there should be a separate one for other

16:06 S11001001: weavejester: since the only way to learn a new framework is to assume it's like the one you already know, after all

16:07 brehaut: weavejester: i think that often peoples preconceptions from other frameworks and libs blind them to what is actuall going on

16:07 Bracki: Ok, so given the above project https://github.com/technomancy/server-socket/blob/master/src/server/socket.clj what do I :use?

16:07 amalloy: Bracki: https://github.com/technomancy/server-socket/blob/master/src/server/socket.clj#L9

16:07 weavejester: Bracki: server.socket it looks like

16:08 TimMc: src/NAMESPACE/IS/IN/HERE.clj

16:08 except munged for use as a path

16:08 Bracki: Ha, thanks

16:08 TimMc: so you look at the top of that clj file to be sure

16:08 Bracki: Now I only need str-join

16:08 Where did that go?

16:08 duck1123: clojure.string/join

16:10 Bracki: Can I do aliased usage?

16:11 Replacing str-join with join gives me ould not locate join__init.class or join.clj on classpath

16:12 borkdude: Bracki: try (use '[clojure.string :only [join]) and then try again

16:15 hcumberdale: weavejester: with your solution "other" is also templated

16:16 weavejester: hcumberdale: Yeah, that was a mistake. Just apply the middleware to all the routes *except* the "other"

16:17 Bracki: Exception in thread "main" java.lang.IllegalStateException: join already refers to: #'clojure.string/join in namespace

16:17 weavejester: e.g. (def r (routes (wrap-foo (routes a b c)) d e f))

16:17 Or: (defroutes r (wrap-foo (routes a b c)) d e f)

16:18 Or: (defroutes admin a b c) (defroutes other d e f) (defroutes all-routes (wrap-foo admin) other)

16:18 Bracki: It's always the same, being a parent I spent 90% of my evening on class loading/bootstrapping stuff and then I go to bed.

16:19 dr1: Hi, I'm new to functional programming and am stuck on something simple. I'm trying to run a function from a project I'm working on in a repl. I'm seeing this: IllegalArgumentException No implementation of method: :priority of protocol: #'gui2.list/IInterface found for class: clojure.lang.Symbol clojure.core/-cache-protocol-fn (core_deftype.clj:527)

16:19 hcumberdale: java.lang.IllegalArgumentException: Don't know how to create ISeq from: clojure.lang.Keyword

16:19 hiredman: http://dev.clojure.org/jira/browse/CLJ-1085

16:19 dr1: does that mean I am passing the wrong data type?

16:20 amalloy: dr1: probably

16:20 Bracki: lib names inside prefix lists must not contain periods, aha

16:21 mthvedt: dr1: you're passing a symbol, and it doesn't implement that protocol… this error is commonly caused by accidentally using a symbol instead of what the symbol refers to

16:21 dr1: amalloy: how do I figure out what I'm supposed to pass… priority should be some non-negative number and I tried passing it in as 0 or "0" and get the same error complaining that it's a java.lang.symbol

16:22 agh, so then it's likely that priority is not just a simple number?

16:22 TimMc: It sounds like you're not passing in the args that you think you're passing.

16:22 hcumberdale: weavejester: it returns some crazy things now: [:status 200][:headers {"Content-Type" "text/html;charset=UTF-8", "Character-Encoding" "UTF-8"}][:body ...

16:22 mthvedt: dr1: in that error message, priority is a fn being called

16:22 hcumberdale: not the html ;(

16:23 mthvedt: numbers and strings are not symbols, so that's probably not the cause

16:23 weavejester: hcumberdale: Well, a handler returns a response map

16:23 hcumberdale: You need to apply your template to the body of the response

16:24 hcumberdale: mhh,...

16:24 TimMc: dr1: Seeing a small code snippet would be helpful: http://refheap.com/

16:25 Bracki: Does anybody spot whats wrong here: http://pastebin.ca/2291229

16:26 llasram: Bracki: You're excessively quoting the first :use "argument" vector

16:26 hcumberdale: I've used a fn to ensure utf-8 is send back (defn utf8r "Ring skeleton with headers." [body] {:status 200 :headers { "Content-Type" "text/html;charset=UTF-8" "Character-Encoding" "UTF-8"} :body body})

16:26 llasram: Bracki: (i.e., you need to delete the ' character)

16:27 hcumberdale: How to I use it in the middleware? Or is it the wrong place?

16:27 Bracki: llasram: That gives me join already refers to: #'clojure.string/join in namespace: urkle.core

16:28 llasram: That's a just warning, and means you already pulled it into the namespace / are pulling it in via a raw use/require call elsewhere in that namespace

16:28 weavejester: hcumberdale: Everything in Ring is just functions and maps, so you could just alter the response with middleware to add the content type.

16:29 Bracki: llasram: Exception in thread "main" java.lang.IllegalStateException, doesn't look like a warning to me...

16:29 weavejester: hcumberdale: Though Compojure defaults to returning text/html;charset=UTF-8 anyway with strings

16:29 hcumberdale: why do I need if-let [response (handler request)] ?

16:29 is it possible that there is no (handler request) ?

16:29 weavejester: hcumberdale: Just in case the response is nil

16:29 hcumberdale: That's what happens when a route doesn't match

16:30 llasram: Bracki: Hmm. Usually it's just a warning. Do (ns-unmap *ns* 'join) in your REPL, then reload

16:30 dr1: agh! While trying to write a code snippet, I think I found the problem.. priority ISN'T just a number. Now, I guess I have to figure out how to create a priority properly. Thanks, I'll be back if/when I get lost again

16:30 weavejester: hcumberdale: I wrote a blog post on how Compojure routes were made up

16:30 hcumberdale: http://www.booleanknot.com/blog/2012/09/18/routing-in-compojure.html

16:32 hcumberdale: So it will be some kind of: (defn wrap-utf8 [handler]

16:32 (fn [request] (if-let [response (handler request)]

16:32 (assoc-in response [:headers] { "Content-Type" "text/html;charset=UTF-8" "Character-Encoding" "UTF-8"}))))

16:32 Bracki: llasram: ain't got no repl, lein test says that

16:33 llasram: Bracki: Then you've got a call to (use ...) somewhere else in there, or something

16:35 weavejester: hcumberdale: Yep, though there are some functions in ring.util.response that could make things easier

16:35 hcumberdale: weavejester: is there a chance of overwriting other headers using assoc-in?

16:36 weavejester: remembering to have problems with jetty and UTF-8

16:36 weavejester: hcumberdale: e.g. (content-type response "text/html;charset=UTF-8")

16:36 llasram: Bracki: Or potentially, multiple files which are actually declaring they implement the same namespace

16:36 weavejester: hcumberdale: Well, the way you wrote it it would overwrite

16:36 hcumberdale: how to merge?

16:36 is there a merge-in ?

16:36 weavejester: hcumberdale: Because you wrote (assoc-in response [:headers] …) instead of (assoc-in response [:headers "Content-Type"] …)

16:37 hcumberdale: There is an update-in

16:37 hcumberdale: But this will replace them too

16:38 weavejester: hcumberdale: I'm not completely sure what you want to do...

16:38 hcumberdale: Is it a good idea to overwrite the headers?

16:38 Or is it better to merge them?

16:39 weavejester: hcumberdale: That depends on what you want to do...

16:39 assoc-in won't overwrite *all* the headers, if used correctly

16:39 hcumberdale: Settingthe Content-Type and Caracter-Encoding headers, leaving other headers untouched

16:39 weavejester: And you can use update-in for more nuanced changing of the header

16:40 hcumberdale: If you just want that, then use assoc-in

16:40 hcumberdale: weavejester: two calls?

16:40 weavejester: weavejester: Or use the ring.util.response/header and ring.util.response/content-type

16:40 hcumberdale: one with [:headers "Content-Type"] and another with [:headers "Character-Engoding"] ?

16:41 weavejester: hcumberdale: Well, there isn't a Character-Encoding header in HTTP

16:42 TimMc: One of many annoyances!

16:44 Bracki: llasram: Whatever I do, I keep getting that error

16:48 llasram: Bracki: If you posted a git repo of the entire project state, I'd be willing to take a look, but there's not much more I can say ATM

16:52 hcumberdale: Thx weavejester it works

16:55 egghead: work just set me up for clojure west :D :D :D

16:57 weavejester: hcumberdale: You're welcome :)

17:02 Bracki: llasram: https://github.com/bracki/urkle

17:05 llasram: Bracki: Oh! Both clojure.string and clojure.set have a 'join' function

17:05 So you can't blindly pull in all symbols from both namespaces

17:05 Raynes: You wouldn't want to do that anyway

17:05 llasram: Bracki: Best practices is to use :require with :as anyway

17:05 amalloy: let this be a lesson to never :use a whole namespace, for the perils are beyond mere mortal comprehension

17:06 Raynes: If you don't qualify your requires, you end up with code that makes no sense because there is no way to tell where anything came from.

17:06 Bracki: 4 years ago that was recommended practice...

17:06 Raynes: You end up with Ruby.

17:06 Oops, did I say that out loud?

17:06 amalloy: Bracki: maybe it was common practice, but i doubt it was recommended

17:06 hiredman: it never was

17:06 hcumberdale: Haha Raynes

17:07 Bracki: I'm fine with common...

17:08 bbloom: dnolen: just watched your core logic talk via skills matter. good stuff!

17:08 Raynes: Bracki: Please, don't be.

17:10 Bracki: I was refering to what was common 4 years ago.

17:10 amalloy: Raynes: the poor guy is trying to bring a 4-year-old project up to date. give him a break

17:10 Raynes: amalloy: Go play with your Emacs and let the adults talk.

17:10 amalloy: you'll never be as swank as i am

17:10 llasram: "You'll never be as nrepl as I am" really doesn't have the same ring to it, does it?

17:11 Well, unless you use drawbridge

17:12 Bracki: Thanks, it runs again.

17:12 technomancy: llasram: well there's always http://www.youtube.com/watch?v=-VJcfXdR1X0

17:12 Bracki: Now I'll commit it and ask again in 2 yrs time ;)

17:12 llasram: nice

17:12 Sgeo|web: Raynes: is it ok if the macroexpander that Clojail uses does weird things like putting the whole thing in an fn and immediately calling it?

17:13 Or using ... I forget what it does when it sees +

17:13 Bracki: What did the *foo* syntax mean?

17:13 Anything special or just some convention?

17:13 Sgeo|web: Convention for dynamically-scoped vars

17:13 amalloy: technomancy: what an interesting cover

17:14 Raynes: Sgeo|web: Not sure what you're asking.

17:14 technomancy: amalloy: it's the first version I heard

17:15 ipostelnik: how can I convince lein to never look in central and clojars?

17:15 llasram: ipostelnik: :omit-default-repositories true

17:15 technomancy: ipostelnik: or add ^:replace metadata to your :repositories map

17:15 Sgeo|web: Raynes: I want to scrap macroexpand-most and replace it with (comp map->form analyze-form)

17:15 technomancy: vector

17:15 whatever

17:15 weavejester: Does anyone know if there's an in-memory queue for Java that will put items back on the queue if a worker times out?

17:15 llasram: technomancy: Oh, does that work with preview10 ?

17:16 ipostelnik: I have :repositories ^:replace [["my-repo" "url"]]

17:16 technomancy: llasram: it should; haven't tried it myself

17:16 Raynes: Sgeo|web: Everything in clojar does weird things. If it works, go for it.

17:16 clojail*

17:16 Sgeo|web: https://www.refheap.com/paste/7471

17:16 ipostelnik: yet I get lots of "Could not find artifact ... in central" and same for clojars

17:17 technomancy: ipostelnik: maybe you need :omit-default-repositories then

17:17 Sgeo|web: That fn should really be fn*

17:17 I think

17:17 hcumberdale: ,(type :x)

17:18 clojurebot: clojure.lang.Keyword

17:18 Sgeo|web: I don't really know the difference though, and don't know if that could be an exploitable hole

17:18 llasram: technomancy, ipostelnik: Yeah, I def need :o-d-r

17:18 hcumberdale: ,(type #^Keyword :x)

17:18 clojurebot: #<ExecutionException java.util.concurrent.ExecutionException: java.lang.IllegalArgumentException: Metadata can only be applied to IMetas>

17:18 technomancy: they should be the same thing; hrm

17:20 hcumberdale: ,(let [#^Keyword x :y] (type x))

17:20 clojurebot: clojure.lang.Keyword

17:21 hcumberdale: Is clojure.lang default included for type hinds? It seems

17:21 ,(type [:y nil :x nil])

17:21 clojurebot: clojure.lang.PersistentVector

17:22 hcumberdale: ,(type {:y nil :x nil})

17:22 clojurebot: clojure.lang.PersistentArrayMap

17:22 llasram: hcumberdale: It is not. And also, the #^Class syntax is obsolete -- you can just use ^Class

17:23 hcumberdale: What's the best type hind for map and vector?

17:24 llasram: why does ^Keyword work then ?

17:24 llasram: hcumberdale: Probably none. Unless you're directly invoking methods on the passed in values, the hints won't do anything

17:24 hcumberdale: ,(let [^Map x {:x 1}] (type x))

17:24 clojurebot: clojure.lang.PersistentArrayMap

17:25 nDuff: hcumberdale: Do you mean "why doesn't"? (And that would be a surprise, if it didn't, unless clojure.lang.Keyword weren't in your namespace)

17:25 llasram: hcumberdale: Because ^Symbol is just shorthand for ^{:tag Symbol}, where the "Symbol" value is quoted, and resolved when needed. This can be kind of confusing at times, but allows ^int etc for primitives

17:26 hcumberdale: ,^Keyword x

17:26 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: x in this context, compiling:(NO_SOURCE_PATH:0)>

17:26 hcumberdale: ,^Keyword :x

17:26 clojurebot: #<ExecutionException java.util.concurrent.ExecutionException: java.lang.IllegalArgumentException: Metadata can only be applied to IMetas>

17:26 hcumberdale: hmpf

17:26 llasram: &(meta (first '(^Example x)))

17:26 lazybot: ⇒ {:tag Example}

17:27 hcumberdale: &(meta (first '(^Keyword :x)))

17:27 lazybot: java.lang.IllegalArgumentException: Metadata can only be applied to IMetas

17:28 llasram: Yeah, keywords are singletons, so can't have metadata

17:28 amalloy: hcumberdale: there is also no reason to ever typehint a keyword literal (and very rarely a reason to typehint a literal of any sort)

17:28 TimMc: Besides, you can't reliably attach metadata to runtime values using ^ anwyay.

17:29 amalloy: TimMc: i thought that for a long time, but apparently i'm basically crazy

17:29 TimMc: Oh, has it changed?

17:29 amalloy: i don't think so

17:29 it's always worked

17:29 TimMc: I could swear I've seen it fail in the recent past.

17:29 amalloy: it's just that (my fault, again) it doesn't work in lazybot

17:29 clojurebot: Huh?

17:29 TimMc: Oh, ha.

17:30 amalloy: clojurebot: go away

17:30 clojurebot: Gabh mo leithscéal?

17:30 hcumberdale: Should I use type hints with defrecord?


17:30 amalloy: ,(meta ((fn [x] ^:even x) 'sixteen))

17:30 hcumberdale: I thought they are used to avoid reflection

17:30 clojurebot: nil

17:30 hcumberdale: ,(type :x)

17:30 clojurebot: clojure.lang.Keyword

17:30 amalloy: god damn it. really? how can i never be right about this?

17:31 TimMc: I would certainly not expect that to work.

17:31 amalloy: ,(meta ((fn [x] ^:even [x]) 'sixteen))

17:31 clojurebot: {:even true}

17:31 hcumberdale: (= (type :x) 'Keyword)

17:31 ,(= (type :x) 'Keyword)

17:31 clojurebot: false

17:32 hcumberdale: ,(= (type :x) 'clojure.lang.Keyword)

17:32 clojurebot: false

17:32 hcumberdale: ??

17:32 lazybot: hcumberdale: What are you, crazy? Of course not!

17:32 llasram: hcumberdale: It avoids reflection, but that only matters when you actually invoke JVM methods. If you just pass them to clojure functions there's no reflection to avoid

17:32 amalloy: TimMc: i think it works on collections but not symbols? i just never try to do it, but it works more often than you'd expect

17:33 TimMc: hcumberdale: First off, you want class, not type (to make things simpler).

17:33 hcumberdale: Second, the return type is a class, not a symbol.

17:33 hcumberdale: Direct access is faster by 10 times I think

17:33 TimMc: amalloy: a.k.a. not reliably

17:33 llasram: amalloy: That boggled my mind for a second, but now I see what's happening

17:34 TimMc: hcumberdale: ##(= (class :foo) clojure.lang.Keyword) Note the lack of ' in front of the classname.

17:34 lazybot: ⇒ true

17:34 pyr: is there a way to control aot compile order ?

17:34 Bronsa: ,(meta ((fn [x] (with-meta x {:f true})) 'sixteen))

17:34 clojurebot: {:f true}

17:34 hcumberdale: TimMc: ahh

17:34 Bronsa: amalloy: ^

17:34 llasram: TimMc: I think the confusion is around type-hinting, which *does* use symbols. Just symbols which are resolved to class names at certain times

17:35 TimMc: &(meta ((fn [x] ^:even [x]) 'sixteen))

17:35 lazybot: ⇒ nil

17:35 amalloy: Bronsa: we're well aware

17:35 hcumberdale: ,(defrecord Foo [a b c d e f g h i j k l m n o p q r s t])

17:35 clojurebot: #<Exception java.lang.Exception: SANBOX DENIED>

17:35 hcumberdale: ;9

17:36 ,(class 1)

17:36 clojurebot: java.lang.Long

17:36 hcumberdale: ,(class :1)

17:36 clojurebot: clojure.lang.Keyword

17:37 hcumberdale: ,(class clojure.lang.Keyword)

17:37 clojurebot: java.lang.Class

17:37 hcumberdale: ahh!

17:38 Is the correct type hint ^Keyword or ^clojure.lang.Keyword ?

17:39 Or do they work only with primitives ?

17:41 thought about using (defn +typeX [& [init]] (merge {:x nil :y false} init)) or defrecord.

17:42 But performance will be an issue with ~15 parameters and thousands of instances

17:49 How to change values in records?

17:50 AimHere: I think you can't; you have to use types for mutable values

17:50 You could consider making a new record with the updated value in proper functional style.

17:51 * nDuff nods.

17:51 nDuff: hcumberdale: What's your situation/use case?

17:52 hcumberdale: nDuff: I have ~2500 xml files stored on the file system

17:52 I want to write an UI to attach meta information to these files

17:53 like assign a file to a category

17:53 ~15 attributes for each file

17:53 clojurebot: _seanc_: Your files don't get reloaded when a request is made.

17:53 nDuff: hcumberdale: I typically use atoms in that kind of case -- you can have the UI subscribe via listeners to know when there's an update coming from other code so it can respond.

17:54 hcumberdale: nDuff: it is a web ui, currently without websockets

17:54 nDuff: hcumberdale: ClojureScript supports atoms.

17:55 hcumberdale: in general I would use a map

17:55 nDuff: hcumberdale: ...yes, but Clojure's native maps are immutible.

17:55 hcumberdale: ...so, you have the same question with them you have about records, ie. "how do I change these?"

17:55 hcumberdale: ...and the answer to that question is "put the object behind an atom".

17:56 hcumberdale: but I have multiple values there

17:56 Is a ref better then a atom then?

17:56 nDuff: hcumberdale: If you're only using _one_ map to hold your multiple values, an atom is the right thing.

17:57 hcumberdale: refs are useful when you want to have coordinated transactions across several entry points into your mutable state

17:57 hcumberdale: ...in general, it's better to avoid doing that.

17:57 (also, refs aren't available in ClojureScript, so if you're doing this browser-side, you can't use 'em anyhow)

17:57 hcumberdale: I'd suggest reading Joy of Clojure, btw.

17:58 hcumberdale: ...it has a lot of focus on the kind of conceptual grounding that your questions seem to be centered around.

17:58 nkkarthik: how can I start nrepl server in tomcat webapp?

17:59 hcumberdale: nDuff: maps = bad performance, they are 25 times slower then direct access to a record

17:59 nDuff: hcumberdale: ...so, this is another thing that reading Joy of Clojure would be answering for you. :)

17:59 hcumberdale: nDuff: I'm writing server-side

18:00 nDuff: hcumberdale: Clojure's native record types provide a compatible interface with its native map types.

18:00 hcumberdale: ...so, you can prototype with native maps and move to defrecord without changing the rest of your code.

18:00 hcumberdale: changing means a second instance then?

18:00 nDuff: ...huh?

18:01 hcumberdale: ...oh, you don't understand structural sharing.

18:01 hcumberdale: Seriously, go read JoC.

18:01 hcumberdale: I know what it is. But not how it affects records

18:01 nDuff: hcumberdale: ...basically -- Clojure's native datatypes share their content as much as possible on updates.

18:01 hcumberdale: That's true for records too.

18:02 hcumberdale: but they are java objects, how is that possible?

18:02 nDuff: ...by implementing structurally-shared datatypes in Java?

18:02 sshack: So what's the current user friendly Clojure repl to use?

18:03 hcumberdale: How does a Type hint work then?

18:03 nDuff: ...

18:03 brehaut: sshack: lein repl / reply (its the same thing)

18:03 nDuff: hcumberdale: ...I'm having trouble following the train of thought that would lead to that follow-up question.

18:03 (and I don't have time for 20 questions)

18:03 hcumberdale: ok

18:03 brehaut: nDuff: i was under the impresion that records didnt do structural sharing for their intrinsic fields, only conj'd on map fields?

18:04 sshack: brehaut: Any with syntax highlighing/paren matching?

18:04 nDuff: brehaut: ...well, yes -- there's not really so much structure there.

18:04 brehaut: sshack: the ccw / eclipse repl might? or an emacs nrepl?

18:05 nDuff: sshack: emacs+paredit+nrepl.el certainly does all that, and a whole lot more.

18:05 sshack: Might play with emacs, thanks.

18:05 Wish we could get beyond emacs though. It's so 1970's.

18:05 nDuff: sshack: I'd suggest Emacs Live if you're a newcomer -- has a whole lot of shiny plugins all in one place, and some videos showing off features/usage

18:05 sshack: (Yeah, I know about light table, it looks wonderful)

18:06 hcumberdale: awww!

18:06 * nDuff isn't impressed by Light Table yet.

18:06 sshack: nDuff: 15 year emacs user. But I gave it up a few years ago out contempt for its user apathy.

18:06 nDuff: I agree. But the intent and potential is there.

18:11 hcumberdale: Is there a JSON FlatFile Store for Clojure data structures?

18:12 Apage43: a who

18:12 I just do line-separated

18:12 oskarth: how are people setting up emacs with clojurescript repl?

18:13 Apage43: you can JSON encode it, but you lose stuff like sets

18:15 hcumberdale: Apage43: How do you sync changes with the file?

18:16 Apage43: depends. If it's just one big structure, it's just (->> "file" slurp read-string make-changes pr-str (spit "file"))

18:16 dnolen: hmm what's w/ the "Namespace not found." nrepl.el errors again after a nrepl-quit and restart?

18:17 oskarth: I just use inferior lisp

18:17 oskarth: dnolen: how do you set it up?

18:17 it tells me CLOJURESCRIPT_HOME isn't configured, but it's in my env

18:18 dnolen: oskarth: you may need to setup .bashrc w/ that info too.

18:18 oskarth: dnolen: it's in there

18:18 dnolen: oskarth: perhaps you need to set in .profile too? or .bash_profile?

18:19 oskarth: I always get confused so I just do it in all 3.

18:19 oskarth: possibly, I'll do some more trial and erorr and googling

18:19 haha

18:19 dnolen: but you tie it to $CLJS_HOME/script/repljs, right?

18:19 dnolen: oskarth: not unless I'm doing something w/ the compiler - I use lein-cljsbuild's repl support

18:20 oskarth: ah

18:20 dnolen: could you paste the line you use to config that? maybe I'm doing something wrong there

18:20 dnolen: oskarth: what I use to config Emacs?

18:20 Apage43: hcumberdale: what exactly do you need?

18:20 oskarth: dnolen: yeah, the inferior-lisp hook

18:21 * technomancy can't believe people still release software that will completely refuse to work without setting a *_HOME environment var

18:21 dnolen: oskarth: http://gist.github.com/4254233

18:22 Apage43: i like hadoop. Depending on the version you either -have- to set HADOOP_HOME, or you get yelled at because you set HADOOP_HOME

18:23 technomancy: Apage43: ah, glad to see it hasn't lost any of its charm in the 3 years since I briefly glanced at it and fled in horror

18:24 gfredericks: does korma's select ever return a lazy thing? or is the data always loaded by the time it returns?

18:24 brehaut: gfredericks: from memory it always realizes the data so that it doesnt have cursors hiding in unrealized seqs?

18:24 oskarth: dnolen works, thanks!

18:24 gfredericks: brehaut: that's what I would hope

18:25 brehaut: gfredericks: (incase the connection is closed)

18:25 gfredericks: caveat: i dont know what im talking about

18:25 gfredericks: I'm a little concerned about the behavior of (select foos (with bars))

18:25 technomancy: wouldn't you want cursors to translate into clojure lazy seqs?

18:26 brehaut: technomancy: i dont make the decisions, i just parrot them in a lossy form

18:26 hiredman: technomancy: korma doesn't using a with-connection macro

18:26 so there is nothing else to control the scope of the connection

18:27 so the connection and associated resources (cursors, results, etc) must be closed before the select returns

18:27 technomancy: oh right, bleah

18:27 hiredman: yep

18:27 gfredericks: oh so korma is inherently terrible for reducing over large result sets?

18:28 * TimMc points out the obvious s/ for.*// joke

18:28 hcumberdale: Apage43: Holding 15 metadata attributes for ~2000 xml files

18:28 Modify them using a web ui

18:29 hiredman: I am not a fan

18:29 hcumberdale: It should be possible to cluster the application. Then they share a disk for the shared data

18:29 gfredericks: I'm not particularly enamored with korma. But I do think there is value in assembling a query programmatically rather than using SQL strings

18:30 hcumberdale: When I write logic to store data structures and load them + Sync logic so every client is up-to-date maybe the best solution is mongodb or a rdbms...

18:30 technomancy: gfredericks: it's clear that c.j.jdbc is not the right abstraction, but I'm pretty sure korma isn't it either

18:31 hiredman: a problem with korma is it combines sql generation with database connections and management there of

18:31 hcumberdale: + korma does not handle ddl

18:31 TimMc: You can separate those somewhat...

18:31 technomancy: hcumberdale: that's a feature

18:31 jeremyheiler: gfredericks: jkkramer is working on a library to do just that, but im not sure if he's released it yet

18:31 Apage43: hcumberdale: yeah, once you have more than one machine, I don't know that file based is the way to go. But https://github.com/flatland/masai w/ tokyo cabinet would probably be what you want otherwise.

18:31 TimMc: Korma can emit the SQL strings instead of sending them.

18:32 hiredman: use sql-form or whatever and pass it to clojure.java.jdbc

18:32 I guess

18:32 technomancy: hcumberdale: there's no way to handle DDL in a way that works across databases. it's just impossible to do consistently.

18:32 gfredericks: jeremyheiler: I particularly like having the compiler notice if I have a typo. But that requires declaring your tables at a minimum.

18:32 which feels verbose if typo-checking is the only thing you're getting from it.

18:32 hcumberdale: technomancy: but a subset like hibernate does

18:32 hiredman: anyway, some needs to spec out a sql ast in clojure datastructures, and write a compiler that generates sql strings from that

18:33 technomancy: hcumberdale: even then it's impossible to do on the scale of clojure

18:33 gfredericks: hiccup-for-sql

18:33 hiredman: maybe

18:33 gfredericks: sqicclup

18:33 technomancy: it takes an immense amount of work to catch all the edge cases needed for that

18:33 no single clojure project has that kind of manpower

18:33 hiredman: I was thinking something more ast like, like the output of the cljs analyzer

18:34 gfredericks: technomancy: are you talking about query generation or ddl?

18:34 technomancy: gfredericks: ddl

18:34 gfredericks: hiredman: for the end user, or for other tools to build on?

18:35 hiredman: gfredericks: the latter

18:35 gfredericks: that doesn't sound remotely terrible

18:35 hiredman: the ast would be the "interchange" format so the layer of macros can just spit out an ast, then another tool knows how to check the ast against your table definitions to see if they make sense

18:36 gfredericks: very nice

18:36 hiredman: please do it

18:36 jeremyheiler: here's one of jkkramer's projects, but its not the one i saw at conj https://github.com/jkk/honeysql

18:36 gfredericks: :)

18:37 hiredman: jeremyheiler: interesting

18:37 it looks like it tries to hard to be human consumable though

18:38 but maybe in practice it could be fine, and I am just biased towards my own vision

18:38 jeremyheiler: haha yeah. definitely get in touch with him about his other project.

19:07 bbloom: i've got an algorithm that produces an extremely large tree of maps. many of the elements are only one assoc away from each other, so it's pretty memory efficient, but if i prn it to a file and read it back in, then it's huge. i kinda wish i had a way to "compress" a recursive persistent datastructure...

19:08 hiredman: bbloom: interesting

19:09 you'd want to print out a collection of deltas and bases and apply the deltas on read

19:10 bbloom: i think it's actually simpler than that… if you could treat every internal tree node as a "value" then you could simply walk the tree and memoize look up an instance for every node

19:10 hiredman: bbloom: there is always java serialization

19:10 bbloom: how is that relevant?

19:11 hiredman: hmmmm, I guess it isn't

19:11 I was thinking you could use it to just dump everything exactly as is, but of course there are no bck pointers

19:12 bbloom: i wish there was some InternalRepresentation protocol

19:12 if i called it on a PersistentTreeMap, i'd get back an immutible array, or on a PersistentTreeMap i'd get back the trie or red black tree or whatever it is

19:13 then i could just stick every node into a map and each time i build one up, check the map to see if i already have it, if so, throw out the new value and reuse the existing instance

19:13 then throw out the memo table after reading the large data structure

19:17 but none of the internals provide hashCode or equality implementations

19:20 oh well maybe some of them do....

19:20 tpope: bbloom: I'm not sure how to follow up to Meikel

19:22 bbloom: tpope: *shrug*

19:22 he said feel free…. i guess go for it? :-P

19:22 i guess the issue then becomes the maintenance burden

19:23 tpope: I feel like stealing his static files, bikeshedding them, and submitting them upstream would be a bit douchey

19:24 bbloom: by bikeshedding, you mean modifying them to meet your/bram's arbitrary requirements for inclusion in vim?

19:25 tpope: I actually meant the more traditional definition of petty changes

19:25 e.g. I think making the options look like vimclojure#foo is dumb

19:25 why am I defining stuff in your namespace?

19:26 I guess Meikel wasn't the original author of the syntax file anyways

19:27 bbloom: which pieces do you want specifically? syntax, indent, ftdetect, what else?

19:27 tpope: a subset of the ftplugin

19:27 and that's pretty much it

19:28 bbloom: what functionality is in that subset?

19:28 tpope: stuff like 'comments' and 'formatoptions'

19:28 I could write the ftplugin from scratch easy

19:28 bbloom: yeah, hm

19:28 well, considering:

19:29 tpope: syntax is harder, and indenting a nightmare

19:29 bbloom: 1) he's not the original author of many bits

19:29 tpope: I still don't understand clojure indenting

19:29 bbloom: 2) it's MIT and he said go for it

19:29 and 3) my strict adherence to the "better to beg for forgiveness than ask for permission" philosophy

19:29 i say go for it

19:30 indenting is a whole nother topic

19:30 tpope: his indenting stuff looks kind of complected with the dynamic stuff

19:30 bbloom: so, generally, people line up arguments

19:31 but only indent 2 spaces for the body of blocks

19:31 but thanks to macros, there is no easy syntactical clue as to what is a block and what is an argument

19:31 tpope: what *is* a block

19:31 bbloom: so it looks like he has some heuristics for guessing if something is a block

19:31 in this case starts with def, with, let, etc

19:32 technomancy: just steal the list from clojure-mode.el =)

19:32 tpope: an excellent idea

19:33 technomancy: https://github.com/technomancy/clojure-mode/blob/master/clojure-mode.el#L781

19:33 bbloom: but for a real fuzzy definition of what a block is, i'd say it's anywhere you'd imagine a macro expands out to some implicit 'do form :-)

19:33 cemerick: tpope: just 2 spaces everywhere is the only sane thing, if you were looking for easy opionions

19:33 technomancy: docs for that macro are here: https://github.com/technomancy/clojure-mode/blob/master/clojure-mode.el#L630

19:33 bbloom: or something that is the spiritial equivilent of a 'do, like the top level logical conjunction in core.logic

19:33 tpope: cemerick: I like that but clearly it's not the norm :)

19:33 cemerick: macro-or-not is not a solvable problem statically

19:33 technomancy: cemerick: it is if you name your macros right =)

19:34 if you want indentation support, name it with-*

19:34 cemerick: oy :-P

19:34 bbloom: personally, i find vimclojure's intenting somewhat annoying

19:34 cemerick: ccw has done away with any kind of special macro indenting support AFAIK. Even ever-present REPLs aren't enough to make it workable.

19:35 tpope: I know enough clojure that maybe, just maybe I'm finally up for the task of muddling through elisp

19:35 bbloom: i'd prefer what cemerick says, just indent 2 spaces if i'm inside an unclosed block and i'll line it up myself beyond that

19:35 brehaut: i just watched dnolen's clojure exchange presentation. i really want an excuse to use core.logic

19:35 technomancy: tpope: I think the docstring should give you all you need to know

19:35 hopefully you don't have to read the implementation

19:35 cemerick: bbloom: anything that isn't automatic is too irritating to bother with

19:36 tpope: technomancy: "addition to those that are built-in" <-- do I need a list of built-in ones?

19:36 bbloom: i abuse the hell out of block selection to insert and remove whitespace in a very percise way before/after/within lines

19:36 technomancy: tpope: there are two types of exceptions to the regular indent rules: 0) always indent the second line with 2 spaces, or 1) treat the first N args as special and line up everything beyond those according to traditional rules

19:37 0) in this case is for those forms marked with 'defun and 1) is for those marked with an integer

19:37 amalloy: technomancy: i can't think of any instances of (1)

19:37 bbloom: amalloy: deftype and defrecord?

19:37 proxy?

19:37 clojurebot: proxy is not reify

19:38 bbloom: any conditional or binding form

19:38 technomancy: amalloy: in practice they're usually indented like 0) unless you put newlines in funny places

19:38 maybe 0) is all you need

19:38 I'm not really sure why it's implemented that way in clojure-mode

19:38 bbloom: there is a difference between reformat and indent while editing

19:38 technomancy: amalloy: wait didn't you submit some indentation patches to this? you probably know more about the implementation than I do

19:38 bbloom: if you're going to reflow a form, you need to know how many args to preserve on a line

19:39 if you're just looking for "how many spaces should i insert when you press <cr>"

19:39 then the answer is "generally: 2"

19:39 amalloy: technomancy: well, i submitted a way to ask for a given symbol to be indented like (0)

19:39 i still don't understand the indent specification for deftype and friends

19:39 bbloom: deftype, reify, and proxy are neither (0) nor (1)

19:40 technomancy: amalloy: me neither woooooo

19:40 bbloom: maybe i misunderstood technomancy's definitions

19:40 technomancy: maybe I misdefined them

19:41 bbloom: i'm thinking (do x y z) would put x y and z on new lines indented 2 spaces, but (let [x 1] y z) would leave [x 1] on the first line

19:41 tpope: how much of this is absolute and how much is opinion?

19:41 bbloom I get the impression you're trying to challenge the existing conventions

19:42 amalloy: bbloom: https://www.refheap.com/paste/7479

19:42 bbloom: tpope: that's not my intention

19:42 technomancy: tpope: bonus points if you don't include a way to change indentation from two spaces

19:42 amalloy: oh, except i labeled them wrong like an idiot

19:42 seangrove: Is there a concise way of sorting a map on a key, and then if that key is equal in both args, sorting on a secondary key?

19:43 Well, sorting a vector or maps, sorry

19:43 bbloom: seangrove: vectors are comparable, so you can sort on a function of each element, where that function returns a vector in order of keys to sort by

19:43 use juxt :-)

19:43 technomancy: oh man beat me to it

19:44 tpope: technomancy: a tricky one. overwhelming dogma of indent files that ship with vim is "that's up to the user"

19:44 callen: does anyone know what the current state of sourcemaps in ClojureScript are? http://dev.clojure.org/display/design/Source+Maps this seems old and not very encouraging.

19:44 amalloy: well, juxt doesn't let you be lazy about not calling (g a) if (= (f a) (f b))

19:44 seangrove: Will try juxt I support

19:44 technomancy: tpope: actually as long as they can't turn on tab indentation I'm good

19:44 amalloy: juxt would be the right answer in haskell, i guess. in clojure it's pretty good and fine most of the time

19:44 tpope: do people actually do this?

19:45 bbloom: amalloy: is there a short circuiting solution?

19:45 technomancy: tpope: I guess I mostly only see it in old code

19:45 cemerick: tpope: I think I found the fix to #11

19:45 tpope: cemerick: :D

19:45 cemerick: tricky little bastard

19:45 amalloy: bbloom: sure. nothing built in, but it's easy to write

19:45 bbloom: amalloy: yeah, i was asking about built in

19:45 seangrove: amalloy: There will only be a few items in the vector ~100 at most

19:45 cemerick: tpope: I need to put together some good tests to verify and such, but an 0.2.0-RC2 should be ready for you tomorrow morning.

19:45 tpope: bbloom: ^

19:46 bbloom: excellent.

19:46 tpope: I guess I'll need to add some sort of detection to foreplay to only use sessions if this bug doesn't exist

19:46 cemerick: tpope: Thank you very much for the report. In the end, it *was* provoked by the different connections. Hopefully _now_ we can say that sessions and connections/transports are properly separated.

19:47 tpope: bbloom et al: can you keep an eye out for concrete examples of indent failures with the VimClojure stuff?

19:47 cemerick: All the existing (popular) nREPL clients maintain mostly-persistent connections, which explains why this bugger hid for so long.

19:47 tpope: I won't be solving that tonight

19:48 cemerick: guess you didn't plan on an editor with one foot still in the seventies :D

19:48 bbloom: tpope: i might be beyond help there. my brain adjusts to indent annoyances until it's transparent to me

19:48 cemerick: tpope: always using sessions is highly recommended. Later futures (like subscribing to System/out and System/err) will end up streaming on a per-session basis.

19:48 tpope: bbloom: I see stuff that feels wrong, but it's hard for me to say *why* it's wrong

19:48 bbloom: don't knock the 70s. there's some damn good 70s tech :-)

19:48 cemerick: tpope: quite the opposite; I've been trying to design around probable issues around vim et al. from the beginning

19:49 Thus the (almost fulfilled) disconnect between transports/connections and sessions.

19:49 tpope: cemerick: well I can't really turn them on if it's connected to an nrepl with this bug

19:49 cemerick: right

19:49 well, you could just say "requires nREPL 0.2.0" :-P

19:50 tpope: maybe a year from now I cna

19:50 cemerick: oh?

19:50 tpope: I mean I don't want to require an RC that was released 3 hours ago

19:50 cemerick: no one's using anything before 0.2.0-beta something

19:51 tpope: yeah but beta something has the bug

19:51 bbloom: does lein auto self update? and does it bring new releases of nrepl with it?

19:51 cemerick: they'll all roll forward once lein 2 is finalized, I promise you

19:51 bbloom: no, and yes

19:51 tpope: okay

19:51 well after lein 2 is finalized I can do that

19:51 cemerick: bbl

19:51 sounds very reasonable

19:52 tpope: as it stands I still support lein 1.7

19:52 seangrove: Wow, juxt worked wonderfully

19:53 (sort-by (juxt #(or (:order %) 999) :source :name) (flatten field-descriptions))

19:53 bbloom: (inc juxt)

19:53 lazybot: ⇒ 3

19:53 technomancy: seangrove: you don't need or there; just do #(:order % 999)

19:53 bbloom: i just keep finding new uses for juxt, love that little function

19:54 seangrove: technomancy: That's why I pasted it, thought there might be something nifty like that :)

19:54 amalloy: also jesus, flatten? that's like 100% to be wrong

19:55 brehaut: is there a kibit rule for flatten?

19:55 amalloy: brehaut: it just reformats your hard drive

19:55 technomancy: System/exit

19:55 brehaut: ahaha

19:55 literally lolling

19:56 seangrove: amalloy: Mind explaining a bit?

19:56 brehaut: ~flatten

19:56 clojurebot: flatten is rarely the right answer. Suppose you need to use a list as your "base type", for example. Usually you only want to flatten a single level, and in that case you're better off with concat. Or, better still, use mapcat to produce a sequence that's shaped right to begin with.

19:56 hcumberd`: is there any lib in clojure to help with file locking?

19:57 seangrove: I'll re-examine it and see if I can get rid of flatten

19:57 bbloom: hcumberd`: it would be nice if there was an https://github.com/liebke/avout type thing for that….

19:58 in fact, avout probably could be extended to work on a normal posix file system

20:51 cemerick_away: tpope: wow, 1.7?

20:51 technomancy: do you have usage stats at all between versions?

20:53 tpope: cemerick: the second thing I did when trying out clojure was brew install leiningen. I can't be the only person to make that mistake

20:54 cemerick: heh

20:54 Probably not _only_, but...

20:54 ;-)

20:54 tpope: cemerick: and really, I didn't have to go out of my way to support it

20:55 cemerick: fair enough

20:55 tpope: I just have to make sure I say "Lein 2" when talking about target/repl-port

20:55 bbloom: what's blocking the lein 2 release? i seem to recall it being something small

20:55 cemerick: tpope: are you planning on supporting remote connections and such?

20:56 tpope: cemerick: it should already work

20:56 I don't have any remote servers running clojure yet

20:56 bbloom: cemerick: i'll probably figure out how to get clojurescript working with it soon

20:56 hiredman: bbloom: the final release of lein 2 will only pull from the signed clojars releases by default, but they are not many signed clojars releases

20:57 bbloom: hiredman: ouch. that's gonna take forever to evolve, is it not?

20:57 hiredman: dunno

20:58 tpope: bbloom: I made the repl interface small and well defined, so hopefully it will be pretty easy

20:58 bbloom: tpope: cool. i'll trade you more Clojure help for VimL help :_)

20:58 tpope: cemerick: how do people usually do that. ssh tunneling? I don't see any authentication

20:59 hiredman: tpope: I dunno that people usually do that, nrepl has an http transport and you can drop cemerick's http auth stuff (friend) in front of that

21:00 cemerick: tpope: what hiredman said. nREPL is channel-agnostic. HTTPS + Basic auth is easy mode.

21:01 tpope: HTTP was the first thing I tried and I couldn't get it to work

21:01 cemerick: I've been meaning to get a JMX transport wired up, eventually.

21:01 hiredman: cemerick: that would be neat

21:01 tpope: or rather, I couldn't find enough documentation to convince me that was a viable path

21:02 cemerick: tpope: see https://github.com/cemerick/drawbridge

21:02 technomancy did a writeup on using it on heroku, which might be of some interest https://devcenter.heroku.com/articles/debugging-clojure

21:02 hiredman: the thing to watch out for are the middleware requirements

21:02 cemerick: Though, heroku's lack of session-affinity is a bit of a bummer.

21:03 tpope: cemerick: "Other nREPL transports are provided by the community" in the README links to https://github.com/clojure/tools.nrepl/wiki/Extensions

21:04 I took that very literally

21:04 cemerick: jeez

21:04 I didn't realize that changing the title changed the URL :-/

21:04 bbloom: cemerick: what is the state of piggyback?

21:05 piggieback*

21:05 tpope: cemerick: is drawbridge simple enough that I could talk to it with curl?

21:05 brehaut: oh now i want to be insane and implement an xmlrpc nrepl transport

21:05 cemerick: tpope: fixed

21:05 tpope: great

21:05 * brehaut slaps himself

21:06 hiredman: you can talk to it via curl, data is json encoded though

21:07 (I've used curl to verify that drawbridge was working)

21:07 bbloom: i guess i need to wait for the sessions fix to use piggieback

21:07 cemerick: tpope: yes

21:07 bbloom: and, yes

21:07 tpope: I can actually parse json in VimL with eval()

21:07 cemerick: piggieback is solid AFAICT

21:08 hiredman: tpope: sounds gross

21:08 bbloom: cemerick: glad to hear it. is there anything that could move upstream to the cljs repl protocols and stuff?

21:08 cemerick: bbloom: much of it really should be in cljs already, w.r.t. eliminating the REPL's assumption about being on stdin/out

21:08 tpope: a drawbridge adapter should be pretty easy to implement

21:08 bbloom: cemerick: yeah, that's what i was asking about. i'd be happy to contribute patches to cljs to get it there

21:09 i want to get foreplay working as smoothly with cljs as it does with clj

21:09 tpope: is there a good oss project with drawbridge set up I can play with?

21:10 cemerick: bbloom: There's not a lot of code, and I commented as I went along and hit pain points. ;-) https://github.com/cemerick/piggieback/blob/master/src/cemerick/piggieback.clj

21:10 tpope: I mean I could roll my own, but exposure to another code base is a win for me learning

21:10 bbloom: cemerick: yeah, skimming it now

21:10 cemerick: Much of it would be super-simple to fix, if one has cljs commit.

21:10 bbloom: i want to press cpp and have an expression evaluated like magic and not have to care about if it's a clj or a cljs form :-)

21:11 cemerick: I just didn't have the energy to produce tickets and patches.

21:11 bbloom: i don't have cljs commit, but dnolen tends to at least look at my patches :-)

21:11 cemerick: bbloom: exactly what piggieback does; same with load-file, interrupt, etc

21:12 amalloy: being in #clojure is practically like having cljs commit rights, given dnolen exists

21:12 tpope: bbloom: me too

21:12 cemerick: Yeah, I've never had any problem getting patches in. I just couldn't bring myself to spend more time on it, once I got the thing working.

21:12 bbloom: fair enough

21:12 cemerick: mental budget blown, and all that

21:13 I doubt I'll ever know cljs internals the way I grok Clojure.

21:13 bbloom: cljs' internals are a mix of messy/hacky/dammit-it-works and "oh, that's nice"

21:14 analyzer and compiler, despite not being sliced up into smaller passes, are actually quite understandable

21:14 it's all the rhino and closure and module system gunk that leaves me scratching my head

21:14 cemerick: Yeah, it's always the interop bits that I gloss over on.

21:15 right

21:15 And the weird node bits that poke through here and there

21:15 bbloom: heh

21:15 * cemerick <3's node

21:16 bbloom: but now that there are a bunch of parties interested in self hosting the cljs compiler (such as light table and other dev tools), there may be more pressure to decouple from the JVM

21:16 which will surely yield cleaner protocols for those messy bits

21:16 the biggest wrinkle in this is our dependence on the google compiler for performance of the resulting targeted code

21:17 but that's not strictly necessary for non-optimized code generation

21:17 and ultimately we want clojure-specific optimizations, such that we can apply them to any backend

21:21 sshack: There aren't any kernel density estimators (statistics) done in clojure are there?

21:21 cemerick: I'm a blissful user of cljs.

21:22 Need that easy dial turned up to 11. :-P

21:23 bbloom: cemerick: luckily, most clojure code ports to cljs pretty seamlessly

21:23 right now i'm working primarily in clojure with a very small runtime component in cljs

21:24 cemerick: hrmph

21:24 bbloom: since all the data structures are printable/readable, i just forward them across the wire to render in the browser :-)

21:24 perf is obviously shit this way, since i need to serialize and deserialize application state on every change

21:24 but testing is sooo much easier

21:24 cemerick: That's been my biggest problem: keeping libs portable

21:25 Even using crossovers, cljx, everything I can get my hands on.

21:25 bbloom: yeaaaaah....

21:25 cemerick: So many little twiddly silly differences.

21:25 bbloom: there's been some talk of feature expressions

21:25 cemerick: Sounds like dnolen wants them bad, so that's something.

21:25 They're going to lead to a lot of *really* messy codebases.

21:25 bbloom: yeah, he's been trying to maintain core.logic on clj and cljs at the same time

21:25 it's tricky

21:26 well that's the big problem: people are gonna use feature expressions like C preprocessor macros

21:26 :-/

21:26 cemerick: well, it's sorta inevitable

21:26 ever see some super-portable CL?

21:26 :-O

21:26 bbloom: heh, well yeah, i mean that's what people did with C preprocessor: they ported software

21:27 cemerick: I've started to wonder if portability really is a lost cause.

21:27 bbloom: and then people were like "this is ugly" so people have crazy tools that take the preprocessor and REMOVE IT and generate a patch file

21:27 haha

21:28 cemerick: The semantics around hosty bits may always conspire against us.

21:28 bbloom: there are a bunch of java-isms that people use a lot that we need to wrap in the standard lib

21:28 cemerick: esp. numerics.

21:28 bbloom: … like "throw"

21:28 cemerick: hah

21:28 bbloom: i don't even want to think about numerics :-P

21:28 cemerick: That was my first custom cljx/kibit rule I wrote

21:29 bbloom: (throw (Exception. ?e)) -> (throw (Error. ?e))

21:29 yeah?

21:30 cemerick: (try ... (catch AnyJVMExceptionType e ...)) => (try ... (catch js/Error e ...))

21:30 and yeah, the throw, too

21:30 bbloom: better yet, do: (try ... (catch* e ...))

21:31 cemerick: oh really!

21:31 When did that become kosher?

21:31 bbloom: it's not kosher.

21:31 :-P

21:31 cemerick: heh

21:31 You're not going to troll me into looking at whatever `try` emits :-P

21:32 Or are you proposing a variant of try on the fly?

21:32 bbloom: oh, i might be wrong, it's not catch* it's try*

21:32 catch isn't really a form, it's processed by try

21:33 https://github.com/clojure/clojurescript/blob/master/src/clj/cljs/core.clj#L874

21:33 (try* … (catch e …))

21:33 technomancy: cemerick: download stats are at https://github.com/technomancy/leiningen/downloads but don't really include timestamps unfortunately

21:33 I'd pay a fair bit to get raw logs out of github =\

21:34 I should start timestamping snapshots of those numbers though

21:34 cemerick: technomancy: huh, strong numbers for 1.7.1

21:34 bbloom: technomancy: yeah, and they got rid of the traffic graph when the redesigned the graphs

21:35 :-/

21:35 cemerick: ClojureScript sources are the new rickroll

21:36 bbloom: cemerick: i have a tendency to force people to look at the source any chance i get :-)

21:36 tpope: cemerick: as someone who was confused by the state of affairs with the preview releases, I am unsurprised by this

21:36 bbloom: quite a few junior devs have thanked me for it years later ;-)

21:37 tpope: it took me a long while to figure out that using the preview was the preferred course of action

21:38 cemerick: tpope: I never had any use for 1.x, so I've never known anything else.

21:39 technomancy & co. are relentless though, so it was probably only a matter of time

21:39 tpope: wait how long has 2.x been a thing?

21:40 cemerick: Development started on it more than a year ago

21:40 tpope: I expected worse actually

21:40 cemerick: worse?

21:40 clojurebot: worse is slurp

21:41 cemerick: clojurebot: that's dumb

21:41 clojurebot: I don't understand.

21:41 gfredericks: clojurebot: that is dumb

21:41 clojurebot: c'est bon!

21:41 tpope: well you've been doing clojure for well over a year, no?

21:41 bbloom: ~that

21:41 clojurebot: that is a completely unrelated, but entirely useful link

21:41 bbloom: ~dumb

21:41 clojurebot: dumb is that

21:41 bbloom: heh.

21:42 tpope: for a brief moment I failed to consider that you may have been using some tool other than lein

21:42 *shrug*

21:43 bbloom: tpope: there's a bunch of shell scripts in the clojurescript tree… that's what i was using :-P

21:43 cemerick: tpope: Started in 2008

21:43 bbloom: don't get me started :-P

21:55 tomoj: bbloom: any guesses what that more fundamental abstraction (than INotify) might look like as a protocol?

21:55 (or protocols..)

21:55 bbloom: tomoj: not sure… i suspect i'd have to study erlang's OTP

22:00 tomoj: you're interested in push sequences too, right?

22:00 tomoj: are you suggesting it replace INotify? or just that there's this other thing we need to think about too?

22:00 bbloom: well i'm not sure INotify is sufficient

22:01 but there are definitely other things to consider too

22:01 considering that there is no unregister… i worry about resource leaks with INotify

22:01 tomoj: oh yeah, me too

22:01 bbloom: but there are other concepts to consider

22:02 tomoj: but for the one example I had in mind, I realized there is no resource leak

22:02 bbloom: process links/trees, etc

22:02 executors

22:02 pools

22:02 schedulers

22:02 tomoj: (specifically (any a b) where one of a and b is never realized, or is realized much later than the other)

22:02 bbloom: queues

22:02 tomoj: does IScheduler satisfy your process tree concerns?

22:02 bbloom: composite futures, processes, sequences, etc introduce all sorts of interesting riples

22:03 where is IScheduler?

22:03 tomoj: Rx

22:04 bbloom: looking at it now

22:04 this is a scheduler in the cron sense

22:04 i'm talking about a scheduler in the kernel sense

22:04 tomoj: well, ignore the complection with time stuff

22:05 without that IScheduler looks something like executors I think

22:05 (in one video the Rx team conveniently tells us that IScheduler is three different things stuck together :D)

22:05 bbloom: so convenient :-P

22:06 i'm looking at http://msdn.microsoft.com/en-us/library/dd460693(v=vs.100).aspx now

22:06 task schedulers are different than reactive schedulers

22:06 there are also "partitioners"

22:07 you see rich's talk about reducers? somebody asks when reducers stops breaking it down into smaller parts to be executed sequentially per part?

22:07 rich says that he picks an arbitrary configurable threshold and that somebody else can figure that problem out :-P

22:08 well that whole partitioning/load balancing/whatever thing is a tough problem too

22:08 there's lots of stuff

22:09 i guess my main thought was that we're putting the cart before the horse by focusing on listenable futures without the underlying bits and pieces for multiprocessing

22:10 i recall Erik Meijer (architect of Rx) saying that the first version of Rx was stand alone and they rewrote it on top of Px and everything got much simpler and faster

22:10 tomoj: I think I agree - there shouldn't be an ExecutorService param in INotify

22:10 but getting rid of it requires answering some of your questions (if I understand them)

22:10 ...luckily I mostly care about cljs

22:12 bbloom: dopey single threaded javascript :-/

22:12 anyway, concurrency and parallelism have many design concerns in common

22:13 i think if you design a solution for a concurrent AND parallel environment, it's reasonably straight forward to make it run in a concurrent but NOT parallel environment

22:13 you just pretend that there is 1 CPU

22:13 and no threading :-P

22:13 probably can optimize a bunch of things, but i would design in java land and port to javascript for Px and Rx type things

22:14 as long as you never call (Thread. X) in client code and only ever enqueue work, then it should abstract cleanly

22:15 the really hairy bit comes in when you consider blocking…. suddenly you need a CPS transform :-P

22:21 tomoj: I have the cps transform bucketed into the "easy" side — but haven't started working on it yet :(

22:21 bbloom: tomoj: feel free to fork and contribute to mine: https://github.com/brandonbloom/cljs-cps/

22:22 i lost all my momentum on it while i waited to get some fixes into cljs that i needed

22:22 all the fixes are in now, but i haven't gone back to it yet

22:28 holo: i have: "No method in multimethod 'to-source' for dispatch value: class clojure.core.match.WildcardPattern" when compiling on heroku. i don't have this problem in my local machine. i can't understand why this behaviour is different

22:40 tomoj: any reason not to implement the cps as a normal macro instead of on analyzer output?

22:41 eventually want it on the jvm too, and likely before there is an analyzer there like cljs's

22:41 bbloom: tomoj: so the analyzer currently whole bunch of things all in one pass

22:41 i really just need the "parse" piece of it

22:41 consider for example try* https://github.com/brandonbloom/cljs-cps/blob/master/src/cps.clj#L157

22:42 it's actually a non trivial piece of logic to parse a try/catch/finally block

22:42 similar story with fn: https://github.com/brandonbloom/cljs-cps/blob/master/src/cps.clj#L200

22:42 tomoj: yeah, I see. and I think macroexpansion may be a problem on the jvm, if some macros use &env

22:42 bbloom: but yeah, was gonna say: macro expansion is the big part

22:43 if you have macros that themselves use the environment, you can't do macro expansion

22:43 in theory, you could just macroexpand up front, but the analyzer does that for you

22:43 i don't need any tag inference or any of the other fancier bits in the analyzer

22:44 but also the :children model makes it easy to walk the AST and search for serious/non-trivial expression

22:46 that ANF transform is reasonably robust, so you can see how nice an AST transform can be

22:46 the CPS part isn't finished, but primarily because i was still designing IContinuation, etc

22:50 the ANF transform makes the :default case for the CPS transform pretty nice: https://github.com/brandonbloom/cljs-cps/blob/master/src/cps.clj#L226

22:50 since you can trust all of the serious expressions have already been hoisted out into a :let form

22:59 i'm interested in breaking up the clojure analyzer dramatically

22:59 should be able to opt into or out of macro expansion

23:00 for example

23:00 what if codeq just wants to see how often a macro is used?

23:00 right now there isn't a way since the macros are expanded upon analysis

23:01 akhudek: does anyone know why clojure would be trying to compile an installed jar instead of it's checkout version?

23:02 the classpath looks right: the checkout source comes before the maven copy

23:11 cemerick: tpope: are you set up to be able to test against a SNAPSHOT rev of nREPL? I'd love to get confirmation from you on the fix before cutting -RC2

23:11 tomoj: that by itself seems like a potentially easy change, since macroexpand-1 is only called in analyze-seq ? maybe I underestimate

23:12 tpope: cemerick: I think so. I've never done it before

23:12 pendlepants: if I've got a list like (1 2 3 4 5 6), is there a function that returns ((1 2) (3 4) (5 6))?

23:12 cemerick: tpope: add this to your project.clj:

23:12 :repositories {"sonatype-oss-public" "https://oss.sonatype.org/content/groups/public/&quot;}

23:13 tpope: then change the nREPL version to 0.2.0-SNAPSHOT

23:15 tpope: cemerick: first thing I notice is "nREPL server started on port 57778" (from lein?) is now printed after the prompt

23:16 cemerick: it works!

23:16 cemerick: tpope: the printing of stuff like that (prompt, server started on X, etc) is all up to the clients (in this case, reply/lein)

23:17 tpope: awesome

23:17 tpope: yeah that's what I figured

23:17 cemerick: Thanks again for the report! Hope I didn't hang you up too much

23:17 tpope: no it's all good

23:17 cemerick: I hope I can get to giving foreplay a try soon.

23:18 tpope: who would I ping about the prompt thing? technomancy?

23:18 :D

23:18 cemerick: tpope: trptcolin, mostly

23:19 He's only occasionally on irc; probably best to open an issue on the reply project

23:19 tpope: this is just from running `lein repl`?

23:19 tpope: cemerick: yep. That string appears in the source to leiningen

23:20 cemerick: well, in that case, there's lots of people you can bother :-P

23:20 tpope: if I blame the line of code it goes back to trptcolin :P

23:21 cemerick: it was printed *before* the prompt? Seems nigh-impossible, since that println happens before reply is connected to the REPL.

23:21 tpope: he's mostly to blame for the lein repl task these days ;-)

23:22 tpope: do you mind a general vim Q?

23:22 tpope: cemerick: it looks like user=> nREPL server started on port 54346

23:22 cemerick: not at all

23:22 cemerick: yuck

23:22 raciness around System/out?

23:23 tpope: have you ever used eclim successfully, or do you know of anyone who has/does?

23:23 tpope: it feels like there's a split second between the prompt and the port announcement

23:23 cemerick: I haven't, but I get bug reports against other plugins from people who apparently have

23:24 cemerick: interesting

23:24 I'd love to use it, but it doesn't support macvim :-((((

23:24 good to know that it's apparently viable

23:24 tpope: curious that macvim isn't supported

23:25 I have no idea if these people run on a mac at all

23:28 cemerick: tpope: Not surprising, given the ways swt and any-other-ui-toolkit interact.

23:28 tpope: my vague understanding was that eclim worked by talking to an external eclipse instance, not by embedding in it

23:28 cemerick: Killer vim Clojure support + the promise of eclim working well may be just another little push to get away from OS X for work.

23:28 tpope: but it's been years since I looked

23:29 cemerick: it can do both, apparently

23:29 rbxbx: cemerick what do those have to do with OS X?

23:30 cemerick: rbxbx: You just missed it. eclim apparently can't embed macvim into eclipse, but gvim on linux or windows is fine.

23:31 rbxbx: hmm

23:32 tpope: cemerick: do you get much out of eclipse for clojure? or do you want it mostly for java?

23:33 cemerick: tpope: The Clojure support is roughly on par with e.g. SLIME IMO. Different tradeoffs. I've been contributing to ccw for years now, so...

23:33 Laurent would be so disappointed if I started using vim for clojure :-P

23:34 Actually, I'd still use ccw's REPL support; it's just the editor that I'd like to swap out

23:34 But, yes, having that JVM stuff underneath you is the motivating factor. Java-the-language capabilities, debugger, profiler, etc etc etc

23:34 tpope: hmm, ok

23:35 rbxbx: tpope: it looks like eclim works in two ways, either a headless instance that vim can talk to, or (on unix & windoze) embedding a vim editor inside of eclipse itself

23:35 tpope: (though admittedly until this talk of embedding I was only familiar with the former)

23:35 cemerick: rbxbx: funny, I can't get to their page at all now

23:35 tpope: cemerick: yeah that's what I just tried

23:35 I'm a little curious to try it

23:35 rbxbx: cemerick: had to use cached & text only

23:35 cemerick: ah

23:35 tpope: I *am* sitting in front of a linux box currently

23:36 * cemerick goes off to buy windows 8 :-P

23:36 rbxbx: I tried to use ccw without prior eclipse experience and just found myself overwhelmed and dumbfounded.

23:36 Raynes: Eclipse has that effect on people.


23:37 frozenlock: How does one close an NREPL buffer and kill the process at the same time? (Like slime did with swank...)

23:37 tpope: my gut has been screaming DON'T DO IT and you just explained why

23:37 rbxbx: Raynes: yeah. All the wizards in the world couldn't save me

23:38 cemerick: All these geeks managing to browse the web with all its funny buttons, links, and geegaws, but then get flummoxed by a systematic, consistent UI

23:38 rbxbx: tpope: yeah. You'll have to lose your sense of smugness toward IDE users after their primitive tooling destroying you in minutes.

23:38 tpope: it's more robust than that :)

23:39 rbxbx: ha

23:39 Raynes: Systematic like cancer, consistent like Hitler.

23:40 rbxbx: damn.

23:40 bbloom: tomoj: simply conditionally executing macroexpand-1 in analyze-seq would yield yet another dynamic configuration variable

23:40 rbxbx: cemerick: I'm sure had I grown up on IDEs or sat with a proficient user of one it'd be a non-issue

23:40 bbloom: but macroexpansion is just a basic case

23:41 tomoj: i want to add other passes, stuff like what's going on inside of GClosure: all your typical compiler stuff. constant folding, closure lifting, etc

23:41 rbxbx: cemerick: xcode and squeak do the same thing to me, so it's not just eclipse

23:41 bbloom: tomoj: so a pluggable pass pipeline is desirable

23:41 cemerick: rbxbx: *shrug* I'm convinced it's a social-signaling thing amongst certain classes of programmers.

23:42 textmode good/hip/cool/efficient, GUI bad/gauche/dilbert

23:42 tpope: rbxbx I seem to recall you basically became a web developer because you couldn't figure out how to pirate visual studio

23:43 rbxbx: tpope this is true. And I knew how to, but my AOL connection wouldn't stay alive long enough to download 6 megs :(

23:43 cemerick: Oh, pleeeze let that be true!

23:43 tpope: it's pretty much my backstory too

23:43 rbxbx: It was just preordained that I not be an IDE user

23:43 cemerick: you just needed to find the right AOL group that had the bits split across 6 .pk files.

23:43 bbloom: heh. that is awesome

23:44 cemerick: gawd, now I feel old

23:45 rbxbx: cemerick: to address your previous point though, there are swaths of languages that don't benefit much from the tooling provided by IDEs... and a lot of those languages are more "hackery" than "enterprisey"... so... the issues maybe get conflated?

23:45 * rbxbx runs

23:45 bbloom: if you plot knowledge against productivity, you get two very different plots with or with access to the internet

23:45 with the internet, your knowledge grows faster, but has this sine-wave format to it where you learn backwards wrong shit from the internet

23:45 and then that sine wave is amplified times a million along the productivity axis

23:46 in part because you spend too much time reading, but mostly b/c you fall down a whole into reddit

23:46 … or irc....

23:46 s/whole/hole

23:46 rbxbx: some people fall into a whole with reddit as well ;)

23:46 bbloom: sometimes i intentionally disconnect my internet connection when i'm working :-)

23:47 cemerick: rbxbx: You might be right, though that's changing significantly.

23:47 rbxbx: bbloom I've heard of many doing that... I've tried but found it difficult. Especially when working with a team.

23:47 cemerick: Text editor + terminal sorta sucks for Clojure, for example. Racket and factor have been producing killer environments for years. None enterprisey at all, at least in the pejorative sense.

23:47 bbloom: rbxbx: the trick with a team is to negotiate quiet hours

23:48 rbxbx: cemerick: s/enterprisey/academicy

23:48 ;)

23:48 bbloom: "monday through wednesday, i am not going to check my email or respond to low priority interrupts between 1 and 6pm"

23:48 cemerick: rbxbx: bah

23:49 rbxbx: cemerick: I don't know what I'm talking about. You should likely ignore me.

23:49 bbloom: cemerick: tpope just halved the suck-factor of my text editor + terminal workflow

23:49 tpope: rbxbx, bbloom: counterpoint: http://weblog.therealadam.com/2012/12/08/focus-mode-considered-harmful/

23:50 technomancy: cemerick: it's changing because it's only recently that you've been able to perform interactive development on an IDE using itself maybe?

23:50 cemerick: rbxbx: nah, don't discount like that

23:50 bbloom: tpope: yeah, that too. i'm trying something like that now

23:50 rbxbx: bbloom tpope +1 to that. My workflow was janky at best.

23:50 technomancy: s/IDE/Java IDE/; obviously most things said about IDEs don't apply to smalltalk

23:51 bbloom: trying to "release" something every week

23:51 cemerick: bbloom: well, it's getting into semantics at some point. At which point is your text editor + terminal + JDI wire debugger + etc become an IDE...

23:51 bbloom: component, project, bug fixes, blog post

23:51 Raynes: technomancy: But smalltalk doesn't have an IDE.

23:51 bbloom: something like that

23:51 technomancy: Raynes: smalltalk *is* an IDE

23:51 Raynes: technomancy: It has its own dimension and planet and such.

23:51 cemerick: technomancy: Right; good tools are good, regardless of labels

23:51 Raynes: technomancy: You've got to give me time to finish being funny before you take me seriously brow.

23:52 technomancy: Raynes: brb switching to qwerty

23:52 * rbxbx waits for the joke around brows

23:52 cemerick: i.e. if we could all use something like Dr. Racket for Clojure, I'd be surprised if many among us stuck with vim/emacs/ccw/whatever

23:53 rbxbx: cemerick: old tools/habits/muscle-memory die hard, not to mention portability.

23:53 technomancy: cemerick: well, to a degree good tooling requires interactive development. back when you had to use Java to extend Eclipse, it was a lot less fun and productive; you would experiment less

23:53 bbloom: cemerick: i dunno, i don't think i'll ever leave vim unless i leave unix behind with it…

23:53 cemerick: technomancy: believe me, extending eclipse with anything other than Java is still full of suck

23:53 technomancy: oh =(

23:53 Raynes: cemerick: I'd be extremely surprised if a large portion switched.

23:54 technomancy: I thought ccw was leveled up beyond that by now

23:54 cemerick: technomancy: We do it with Clojure, but the API vocabulary overhead is *huge*

23:54 It's probably a 50/50 split now

23:54 technomancy: ah, gotcha; because you're supposed to be writing it in a tool that does all kinds of autocomplete stuff, so reducing the surface area isn't a priority?

23:54 bbloom: IDEs, runtimes, and OSes just have too much in common....

23:54 cemerick: Laurent's working on putting userland hooks into it these days, so you can have the equivalent of a .emacs directory for ccw.

23:55 technomancy: Yeah. Your head would fly off if you looked at it.

23:55 bbloom: i worked on visual studio…. let me tell you…people joke that emacs is an operating system…. it's not a joke

23:55 visual studio is a poorly implemented operating system built on top of windows….

23:55 cemerick: Raynes: That'd be shocking to me. Dr. Racket blows the doors off of any Clojure environment around.

23:55 technomancy: the whole "it's not intended to fit in your head" paradigm of development

23:56 Raynes: cemerick: You underestimate how much I like having one environment for everything I use.

23:56 bbloom: I second what Raynes says. i don't only do Clojure. i do like 10 other languages in any given week :-P

23:56 consistency counts.

23:56 rbxbx: Raynes you're not the only one, or things like smalltalk-80 wouldn't have existed

23:56 technomancy: cemerick: does Dr. Racket have two IRC clients, three MUAs, a couple jabber clients, version control integration for every VCS imaginable and a few in-editor shells?

23:57 cemerick: Raynes: given the differential between nrepl.el/SLIME and Dr. Racket, that's like saying you like carrying one saw for all of your carpentry needs.

23:57 Raynes: I think you just agreed with me.

23:57 tpope: really need that second irc client huh?

23:57 cemerick: Good luck knocking in that screw, I think was my point. :-P

23:58 Raynes: cemerick: I can use the butt of the saw for that.

23:58 I can also write a screwdriver in elisp if I want.

23:58 cemerick: Damn, I just knew you were going to say that.

23:58 Raynes: *shrug*

23:58 cemerick: You're not going to write Dr. Racket in elisp. Sorry.

23:58 bbloom: see what happens tpope? you show up in here, making everyones lives better, and none of us can resist an editor war. it's terrible.

23:58 :-P

23:58 Raynes: I said I'd write a screwdriver, sir.

23:58 cemerick: Anyway, my broader point was, best tool for the job, etc.

23:58 vsync: gnu emacs lisp or xemacs lisp? ;)

23:58 tpope: editor warmongerer

23:59 rbxbx: bbloom but who knew that war would be between Dr. Racket and Eclipse!

23:59 cemerick: M-x replicator "screwdriver, philips, 6" long, 1/4" wide head"

23:59 rbxbx: ... er, I guess it's emacs now.

23:59 bbloom: rbxbx: us clojurians are ahead of the curve, even on irc flame wars

23:59 vsync: http://anglicancontinuum.blogspot.com/2008/04/die-heretic-scum.html

Logging service provided by n01se.net