#clojure log - Mar 10 2012

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

0:40 alex_baranosky: I just used fnil for the first time in production :)

0:40 * TimMc hifives

0:41 TimMc: o/

0:41 mdeboard: That's tight

0:41 alex_baranosky: hehe

0:41 mdeboard: alex_baranosky: You're not at pycon right? I Could've sworn I saw someone with that name on a nametag today

0:42 alex_baranosky: no, today I was at the North East Scala Symposium in Boston though

0:42 mdeboard: ahh

0:42 alex_baranosky: (assoc foo :bar ((fnil inc 0) some-value))

0:43 ... used inside a swap! function

0:43 TimMc: alex_baranosky: (inc (or some-value 0))

0:45 alex_baranosky: TimMc, nice. Now I wonder which is 'simpler'

0:45 I like the way fnil isolates the variation in the function

0:45 but the or is probably less esoteric

0:52 kibit!!!!

0:54 devn: kibit!!!!!!!

0:54 kibbles and bits.

0:54 mdeboard: slarty blartfast

0:54 devn: paul blart...mall cop

0:55 alex_baranosky: nice the new version of kibit found a few more kibbles and bits in Midje

0:55 devn: nice

0:55 alex_baranosky: do you know of a lib that /isn't/ enlive that people use for scraping?

0:56 im going to probably be strung up for saying this, but i really don't like enlive

0:57 alex_baranosky: devn I don't either

0:57 sorry I dont really

0:58 TimMc: I want to like enlive.

1:02 Cozey: is :dev-dependencies deprecated by :profiles

1:02 ?

1:03 alex_baranosky: think so!

1:05 Cozey: hmm. so howto use swank now? before it should be placed in :dev-dependencies, and now? in :profiles { :dev { :dependencies ... }} or installed by 'lein plugin' ?

1:07 rlb: Is it possible to define a record that supports .close (so you can use it with with-open)?

1:09 arohner: rlb: yes. with-open calls .close on whatever it's passed

1:11 rlb: right, but I didn't think you could define a protocol with a ".foo" method

1:13 I actually don't need a protocol or record specifically; I just was trying to figure out if I could define something that would work with with-open, without resorting to a java class.

1:19 arohner: oh right. Forgot with-open calls methods, but defrecord generates protocol fns. defrecord can inherit from java interfaces

1:19 you could also use reify or proxy

1:23 amalloy: reify. proxy here sounds terrible

1:25 &(with-open [x (reify java.io.Closeable (close [this] (println "closing")))] (println "currently open"))

1:25 lazybot: ⇒ currently open closing nil

1:25 amalloy: rlb: ^

1:26 Cozey: Guys, what emacs package is this guy using for code completion and displaying candidates [and i believe doc strings too!] https://vimeo.com/22798433

1:26 ?

1:28 rlb: Thanks -- I'd looked for Closable, but just realized I was looking in the wrong place.

1:28 s/Closable/Closeable/

1:30 (In this case defrecord is what I want.)

1:57 alex_baranosky: anyone played with datomic at all?

2:21 Raynes: alex_baranosky: I'm waiting for the email back.

3:08 JorgeB: hmm, any idea why my (defroutes ..) would work for a simple GET but throw a 500 on a POST?

3:09 handler returned nil (no response map)

3:09 even tho it's a simple:

3:09 (POST "/search" _

3:09 {:status 200})

3:49 kenneth: hey all

3:49 hey JorgeB

3:51 if anybody wants to review my style / code, this is my first clojure script. works as expected, yay! https://gist.github.com/3b9ca8728fae1ee9b5dd

4:41 * gtuckerkellogg is really confused about whether to use an atom, agent, or ref in a particular circumstance

4:47 ejackson: gtuckerkellogg: what are you trying to do ?

4:48 gtuckerkellogg: there's a largeish data structure that i'm implemeting as a ref to a hashmap

4:48 because *that* part I'm clear on: I need to add members to the hashmap frmo time to time and all threads must know

4:48 ejackson: does that hashmap need to coordinate with another piece of data ?

4:49 gtuckerkellogg: possibly

4:49 enough that for *that* part I'm willing to use a ref

4:49 but what's happening inside the hashmap, to the invidual values that the thing

4:50 ejackson: if you're using assoc / dissoc etc then its the usual structural sharing update stuff

4:50 gtuckerkellogg: this is a non-deterministic algorithm, where individual members of the hashmap are being randomly checked, examined, and occasionally altered

4:50 and I wonder if in practice it would be useful to have the invidual members as atoms

4:50 as well as having the whole thing as a ref

4:51 ejackson: so a ref of atoms ?

4:51 gtuckerkellogg: yes

4:51 ejackson: i think you're probably over thinking

4:51 gtuckerkellogg: maybe so :)

4:52 my (over) thought was that if the data size is relatively large, I don't want to lock up the whole hash when altering a single value

4:52 but perhaps that's not actually a correct understanding of the use of refs

4:52 (i'm new to clojure)

4:52 ejackson: it depends on the number of threads banging on it

4:53 gtuckerkellogg: yes

4:53 i'd eventually imagine the number of threads could grow fairly large

4:53 ejackson: i'd try with just a ref to start, and if it doesn't work, get more complex

4:54 gtuckerkellogg: just ref + alter + assoc / dissoc?

4:56 ejackson: yup

7:24 darq: hello. yesterday i thought that i understand them... macros :) Why can't I use a LSeq as a argument for the macro... i have even written the macro without using other macros to see if i have missed something .. https://refheap.com/paste/1011

7:26 I want to evaluate the value of mlist in vector so i can generate something...

7:29 *the vaule of mlist in the macro

7:30 raek: darq: a macro works much like a function, but unlike a function it does not get its arguments evaluated

7:30 a macro receives the code for the subexpressions

7:31 if you call a macro foo like (foo a b c), it receives the three *symbols* 'a 'b and 'c

7:31 it is what the macro returns that is later evaluated

7:31 darq: raek: and how else can i do what i intendet (loop true a vector and generate code)?

7:32 raek: darq: first you need to know what the "replacement code" should look like.

7:32 from the code I think you wanted something like this:

7:33 (testm abc) should be the same as writing

7:33 (do (println "start") (doseq [el abc] (println el)) (println "stop"))

7:34 this is a little different from your code

7:34 one imporant thing is that the macro cannot know what "abc" will end up evaluating to

7:34 so you need to generate code that iterates, rather than doing the iteration in the macro

7:35 macro expansion only happens once - when the code is compiled

7:37 darq: hmmm... I createad this as an example .. my actual code has "doto" and creates a object from a java lib and then executes the methods on it... now i have 2 static methods on it but the rest i want to generate (i pass a value to the method)..

7:38 and the values are in the vector

7:38 raek: darq: https://refheap.com/paste/1012

7:40 darq: and here's a version that uses syntax-quote: https://refheap.com/paste/1013

7:41 darq: can you show us an example of how a call to the macro and how the generated code should look like?

7:42 darq: raek: thx... but i think that the doseq wont be executed on the object

7:43 raek: https://refheap.com/paste/1014

7:45 raek: darq: what does a call to mknet look like?

7:45 darq: So basically i want to generate code which creates an object and repeadtly executes methods on it ... in this case a neural network with hidden layers

7:45 raek: can the value of 'coll' be known at compile time?

7:45 darq: (mknet 2 2 [2 3])

7:46 raek: do you want to be able to call the macro like (let [a 2, b 2, c [2 3]] (mknet a b c))?

7:46 darq: ;;(mknet inputlayer outputlayer [hiddenlayers])

7:47 yes

7:47 raek: then you can't perform the iteration inside the macro

7:47 it has to be done in the generated code

7:47 do you see the difference?

7:48 darq: yes.. kinda :)

7:48 Can you provide an example?

7:48 raek: think of what happens when you call (mknet a b c)

7:48 (.addLayer (BasicLayer. nil true ~fst)) will become (.addLayer (BasicLayer. nil true a))

7:49 so in that case everything's fine

7:49 but the problem is ~@(for [tcn coll] ...)

7:49 now, the for is executed in the macro at compile time

7:49 what is "coll" bound to here?

7:50 the symbol c!

7:50 darq: to a symbol :)

7:50 raek: so you are trying to do stuff too early

7:50 darq: yep i get it.. How would you do it?

7:51 raek: I would generate a for instead

7:51 but that doesn't fit very well in the doto form, so you need to split it up

7:51 darq: yep thats the problem :)

7:52 * raek prepares a new paste

7:52 raek: also: don't use for here. use doseq

7:53 for does evaluated the body expression unless you iterate through the lazy sequence it generates

7:53 *does not

7:53 *does not evaluate

7:57 darq: https://refheap.com/paste/1015

7:57 then you can take a look at the output of (macroexpand-1 '(mknet a b c))

7:58 sorry, forgot net# as the last expression in the let... https://refheap.com/paste/1016

7:59 doto is a syntactic sugar you can use if your code has a certain shape

8:00 in your case the generated code does not have that shape, so you can't use doto :-)

8:01 now in this case, I don't know if there is any reason to have this as a macro, even

8:02 darq: there: https://refheap.com/paste/1017

8:02 darq: nice :) thx. I was looking at 1015 and figured the last statement missing .. but thx for 1016:)

8:03 :) cool .. But that's not a macro :D

8:03 raek: implementing mknet as a macro (at least in the 1016 form) does not provide any advantages over making it a function

8:03 darq: Thx. again

8:06 Blkt: good day everyone

8:07 could anyone explain me how to programmatically generate functions in Clojure?

8:07 I mean consing

8:08 gtrak: what?

8:08 clojurebot: What is meta

8:08 Blkt: something like Common Lisp's (let ((sexp (* 2 x))) (list 'lambda '(x) sexp))

8:08 gtrak: sounds like a macro

8:09 read about macros, syntax quoting and such

8:09 or you can work on the data at runtime and eval the result

8:10 Blkt: a good resource for Clojure's macros?

8:10 do you know one?

8:10 Iceland_jack: Blkt: On Lisp, it's for Common Lips but it still applies

8:10 gtrak: blog posts, let me find one for you

8:11 Blkt: Iceland_jack: same exact syntax? I know On Lisp, but I needed help with syntax

8:11 gtrak: slightly different behavior in syntax-quote

8:12 Blkt: I see

8:12 thank you

8:12 gtrak: http://techbehindtech.com/2010/09/28/clojure-macros-simplified/

8:13 but if you don't want to use quoting you can just build lists and such

8:14 i haven't gotten far enough myself to know why someone would want to do that though :-)

8:16 Blkt: I'd rather use quoting, I used list previously just to be clear :D

8:16 raek: if you build lists manually, you have to remember to namespace-qualify the symbols

8:19 gtrak: anyone know where I can find explanations of reasoned schemer items? or care to help me with one?

8:22 specificially, chapter 2, item 55, (run* (q) (pairo ()) (eqo #t q)) returns ()? why wouldn't it return #t

8:25 ah, maybe the pairo goal fails since no pair of freshed vars can result in an empty list

8:32 and why is the elephant in the middle sitting in the reflection but actually standing?

8:44 gtuckerkellogg: I'd like to do something like (sorted-map (interleave keys vals)), but it fails.

8:48 jeremyheiler: gtuckerkellog: use apply, (apply sorted-map (interleave keys vals))

8:48 interleave returns a sequence, which you want to use the values as params, not the sequence.

8:50 gtuckerkellogg ^

8:51 gtuckerkellogg: yes?

8:51 clojurebot: yes is is

8:51 gtuckerkellogg: haha

8:51 ahh, thanks jeremyheiler

8:51 jeremyheiler: i originally misspelled your name :-P

8:51 gtuckerkellogg: no wonder i got no beep

8:51 i get a lot of that

8:52 my last name used to be spelled out in an advertising jingle in america, and *still* people misspelled it

8:53 jeremyheiler: haha

9:33 gtuckerkellogg: ,(replace {2 :a 4 :b} (vec '(1 2 3 4)) )

9:33 clojurebot: [1 :a 3 :b]

9:33 gtuckerkellogg: ,(replace { 2 "!"} (vec (clojure.string/split "foo" #"") ))

9:33 clojurebot: ["" "f" "o" "o"]

9:33 gtuckerkellogg: why is that?

9:37 Bronsa: ,(doc replace

9:37 clojurebot: #<ExecutionException java.util.concurrent.ExecutionException: java.lang.RuntimeException: EOF while reading>

9:37 Bronsa: ops.

9:37 ,(doc replace)

9:37 clojurebot: "([smap coll]); Given a map of replacement pairs and a vector/collection, returns a vector/seq with any elements = a key in smap replaced with the corresponding val in smap"

9:38 Bronsa: there is no key equal to "2" in that vector

9:39 gtuckerkellogg: oh i thought it worked on positions in vectors

9:39 my bad

9:39 i had assoc and replace confused

11:17 budu: hi, i'm wondering if there's already a function for the simple pattern for composing predicates

11:17 for example: #(or (pred1? %) (pred2? %))

11:18 sometimes i use an helper i call `orp` like that (orp pred1? pred2?)

11:18 much less annoying to type! ;-)

11:23 devn: ive used it probably a dozen

11:23 whoops

11:33 Frozenlo`: I'm used to do '(1 2 3) when I want a list. However, many clojure examples I saw used instead [1 2 3]. Is is better to use a vector? Faster?

11:33 qbg: No need for the '

11:33 And the contents are evaluated

11:34 TimMc: &[1 2 3 (+ 4 5)] ;; Frozenlock

11:34 lazybot: ⇒ [1 2 3 9]

11:34 TimMc: &'(1 2 3 (+ 4 5)) ;; Frozenlock

11:34 lazybot: ⇒ (1 2 3 (+ 4 5))

11:34 TimMc: &'[1 2 3 (+ 4 5)]

11:34 lazybot: ⇒ [1 2 3 (+ 4 5)]

11:34 Frozenlock: Oh, so it would be the equivalent of (list args) but faster to write?

11:35 qbg: Basically

11:35 By being a vector you also get better random access time

11:36 Frozenlock: So win-win :D

11:37 qbg: Yep

11:39 Scriptor: Frozenlock: You do need the ' to create an actual list

11:39 Frozenlock: &(reverse [1 2 4])

11:39 lazybot: ⇒ (4 2 1)

11:40 Scriptor: Frozenlock: Also, first and conj happen in constant time for lists

11:40 Frozenlock: Input vector --> output list?

11:40 Scriptor: Yes, reverse always returns a list

11:41 Because reversing is the sort of operation lists excel at

11:41 qbg: &(rseq [1 2 4])

11:41 lazybot: ⇒ (4 2 1)

11:42 qbg: No need to do any computation

11:42 Scriptor: Use vectors when you need a random access to an ordered collection

11:45 TimMc: Scriptor: "You do need the ' to create an actual list" <-- only when trying to use the literal syntax

11:46 Frozenlock: If I don't need constant time, should I still use vector, or can I stick with lists?

11:46 Scriptor: If all you're doing with a list is first and conj and so on, use a list

11:47 Is you find yourself accessing the 5th or 100th element a lot, use a vector

11:48 phil_: quit

11:49 TimMc: Frozenlock: There are several performance axes to evaluate collections on: Appending, random access (and capability), insertion, prepending, sequential walking, membership testing/lookup

11:49 Frozenlock: But first, make sure you're in the right part of the Venn diagram: http://www.brainonfire.net/files/seqs-and-colls/main.html

11:50 Frozenlock: Will do immediately

11:58 A little typo here "Nota Bene: Sequences are not implemented as lists, they just act a lot like them and are may be backed by similar data structures." are/may. (If someone here has edit access)

12:00 TimMc: Frozenlock: Pull requests accepted. :-P

12:00 (Thanks.)

12:01 Scriptor: TimMc: Git repo link? ;)

12:12 TimMc: bottom of the page

12:12 I've got the file open in Emacs, though.

12:13 But if you've never done a pull request and want an excuse to experiment with it, be my guest!

12:14 Scriptor: Frozenlock: If you haven't, definitely try it. Github even let's you do everything from the website

12:14 Including editing

12:15 Frozenlock: Oh wait, you were serious?

12:15 TimMc: yup

12:15 Fork, edit, pull request.

12:16 Frozenlock: Awww god. Used it about 5 times, hated each single one of them :P

12:16 TimMc: Pull requests?

12:16 Frozenlock: Might be a good time to learn magit though

12:17 TimMc: or git?

12:17 Frozenlock: git

12:17 TimMc: There's a learning curve for sure.

12:17 Frozenlock: No, Emacs and org mode have learning curves. Git is goddam cliff :P

12:18 TimMc: Nah, you just need the right explanation.

12:18 (And how did "steep learning curve" get the wrong pop psych interpretation, anyhow?)

12:19 (Technically, an *easy* task has a steep learning curve... just not in colloquial usage.)

12:20 Frozenlock: An easy task could be single point, in which case, yes the curve could infinitely steep.

12:20 (But learning curve implies more than a single button)

12:20 Could you point me to the repo in question? I'll do my best not to break everything.

12:21 git reset --hard

12:27 Does `filter' uses the same time when applied to a list / vector? (Given that each item needs to be checked)

12:27 mdeboard: What

12:28 Does it use the same time?

12:28 Frozenlock: Yes

12:28 mdeboard: What do you mean?

12:29 Frozenlock: Is it faster for a list, a vector, or are they equivalent in this case?

12:29 mdeboard: Oh

12:30 I don't know that one, but if item needs to be checked it's surely going to be O(n) for any data structure no

12:31 Frozenlock: Sure, but some may have bigger overhead.

12:31 TimMc: Frozenlock: https://github.com/timmc/seqs-and-colls -- now that I look, I notice that the link back to the repo at the bottom of the page is actually quite non-obvious...

12:32 Frozenlock: TimMc: Oh... generated from "this"... I see :p

12:32 mdeboard: So the short answer is... ?

12:32 qbg: dnolen: Created LOGIC-30 for you on JIRA

12:33 mdeboard: There's no preprocessing done on vector/list data structures

12:38 Frozenlock: TimMc: Did you wrote everything in html?

12:38 TimMc: Frozenlock: The tables are generated by Clojure (with help from Enlive), but the main text is in src/.../html/main.html

12:39 Frozenlock: By the way, this really helped me understand git (not right away, but it gave me tools for future understanding): http://eagain.net/articles/git-for-computer-scientists/

12:40 Also, you won't understand "pull" until you understand that it is an amalgam of fetch, merge, and rebase. :-)

12:43 alex_baranosky: I think pull is actually either fetch and merge, or fetch and rebase, depending on how you have your pulls configured

12:44 by default fetch and merge

12:44 but you can also say `git pull --rebase` to have it rebase instead

12:48 TimMc: Well, it will rebase automatically on fast-forward merges.

12:49 alex_baranosky: ah yes, good point

12:50 but if you use git pull --rebase it will also rebase instead of merging at all

12:53 ssideris_: hello... is anyone maintaining a library that is compatible both with clojure 1.2 and 1.3?

12:53 if yes, how?

12:53 TimMc: ssideris_: Depending on the lib, that can be quite easy.

12:54 ssideris_: TimMc: my question is mainly about how to set up project.clj

12:54 TimMc: Be careful about Integer vs. Long hashing in maps/sets, use :dynamic when necessary on vars, use #^{} metadata syntax...

12:54 ssideris_: https://github.com/timmc/handy/blob/master/project.clj

12:55 That's the lein 1.x approach, using the multi-deps plugin for testing against multiple versions.

12:55 *versions of clojure

12:56 ssideris_: ok that's for testing, and I have something similar in mine

12:57 https://github.com/stathissideris/clarity/blob/master/project.clj

12:58 TimMc: Yeah, I don't know if there's anything else to mess with.

12:58 ssideris_: I think that if I compile my library with 1.3, the jar produced is incompatible with 1.2

12:58 TimMc: You might want to put a :url in your config, by the way (linking back to the repo)

12:58 Ah, why AOT compile, though?

12:59 ssideris_: no reason, just not sure how I can control it

13:00 TimMc: If you change :main to (I think) :repl-init, that might prevent any AOT compilation.

13:00 :main is an AOT trigger

13:00 raek: you can add :skip-aot metadata to the :main symbol, I think

13:00 it's in the leiningen docs

13:00 in the sample project file

13:00 ssideris_: nice, thanks

13:01 I do have an obsolete main somewhere from when I was first starting the library

13:01 I'll get rid of it completely, it's full of crap anyway :-)

13:01 thanks for your help, I'll try and fix it now

13:02 alex_baranosky: ssideris, Midje is compatible with 1.2, 1.2.1, 1.3.0 and the new 1.4 betas

13:02 TimMc: If you do have a true :main ns, you can also use my lein-otf plugin to create a non-AOT uberjar. :-)

13:02 ssideris_: and otf stands for?

13:03 TimMc: On The Fly

13:03 ssideris_: should have guessed...

13:03 TimMc: opposite of "AOT", but not ambiguous like "JIT" is :-P

13:03 ssideris_: thanks, I'll check it out

13:03 TimMc: It doesn't do jars yet, only uberjars.

13:04 tmciver: TimMc: </end-of-shameless-plug> ;)

13:04 ssideris_: haha

13:04 TimMc: yup

13:04 I don't think there are too many executable libs.

13:04 ssideris_: by the way, what's the feeling about EuroClojure, are many people from the US attending?

13:05 TimMc: Not me. :-(

13:05 ssideris_: I'm in London so I have no excuse to not attend

13:05 TimMc: Haha, nice.

13:06 ssideris_: but I haven't bought my ticket yet

13:06 TimMc: I procrastinated on getting a ticket to the 2012 Connj and missed out as a result.

13:06 The scheduling was inconvenient, but I kind of regret not going.

13:07 (scheduling + location)

13:08 ssideris_: As a true procrastinator myself, I'm only now motivated to submit a talk proposal for EuroClojure (deadline is on Monday)

13:10 TimMc: eep

13:12 Frozenlo`: TimMc: I will look in the link you submitted later today. However I probably won't fix the typo in a timely manner, you should do it. Thanks for your eagerness to help! ;)

13:12 TimMc: Haha, OK.

13:29 ssideris_: TimMc: more questions! with https://github.com/stathissideris/clarity/blob/master/project.clj

13:29 ...if I setup a new porject that uses clojure 1.2.1

13:29 and clarity

13:30 leiningen will still retrieve the dependencies of clarity (the default ones)

13:30 but I need a way to tell it to get the dependencies for the "1.2.1" group

13:31 TimMc: Hmmm... I don't know how to manage transitive deps in leiningen.

13:32 ssideris_: ok

13:32 TimMc: technomancy! Halp.

13:32 ssideris_: maybe I could just put it in the readme

13:32 that 1.2 users should make sure to include contrib

13:33 TimMc: What I'd really like to know is this: Should there be separate releases for different dependency-version-variants of a lib?

13:34 Like, clarity-0.5.6+clj-1.2 vs. clarity-0.5.6+clj-1.3

13:34 ssideris_: well maybe, also there should probably be a different branch in my repo, but there isn't

13:35 we don't want to spoil those luddites too much, otherwise they'll stay with 1.2 forever :-D

13:37 TimMc: It's true.

13:40 rlb: Does line-seq buffer content, i.e. if you do a (first (line-seq some-reader)) (first (line-seq some-reader)), can lines ever be dropped?

13:40 (between the two line-seqs)

13:41 TimMc: Seems like dropping is pretty likely there.

13:41 Oh...

13:42 I see what you're asking. line-seq docs say "rdr must implement java.io.BufferedReader", so I'm wondering if there's a reset happening.

13:43 In general, I have the impression that it's not safe to share readers.

13:43 rlb: They're not shared.

13:43 TimMc: some-reader is shared, right?

13:44 rlb: What I mean is -- think of that as sequential code.

13:44 (or is that not addressing your concern?)

13:44 Those two line-seqs will never exist at the same time.

13:45 TimMc: &(import '[java.io StringReader BufferedReader])

13:45 lazybot: ⇒ java.io.BufferedReader

13:45 rlb: Looking at the line-seq source, it might be fine -- it's lazy, and only cals .readLine.

13:45 My problem is likely elsewhere...

13:46 TimMc: ,(let [r (BufferedReader. (StringReader. "a\nb\nc\nd\ne"))] [(first (line-seq r)) (first (line-seq r))])

13:46 clojurebot: #<CompilerException java.lang.IllegalArgumentException: Unable to resolve classname: BufferedReader, compiling:(NO_SOURCE_PATH:0)>

13:46 TimMc: bah

13:46 &(let [r (BufferedReader. (StringReader. "a\nb\nc\nd\ne"))] [(first (line-seq r)) (first (line-seq r))])

13:46 lazybot: ⇒ ["a" "b"]

13:51 ssideris_: TimMc: Clarity 0.5.6 now has support for Clojure 1.2, thanks for your help!

14:01 * zamaterian just bought Reasoned Schemer - to see whats all the fuzz with core.logic is about :-)

14:05 devn: zamaterian: there's a second edition coming soon FWIW

14:11 rlb: In noir, what's the best way to present several clickable "actions" on a page that will work in the absence of any javascript? I can use multiple forms like this: (form-to [:post foo] (submit-button "bar")), but wondered if that was reasonable.

14:15 ibdknox: rlb: why wouldn't they just be links?

14:16 rlb: ibdknox: could be -- I'm relatively new to this sort of thing, though I'd heard people complaing about not using post for destructive actions.

14:16 ibdknox: rlb: ah, that's a rest purity thing

14:17 rlb: I'd fail the purity rest? ;>

14:17 ibdknox: haha

14:17 yes ;)

14:19 rlb: I'm assuming that links would be a lot easier to work with (adjust the appearance of, etc.).

14:19 ibdknox: they would be

14:22 Vinzent: rlb, you can wrap (form-to ...) in a function and use it similary to link-to

14:22 rlb: ibdknox: any resources you'd recommend wrt this sort of thing, especially clojure oriented? I think I understand a lot of the basics, but the s/n ratio for some of this stuff seems a little low sometimes.

14:23 (i.e. lots of opinions, hard to tell what really matters)

14:23 ibdknox: honestly, very little actually matters in this regard. My suggestion would be to do it the way you think you should and then ask for feedback on it

14:24 you'll learn a lot more that way then trying to figure out what's "right" off the bat

14:24 rlb: Vinzent: right, thanks.

14:29 zamaterian: devn, do you know when ?

14:31 rlb: ibdknox: sounds good -- the "post issue" just got me wondering about any obvious things I should know (do/don't/etc.) wrt web interfaces. Though I'm sure there's no simple answer to that.

14:31 ibdknox: rlb: yeah, unfortunately it largely depends on what you're doing and how you intend for others to understand it.

14:33 rlb: Wrt links, I'll have to see if you can adjust the "size" of the link sensitivity area -- this is for a "fat finger" interface.

14:34 ibdknox: rlb: if you add padding to the a element

14:34 you can make it just like a button

14:34 rlb: I'm just playing around with something I'd like to be able to use from a phone to control mpd (and yes I know about the mpd clients).

14:34 ibdknox: rlb: take a look at my overtone ipad controller thing and the noir-blog

14:34 both have solid examples of some of this stuff

14:35 rlb: Wll look at that ;>

14:35 s/Wll/Well,/

14:35 ibdknox: :)

14:36 rlb: Umm, yeah, that might be relevant.

14:37 And many thanks to those responsible for noir (and its deps) -- though mine's no expert opinion, it's been a pleasure to work with.

14:37 ibdknox: rlb: you're welcome :)

14:37 Vinzent: ibdknox, hey, can you share some experience on developing cljs apps? I'm trying to write a little game now and, uh, it feels terrible - when something goes wrong, it just silently shows me the blank page, thus making debugging very uncomfortable

14:38 ibdknox: Vinzent: how are you doing it? monet makes errors on the canvas level suck a little less

14:38 TimMc: rlb: Definitely use post.

14:39 rlb: Also, I don't know if there'd be any interest, but if I come up with something reasonable (right now it's a mess), perhaps I'll publish my clojure mpd lib.

14:39 Vinzent: ibdknox, mostly lein cljsbuild auto

14:39 TimMc: rlb: Especially if there's any chance someone might want to mess with your users.

14:39 ibdknox: TimMc: ?

14:39 I can guard a normal route just as easily as any post route

14:39 I can even csrf protect it

14:39 if that's what you're hinting at

14:40 Vinzent: you're not using any cljs libs?

14:40 rlb: BTW, just curious, with noir, can you distinguish multiple different submit buttons in one form-to? I tried that (briefly), but didn't get it to work.

14:40 TimMc: ibdknox: Right, but there are additional protections if you use POST -- even though you should be guarding against CSRF anyway.

14:41 ibdknox: TimMc: what additional protections?

14:41 Vinzent: I'd take a look at my game editor as an example of building a game in CLJS.

14:41 rlb: not without JS

14:41 TimMc: ibdknox: E.g. Noscript blocking cross-domain POST

14:41 Vinzent: ibdknox, no, I'm following an example from http://nakkaya.com/, where he builds an breakout with canvas

14:41 TimMc: It's just a good habit to have.

14:43 rlb: I wondered how much it would be possible to adjust the look of the submit buttons without javascript (though not the end of the world, and not really a clojure question...).

14:43 (as compared to links)

14:43 ibdknox: rlb: that's not JS that's all css

14:44 TimMc: Reddit uses a JS approach: <a onclick="$(this).parent().submit()" href="javascript:void(0)">logout</a>

14:44 but CSS to style a button as a link would be preferable on many sites

14:46 rlb: ibdknox: OK -- didn't know how much (if any) of that kind of adjustment was handled in javascript. So I suppose it's just a matter of how much you can adjust links vs buttons; I'll poke around -- what you have in overtone would be just fine.

14:47 Vinzent: ibdknox, thank, but I've looked at the code and found that it uses many wrapper libs, some of them (e.g. monet) aren't documented (yet), so I'd spend more time looking at its source than actually writing stuff :) Actually, my question was mostly about the workflow and dev environment

14:47 rlb: (the overtone interface)

14:47 Vinzent: e.g. in clojure I could press C-c d and it'll show me doc on the symbol

14:47 ibdknox: Vinzent: monet is like 100 lines of code lol

14:47 but sure

14:47 Vinzent: I use vim, and noir-cljs

14:48 Raynes: ibdknox: It's the only way to roll, son.

14:48 ibdknox: Raynes: srsly

14:49 zamaterian: ibdknox, do you use paraedit in vim ?

14:49 Vinzent: ibdknox, so you basically making change, waiting why it'd get recompiled, refresh the browser, too?

14:49 ibdknox: zamaterian: yes

14:49 Vinzent: not anymore, that's why I built the live game editor :p haha noir-cljs also provides an instantaneous compilation mode

14:50 sjl: ibdknox: hey, the docs at http://www.webnoir.org/tutorials/sessions say to use (session/flash-get) to get flashed messages, but there doesn't seem to be any 0-arity version of flash-get

14:50 ibdknox: sjl: using which version of noir?

14:50 I assume the as of yet unreleased 1.3? ;)

14:50 zamaterian: ibdknox, how well does it work compared with emacs ? (i'm using vim, the other guys at work uses emacs )

14:50 ibdknox: sjl: flashes changed in 1.3 to be more map-like :)

14:50 sjl: ibdknox: the one you told me was stable and would fix my json problem the other day :)

14:51 arg

14:51 ibdknox: it's basically the only change

14:51 sjl: ibdknox: so I basically just use a dummy key to get the old behavior?

14:51 ibdknox: zamaterian: I don't know? I don't use emacs.

14:52 sjl: that would work. Flashes now work the way they do in every other framework - they last exactly the length of one request

14:52 Vinzent: ibdknox, yeah, but I thought it forces you to use in-browser editor? Do you use some browser extension which allows you to edit input boxes with vim? or what do you mean by instantaneous

14:52 zamaterian: ibdknox, doh I should have expected that answer ;-) thx

14:53 sjl: ibdknox: they don't last "until get'ed"?

14:53 ibdknox: what if a request for a CSS file in another tab or something happens to be the next request?

14:54 ibdknox: sjl: resources don't invoke flashes

14:54 sjl: ibdknox: ok, then a json response from long-polling JS in another tab

14:55 ibdknox: sjl: if you're using JS, I'm not sure why you'd use flashes anyways? The primary reason to use a flash is that you post something, and redirect someone to another page that says "you added blah"

14:56 sjl: ibdknox: sure, and maybe one view works that way (a user's profile edit page) while on another page there's some JS that updates some counter or timeline

14:56 ibdknox: sjl: in any case, while I'm not one to say that it's best to just follow the pack, I think being consistent with the way the rest of the web works is valuable

14:56 NoICE: when you guys are into this... is it possible to add one-time flash when no redirect is involved (e.g. to preserve form values)?

14:57 ibdknox: sjl: to get the exact same behavior it would take a two-line function just using the session :)

14:57 sjl: ibdknox: example: twitter.com

14:59 ibdknox: and Django's message flashing, at least, works like the old version (cleared when read): https://docs.djangoproject.com/en/dev/ref/contrib/messages/

15:00 NoICE: Rails flash messages lasts one request too, so they have flash.now[:notice] method to store flash for this one precious request.. and I thought for a long time they had it like Django

15:00 ibdknox: sjl: and there's django-flash

15:02 Raynes: Dear world: we've merged the noir 1.3 (where development of the next major version has been ongoing) into master and tagged the old master (which was the 1.2.x versions) as '1.2'. Future development will be in the master branch.

15:02 ibdknox: Vinzent: the instant mode of noir-cljs watches for changes and immediately beams the changed code to the browser

15:02 Vinzent: it's like having the in-browser editor, but it works based on file modifications instead

15:03 * NoICE forgot his manners and sais Hi

15:03 sjl: ibdknox: also, Flask appears to also handle it the old-noir/Django way

15:03 Vinzent: ibdknox, isn't it exactly what cljbuild do?

15:03 ibdknox: no

15:04 it's not

15:04 Vinzent: no page refresh

15:04 sjl: ibdknox: It just seems like making them only last for a single request regardless of reading makes it possible to drop messages without any added benefits

15:04 ibdknox: sjl: other than being consistent with 80% of all modern websites?

15:05 sjl: this is now possible

15:05 it was impossible before

15:05 the old way is simple a special case of using a session

15:05 it really is a two-line function

15:05 Vinzent: ibdknox, ah, got it! Then I should check it out immediately, thanks :)

15:05 Raynes: Wait, what are we talking about?

15:05 ibdknox: sjl: why is this an issue?

15:05 is it really so bad to write that two line function?

15:06 sjl: ibdknox: I'd be surprised if you found lots of websites where making an API request between a POST/redirect killed a flashed message

15:06 ibdknox: sjl: http://guides.rubyonrails.org/action_controller_overview.html

15:06 Raynes: Are we arguing because I wanted flash sessions to be one-request instead of one-read?

15:06 ibdknox: please take a look at The Flash section

15:06 Raynes: Because not wanting it is pretty silly.

15:07 Making them last for one request makes pretty much everything you want to do with a flash session difficult for no reason that I can discern.

15:07 sjl: Raynes: yes, because now something like an API request made at the same time in another tab can silently wipe out a flash

15:07 Raynes: Er, one read.

15:07 ibdknox: sjl: that's the contract of a flash

15:07 seriously dude

15:07 do you want me to write the function for you?

15:08 Raynes: Wouldn't that happen anyway? :\

15:08 sjl: ibdknox: No, I'll write it

15:08 ibdknox: sjl: there's nothing wrong with wanting it the other way. I completely buy that

15:08 sjl: Raynes: no, not if the API request doesn't read the flash

15:09 Raynes: Okay then. Either way, this new flash session is a thousand times more useful than the old one and the old one was simplistic enough that I don't see a reason that both can't exist.

15:10 sjl: Raynes: What makes the new one more useful?

15:10 Raynes: Well, 'more useful' may be going out of my way there, but it is certainly easier to use and more consistent with the regular sessions.

15:11 ibdknox: my logic for this: doing flashes per-request was essentially impossible before

15:11 it's not possible

15:11 using the other behavior is a special case of a session value

15:12 and is completely trivial to implement

15:12 sjl: ibdknox: But what would you actually use it for?

15:12 ibdknox: sjl: you can look in any one of 20 rails books to discover that

15:12 I don't honestly never use flashes

15:12 ever*

15:12 sjl: ibdknox: that wouldn't be safer and just as effective with a Django/Flask -style "store til read"

15:13 Raynes: ibdknox: I tend to use them to communicate error messages in forms/

15:13 ibdknox: I always just re-render the form to do such things

15:13 Raynes: Yeah, I don't use Javascript for every little thing all the time.

15:13 sjl: Yeah, I tend to use them for stuff like "Your changes have been saved"

15:13 ibdknox: I mostly believe flashes are hold-over from times before there were better ways of doing things.

15:14 they still have a place certainly

15:14 but *shrug*

15:14 sjl: or "you have been logged out"

15:14 ibdknox: this new system is more flexible

15:14 in that either the rails or django style can be used

15:14 so do whichever you want

15:15 Vinzent: why not introduce some "flash-style" setting which can be either :one-request or :one-read

15:15 it'd be also backward-compatible

15:16 ibdknox: sure someone could do that if they cared to

15:18 seems reasonable, and a much better overall conversation to have than the one that just was.

15:18 rlb: Ahh, didn't realize that things like submit-button also accept an attribute map.

15:23 Vinzent: rlb, btw, i think it should be reported as a bug

15:24 I mean, the fact that it's not reflected in submit-button's arglist

15:24 rlb: Vinzent: nor in the docs (which might be generated from that).

15:24 ibdknox: rlb: Vinzent: it's one of those semi-hidden features of hiccup. All the hiccup functions can take an arg maps

15:25 args map*

15:25 which is wonderful :)

15:25 rlb: Might make sense to have a bit in the README.md mentioning that as a global feature.

15:25 ibdknox: weavejester: ^

15:25 rlb: Though I inferred it from the discussion of primitive forms like [:p ...].

15:25 ibdknox: I don't remember how I figured that out

15:26 I think I just tried it lol

15:26 rlb: I just tried it.

15:26 ibdknox: at some point I read all the source

15:27 rlb: I figured there had to be some way to style form items, though I suppose you could have been required to drop the submit-form-ish helpers, and drop down to [...].

15:28 daaku: is there a good library for parsing/building urls? a basic wrapper around java.net.URL seems to be fine, but seems like something more clojure like would be nice.. also it seems like java.net.URL needs the protocol/host part too

15:38 Vinzent: daaku, I definitely saw one on github, but can't remember the name

15:38 weavejester: ibdknox: I should really mention defelem in the hiccup README

15:39 ibdknox: weavejester: yeah, it's a good thing to know about

15:39 weavejester: ibdknox: Or somewhere at least.

15:40 technomancy: A very basic "lein ring server" is now working for Lein2

15:40 ibdknox: sjl: btw, I'd be happy take a patch that did something like what vinzent suggested. That'd enable everyone to do what they want.

15:40 best of both worlds :)

15:41 sjl: ibdknox: Maybe I'll write that later... though I wouldn't be able to use it anyway because I realized that new puts overwrite old ones

15:41 so I'll need my own custom version no matter what

15:41 ibdknox: sjl: can you explain a bit more?

15:42 sjl: ibdknox: say I flash a message saying "Your new project has been saved"

15:42 ibdknox: k

15:42 sjl: ibdknox: then I run a check to see if they're at the max number of projects for their account

15:42 ibdknox: if so, flash a message saying "Hey, you've just reached your limit, you might want to upgrade."

15:43 ibdknox: then return the redirect

15:43 ibdknox: sjl: here you could use the keying to your advantage :)

15:43 sjl: ibdknox: message 1 is lost

15:43 ibdknox: well yeah, but they my templates need to know about every possible message key

15:44 gf3: sjl: ohai

15:44 sjl: gf3: hey

15:45 gf3: sjl: btw, unrelated, launched cljbin with some positive results, thanks for your feedback

15:46 sjl: gf3: ah, nice

15:46 ibdknox: sjl: true, seems like you'd want to add it as a collection, which you could certainly do. You'd have to be somewhat less imperative about it than just putting twice

15:46 you might build up the vector of messages at the end of your add

15:46 for example

15:47 sjl: ibdknox: this seems to do pretty much what I want: http://cljbin.herokuapp.com/paste/4f5bbde3e4b0edcdd5b0c969

15:48 dabd: I would like to do the following: (map (comp URLEncoder/encode first) data)

15:48 but URLEncoder/encode is not a function

15:48 is there anyway to wrap an external method in a function so I don't have to write: (map (comp (fn [x] (URLEncoder/encode x)) first) data)

15:48 ibdknox: sjl: yep, that'd work well enough for this case

15:49 gf3: sjl: (also, http://cljbin.com/ :)

15:49 qbg: &(doc mem-fn)

15:49 lazybot: java.lang.RuntimeException: Unable to resolve var: mem-fn in this context

15:49 Vinzent: &(doc #'mem-fn)

15:49 lazybot: java.lang.ClassCastException: clojure.lang.LazySeq cannot be cast to clojure.lang.Symbol

15:50 qbg: &(doc memfn)

15:50 lazybot: ⇒ "Macro ([name & args]); Expands into code that creates a fn that expects to be passed an object and any args and calls the named instance method on the object passing the args. Use when you want to treat a Java method as a first-class fn."

15:50 qbg: That isn't for static methods though

15:50 Vinzent: ah, of course

15:51 sjl: gf3: ah, heh, the heroku address was in my browser history so it tab completed

15:52 Vinzent: weavejester, I've sent you a little pull request. Btw, why you decided to move defhtml away from core?

15:52 Raynes: y u no keep defhtml in core

15:53 weavejester: Vinzent: It seemed more appropriate to put all the def* macros in their own namespace, as they're not used as nearly as often as "html"

15:55 Vinzent: hm I used to use it pretty often, looks like it's just me

15:55 weavejester: Vinzent: Am I reading this wrong, or does it add a "attrs" symbol to *every* argument list?

15:55 arohner: can you add watchers to an agent?

15:56 Raynes: gf3: You should totally redirect cljbin.com to refheap.com

15:56 arohner: and if so, when does it get called?

15:56 Raynes: Nobody would notice.

15:57 Vinzent: weavejester, yes, shouldn't it?

15:57 weavejester: Vinzent: Well, no because the attribute map is optional, not required.

15:57 Vinzent: A more correct mapping would be something like...

15:57 Vinzent: ([x]) => ([x] [attrs x])

15:58 Vinzent: hm, I should just named it "attrs?"

15:58 weavejester: Vinzent: That more implies it's a boolean, rather than optional.

15:58 Probably something more like...

15:58 Vinzent: weavejester, yes, but clojure.core function use this convention

15:59 weavejester: Vinzent: Which ones in particular?

15:59 Vinzent: weavejester, defn and others. It always confused me.

16:00 weavejester: Vinzent: Hm, you're right...

16:00 Vinzent: Maybe something needs to be added to the arglists and the docstring?

16:00 Raynes: If it always confused you, you probably don't want to use it in your own code.

16:01 "I always hated they way they did this, so we should probably do it that way too."

16:01 daaku: Vinzent: i found https://github.com/michaelklishin/urly .. looking at it now

16:01 weavejester: Raynes: True...

16:01 I think ([x] [attrs x]) probably conveys an optional attrs argument better than ([attrs? x])

16:01 Vinzent: weavejester, you mean some convention for optional params?

16:01 weavejester: Maybe...

16:02 Vinzent: Raynes, 3 arglists confuse me much more

16:02 Raynes: I don't know why.

16:03 weavejester: I'm torn between adding ([attrs? x]) and then a docstring addition like "This function can take an optional map of attributes as its first argument"

16:03 Or adding in an additional arglist, e.g. ([x] [attrs x])

16:03 seancorfield: fwiw, in congomongo, it has optional arguments that actually have ? as part of their name because they are booleans

16:04 Vinzent: weavejester, yes, but when you have someting like ([name] [name value] [attrs name] [attrs name value]) - it's not that clear and even incorrect

16:04 seancorfield: i see ([attrs? x]) and think "that takes a boolean and a something"

16:04 weavejester: Vinzent: Is it incorrect? What if attrs was attr-map instead? Wouldn't that make it clear?

16:04 In the API docs, it would look like

16:04 Vinzent: seancorfield, there defintely should be some convention for such thing... Does Scheme has one?

16:05 weavejester: (foo name)

16:05 (foo attrs name)

16:05 (foo name value)

16:05 (foo attrs name value)

16:05 Which seems like the best way to convey usage.

16:05 seancorfield: Vinzent: no idea, but the clojure convention seems to be foo? means boolean

16:05 weavejester: The alternative is:

16:05 (foo attrs? name)

16:05 Vinzent: weavejester, I've just never seen ([foo bar] [qux baz])-style arglists...

16:05 weavejester: (foo attrs? name value)

16:06 seancorfield: if there are some arglists with ? meaning optional in core, i'd open a JIRA ticket to get them changed (since it's just metadata)

16:06 Vinzent: seancorfield, and it has came from Scheme :)

16:07 weavejester: I think I prefer the first style. The arglists are just metadata after all.

16:09 Vinzent: weavejester, they are, but imagine novice who trying to figure out what he can pass to the function. ([attrs? name] [attrs? name value?]) reads as "you can pass either just name or both name and value to it, and also you can pass attrs as a first arg.", and in the case of 4 arglists I don't know how I'd read it. Also, since all elem functions would have that attrs? in arglist, it's more clear what each funtion actually take.

16:11 weavejester: Vinzent: But how would they know what attrs? means? Isn't it better to have one arglist for each set of arguments you can have?

16:11 TimMc: Dunno, ? is a valid char in symbols.

16:11 and is used idiomatically in predicate names.

16:13 Vinzent: weavejester, it's widespread convention. I think the better is what makes it cleaner and more understandable, since it's a documentation

16:14 TimMc, look, I know! I'm not saying that such overlaping of meanings is good, but core guys use it and there is no other convention for optional args (yet), so it seems reasonable to take advantage of it

16:15 weavejester: Vinzent: But if someone sees (foo attr-map name) and (foo name value), wouldn't it be obvious that foo can take an attribute map and a name, or a name and a value?

16:15 Vinzent: I'm not sure I see why two arglists with the same cardinality would confuse a human.

16:16 Vinzent: So long as the arglists have different named symbols

16:16 qbg: ? args makes sense for constructs such as defn

16:17 weavejester: Maybe I should write a post to the Clojure group and get a consensus of what people prefer.

16:19 Vinzent: weavejester, it's not just about same cardinalities, what I'm trying to say is that ([attrs? name] [attrs? name value]) looks nearly the same as ([name] [name value]) - that is, optional arg doesn't pollute the arglists and it's immedietly clear what args this function takes.

16:19 ibdknox: if I see & attrs

16:19 I know it's optional

16:19 that seems the clearest solution to me

16:19 & [attrs value]

16:19 lazybot: java.lang.RuntimeException: Unable to resolve symbol: attrs in this context

16:19 ibdknox: for example

16:20 sjl: What's the closest Clojure equivalent to Python/Django's South migration library?

16:20 ibdknox: lobos

16:20 weavejester: ibdknox: But the attrs are at the beginning

16:20 ibdknox: weavejester: hm, good point :/

16:21 Vinzent: weavejester, sounds reasonable. Also, you could start discussion about convention for optional attrs, so it'd changed in core too

16:22 [optional] is another widely used convention, but it doesn't fit for obvious reasons

16:22 weavejester: Vinzent: Yeah, I can see your point, but I'd like to get some consensus, since we're talking about a subjective documentation style, rather than some techincal problem that has an obviously better solution.

16:23 Vinzent: weavejester, sure

16:23 weavejester: Vinzent: I'll start up the discussion :)

16:33 https://groups.google.com/forum/?fromgroups#!topic/clojure/kNY1hoXKohE

16:33 * weavejester hopes he wrote it in a neutral enough style.

16:41 sjl: OK, I give up: does anyone using Lobos know what this error means? "A schema definition needs at least a name."

16:42 I get it when I try to (migrate) this: http://cljbin.com/paste/4f5bca98e4b0edcdd5b0c96c

16:44 worrelsik: I'm trying to get started with ClojureScript One; third step is 'lein bootstrap'. But lein (2preview2) tells me that's not a task.

16:44 Is there an alternative to use?

16:45 seancorfield: i doubt clojurescript works with lein2 - use lein 1

16:46 worrelsik: can lein1 and lein2 exist next to each other?

16:47 weavejester: sjl: I might be wrong, but do up and down take an argument list?

16:47 sjl: I seem to recall it would be (up (create …)) and (down (drop …))

16:47 Vinzent: they do

16:48 kenneth: if anybody wants to review my style / code, this is my first clojure script. works as expected, yay! https://gist.github.com/3b9ca8728fae1ee9b5dd

16:48 sjl: weavejester: I'm working from http://www.vijaykiran.com/2012/01/17/web-application-development-with-clojure-part-2/ because Lobos doesn't have any real docs for migrations

16:49 or if there are I can't find them

16:49 gf3: hey guys, why would clojure.lang.Var be bad in a sandbox?

16:50 sjl: oh, fun, that lobos error doesn't happen when I use h2 instead of SQLite

16:51 so some of those magic values in the sqlite db connection info must be wrong

16:51 worrelsik: seancorfield, thanks; step 3 is running now :-)

16:51 TimMc: gf3: Look at all the methods it has that a user shouldn't call in a shared sandbox.

16:54 Vinzent: what should I write instead (update-in ... (if foo? f identity)), so it'd not evaluate update-in at all (like in (when foo? (update-in ...))), but can be used with ->?

16:55 gf3: TimMc: crap

17:03 rlb: I have a Socket for communication with mpd, and from that a reader and writer. After a bit of idle time, mpd will close the connection, which is fine -- I just need to detect that and reestablish.

17:03 amalloy: Vinzent: https://github.com/flatland/useful/blob/develop/src/useful/fn.clj#L66 - (-> x (given foo? (update-in ...)))

17:03 rlb: I'm wondering what might be a reasonably idomatic way to handle the mpd connection in clojure.

17:04 gf3: hmm, I'm having an issue writing a macro, if someone has as sec → http://cljbin.com/paste/4f5bcbf5e4b0edcdd5b0c96d

17:04 I need to quote some things, but I essentially want the unquoted version of `(fn…

17:04 rlb: (Up to now I just hacked up a MPD record with the socket/reader/writer, but I may need mutability to handle reestabilshing the connection.)

17:05 s/reestabilshing/reestablishing/

17:05 Vinzent: amalloy, thanks! I should learn this lib and start use it on a regular basis (why even is it not in clojure.utils or something?)

17:05 rlb: (And this is in the context of creating a (trivial) mpd lib.)

17:07 kenneth: what does map do if i map a hash?

17:09 gf3: kenneth: you get a pair, IIRC

17:09 Raynes: Because utility libraries are the devil.

17:11 rlb: ...in C, I might just "lock; send-request; receive-result; unlock;" (and reestablish the connection if it's dead).

17:11 Raynes: And if useful was a Clojure library, we wouldn't be able to add stuff to it and change+release every half hour.

17:13 TimMc: kenneth: What does that mean?

17:14 actsasgeek: is anybody familiar with the HTML notebook feature in ipython? Is there anything similar for Clojure?

17:14 Vinzent: Raynes, well clojure.core is essentialy an utility library :)

17:14 Raynes: A big mess of one, yes.

17:15 Useful is at least organized. :P

17:16 sjl: Has anyone used Lobos with SQLite? I just need to know the format of this magic DB connection map...

17:17 y3di: its so wierd and interesting that maps and keywords are also functions

17:18 qbg: maps make sense because of what a function is mathematically

17:19 TimMc: It's all just convenience wrappers over clojure.core/get, in an abstraction sense

17:19 gf3: but srsly, if anyone has a moment to lend a hand with a simple macro → https://refheap.com/paste/1021/fullscreen

17:21 qbg: I think you want the syntax-quote around the (swap! ...) form

17:22 TimMc: gf3: What is *routes* supposed to contain?

17:23 gf3: qbg: how do I "call" it then?

17:23 qbg: The macro expands into the code

17:23 So when the defroute form is evaluated at runtime, the route fn will be added to *routes*

17:23 Vinzent: Raynes, hah don't judge them too severely :)

17:24 TimMc: gf3: Right now, *routes* is being loaded up with syntax, not fns.

17:24 gf3: qbg: hmm, it's not evaluated for me

17:24 TimMc: yes, that's what I need help with :(

17:24 qbg: Like I said, syntax quote the (swap! ...) form

17:24 So you get fns in *routes*

17:25 Right now you are adding updating *routes* at compile time

17:25 Vinzent: and remove ` from the (fn ...)

17:25 qbg: You want to do it at runtime

17:25 gf3: qbg: right right, thank you, I understand now

17:27 qbg, TimMc: fixed → http://cljbin.com/paste/4f5bd51fe4b0edcdd5b0c96f

17:27 qbg, TimMc: thank you

17:29 Raynes: ibdknox: ^ You said nobody used the maximize button

17:29 WHAT NOW?

17:31 Frozenlo`: Variables and functions share the same namespace in clojure, correct?

17:31 qbg: Yes, Clojure is a Lisp 1

17:31 Raynes: Yes. It is a lisp-1.

17:36 gfredericks: what might I be doing wrong if I have (add-hook 'clojure-mode 'paredit-mode) in my .emacs, yet I still have to M-x paredit-mode manually whenever I open a clojure buffer?

17:36 pipeline: that' not the hook i used

17:36 also i find paredit mode insufferable

17:36 * gfredericks decides not to like paredit mode

17:36 gfredericks: pipeline: that fixed it, thanks!

17:36 pipeline: ;(add-hook 'clojure-mode-hook (lambda () (paredit-mode +1)))

17:37 well i did bring you the commented out snippet also

17:37 gfredericks: :)

17:38 TimMc: My .emacs more closely resembles pipeline's snippet.

17:38 gfredericks: trying it out now...

17:38 TimMc: except I have t, not +1

17:38 gfredericks: there it goes working

17:38 pipeline: thank you sir!

17:38 and/or madam

17:42 pipeline: and, definitely and

17:42 rlb: Am I correct to assume that ref/agent/atom may not be ideal for handling something like IO, since it inherently involves side-effects?

17:43 TimMc: rlb: Agents are great for I/O, since they can help you serialize uncoordinated actions.

17:44 Refs... right, you don't want to do I/O in a dosync block.

17:44 rlb: I probably misunderstand, but how to you make sure that request and response pair up?

17:44 TimMc: Hmm. Well, agents are good for O, at least. :-P

17:45 rlb: right

17:45 I feel like I must be "doing it wrong", but I've begun to wonder if I might need to use deftype, set!, and locking.

17:46 TimMc: heh

17:46 What are you trying to do?

17:46 rlb: TimMc: and another problem with an agent is that it can retry, right?

17:46 qbg: If you have a handler function with request/response args, you could throw a fn that closes over the response into an agent

17:46 TimMc: rlb: I don't think agents retry.

17:46 qbg: agents don't retry

17:47 rlb: TimMc: wait -- thinking about refs

17:47 TimMc: writing a (trivial) lib to talk to mpd.

17:47 TimMc: mpd?

17:48 rlb: http://mpd.wikia.com

17:48 It obviously has to send/receive the request/response atomically.

17:48 TimMc: rlb: futures?

17:48 rlb: And I'd like to be able to transparently reestablish the connection if/when the server closes it.

17:49 (which requires some form of mutation to create the new socket/reader/writer)

17:50 With a mutuable approach, I'd just "lock; close-old-connection; setup-new-connection; unlock;".

17:51 And it looks like I can do all that with deftype/set!, but as I said -- felt like I was "doing it wrong".

17:53 One question about set! -- if all use of a field is going to be inside a (locking this ...) block, is :unsynchronized-mutable OK?

17:53 * rlb thinks he needs to go off and read a bit more about java concurrency...

17:55 qbg: If all uses of that field occurs within (locking <the object the field is a member of> ...), yes

17:55 The Java Memory Model isn't that hard to understand, thankfully

17:56 You just need to make sure that you have the appropriate happens-before relationship between your reads and writes

17:59 rlb: qbg: yeah, thanks. I think I understand it a bit, but I don't know it nearly as well as posix threads, etc.

17:59 qbg: This is useful: http://www.cs.umd.edu/~pugh/java/memoryModel/jsr-133-faq.html

18:00 rlb: I suppose I could just use an atom and swap, and not worry about the (unlikely) chance that we'd throw away an extra connection to the server on a retry.

18:01 (at least wrt reestablishing the connection)

18:02 TimMc: Yeah, I'd advice staying far, far away from locking.

18:03 You'll sometimes encounter a Java lib that requires that you hold a lock, but that's the only time I've heard of it being required.

18:04 qbg: Serializing through a ConcurrentLinkedQueue might be an option

18:05 rlb: I still need to keep the request and response paired for each caller, i.e. several threads all calling (mpd-status x) at the same time.

18:06 qbg: Perhaps an async api would be better?

18:06 rlb: I suppose the simple solution would be for every caller to have their own socket -- maybe that's good enough.

18:06 (in this case)

18:07 But that would mean that mpd objects aren't "thread safe".

18:07 s/objects/"objects"/

18:07 TimMc: rlb: What if you wrapped each mpd object with an agent and sent it actions?

18:09 rlb: TimMc: once you send it an action, how do you make sure you get *your* response?

18:10 TimMc: rlb: Callbacks? Shared atom? Promise/deliver?

18:10 rlb: i.e. if I tell it to send a "status" request. Also I don't want it to retry the network send.

18:10 Vinzent: rlb, just in case, have you looked at lamina?

18:11 rlb: Vinzent: I'll take a look.

18:12 TimMc: wait, confusing ref and agent again, sorry.

18:12 technomancy: weavejester: I'm a huge fan of de-emphasizing def* macros FWIW

18:12 I hope noir will take a hint from you =)

18:13 TimMc: technomancy: Thoughts on how to version and release libs that have different dependency sets? e.g. foolib-for-clojure-1.2 and foolib-for-clojure-1.3

18:13 rlb: TimMc: I imagine that might work, but in this particular case, everything seems more complicated than the "old school", explicit locking approach. But I may well be missing something obvious.

18:14 technomancy: TimMc: with maven that's something you would use classifiers for. I haven't looked into it much further beyond that, but I'd recommend reading up on classifiers.

18:14 TimMc: Ah, interesting.

18:14 rlb: As long as you're just locking one thing, it might be easier. As soon as you need to coordinate multiple objects, it is hell.

18:15 rlb: TimMc: right

18:15 OK, I'll play around; thanks all - for the help.

18:21 weavejester: technomancy: My view is that a "defblah" macro is okay if you have a "blah" function.

18:21 daaku: is there a new home for -?> somewhere?

18:22 weavejester: core.incubator, I believe

18:22 ibdknox: daaku: core.incubator

18:22 daaku: ibdknox: thank you

18:24 add-dependencies is awesome

18:58 sjl: anyone know why I would be getting "repl is not defined" when trying to connect to a cljs repl from a browser?

18:59 I have (:require [clojure.browser.repl :as repl]) in the ns...

19:02 ideally_world: does lein test only run core.clj?

19:02 ah, nevermind

19:12 rlb: What does print do if *out* is closed (i.e. if an underlying socket is closed)?

19:15 ideally_world: rlb: at a total guess I'd say there'd be an exception thrown?

19:21 rlb: Looks likely -- underlying method should be OutputStream .write. I don't know where I thought I'd read something else.

19:21 Just need to detect a closed socket so I can retry.

19:22 Hmm, ClosedChannelException looks promising...

19:31 bsteuber: is there a function x with (x 'foo) => `foo ?

19:32 ok I could recolve and then read the full qualified name from the var

19:32 anything simpler possible?

19:39 ideally_world: Anyone know of a way to run lein midje in emacs?

19:40 Raynes: M-!

19:44 ideally_world: Raynes, bah, that's not much better :(

19:45 looking for something a *little* more intergrated...

19:46 napping: why would lein deps do nothing for a [gloss "0.2.1-alpha2-SNAPSHOT"] line, as suggested at clojars.org/gloss

19:47 ibdknox: bsteuber: ##(symbol (str *ns*) (name 'foo))

19:47 lazybot: ⇒ sandbox6997/foo

19:47 tacoman: I'm going through 4clojure and have a function that has different responses for an arity of 1 versus an arity of 2. recur doesn't work if I try to get the 1 argument form to call the 2 argument form; would just calling the function again without recur work?

19:48 bsteuber: ##(symbol (str *ns*) (name 'let))

19:48 lazybot: ⇒ sandbox6997/let

19:48 tacoman: (yes, I know that with enough recursion I'll hit a stack overflow, but that's not a worry in the exercise)

19:48 actually, wait. dumb question, that was.

19:48 Raynes: Holy shit.

19:48 He is using alpha's *and* snapshots?

19:48 tacoman: problem is I can't use def, so the function has no name to call with.

19:48 Raynes: alphas*

19:49 bsteuber: ibdknox: I want the semantics of resolve, but a symbol as return value

19:49 Raynes: That is utterly insane.

19:50 qbg: &`monitor-enter

19:50 lazybot: ⇒ monitor-enter

19:50 ibdknox: bsteuber: I don't understand

19:50 bsteuber: that gives you the symbol, then just resolve it if you need the value?

19:51 bsteuber: ##(resolve (symbol (str *ns*) (name 'foo)))

19:51 lazybot: java.lang.SecurityException: You tripped the alarm! resolve is bad!

19:51 bsteuber: I want 'let to be mapped to 'clojure.core/let in any namespace that uses core

19:51 like resolve would do

19:52 qbg: You have to watch out that the (real) special forms don't live in a namespace

19:52 bsteuber: but resolve gives me a var

19:52 qbg: I know, but let* is the special form here

19:52 Raynes: (symbol (clojure.string/join "/" ((juxt :ns :name) (-> 'println resolve meta))))

19:53 qbg: Just pointing out a nasty edge case

19:53 napping: Raynes: I thought that was a bit odd when ztellman's github suggests 0.2.0 is the current verison, but I'm more confused that lein neither fetched a jar nor complained about an unresolved dependency

19:53 tacoman: is there a way to get recur or the equivalent to call the function with a different arity, then?

19:53 Raynes: I don't know why he insists on insane versioning.

19:53 bsteuber: Raynes: nice one ^^

19:54 Raynes: bsteuber: I used juxt and -> in the same piece of code. God has smiled on me today.

19:54 bsteuber: I got (-> sym resolve str (.substring 2) symbol)

19:54 qbg: tacoman: No. A different arity is effectively a different fn

19:54 bsteuber: but I thought there might be sth more direct

19:54 ztellman: napping: can you clarify exactly what happened?

19:54 bsteuber: well not like you usually need that kind of function

19:55 Raynes: bsteuber: If vars were Named this would be easier.

19:55 bsteuber: mm

19:55 ztellman: you put 0.2.1-alpha2-SNAPSHOT in your project.clj, and it didn't get pulled down?

19:55 or was it a transitive dependency?

19:56 napping: Oops, I just misspelled the dependency line

19:56 Raynes: ztellman: You should tell me to piss off or something. I called you insane like 20 seconds ago.

19:56 napping: it's less surprising that [org.clojure/clojure "1.3.0" gloss "0.2.1-alpha2-SNAPSHOT"] doesn't fetch gloss

19:57 Raynes: Haha

19:57 ztellman: Raynes, you can make it up to me by reading https://github.com/ztellman/potemkin/blob/master/README.textile and telling me what's so insane about that

19:57 TimMc: haha

19:57 Raynes: ztellman: Oh, I was talking about snapshotting an alpha.

19:58 ztellman: yeah, fair enough

19:58 even so, you've called me insane before

19:58 I need to address these one at a time

19:58 Raynes: I thought I was less brutal about potemkin.

19:59 I throw around the word 'insane' a lot though, so I probably did.

20:00 I'll read that in a bit. Currently on the road. Too bumpy to comfortably read.

20:01 napping: ztellman: do you know much about gloss-b?

20:01 ztellman: napping: I don't know what the "-b" signifies

20:01 so… maybe?

20:03 napping: a fork said to add some half support for files where bits refer to others by offsets https://github.com/jasonjckn/gloss

20:03 ztellman: I had no idea that existed

20:03 wild

20:04 napping: is 0.2.1-alpha2-SNAPHSOT the only version of gloss you have on clojars?

20:04 ztellman: all previous versions should be there

20:05 napping: then I don't know how to look - that's all the search turned up

20:05 ibdknox: ztellman: why are you snapshotting alphas? lol

20:05 napping: Now I see more at http://clojars.org/repo/gloss/gloss/ from "browse"ing

20:05 ztellman: ibdknox: raynes already called me on it, it doesn't make much sense

20:06 ibdknox: :)

20:07 napping: Am I just missing something on clojars.org? I don't see older versions mentioned anywhere expect by browing all repos

20:07 daaku: napping: i think all versions that ever existed will always exist (barring snapshots i think)

20:09 napping: sure, but I search for "gloss" and it only turns up the doubly bleeding-edge SNAPSHOT alpha, and no link or anything to list older versions

20:09 ibdknox: napping: http://clojars.org/repo/gloss/gloss/

20:09 clojars only shows the latest by deafult

20:09 napping: quite. I guess I shoudl just skip the friendly search box?

20:11 or start hacking on https://github.com/ato/clojars-web

20:12 TimMc: ztellman: Versioning still doesn't make any sense to me, and I don't think it's my fault.

20:12 ztellman: TimMc: my versioning, or the entire concept?

20:13 TimMc: ztellman: The current practice.

20:13 ibdknox: TimMc: we spent months figuring out how to version the editor at MSFT, I was amazed at how contentious of an issue it was

20:13 napping: I'm actually a bit cross because I'm trying to get going with CCW, and Maven and especially it's eclipse plugin seem to lack any reference manual

20:14 I just want get dependencies for a project without much more trouble then lein, if there's some better way to do that

20:18 tacoman: nevermind! I got it. I didn't realize that you could still name something with fn, even without def.

20:19 (no, I wasn't spending my entire time working on this, for those wondering just how stupid I could be.)

20:25 so... any interesting news in the community lately? for that matter, what's a good way to keep on top of what's new?

20:26 TimMc: tacoman: Well, there's datomic.

20:26 1.4 is coming along

20:27 I just keep this channel open 24/7 and eventually I hear about many interesting things. :-)

20:27 ibdknox: tacoman: we've discovered that TimMc is a robot controlled by clojurebot, it was quite an ordeal

20:27 TimMc: *bleep*

20:27 ibdknox: tacoman: http://disclojure.org/ is a good resource

20:27 TimMc: ibdknox: SANBOX DENIED

20:28 ibdknox: haha

20:28 TimMc: Access to java.net.* is forbidden.

20:29 hhutch: tacoman: google plus (make a "saved search for clojure") and twitter:#clojure

20:30 TimMc: There's the mailing list, but that's kind of traffic-y.

20:31 Planet Clojure, if you want a bit of a firehose.

20:31 hhutch: the mailing list is pretty good, lots of internals-type stuff you wouldn't pick up otherwise

20:34 ibdknox: what's your preferred stack for deploying a noir app in production?

20:35 ibdknox: hhutch: I just run it off of jetty :)

20:35 typically with nginx in front of it as a reverse proxy

20:35 hhutch: ibdknox: that's what i thought

20:35 that's how i'm doing it

20:35 ibdknox: I've had no issues with it

20:36 hhutch: you use ring uberwar ?

20:37 ibdknox: hm?

20:37 wars are for deploying to tomcat

20:38 I guess you could run the war too somehow

20:38 I just do lein trampoline run prod

20:40 hhutch: ibdknox: cool, thanks

20:41 ibdknox: np :)

20:41 Raynes: I thought wars were typically for territory disputes and moral or religious values.

20:42 ibdknox: Raynes: nope. just tomcat. ;)

20:42 hhutch: http://sadtrombone.com/

20:42 ibdknox: ~rimshot

20:42 clojurebot: Badum, *tish*

20:42 duncanm: anyone running JDK 7 here on a Mac?

20:42 romanandreg: has anyone had tried to use cljsbuild or the cljs repl with lein2 ?

20:45 hhutch: romanandreg: just 1.7/cljsbuild here

20:45 romanandreg: hhutch: does the repl-listen works properly? doesn't hang or anything?

20:45 hhutch: works fine for me

20:47 romanandreg: uhmm lein2 still a bit buggy, I guess I'll use lein1 for now, had spent at least 3 days trying to make this thing work the way it should work

20:47 and my foo on leiningen internals and cljs repl impl is not that good to know what the hell is going on

20:47 hhutch: does lein2 have something specific you need?

20:48 romanandreg: hhutch: not really… I'm moving to lein1 now

20:49 hhutch: yeah the cljsbuild repl-listen needs some work in lein2… I'm trying with lein1 now and everything works great

20:49 hhutch: the only thing that i know of i'd want in lein2 is built in lein-newnew

20:50 but lein-newnew works fine with 1.7 as is

20:50 kwertii: I downloaded lein2 last night to try it, and found that the "plugin" command referenced in its installation instructions is totally missing.. O_o

20:56 napping: wasn't that saying to run lein1's plugin to install some lein1 plugin for upgrading project files?

21:01 kwertii: napping: Oh. Really? I totally missed that

21:02 napping: I thought you were supposed to do that with lein2

21:22 gf3: ibdknox: do you use a specific lein plugin to generate your clojurescript project skeletons?

21:22 ibdknox: gf3: I'm making one tomorrow

21:22 gf3: CONVENIENT

21:23 gtuckerkellogg: timing!

21:23 what happens when an alter statement is enclosed inside a conditional?

21:25 Something like http://pastebin.com/XtA80WF7

21:25 TimMc: &(if false (alter 5 6) "fine")

21:25 lazybot: ⇒ "fine"

21:26 TimMc: gtuckerkellogg: Now you know.

21:26 gtuckerkellogg: that part i knew, :-)

21:27 what I mean, is, if a dosync wraps a conditional which wraps an alter, does the data conditionally being altered get "locked" bu the STM if alter never happens?

21:30 ztellman: gtuckerkellogg: dosync doesn't analyze its body to figure out what gets changed

21:31 invoking 'alter' or 'ref-set' will do all the consistency checking

21:31 nothing happens until those functions are invoked

21:31 gtuckerkellogg: great

21:31 that helps

21:32 TimMc: gtuckerkellogg: Look at my example again -- that alter statement is invalid, but no error occurs. :-)

21:32 gtuckerkellogg: :O

21:32 good point

21:32 D'oh!

21:32 TimMc: gtuckerkellogg: More importantly, analysis is impossible, since I could do (fn [f] (dosync (f)))

21:33 gtuckerkellogg: ah

21:40 TimMc: gtuckerkellogg: A good way to think about these things is, "What is the worst code I could throw at the compiler/runtime?"

21:40 romanandreg: how do I do to include a clojurescript library to a project

21:40 would be the same as a normal library?

21:40 add them to :dependencies on the project.clj file?

21:40 gtuckerkellogg: TimMc, that's my kind of code!

22:10 _rcc: Basic question: I'm using leiningen and clojure 1.3. How do I include clojure.contrib.server-socket in my project? I'm not even clear if server-socket is still part of contrib?

22:12 I see technomancy has a version. How should I use that one? How would I use it? e.g. what is the depencency name/version to put in project.clj

22:14 xeqi: _rcc: searching clojars brings up http://clojars.org/server-socket

22:15 which looks to be technomancy's version

22:17 _rcc: https://github.com/technomancy/server-socket

22:17 leiningen uses maven (or at least, maven's repos). Correct?

22:18 xeqi: the repos, yes

22:21 TimMc: ~contrib

22:21 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

22:22 TimMc: _rcc: ^

22:22 _rcc: TimMc: Thanks

22:23 TimMc: The contrib breakup was the biggest disruption in the 1.2 -> 1.3 transition.

22:26 _rcc: I'm trying to do a lein search (cool!) but the index is taking a while to download...

22:32 juhu_chapa: clojurebot: i don't find server-socket in the actually-maintained libs, i hava to keep using old contrib?

22:32 clojurebot: Cool story bro.

22:33 TimMc: juhu_chapa: That's a bot, and look a few lines above the original message.

22:34 cgag: when using swank-clojure, how do I bring up the repl in a split window? When I played with it before it did this when i ran clojure-jack-in, I guess it doesn't anymore?

22:37 kwertii: cgag: mine brings it up in a split window automatically. C-c C-z will split it and switch you to the REPL

22:38 cgag: C-c C-z just switched me to a new buffer and started a repl in that. I guess I could just split it manually first, though I wonder why it's not doing it on its own.

22:38 kwertii: cgag: It should be. maybe something configured your Emacs to disallow splitting?

22:38 _rcc: I found it, I think: http://clojars.org/server-socket

22:51 uvtc: My understanding is that the customary way to use a Java lib in your Clojure project is to find the lib at Maven Central. What's the customary way to use one that's *not* at Maven Central? That is, if you just have a jar file?

22:52 If I just drop it into my project's lib dir, how do I tell lein "hey, this is a dependency, but don't worry -- I'll just provide it myself"?

22:53 TimMc: ~repeatability

22:53 clojurebot: repeatability is crucial for builds, see https://github.com/technomancy/leiningen/wiki/Repeatability

22:53 TimMc: uvtc: ^ there's some good info in there

22:53 "Free-Floating Jars"

22:54 technomancy: TimMc: botsnack

22:54 TimMc: Om nom nom; that was delicious

22:54 technomancy: =D

22:56 uvtc: Whoops. Sorry. Yes, I did read that, but I followed the link to the lein-localrepo README and did not know what they meant by "leiningen (maven) coordinates of a file" and that most likely got pulled away.

22:58 _rcc: I'd like to add a "console" that I can telnet into so I can run arbitrary commands inside of my JVM. I'd like to execute inside of some environment (e.g. maybe have some macros defined and/or some variables). I'm thinking of using clojure.contrib.server-socket for this. Is this a good approach?

22:59 amalloy: that sounds like swank/slime, or nrepl or something

23:00 _rcc: The app running in the JVM is not a clojure app

23:00 I'm not sure if that matters

23:00 It's a Java app

23:01 juhu_chapa: TimMc: Thank you! :D

23:01 TimMc: uvtc: "Coordinates" is a weird bit of jargon for group ID, artifact ID, and version.

23:02 uvtc: like [org.clojure/clojure "1.3.0"]

23:02 technomancy: _rcc: see mire for a (somewhat dated) example of code that does that

23:02 it uses server-socket

23:03 _rcc: technomancy: thanks! I'll have a look.

23:03 technomancy: also check out the peepcode screencast if you want a more detailed walkthrough</shill>

23:04 napping: ztellman: is gloss broken on 1.3.0?

23:04 ztellman: napping: 0.2.1 should work

23:04 with both 1.2 and 1.3

23:04 uvtc: TimMc, Thanks! Regardless though, the top line of the lein-localrepo readme says that it's for working with a local Maven repository. I was looking for a way to skip that and just tell lein, "don't worry, just use this jar I'm putting here" (even though that might not be the best for repeatability).

23:04 napping: I'll try that

23:06 TimMc: uvtc: You *can* explicitly add stuff to the classpath, but that will only work on your machine.

23:06 uvtc: TimMc, Just out of curiosity though, is lein-localrepo talking about my ~/m2/repository when it says "local maven repository", or is it talking about some other one that I might create myself for other local users to have access to?

23:06 TimMc: Yep, that's the one.

23:07 Well, I assumed so.

23:08 uvtc: TimMc, Ok. Thanks.

23:08 napping: ztellman: thanks, that helsp

23:08 ztellman: napping: np

23:08 napping: I guess I did need the scary alpha2-SNAPSHOT :)

23:09 how is a repeated with :delimiters supposed to behave?

23:10 uvtc: When would I want to use the `lein compile` command (given that `lein run` implicitly compiles for me)?

23:10 napping: I was about to test it, but you probably meant the docs to make it clear

23:10 cgag: ls

23:10 oops

23:10 TimMc: uvtc: I would hazard a guess that that allows mroe complicated builds where Java links against the Clojure classes.

23:11 uvtc: TimMc, Ah! Makes sense, since Java would need those class files. Thanks again!

23:11 TimMc: I think I played around with that at work.

23:14 napping: (let [fr (repeated :int16 :delimiters [0])] (decode fr (encode fr [1])))

23:27 uvtc: Will MS Windows run a jar file Clojure gui app if double-clicked on?

23:28 ztellman: napping: sorry, I usually keep IRC in the background, didn't notice your questions

23:29 napping: ztellman: it looks like repeated just stops whenever it sees the byte

23:29 like this failing: (let [fr (repeated :int16 :delimiters [0])] (decode fr (encode fr [1])))

23:30 is there anything like (repeate-until frame is-terminator?)

23:30 ztellman: if you want a multi-byte delimiter, that will work too

23:30 unless I'm misunderstanding your question

23:30 napping: it's a one byte delimiter, but it can occur in the sequence also

23:31 ztellman: ah, you want :suffix, then

23:31 but then you need some other indicator of the length

23:32 napping: for a simple example, think of length-prefixed strings repeated until one has length 0

23:32 ztellman: because the trailing byte isn't an unambiguous indicator of when the repeated structure ends

23:33 napping: yeah, there's not really a construct for that

23:33 technomancy: uvtc: you should never have to run deps, compile, or javac explicitly

23:34 ztellman: gloss needs a redesign so it's easier to construct those sorts of operators yourself

23:34 uvtc: technomancy, Thanks!

23:35 napping: it's not documented, but is implementing Reader/Writer that bad?

23:35 ztellman: napping: no, not really

23:35 it's just harder than it should be

23:36 it's pretty easy to infer from the code, but feel free to ask any questions you have

23:39 amalloy: can't you use a header to implement this construct?

23:39 ztellman: amalloy: yes, except that you're increasing the nesting level each time

23:40 amalloy: the header's format is a length-prefixed string, and the body format is either: the same header format again, if the string was non-empty; or a zero-byre format

23:40 doug: when i do a "lein run" on osx, java fires up a window and i lose focus on my terminal.

23:40 amalloy: the nesting level of what?

23:40 doug: anyone know a good way to keep that from happening?

23:40 napping: amalloy: with the header cons'd onto the body

23:40 maybe that works?

23:41 ztellman: amalloy: each element is the body of the previous element

23:41 I'm pretty sure that if you had several thousand elements, that gets ugly

23:41 that was why I didn't suggest it, but maybe I'm wrong

23:41 amalloy: i don't think it does, but it's not something i've thought hard about

23:42 ztellman: napping: that might work, and it's easier than rolling your own

23:42 napping: I'd like to be sure it's not recompiling a frame at each step

23:42 cgag: anyone know how to setup noir with the new leiningen?

23:42 amalloy: it won't, napping

23:42 ztellman: napping: just return a compiled frame

23:42 or one of two compiled frames

23:43 napping: so put compiled-frame outside the fn

23:44 ztellman: yes, just have a (def …) somewhere

23:44 napping: how do I close over the element then?

23:45 ztellman: I'm not sure I understand your question

23:45 oh, right

23:45 I see what you're saying

23:45 amalloy: you need it to be self-referential, right?

23:47 ztellman: I'm back to being pretty sure this won't work

23:47 napping: it's not so much that, as sticking the element parsed by header onto the front

23:47 ztellman: you're right, that will require a recompilation each time

23:48 napping: isn't (compile-frame frame (partial cons x) -) going to be cheap if frame is already compiled?

23:48 ztellman: yes, it will

23:48 but not free

23:50 napping: I should be able to afford that

23:50 the big data will go with finite-block

23:50 Lajla: napping, this fucking adapter is a piece of shit

23:50 I gotta wave it in the air to get a signal to it.

23:51 ztellman: hmm, looking at the code...

23:51 Lajla: It figures when your army production stops my wireless signal drops.

23:51 Call my ISP before I shit a brick, tell the internet tech I'll drill holes in his dick

23:51 he says "Sorry sir, we don't work on routers', so I hang up and rage.

23:51 ztellman: napping: okay, I was overestimating the cost of that

23:52 sorry to be so flip-floppy, it's been a while since I've touched gloss

23:52 napping: amalloy: how to sort out the self-reference? I'd like a letrec

23:52 kwertii: I have a program that works fine via clojure-jack-in/SLIME but fails with "lein uberjar," "lein run," and "lein compile" with a mysterious Exception in thread "main" java.lang.RuntimeException: java.lang.ExceptionInInitializerError -- anyone know what this is about?

23:53 amalloy: yeah, you kinda have to fake letrec with mutation

23:53 (let [self (promise), impl (fn (...use @self...)) (deliver self impl) impl)

23:54 napping: Have you heard the good word of the Church of the Least Fixed Point?

Logging service provided by n01se.net