#clojure log - Aug 28 2013

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

0:01 bbloom: i've got a toy interpreter that is dispatching on type & experimenting w/ some of the ideas related to Cleff. in the theoretical background for algebraic effects, they consider it an effect to allocate a new "effect instance" which, if you're dispatching on type, must be a jvm type

0:01 knowing full well that this interpreter is mega slow & will always be

0:01 i just want it to not like EXPLODE

0:01 so i wonder if types ever get GCed or anything like that

0:02 otherwise, i need to add dispatch on instance, which i might have needed to do anyway :-P

0:03 ie something like http://dev.clojure.org/display/design/specify+i.e.+reify+for+instances

0:04 *shrug* just wondering. probably won't change my hacky hack hacking either way

0:06 grandy: just learning clojure and had a quick question. Trying to use the serial-port library with lein and apparently this library has binary deps and so only works with cake (https://github.com/samaaron/serial-port/issues/2). Anyone have any advice for how I ought to proceed?

0:07 amalloy: grandy: that's a two-year-old issue; lein has long since gotten support for native dependencies (although i don't know how to do it)

0:08 grandy: amalloy: ahh ok, i was hoping that would be the case. So I guess I should google for native dependencies lein

0:08 bbloom: hold on, i was on the PR for that… i can dig it up

0:09 https://github.com/technomancy/leiningen/issues/898

0:10 actually, that's a much more specific issue

0:10 but it might help you find what to grep for. sorry, good luck!

0:11 technomancy: so... who wants faster lein task runs?

0:11 * bbloom raises hand

0:11 bbloom: actually, it's not so bad. i don't really feel the need to complain, but i basically live in the repl

0:12 grandy: bbloom: thanks

0:12 technomancy: bbloom: try a grenchman: https://github.com/technomancy/grenchman

0:13 bbloom: ah, so this is your ocaml project :-)

0:13 technomancy: yes indeedy

0:13 http://p.hagelb.org/grench <- 64-bit linux binary if you don't want to pull in the whole compiler chain

0:13 bbloom: `grench` is quite a bit longer than `lein` :-P

0:14 technomancy: hm; almost 50%

0:14 bbloom: those extra characters are gonna suck up all the time i save with faster load times

0:14 technomancy: there's a cost to everything

0:14 tanstaafl, &c

0:14 bbloom: :-D

0:16 i think i said this last time, but ocaml is so much easier to read than haskell

0:16 grandy: not trying to flood the channel with extremely dumb questions, but just curious, it would appear that serial-port would work with lein, so is it likely that I'm just doing something else wrong in trying to use it? https://clojars.org/serial-port

0:16 bbloom: i've written 10X and read 100X as much haskell as ocaml or ML, but meanwhile, i can actually read/write the latter

0:16 technomancy: bbloom: because of fewer monads?

0:17 (I have never tried to read haskell)

0:17 not having whitespace-sensitivity is nice though

0:17 bbloom: more parenthesis :-P

0:17 technomancy: heh, well I might be putting them where it's not necessary

0:17 I haven't internalized all the insane precedence rules

0:18 bbloom: the bigger thing is that the type-level language in ocaml is MUCH SMALLER

0:18 brehaut: technomancy: moar dollars!!1

0:18 bbloom: haskell is really TWO languages: a term language and a logic engine. the logic engine has totally different syntax...

0:19 brehaut: technomancy: http://www.haskell.org/haskellwiki/Keywords#infix.2C_infixl.2C_infixr is why you cant internalize all the precedence rules

0:19 bbloom: good news is that you can solve a rubix cube at compile time!

0:19 Raynes: I

0:19 I'm totally going to rewrite grenchman in Haskell.

0:19 * bbloom gives haskell shit, but really has a lot of respect for it

0:21 brehaut: bbloom: also, they added a functional view on the type system a year or so back, so you dont have to treat it as a logic engine

0:22 bbloom: brehaut: nice.

0:22 brehaut: bbloom: also hugely magical

0:43 wei_: I'm expecting (let [u (<! c)] (.log js/console u)) to give me a value on the channel. but instead it prints the channel itself. what's going on?

0:44 hiredman: wei_: are you sure you don't have a channel on a channel?

0:44 (do c and u print out the same?)

0:47 wei_: actually, <! seems to not block like I expect. let me post a small gist, thanks for the help

0:51 https://gist.github.com/yayitswei/6362139

0:51 are you allowed to use macros inside of go blocks?

0:55 amalloy: wei_: yes, but you can't use >! or <! from inside a lambda, and many macros expand into lambdas

0:55 go can only transform the current local function, not any functions called from it

0:56 wei_: amalloy: i see, thanks

0:59 so in my code above should I just expand out the shoreleave.remotes.macros/letrpc macro

1:02 amalloy: uhhhh, if that were a solution you wouldn't have to do it: that's the macroexpander's exact job. the problem is that this macro expands to something that go can't work with

1:02 rhg135: quick ?, is theere a way to recurse on every item of a seq or is it a code-smell and I should refactor?

1:03 amalloy: it expands into something like (remote-callback "some-path" [some-args] (fn [result] (<! ...))), which can't be put into a go

1:04 rhg135: i think that describes how almost everything works in a functional language, at a low level, so you have to be more specific about what exactly you want and why you don't like what you have

1:05 rhg135: im working on a fs, and i want this function to return a vector on a file node but recurs on it's subfiles if it's a directory

1:05 huh

1:05 typing it out it makes no sense

1:06 i guess ill have to refactor a bit

1:07 maybe return a map regardless of node kind

1:09 wei_: amalloy: oh right. so I have to turn the callback form into a blocking call instead

1:10 amalloy: rhg135: look up file-seq and tree-seq

1:11 rhg135: no i'm writing a fs, but yeah the source code may help

1:11 thx

1:11 also this is my current code https://www.refheap.com/18094

1:14 futile: Does Clojure have something like select(), or something that can more efficiently communicate over a socket than just spawning new threads all the time?

1:14 rhg135: heh turns out I was re-implementing tree-seq

1:15 amalloy++

1:15 futile: (inc amalloy)

1:15 lazybot: ⇒ 70

1:15 rhg135: oh

1:15 bbloom: futile: the JVM doesn't have anything like select… unless you count something like core.async

1:15 futile: Yeah, you don't want to inc him much more than this. He'll get a big head.

1:15 bbloom: futile: actually, that's not true. check out nio

1:16 futile: Okay, thanks.

1:16 bbloom: nio has Selectors

1:16 futile: more generally though, the JVM doesn't have anything like WaitForMultipleObjectsEx

1:16 but if you only care about OS-level sockets, then nio will do the trick

1:17 futile: Great.

1:18 * futile sighs

1:18 bbloom: the nio API is absurdly complex

1:18 futile: Yeah, I'm not going to deal with that tonight.

1:19 bbloom: it's got about 37974353 interfaces w/ the idea that you can implement your own selectors, but it turns out that lots of stuff is incorrectly private or package level & it's actually impossible to implement custom multiplexing for your own objects

1:19 * futile just focuses on making this even prettier: https://github.com/sdegutis/bahamut/blob/master/bahamutapp.png

1:19 futile: bbloom: wow, that's a terrible design flaw.

1:20 bbloom: I guess they need a nnio now

1:20 bbloom: i think they just need to make 2 or 3 private things public & write a scary docstring

1:21 futile: But backwards incompatibility!

2:08 I want to be that guy that's really smart and helpful but nobody's ever jealous of because he's always making you feel good about yourself and he really believes in you.

2:09 But he does really cool things like works at NASA and writes compilers and text editors and stuff, but he also always seems to find time to sit down with you for however long you want to just chat about what you want to chat about.

2:10 ddellacosta: woah, I didn't realize grenchman existed until now. freaking cool

2:10 futile: Yeah.

2:10 Just found it via trptcolin's public activity.

2:10 Weird.

2:12 What's the best way to parse Clojure code given as a string, and get data back about its structure?

2:18 rhg135: Read-str?

2:18 futile: Where's that located?

2:18 ,read-str

2:18 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: read-str in this context, compiling:(NO_SOURCE_PATH:0:0)>

2:19 rhg135: Ing

2:19 futile: Is there a variation that can support partial forms, like "(+ 1 2" and give you back a data structure with information about how it's unfinished?

2:19 rhg135:

2:20 Um*

2:20 s4muel: ,read-string

2:20 clojurebot: #<core$read_string clojure.core$read_string@17b18c3>

2:20 s4muel: ,(doc read-string)

2:20 clojurebot: "([s]); Reads one object from the string s. Note that read-string can execute code (controlled by *read-eval*), and as such should be used only with trusted sources. For data structure interop use clojure.edn/read-string"

2:21 futile: ,clojure.edn/read-string

2:21 clojurebot: #<CompilerException java.lang.ClassNotFoundException: clojure.edn, compiling:(NO_SOURCE_PATH:0:0)>

2:21 futile: ,(use 'clojure.edn)

2:21 clojurebot: #<SecurityException java.lang.SecurityException: denied>

2:21 futile: :(

2:21 ,(require '[clojure.edn :as e])

2:21 clojurebot: nil

2:21 futile: ,e/read-string

2:21 clojurebot: #<edn$read_string clojure.edn$read_string@100a79b>

2:21 futile: Neat.

2:21 ,(e/read-string "(+ 1 2")

2:21 clojurebot: #<RuntimeException java.lang.RuntimeException: EOF while reading>

2:21 futile: :(

2:34 callen: ,(e/read-string "(+ 1 2)"

2:34 clojurebot: #<RuntimeException java.lang.RuntimeException: EOF while reading>

2:34 callen: ,(e/read-string "(+ 1 2)")

2:34 clojurebot: #<CompilerException java.lang.RuntimeException: No such namespace: e, compiling:(NO_SOURCE_PATH:0:0)>

2:34 callen: ,(require '[clojure.edn :as e])

2:34 clojurebot: nil

2:34 callen: ,(e/read-string "(+ 1 2)")

2:34 clojurebot: (+ 1 2)

2:35 callen: futile: ^^

2:35 ,(eval (e/read-string "(+ 1 2)"))

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

2:35 callen: "SANBOX"

2:35 seangrov`: hah

2:35 futile: callen: I'm trying to get information about an unfinished form.

2:35 callen: i.e. that "(+ 1 2" is only waiting on one level before it's fully closed.

2:48 murtaza52: +cnt

2:49 futile: wat

2:59 clj_newb_2345: anyone have a toy impelemtnation of sql in clojure?

2:59 (I'm not looking for production use; just something for reading the code

3:00 futile: (inc augustl)

3:00 lazybot: ⇒ 1

3:27 SegFaultAX: Hickey's most recent talk is sort of strange.

3:27 It's interesting, but I think he leaned a little too hard on the music analogy.

3:36 ambrosebs: SegFaultAX: FWIW I loved it.

3:36 I might be biased as a muso.

3:37 The analogy of things doing "one thing" really makes sense in the context of musical instruments.

3:37 IMO

3:41 ivan: I wish infoq served video+slides mp4s or could play at faster speeds

3:42 shaunxcode: SegFaultAX: which talk is that?

3:42 ivan: http://www.infoq.com/presentations/Design-Composition-Performance

3:51 ka_: \quit

4:54 * robink is struggling to scrape some ugly HTML with laser

4:55 ddellacosta: is there a way to pass in a string to re-pattern so that it escapes regex chars?

5:11 kral: namaste

5:22 noidi: ddellacosta, http://docs.oracle.com/javase/7/docs/api/java/util/regex/Pattern.html#quote%28java.lang.String%29

5:23 ddellacosta: noidi: thanks. I feel like this should be an option with re-pattern (or an alternative function), but I can see why they wouldn't want to do that by default.

5:23 noidi: ,(java.util.regex.Pattern/quote "\\s")

5:23 clojurebot: "\\Q\\s\\E"

5:25 ddellacosta: in any case, I just ended up manually escaping the "problem" characters, since it was just a few. If I was doing this on a larger scale I'd probably be using Pattern/quote.

6:38 fuz: hey guys, i'm using clojurescript but i'm having an error in my generated javascript. i don't know if it's a bracketing problem as I used to get two errors rather then just one. can someone take a look? http://pastebin.com/jSpKq52f

6:39 clgv: fuz: you should post the error message as well as a more explicit problem description

6:40 fuz: in general, the async channels work - i just get an error just before the 'hello from inside the channel!' - in Javascript, Uncaught TypeError: Object [object Object] has no method 'call'

6:41 the last time i got this error, it was to do with bad brackets, so i'm a bit confused why it works and i still get an error

6:41 could it be clojurescript?

7:50 ciphergoth: How nervous do I need to be about a blocking response to an HTTP request in Aleph?

7:50 Do I need to be strict about making everything properly asynchronous?

8:56 arcatan: is there some command-line program for sending commands to nrepl that does not incur JVM startup times?

9:01 i guess i could hack grenchman a bit to do that

9:23 wei_: is there a shoreleave/fetch like library that blocks instead of uses callbacks? would ilke to use it with core.async

9:29 dnolen: wei_: you can easily make a callback based library work w/ core.async

10:12 noncom: what is the best fifo stack for clojure? i need to be able to read the arbitrary stack entries too..

10:12 will core.cache do/

10:12 ?

10:12 wei_: dnolen: could you give an example of converting a callback-based library to work with core.async? my problem was that I couldn't use a go block in a lambda

10:13 clgv: noncom: vector is a stack

10:13 but a stack is first-in-last-out

10:14 noncom: clgv: i thought about vectors.. is it idiomatic to do a fifo with a vector?

10:14 won't it pollute memory?

10:14 clgv: noncom: what exactly do you want to do?

10:14 noncom: i need to keep a history of events coming from network. say i want to keep track of 100 last events

10:15 and be able to access all the stored events if i need to

10:15 but most often i only access the last one

10:15 clgv: noncom: do you need a persistent data structure?

10:15 there is clojure.lang.PersistentQueue for that case

10:16 noncom: i think that the queue has to be synchronized because some other thread might be reading the stack, while the netwrok acceptor will push in a new event, removing the old one

10:16 clgv: hmm well you need only the last element most of the time and less often the previous ones?

10:17 do you discard the whole structure after you processed it?

10:17 noncom: clgv: it depends. these events are spatial coordinates. if the processor will need previous coordinates, say, to build a characteristic of the curve (a gesture), it will need them. this is for touch interface

10:18 clgv: noncom. so if you need FIFO you can use clojure.lang.PersistentQueue within an atom

10:18 noncom: discard is only done if event becomes too old (number 101) or the touch is released, when the whole history is discarded since the touch is no more

10:19 clgv: or a reference if you need to coordinate more than just the queue

10:20 noncom: hmm sounds not as if there was some datastructure implemented for that yet. you need a bounded queue

10:20 noncom: in java i used a linked list...

10:21 clgv: hmm you could use one of javas data structures in java.util.concurrent - there are bounded queues

10:21 noncom: very good, i will look into those!

10:24 clgv: if i'll just go with atom with [], will it litter the memory much?

10:24 clgv: noncom: you cant use vector in a non-destructive way as FIFO queue. that is not possible

10:26 noncom: but if it is stored in an atom, then i can (conj (drop veñ 1) evt), and whatever thread works with that atom, it works with the dereferenced value, and that ensures thread-safety... ?

10:27 mucker: Hi all, I am looking for a template engine which is like jinja (template inheritance (have existing templates)). Does clojure have one ?

10:28 clgv: noncom: I'd use ArrayBlockingQueue

10:28 ro_st: mucker: i've not used it, but selmer might do it for you: log-for-time-period

10:28 noncom: ok, i'll try

10:28 ro_st: erk

10:28 https://github.com/yogthos/Selmer

10:29 mucker: ro_st: great ! thanks

10:29 clgv: noncom: in case of conflicting changes atoms will retry the computation

11:08 deech: Hi all, how do I pass a mutable variable to a Java function? For instance pass a Colloection from the Clojure side that will be filled up on the Java side.

11:09 llasram: deech: Just like with Java, you'd just pass a reference to a mutable object

11:09 For example, a new ArrayList: ##(java.util.ArrayList.)

11:09 lazybot: ⇒ #<ArrayList []>

11:11 deech: llasram: Ah, so I couldn't just pass in a Clojure vector, right? I'd have to explicitly create a Collection.

11:11 cmajor7: deech: why can't your "Java side" return a collection that you can work with later on. e.g. what is a motive of passing an existing (state) collection

11:11 ?

11:11 deech: cmajor7: Out of my control :). 3rd party lib.

11:12 cmajor7: the API takes an empty List ?

11:12 deech: Yup.

11:12 cmajor7: deech: is it a closed sourced API? just curious why would anybody do that

11:14 deech: Here's the constructor: https://github.com/Cascading/maple/blob/develop/src/jvm/com/twitter/maple/tap/MemorySinkTap.java#L20, and here's where the list is filled (I think):https://github.com/Cascading/maple/blob/develop/src/jvm/com/twitter/maple/tap/MemorySinkTap.java#L52

11:17 cmajor7: deech: as I read it, it actually expects some "tuples", hence is taking a List (e.g. a list may have tuples at the point of creation)

11:18 deech: but then since it is not quite obvious what a "MemorySinkTap" is, it's hard to say

11:19 deech: but yea, if empty is fine then (java.util.ArrayList.)

11:19 deech: but a list does not need to be mutable, why do you think it should?

11:21 deech: e.g. clojure vector implements List interface as well: https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/APersistentVector.java#L19

11:22 deech: cmajor7: I don't think a list should be mutable. That was my first (non-working) pass at trying to figure out how to pass an acceptable argument to the constructor.

11:22 cmajor7: In fact I *love* that it is not.

11:23 cmajor7: deech: right, you said "how do I pass a mutable variable to a Java function?", which lead me to believe you wanted it mutable, but yea, a Clojure vector will do.

11:25 rkneufeld: yogthos: Congrats on the pragprog beta launch of "Web Development in Clojure" (http://pragprog.com/book/dswdcloj/web-development-with-clojure)

11:26 deech: cmajor7: thanks for your help!

11:26 yogthos: rkneufeld: thanks, it's nice to finally have it out :)

11:26 ambrosebs: yogthos: congrats

11:26 yogthos: rkneufeld: looking forward to the Cookbook :)

11:27 rkneufeld: yogthos: Me too! You probably know how stressful it is to be in the midst of writing a book ;)

11:27 yogthos: ambrosebs: thanks

11:28 rkneufeld: it's certainly more work than I originally anticipated, but rewarding as well

11:28 rkneufeld: My sentiments exactly

11:28 callen: I need to get somebody to use bulwark.

11:28 Raynes: you're on deck.

11:28 PREPARE THYSELF

11:30 seangrov`: yogthos: I've heard a lot of authors share the sentiment of the first part of that statement, but not many share the second

11:31 yogthos: seangrov`: I really enjoyed the experience overall, forced me to learn a bunch of stuff and work on my writing skills

11:32 seangrov`: It's very cool from an outsider/non-author perspective, but it does seem a ton of work :)

11:32 yogthos: I won't lie it definitely is

11:32 llasram: deech: Wandering back -- are you doing Cascalog foo, or trying to wire up some "raw" Cascading to Clojure?

11:33 deech: llasram: "raw" Cascading.

11:33 callen: seangrov`: you think he's got it bad, my idea for a book is to make people do something they don't usually want to do.

11:34 llasram: deech: Ok. It might still be worth checking out Cascalog's code to see how they solved these sorts of issues

11:34 deech: llasram: That's a great call. Thanks!

11:35 seangrov`: callen: Altruistically may be good, though capitalism may punish you...

11:36 callen: seangrov`: I know nobody will buy the book, but there needs to be at least one resource out there on how to learn to read code.

11:36 (that you didn't write)

11:36 mlb-: As I understand, (swap! x y & z) is something like (apply y x & z). I've come across code where x and y are not parameters. Is it some idiom/shorthand to use swap! instead of apply?

11:37 seangrov`: callen: Burn it (the code), and rewrite it from scratch. Done.

11:37 I like the idea though if there are actually helpful suggestions

11:37 callen: seangrov`: learning to read code, in my opinion, makes people become better programmers faster - by an order of magnitude.

11:37 llasram: mlb-: swap! is for mutating atoms -- if you didn't know that?

11:37 alexyakushev: mlb: swap! is an apply to change the value of an atom

11:38 callen: seangrov`: take for example libraries like JQuery. Imagine how much better off JQuery users would be if they understood what they were using?

11:38 people need to be more patient. The rushing around to hammer out code and ship doesn't necessarily make you a better or more efficient programmer in the long run.

11:38 seangrov`: callen: So how much of it is "reading code" and how much is "understanding the system it describes"?

11:39 callen: seangrov`: 'tis both laddie. I start from one end and work towards the other. I planned to do it by "modules", each a module a decent sized library or system.

11:39 seangrov`: jQuery isn't too bad to read, function by function, but understanding the whole module system from the code is pretty laborious

11:39 callen: first I explain reading the code, start extracting common patterns, explain idioms, explain how to identify them, and then work towards tying it together.

11:40 I'm also in the unfortunate position of writing an entire book about other peoples' code which leaves infinite surface area to be wrong. Sigh.

11:40 mlb-: llasram, alexyakushev: Oh. my bad. Had confused for haskell swap. Nevermind =]

11:40 callen: I'm considering a "test" blog post or series of blog posts to see how the idea shakes out in reality.

11:41 seangrov`: callen: I'd definitely be interested in reading it. Though part of me wonders how much of it relies on the reader's ability to suss out the patters, and how much is the responsibility of the author to maintain proper separation of code

11:41 Is it meant to work for both "good" and "bad" code bases?

11:41 callen: seangrov`: learning how to suss out patterns is part of the point.

11:42 seangrov`: good/bad - haven't decided, I'm not super-duper concerned about the pathological case, the real problem is that 95%+ of programmers don't even read the good code that they rely on.

11:42 so, why not solve that problem first?

11:42 seangrov`: Ok, that seems tractable

11:42 callen: I don't need to fix the universe in one go.

11:42 I just want to get more programmers in the habit of reading the bloody code they use.

11:42 seangrov`: I'd like to read a post or two of that

11:47 gfredericks: would we expect a (deftype Pair [a b]) to be faster for creation/access than a two-element vector?

11:48 I'm showing a factor of 6 slowdown and am terribly curious where that's coming from

11:49 ambrosebs: deftype is slower?

11:49 gfredericks: using (vector x (inc x)) and (second v) versus (Pair. x (inc x)) and (.right pair)

11:49 yes deftype is 6 times slower

11:49 I'm working on writing this up a bit more formally with criterium for a gist

11:59 yep, six times slower with criterium too: https://gist.github.com/fredericksgary/6367436

11:59 noncom: callen: maybe somehow enforce that unless you read and understand the code of an opensource library, you cannot use it?

12:01 gfredericks: oh wait

12:01 I bet there's reflection in there *facepalm*

12:01 ambrosebs: lol

12:02 gfredericks: (set! *punch-on-reflection* true)

12:08 yes deftype is moderately faster; 32ms vs 45ms.

12:13 callen: noncom: I think that's called just making the library hard to use and undocumented. Not really what I want. I'm in Klishin's camp on that subject.

12:14 gfredericks: you should add ztellman's tuple library.

12:14 gfredericks: to that test, that is. the tuples are WAY faster for things like two elements.

12:15 TimMc: callen: Nah, even that doesn't work, if you can find another codebase that uses the library. Monkey see, monkey do!

12:15 callen: TimMc: stop ruining my dreams of coder literacy with cargo cult :(

12:15 noncom: callen: hey, i was joking :D.. however, interesting, what is it about Klishin's way? never heard of..

12:16 callen: noncom: ClojureWerkz crew, cool guys. Care about documentation and nice libraries. :)

12:16 gfredericks: callen: I hadn't expected any tuple lib's approach to be substantially different from a (deftype Pair [a b])

12:17 callen: gfredericks: please look at the library.

12:17 gfredericks: callen: yessir

12:17 callen: gfredericks: not trying to order you around, I just think it'll be illuminating.

12:18 * gfredericks is looking

12:22 TimMc: Hmm, it uses a single-segment namespace. :-(

12:24 mimieux: technomancy: regarding slamhound what does mean the following output? http://pastebin.com/anAGHbLT

12:24 kyled: Morning all

12:24 jamii: This is fun:

12:24 user> (eval ^{:line 11, :column 20} [])

12:24 ClassCastException java.lang.Long cannot be cast to java.lang.Integer clojure.lang.Compiler.eval (Compiler.java:6597)

12:24 nDuff: mimieux: FYI, pastebin.com is full of animated ads for anyone not using adblock/noscripts/&c.

12:27 gfredericks: callen: this is comprehensive but I haven't seen anything particularly surprising yet; any hints why I would expect it to perform differently?

12:27 jamii: user> (eval '[do (inc 1)])

12:27 2

12:28 clgv: (edn/read (java.io.PushbackReader. (io/reader "samples/seattle/seattle-data0.dtm"))) results in RuntimeException No reader function for tag db/id. although db/id seems to be bound in *data-readers*

12:30 context: I am trying to do the datomic tutorial in clojure

12:31 * gfredericks runs the tuples through criterium

12:33 mimieux: nDuff: now using refheap :D

12:35 gfredericks: callen: yeah it's about the same as the deftype; maybe you missed my facepalm about reflection?

12:36 llasram: clgv: edn/read doesn't use *data-reader* -- you need to pass a map if you want to use tagged literals. Check the docstring

12:37 clgv: llasram: oh thanks. didnt use edn before...

12:39 `cbp: well it IS a deftype just fully featured and 1 deftype per size :D

12:40 gfredericks: `cbp: exactly, that's why I was wondering what callen thought was so illuminating

12:41 noncom: does anyone know, are there plans to add fast unboxed computations in some future?

12:42 i mean without using different quirks to acheive semi-unboxed ones

12:42 llasram: AFAIK Clojure already uses unboxed primitives for local computations, doesn't it?

12:43 noncom: you mean with typehints or coercions?

12:44 llasram: Well, with whatever gives the compiler sufficient type information to know it can use primitives

12:45 noncom: yes, i think it is so..

12:46 clgv: noncom: it is unlikely that it becomes possible to use primitives without type hints

12:47 noncom: yes that would require big changes aside from that it is almost undoable while preserving the paradigm

12:47 clgv: noncom: what problem do you have with type hints?

12:49 noncom: no real problem with typehints... i have been talking in this irc some time ago with ppl that there is trouble for supporting floats and ints. just no real support. it seems to worry nobody, but for me it is a real pain.. oh well..

12:49 i guess my real problem is that i crave for 32-bit types

12:49 unboxed

12:50 clgv: noncom: because you have a scenario with huge memory consuption and want to trade precision/range for memory space?

12:51 noncom: in fact you can "patch" clojure to have functions accepting primitive ints or floats with a custom defn/fn but you will need to put all invocations in a macro.

12:52 noncom: not really. the main reason is that i work with opengl much and with java opengl libraries. they all use 32 bit floats and ints because all the hardware does. all the implications of clojure havingonly 64-bit support boil down to such significant framedrops (even with all the typehinting and casting i can imagine) that i wake at nights

12:52 clgv: I managed to use primitive functions being passed as values that way

12:52 dnolen: bbloom: hrm, I guess with ANF transform will need to carefully propagate line number information

12:52 seangrov`: did you get a chance to try out the keywords branch?

12:52 seangrov`: dnolen: No, I'll try it now

12:52 noncom: patch? i would do this. i have been looking at the clojure sources recently but did not start yet tying the ends... your experience is very interesting.. could you tell more?

12:53 clgv: noncom: well you need arrays for those functions anyway - so why dont you use int or float arrays?

12:53 dnolen: seangrov`: thx!

12:53 bbloom: dnolen: yeah, it's easy to fuck it up anytime you synthesis your own symbols w/o metadata on them

12:53 dnolen: but as long as you're just moving symbol objects, it's not too bad

12:53 clgv: noncom: no! "patch"! that means writing macros :D

12:54 noncom: clgv: arrays are only at the bottom. i have to do dozens of computations which intertwine with opengl java lib calls and them use floats. such an intertwining implies 10x more casts.

12:54 s/dozens/billions

12:54 clgv: noncom: do you have a short example?

12:55 dnolen: bbloom: in your version you would extract the original forms and rewrite into ClojureScript form and analyze - but I guess you have to carefully attach the metadata to generated forms and introduced symbols before calling analyze.

12:56 noncom: clgv: i can post a refheap of an example, i've been working with recently, although i'll have to tear it off of the rest of the code, but it is pretty readable in itself i guess..

12:56 clgv: does datomic have a macro version of datomic.api/q?

12:56 bbloom: dnolen: i think as long as you reuse the symbols, it's fine, right? or do you need the metadata on the lists too?

12:57 dnolen: also the only reason i really do it the way i do it is b/c parsing is complected with analysis

12:57 dnolen: i'll explain that comment in a moment, gotta finish something for a client

12:58 noncom: clgv: here: https://www.refheap.com/18111

12:58 dnolen: bbloom: pretty sure you do if you want accurate stepping information, it's why source maps support lines w/o symbols.

12:58 noncom: clgv: read from the bottom

12:59 there is a println, but sure i was testing without it

12:59 that piece simulates attraction of particles, according to some law

13:00 clgv: noncom: first advice on reading. if you pass data to a clojure function there is no use type hinting it before

13:00 noncom: 300 cubes show a very significant framedrop. about 1500 -> 17 fps. I have recently asynchronized the Control, which makes the calculations, so fps is now about 270, but due to the calculations running in another thread, they lose time coherence and animation is laggy

13:01 clgv: typehinting before you mean where before?

13:01 for ex?

13:02 clgv: noncom: you should annotate your constants with ^:const then the compiler can infer their primitive type if they have one

13:02 noncom: for example in compute-offsets

13:02 noncom: it will infer doubles, but will it infer floats?

13:03 rurumate: I'm trying to connect emacs and the browser to a clourescript repl, using lein cljsbuild or something. lein-cljsbuild's advanced example seems a good starting point. I can manipulate the browser from the cli repl, but the emacs won't play nice yet. Does anyone have this setup (firefox + emacs + cljs-repl) running?

13:03 clgv: noncom: not sure. cgrand had a macro where you could check

13:03 seangrov`: dnolen: As an aside, SpiderMonkey seems to fail on this test: out/core-advanced-test.js:485: Error: Assert failed: (not (integer? 1e+308))

13:04 Is that expected?

13:04 aaelony: hey guys, looking for a bit of advice for a scheduling library. Basically, I am looking for a library to schedule function calls on an hourly interval. I see Chime, Quartzite, and at-at… which one is preferred ?

13:04 rurumate: aaelony: wait, I'll make a pastie

13:04 justin_smith: what's the predicate that tells me if something can be dereferenced?

13:04 aaelony: rurumate: sweet!

13:05 justin_smith: that I even want to know at runtime makes me think something is designed wrong... but I assume there must be some predicate

13:05 aaelony: rurumate: you mean a refheap ?? ;)

13:06 blrm: justin_smith: i think that would be realized?

13:06 justin_smith: ,(realized? nil)

13:06 clojurebot: #<NullPointerException java.lang.NullPointerException>

13:06 jkkramer: justin_smith: (instance? clojure.lang.IDeref x)

13:06 justin_smith: that is the case I am looking at

13:06 cool!

13:07 (inc jkkramer)

13:07 lazybot: ⇒ 5

13:08 noncom: clgv: other than that, you think the code is ok?

13:09 all the jme-related functions are typehinted in the jme-namespace. typehinting them improved performance, but not as much as i would like to...

13:09 jme is the opengl library

13:09 clgv: noncom: well you have no primitive functions there so passing doubles/floats/ints/longs leads to boxing

13:09 noncom: clgv: what about primitive functions?

13:09 seangrov`: dnolen: I'm getting an error compiling on an certain js-obj form ... will look into it

13:09 clgv: noncom: do you know the fibonacci example?

13:09 noncom: ahaha which one?

13:10 clgv: noncom: here http://dev.clojure.org/display/design/Enhanced+Primitive+Support

13:11 noncom: but limited to double and long

13:11 noncom: ugh

13:11 i'm thinking about looking at clojure sources to make it support ints and longs if it is possible. i think it is a matter of a little job. but who knows...

13:12 s/longs/floats

13:12 clgv: noncom: no you do not need to change clojure source. you can implement it as a library

13:12 noncom: i will have to read the fibonacci example carefully when i have some free time today

13:13 clgv: noncom: in fact clojure functions are (simplified) only objects of classes that implement IFn

13:13 rurumate: aaelony: http://pastebin.com/Xz9AtxAs

13:13 zphds: is it ok to use (delay..) for creating 'lazy' vars? Like a db connection?

13:13 seangrov`: dnolen: Seems like it's choking on anonymous functions: https://www.refheap.com/45fd544bac82e81745a19fad5

13:13 Let me see if it happens with master

13:14 jkkramer: zphds: yes, quite common

13:14 noncom: wouldn't it about the compiler's core? adding primitive types knowledge for the compiler does not look like a library case... ?

13:14 zphds: jkkramer: cool… thanks

13:14 noncom: i know about IFn yes

13:14 aaelony: rurumate: thanks, man. So quartz is the way to go?

13:16 rurumate: aaelony: it's not a very nice api, but it works for me

13:17 seangrov`: dnolen: Ok, ran it on my local copy of master, compiled fine, updated to clojure/clojurescript master, same error. Works if I replace #(... %&) with (fn [& args] ... args). Seems like something has changed around this - is the shorthand no longer allowed?

13:17 aaelony: rurumate: cool. have you tried other options and quartz is what you prefer?

13:17 seangrov`: Not the biggest deal in the worls if not, but worth bringing up

13:18 rurumate: aaelony: no, I had used quartz in java for some time, so I just ported my quartz code to clojure at some point

13:20 cmajor7: aaelony: do you need a full blown scheduling framework? will something like a function do: https://www.refheap.com/18114 ?

13:22 bbloom: dnolen: ok i'm ready to chat now

13:23 dnolen: seangrov`: seems unrelated since I didn't change anything around anonymous fn's would need more information

13:23 seangrov`: Ah, specifically it's the %& symbol, this is enough to cause the error: https://www.refheap.com/8a7fe4ec8af9c4f668f392ae3

13:23 bbloom: dnolen: preserving source tracking data is quite tricky with procedural transforms

13:24 dnolen: symbols are atomic, so it's trivial to reuse them, but composites must have the source data copied

13:24 dnolen: it's doable to auto-copy the top-level

13:25 aaelony: rurumate: got it. I''m interested in hearing what people think about each sched lib

13:25 bbloom: dnolen: you basically have a fn that calls the multimethod, and the fn just calls with-meta to copy that data across

13:25 dnolen: that should cover propagating 90% of the composite data, right?

13:25 as long as :line info is "inherited" down the AST, such that un-annotated forms get their parent's source info

13:26 dnolen: bbloom: hmm interesting idea

13:26 aaelony: cmajor7: not sure what "full blown" means for a scheduling lib… I'm looking for an nice idiomatic way to register functions for execution on a schedule, most probably execute on each hour or every h hours

13:26 seangrov`: dnolen: I'll change the syntax for now to test the keyword-related changes

13:27 bbloom: dnolen: ok, so that's step 1 & that should basically prevent the transform from fucking us up

13:27 cmajor7: aaelony: right, so that one function does just that

13:27 dnolen: seangrov`: if you can git bisect that would be helpful - I don't see how keyword changes could have affected this

13:27 aaelony: cmajor7: your refheap looks attractive, that might be enough

13:27 dnolen: seangrov`: or at least write up a ticket if you don't have time for that

13:27 coventry: I'm trying to set up a lein checkouts dependency. I've got a checkouts directory with a symlink a clone of the tools.reader repository, but "lein deps" or "lein classpath" is failing with the complaint that it can't find "artifact org.clojure:tools.reader:jar:0.7.7-SNAPSHOT in clojars". Do I need to do anything else to get lein to recognize the dependency? https://www.refheap.com/18116

13:27 bbloom: dnolen: step 2 is much bigger & we should not tackle this now, but i'll mention it so that you understand where we need to go

13:27 dnolen: we need to split analyze into two phases: parse & analyze

13:27 seangrov`: dnolen: It's not the keyword change, this happens on the latest master

13:28 Just as an aside

13:28 bbloom: dnolen: the ANF transform produces normal syntactical forms, b/c that's what the analyzer accepts

13:28 seangrov`: I'll check it out after I test the keyword stuff

13:28 bbloom: dnolen: but the syntactical forms are a human interface. the AST is the machine interface

13:28 aaelony: cmajor7: I suppose the only other nice feature to have would be to be able to easily cancel or change the execution schedule, and perhaps also to check on what is scheduled at a given moment

13:28 bbloom: dnolen: b/c of the way clojure works, parsing and analysis are mutually recursive

13:29 dnolen: but you can parse something to "i dunno what to do with this" and then analyze & then keep on parsing

13:29 dnolen: bbloom: ANF won't happen at the analyzer, it will happen in a compiler pass

13:29 bbloom: dnolen: yes, but after you rewrite, you need to re-analyze

13:30 dnolen: b/c your analysis is no longer valid

13:30 cmajor7: aaelony: it returns a future, so you can cancel those as you need to

13:30 bbloom: dnolen: you're introducing new local symbols, so the environment has changed

13:30 aaelony: cmajor7: that was my next question. sounds perfect!

13:30 cmajor7: aaelony: I guess changing the execution schedule would be cancel/reschedule

13:30 bbloom: dnolen: but i do things like `(~fn-sym ~@arg-syms)

13:31 again, this is step2 stuff we shouldn't be doing now, but ideally we'd do something like this instead:

13:31 {:op :invoke :f fn-sym :args arg-syms}

13:32 aaelony: cmajor7: i like that. I'll create a collection for the futures and that should work

13:32 bbloom: dnolen: b/c quasi-quoting implies environment & resolution. that's part of why macros in clj are annoying for cljs

13:33 dnolen: there are multiple environments inside the compiler, so it doesn't make sense to quasi-quote in the compiler's runtime environment when we are working with user-code environments

13:33 dnolen: so right now you need to (analyze form env) but i'd rather (parse form env) and (analyze ast env)

13:33 seangrov`: dnolen: After change the anonymous fn syntax, code compiles and Zenbox is running fine alongside Rapportive, and the tests pass

13:34 coventry: Ah, I needed to do "lein install" in the checkout dependency directory before it would work.

13:35 bbloom: dnolen: does that make sense?

13:35 futile: Can anyone recommend a certain fuzzy-string-matching library for use in a Clojure project?

13:35 aaelony: cmajor7: I can cancel any future, but how would I cancel the "every" call at some point?

13:36 futile: Also, why do we call them "libraries" instead of "spellbooks"?

13:36 A function is a whole lot more like a spell than a book.

13:36 dnolen: bbloom: it does somewhat, but it's also not an aspect of the compiler I'm concerned about yet :) it's annoying for sure.

13:37 bbloom: I'm not going to do full ANF, just enough to make a pluggable pass solve this specific issue via ANF transform

13:37 bbloom: dnolen: yeah, that's why i suggested just doing a no-op pass first

13:37 dnolen: so we can see how much that 1) impacts perf and 2) just to prove we can do it

13:37 aaelony: cmajor7: nevermind… getting it now

13:37 dnolen: bbloom: no-op pass is just identity but ok

13:37 cmajor7: aaelony: not sure I understand what you are asking. "every" returns a future, that you can cancel

13:37 bbloom: dnolen: well ok more generally: something that annotates every node with metadata like :was-touched true

13:38 aaelony: cmajor7: understand now.. thanks again

13:38 cmajor7: aaelony: sure

13:38 dnolen: bbloom: we can do this, but I'm really not as concerned about the perf of this as I was before.

13:38 bbloom: we already have ad-hoc passes in the compiler

13:38 bbloom: dnolen: ok then

13:38 dnolen: bbloom: it probably makes sense to apply the first pass to the ad-hoc one around fns

13:39 bbloom: dnolen: yeah, the more we can split things up, the better

13:39 dnolen: it's ok to have LOTS of passes if each pass is relative cheap

13:39 dnolen: bbloom: yep

13:39 bbloom: the biggest perf issue is to avoid consuming fuckloads of memory, that's what makes gclosure slow

13:39 dnolen: bbloom: I'm shooting for [fn-self-recur-pass anf-let-pass]

13:39 bbloom: they copy stuff left & right. we have a huge leg up having immutable structures!

13:40 s/immutable/persistent/

13:40 dnolen: i think a vector of passes is a good starting point

13:46 dnolen: seangrov`: excellent, I think I might wait a bit to merge this into master, I'd like to get the ANF thing in, CLJS is taking a big perf hit right now everywhere because we don't have it.

13:47 seangrov`: dnolen: No worries, I have my fixes locally, I'm able to work on problems for the business rather than the runtime for now. Obviously getting it into master will be nice though.

13:48 The ANF transforms do seem like a big effort though.

13:58 tufflax: I'm making a game. And there are a few subsystems in the game. I thought that most of them need to be updated every frame, so I made a protocol called Updatable, with just one function: (update [this]). But now, I need to pass an argument to one of the subsystems update function, and that's not something my design can easily handle. What am I doing wrong. It seems like such a simple thing, but my design can't handle it.

14:01 mlb-: I see many hyphenated names used as variables in Clojure. Taking a hint that this is the general style, why am I having trouble with hyphenated class names? Are there some filename/class name issues to be aware of?

14:01 cmajor7: mlb-: you mean module names?

14:02 tufflax: mlb-: as far as I know, class names are written in Java style camel case.

14:02 most of the time

14:02 cmajor7: mlb-: if it is indeed a module name, the name of the files needs to have an underscore instead of a hyphen

14:03 mlb-: a namespace/module can have a hyphen

14:03 mlb-: "your-module" would live in "your_module.clj"

14:03 mlb-: cmajor7: ah, that makes sense. I'd seen examples that followed that rule, but I hadn't seen an explicit rule

14:05 cmajor7: mlb-: some more info on the subject => http://stackoverflow.com/questions/4420944/why-does-clojure-convert-dashes-in-names-to-underscores-in-the-filesystem

14:15 Apage43: *cough* I just used leiningen to build a Java project that had no clojure in it

14:16 i feel a bit weird about that, but man was it easier than the other stuff i had handy

14:23 llasram: Apage43: I've got several small internal projects doing that

14:23 Side-benefit: it's easy to then write the tests in Clojure

14:23 And easy to turning it into a Clojure project if you start needing more than boilerplate

14:24 Apage43: ah, yeah. That's pretty fantastic as well.

14:24 I just needed to bang out a single java file command line tool as an API example

14:25 but it had a bunch of dependencies

14:29 callen: I'm guilty of doing this too.

14:29 Too lazy to use maven myself.

14:31 hyPiRion: me too

14:32 TimMc: That's what lein pom is for. :-P

14:32 callen: TimMc: I do that too.

14:33 but that's my point, everything I do with Java or Clojure is wrapped with Leiningen to varying degrees - usually holistically.

14:35 brianwong: this may be more of a java problem, but i need help with my standalone jar that i created with 'lein uberjar'. When i run the jar on my mac workstation, it runs as expected. I move this jar onto the amazon linux instance and run the jar. I get this NPE. https://www.refheap.com/18117 . Could this be caused by different java versions?

14:36 my workstation uses a later version of java than the server.

14:36 zphds: guys, is it ok to do assertions in let forms? as in, see if a var is truthy on something or error out before evaluating the let's body

14:36 callen: brianwong: sure it's not just a null?

14:36 zphds: you can do anything you want in a let form, but try to make it nice.

14:36 zphds: callen: I also just discovered :pre, :post

14:36 maybe I will use that

14:37 callen: also, I'm not really a fan of "error out" in the sense of an exception

14:37 I prefer to return and chain nils, short-circuiting ala Option/Maybe.

14:37 unless it's truly an exceptional case that merits immediate attention from the programmer.

14:37 TimMc: brianwong: Given that it's occurring in your config ns, it sounds like something is making your code take a different path in the Amazon env.

14:38 brianwong: i thought that once i have an uberjar

14:38 zphds: callen: ah… interesting… coming from a python world, I am used to raise exceptions… and then handle them

14:38 brianwong: that it should be portable and behave the same way on the jvm regardless of host OS

14:38 callen: brianwong: the uberjar doesn't freeze your environment variables or make things that don't exist suddenly exist on your deployment target.

14:38 brianwong: that is why im wondering if it is a JVM version issue

14:38 callen: brianwong: do you understand what environment variables are?

14:39 zphds: avoid it unless it is truly exceptional.

14:39 zphds: callen: yep

14:39 callen: zphds: consider the ease of use on the part of the caller.

14:39 zphds: callen: right…

14:39 callen: I *hate hate hate* wrapping try/catch around stuff.

14:39 brianwong: i do know what environment variables are. Im not sure why it is relevant at the moment

14:39 callen: brianwong: what TimMc said.

14:40 zphds: callen: haha… I guess it's because try, catches doesn't look good in a lisp'y language.

14:40 Phil_D: Does anyone have insight as to how to implement a "resolve"-like function in ClojureScript? Its absence is making it difficult to create complex and reusable functions.

14:40 callen: zphds: I will throw exceptions for things like configuration variables that should never be null

14:40 TimMc: brianwong: Without seeing your code, I can only guess that it is taking a different execution path because of different data in the environment. (Config files, working dir, etc.)

14:40 llasram: Phil_D: Like resolving in a namespace?

14:41 callen: Phil_D: clojurescript doesn't have vars, you should avoid prolifically abusing that for metaprogramming, especially for code intended to be cross-platform.

14:41 zphds: callen: a.k.a don't use exceptions to dictate program flows.

14:41 callen: zphds: precisely.

14:41 zphds: but I do use it to catch misconfiguration, "zomg the database disappeared!", things like that.

14:42 zphds: right

14:42 callen: things where I want the program to crash in a pretty mess.

14:42 zphds: for the record, I wrote my Python code like that too.

14:42 zphds: :)

14:42 callen: and still do.

14:44 Phil_D: llasram: Yes, like taking a string or keyword, converting it to a symbol, then resolving it like so in Clojure: (resolve (symbol "helloworld")). It makes passing function arguments as keywords easier.

14:44 callen: I see. Yeah, I understand Clojure and ClojureScript are similar, but far different beasts. I'm confused as to how macros work in CLJS, but I may end up taking that route instead of trying to hack my way around resolving symbols.

14:45 callen: Phil_D: dude, do *not* do that prolifically.

14:45 (resolve (symbol ...)) is extremely bad style.

14:46 I sincerely hope you're not kicking around read-string and eval all over the place too.

14:46 Phil_D: Nooooo no no no, haha.

14:46 callen: I'm unconvinced and regarding you with great suspicion.

14:46 Apage43: dude this isn't ruby

14:47 llasram: Phil_D: callen is overly brash, but I'd argue basically correct. Even in JVM Clojure `resolve` etc are for developer tools, not metaprogramming

14:47 * TimMc looks sheepish

14:47 Phil_D: Oh, God. You guys can tell I used to program with Ruby. '''>.<

14:47 llasram: Phil_D: I'd suggest a different approach, where you create a map (as in {}) for mapping from keywords to functions

14:48 If that's insufficiently dry, you can define a macro which creates the map

14:48 s,dry,DRY,

14:48 callen: Phil_D: Clojure gives you better, safer tools than this.

14:48 Phil_D: specifically, compile-time (macros) tools that allow you to stop doing silly (and often slow) things at runtime.

14:48 Phil_D: Okay, glad I'm getting my knuckles slapped on this one.

14:49 callen: Phil_D: embrace the fact that Clojure is a language that "executes" in two different phases.

14:49 Phil_D: understand what macro-expansion time means, how it works, how things "work" at that time, and how it can help you better structure your code for runtime.

14:49 we're not saying "go hogwild with macros", just that you have more and better options available to you.

14:49 Phil_D: callen: Awesome, thank you for opening my mind on this. I didn't know the implications until now.

14:49 callen: Phil_D: much of the misdesign of languages like Python and Ruby is that they have only one hammer - mutating state and eval'ing string-ish stuff at runtime.

14:50 Phil_D: with Clojure, code is data and you can work with that data at macro-expansion *and* run time.

14:50 Phil_D: embrace the parens :)

14:50 Phil_D: thing in terms of structure, not specific names an dstrings.

14:50 and string*

14:50 think*

14:50 rasmusto: callen: {()}

14:50 callen: jesus I can't type.

14:51 Phil_D: Is (pr-str) horrible practice as well? I only use it on the serverside to respond to (csrf protected) AJAX calls from ClojureScript.

14:51 callen: you know what I mean.

14:51 Phil_D: Otherwise my response doesn't read as EDN. That may be something on my end I'm screwing up, though.

14:51 callen: Phil_D: pr-str is...sub-ideal...but not outrageous. I would strongly consider/recommend proper serialization.

14:51 whether that be JSON, EDN, or otherwise.

14:52 TimMc: When you have two hammers, everything looks like...

14:52 llasram: Is there some why of generating EDN *other* than pr-str?

14:52 s,why,way,

14:52 (well, or `pr` etc in general)

14:52 Phil_D: Yeah, is there? I wasn't aware of EDN "serialization". I'm purposely avoiding JSON.

14:53 callen: a lot of people do it that way, but I'm making the point of encouraging a prinicipled decision to use edn, not using pr-str just because it's there.

14:53 I said pr-str wasn't outrageous.

14:53 I'm just worried about abuse of bidirectional read-string/pr-str

14:54 I haven't seen code so I can't get more specific than that, Phil_D's other indiscretions have me on the cautious side :)

14:54 Apage43: combine pr-str with clojure.edn/read-string rather than clojure.core/read-string

14:54 brianwong: callen: i found it was doing (.toLowerCase nil). The weird thing is that it was throwing an NPE only on the amazon platform and not my workstation

14:54 callen: - http://clojure.github.io/clojure/clojure.edn-api.html

14:55 Phil_D: ^^

14:55 safer reader.

14:55 default read-string in Clojure is not safe.

14:55 and not supposed to be.

14:55 Phil_D: Yeah, I've read about that.

14:55 callen: just making it explicit.

14:55 Phil_D: do you have a copy of Joy of Clojure?

14:56 it happens to cover introducing the Lispy-ness of Clojure and macro-expansion time reasonably well.

14:56 Phil_D: Yes! I ordered the eBook. I've read through the first few chapters, but I'm taking it slow because it's a lot to chew on.

14:58 futile: Phil_D: you should take out the "il" from your nick

14:58 shorter is better

14:58 callen: Phil_D: cool. Sounds like you're on the right track. I've done Python and Ruby before (more Python admittedly) and I'm far from the only one in this channel so if you have any questions/concerns or feel like you're going through an anti-pattern, ask in here.

14:59 futile: callen: what better way to persist data than printing pr-str to a file and reading it back with read-str?

14:59 Phil_D: callen: Haha, I think I will do that. Thanks for your advice! I'm really excited to fully grasp the language.

15:02 futile: Is there a function that prints out its single arg and returns it?

15:03 by prints out I mean using (prn)

15:03 callen: you would know this one

15:04 Basically a shortcut for: &&(second ((juxt prn identity) 3))

15:04 clojurebot: what's your syntax again?

15:04 clojurebot: Cool story bro.

15:04 futile: :/

15:04 ,(second ((juxt prn identity) 3))

15:04 clojurebot: 3\n3

15:06 xeqi: ,(#(doto % prn) 3)

15:06 clojurebot: 3\n3

15:06 futile: ah yes!

15:06 Still it'd be nice to have: (prn-ret 3)

15:06 or something

15:06 Guess I can make one.

15:07 technomancy: futile: doto

15:07 but it's not a function

15:07 oh

15:07 oops

15:07 futile: :)

15:07 callen: futile: a database?

15:08 futile: callen: WAT

15:08 callen: "what better way to persist data than printing pr-str to a file and reading it back with read-str?" - a database.

15:08 futile: callen: i cant agree

15:08 pr-str and read-str are perfect for this

15:09 callen: "perfect"

15:09 futile: thanks

15:09 i think so too

15:09 callen: those were scare quotes.

15:10 futile: so how are things

15:10 Is it true JSON can't contain literal newlines?

15:10 callen: "can't"

15:11 asteve: use vs. require, which is better? I feel that require is more descriptive which should cause less confusion and ultimately less bugs

15:11 futile: this makes my protocol way easier. no longer need a length prefix, just consider \n as msg delims

15:11 technomancy: asteve: require

15:11 futile: asteve: require with :as

15:11 I've seen gigantic (ns) blocks because they use :refer instead of :as

15:12 does not need to be so

15:12 callen: asteve: use require.

15:13 asteve: and if I want to require a group of files under the same namespace should I do multiple [com.package.module :as module] or is there a better way?

15:13 callen: ^^ I am delighting in the ambiguity of that in response to a question that was worded "use vs. require"

15:13 asteve: a group of files under the same namespace? gather them in a core namespace or something.

15:13 asteve: then :as the core

15:15 asteve: I don't know if you noticed, but this is a common pattern in libraries. The core.clj will be used to gather things from all the other modules.

15:15 so that users can just require the core.

15:15 asteve: ah

15:15 TimMc: futile: I've seen amalloy use a macro called "?" (or "spy"?) that prints the form, then the value, then returns the value.

15:15 technomancy: don't call it core though

15:15 you can come up with a better name

15:16 core is clojurese for "I can't think of a good name right now sorry"

15:16 callen: bulwark.core => bulwark.defense mayhaps?

15:16 futile: technomancy: i think of core as "hey everyone start your diggin here"

15:16 callen: ^^ me too, actually.

15:16 TimMc: [clj-thing.core "0.0.1-SNAPSHOT"]

15:16 futile: which is *super* helpful.

15:16 technomancy: futile: I like having internal stuff nested a layer deeper

15:16 futile: TimMc: hmm interesting

15:16 callen: I use core as a signal that it's a "site-map" for the library.

15:16 ro_st: core is the index.html of the clojure codebase :-)

15:16 technomancy: slam.hound / slam.hound.asplode / slam.hound.stitch

15:17 callen: futile: he's making fun of it, not suggesting it.

15:17 futile: technomancy: oh yeah i never think of "core" as internal. im talking about user-facing APIs. sure, the name is backwards for that purpose, but its convention now

15:17 TimMc: futile: I read that as "I was too lazy to start this properly and also too lazy to finish it."

15:17 callen: well now I know what bulwark 0.0.4 will be.

15:17 :P

15:17 futile: TimMc: well if there are others who used the same (legit) line of reasoning as me, that invalidates your way of reading it.

15:18 technomancy: futile: I mean you can tell where to start digging because everything else is a layer deeper

15:18 futile: and you cant safely assume that anymore

15:18 technomancy: oh

15:18 TimMc: futile: If it's an app, foo.main is fine.

15:19 technomancy: yeah, main means "CLI entry point" to me

15:19 TimMc: futile: My "lazy" comment refers to the combination of clj-*, core, 0.0.1, and SNAPSHOT.

15:20 ztellman: I made my first clj-* library recently, made me feel a bit dirty

15:20 callen: TimMc: don't forget the real coup de grace - undeployed to clojars yet has a Leiningen vector in the README.

15:20 ztellman: I can name things. It's the only hard thing in Computer Science I'm good at.

15:20 let me help you!

15:21 TimMc: ztellman: clj-tuple?

15:21 ro_st: ztellman: you write so many libraries i'm sure we can forgive you. just this once.

15:21 callen: TimMc: which is a sweet library.

15:21 ztellman: callen: it's a library that provides a clojure-specific tuple implementation, go

15:21 ro_st: -hides clj-madmimi-

15:21 TimMc: ztellman: Name it after a legume genus, based on tuples looking like "peas in a pod".

15:21 ztellman: it was either that or just "tuple", which has like 100 other entries in github

15:22 TimMc: why didn't I think of that

15:22 callen: ztellman: yeah I know the library, I'm digging into the curry-howard isomorphism of tuples and logic to figure out a clever name.

15:22 TimMc: It's not too late!

15:22 callen: TimMc: whoa that's pretty good.

15:23 TimMc: Hmmm... carob is a legume, and alo very tasty.

15:23 callen: Pisum sativum...

15:23 TimMc: (I discovered a jar of carob pods in the kitchen a couple weeks ago and have been working my way through them.)

15:23 ztellman: I dunno, my rationale is that if something does a thing, and there's more or less only one way to do it, a more straightforward library name is ok

15:23 callen: ztellman: French name for snap peas and snow peas is "mangetout"

15:24 TimMc: Ooh, fancy.

15:24 ztellman: that sounds like someone who bets on mangy horses

15:24 perfect

15:24 callen: LOL

15:24 win.

15:24 TimMc: haha

15:24 callen: Yeah, "Pisum" would be a weird name.

15:25 callen: TimMc: sadly all peas are the same species, snow/snap/etc are just variants, so there's not a lot of naming variety.

15:25 but the French saved the day.

15:26 ystael: but 'mangetout' refers to the fact that you eat the pod, right? is it better metaphorically to say the library does eat the pod (the tuple) or doesn't?

15:26 TimMc: I don't even know what language this is, but https://gn.wikipedia.org/wiki/Kumanda sounds pretty.

15:26 That was a language interwiki link.

15:26 callen: TimMc: Guarani

15:26 Phil_D: This is a newbie question, but I'm trying to wrap my head around data binding in ClojureScript. I've done it successfully with atoms and the 'add-watch' function, but I'm forced to define the atom then pass it to a function. Is there a way to "create" the atom within the function? *braces for callen's wrath on my indoctrinated OO mind*

15:27 callen: I'm not that fearsome am I?

15:27 bbloom: callen: i've told you before, your behavior influences the behavior of others

15:28 for every Phil_D who is willing to speak up, there are a countless others who are afraid to speak

15:28 ro_st: the only stupid question is the one you don't ask.

15:28 llasram: Phil_D: Can you give a more full example?

15:28 bbloom: Phil_D: in my experience, add-watch is only really useful for quick debugging of atoms. it's not a great foundation to build a "data binding" system on

15:30 callen: bbloom: your proclivity for plonking disqualifies the persuasion. :)

15:31 Phil_D: llasram: Basically I watch for the 'input' event from an HTML textarea that calls reset! on an atom bound to a DOM node (a </p> element).

15:31 bbloom: Gotcha. What would you recommend? It 'works', but it's hardly idiomatic.

15:32 bbloom: Phil_D: there are a number of approaches out there, but it's a bit of an open research program to do idiomatic/functional UI stuff

15:32 Phil_D: what approach you choose will depend on the scale of the problem you're trying to solve. what are you aiming for?

15:32 callen: Phil_D: functional reactive programming is one avenue of exploration. There are alternatives.

15:33 llasram: Oh, I missed the Clojure*Script* part this time... I will defer entirely to bbloom

15:33 ro_st: Phil_D: http://keminglabs.com/blog/cljs-app-designs/ might be of interest to you

15:33 clojurebot: Huh?

15:34 bbloom: Phil_D: dnolen has been blogging a bit about using core.async for UI work, which is very promising. check out this post: http://swannodette.github.io/2013/08/17/comparative/

15:34 Phil_D: his blog also has some simpler examples if you go back a few articles in the archives

15:35 Phil_D: there are are also a number of bridges to existing javascript frameworks, such as angular & other popular ones

15:35 Phil_D: Thanks bbloom and ro_st! I'll definitely check this stuff out.

15:35 ro_st: great. have fun with it!

15:35 bbloom: Phil_D: and there are a few more experimental / out-there explorations, such as pedestal

15:36 dnolen: Phil_D: watch out core.async is addictive. I got a couple more things in the pipeline but it needs Hammock Time as they say round these parts.

15:37 xeqi: I'm interested in hearing about any good solutions. Been trying the core.async go/loop with atoms instead of local state and it could be useful there

15:37 dnolen: xeqi: what leverage are you getting out of atoms? watches?

15:38 xeqi: dnolen: debugging mostly

15:38 ro_st: dnolen, it's still early days for me with async. i saw tbaldridge tweet about how channels are for coordination, not for state. is what you're doing in accordance with his statement, or in violation of it?

15:39 bbloom: xeqi: my solution has been to use so few atoms/refs/etc that i can just debug with reductions instead of add-watch :-)

15:39 Phil_D: dnolen: Definitely going to check this out then.

15:39 xeqi: attempting experimentation, I don't have a good feel for the split between what could be an external manipulatable element and internal state

15:39 bbloom: ro_st: keeping "state" in the loop isn't that big a deal as long as you only have one loop/state/brain/whatever per logical unit of state (ie a stateful widget)

15:39 xeqi: take your highlight / selector examples. The selector has to duplicate the highlighted state. I'm not sure how much I like that vs an atom

15:39 dnolen: ro_st: channels are for coordination, and no you should put queryable state into a go/loop

15:40 bbloom: i think "queryable" is the operative word

15:40 go-loops give you encapsulation

15:40 bja: go-loops are the addictive part

15:40 dnolen: ro_st: I meant "no you should *not* put queryable state in a go/loop"

15:40 Phil_D: bbloom: I was using purnam, which plays really nicely with Angular.js. This however was when I was just starting, so I realized I was just writing fancy-looking JavaScript, not embracing Clojure philosophy.

15:40 futile: Is it really true that JSON can't contain newline literals within strings?

15:40 dnolen: xeqi: the duplication is not a problem

15:41 xeqi: you think those two components are related but they are not.

15:41 xeqi: you can use one without the other, as it should be

15:41 ro_st: bbloom, dnolen, thanks

15:41 dnolen: xeqi: and you can test them insolation, as it should be

15:42 ro_st: however it's fine to push out the state changes so people can listen to them, that's the whole point.

15:43 ro_st: one thing I'm struggling with is how this pattern maps to MVC, where multiple components need to listen on some collection of data - I have some ideas, but still looking for cleanest manifestation.

15:43 ro_st: so what bhauman was doing with his dotsters game, there's no actual state in an atom, there. it's all either in channels or in the dom, i guess.

15:44 dnolen: ro_st: I don't think he ever checked the state of the dom? so all in channel.

15:44 ro_st: or rather in the flow of the system.

15:45 ro_st: well, i mean it's in the dom until you gesture and then it's back in channel

15:45 dnolen: ro_st: yes, but his code is nearly abstracted away from event source, this is really important

15:46 ro_st: so anything could generate those events, they could even come from a sequence that you spool - again testing.

15:46 xeqi: dnolen: ack, I meant I was concerned about the duplicated logic in state tracking. But I agree on the composability benefits.

15:47 ro_st: gotcha. yeah, it's a wonderful example. i often go and read through it just to stir up the pot.

15:47 dnolen: xeqi: yes, this is a non-concern

15:48 xeqi: start thinking of your program as mini distributed network of nodes and these sorts idea of "duplication" become entirely irrelevant

15:48 futile: Does anyone use validations libs in Clojure?

15:49 I've just been using functions that return nil or a string (or seq of strings depending on the thing being validated), which works fine with cond and such.

15:49 ro_st: dnolen: it seems like core.async helps us to apply the lessons from the reactivemanifesto.org stuff to the stateful client

15:49 dnolen: ro_st: yep, http://www.coursera.org/course/reactive

15:49 ro_st: i'm loving the idea that what we use for coordination and encapsulation in the large, between servers and processes, can be a big simplifying force in the small, in-process

15:50 dnolen: ro_st: not surprising that the suggested readings are SICP and CTMCP

15:50 ro_st: i'm signed up :-) going to do my homework in clojure though

15:50 yeah

15:50 `cbp: oh nice link dnolen ill sign up for that

15:50 dnolen: ro_st: agreed, it's very liberating, but it doesn't mean some biases about program organization have to be unlearned.

15:50 s/doesn't/does

15:51 ro_st: https://github.com/pedestal/pedestal/tree/with-core-async

15:51 `cbp: aw i need a scala book now though

15:51 ro_st: brenton ashworth has been tackling the dataflow problem with core.asyc

15:52 dnolen: yeah. in some ways, we're using tried and true techniques that are decades old, and in other ways, we're on the very forefront of system design and engineering

15:52 great time to be a developer!

15:54 squidz: ro_st: what kind of changes are expected for pedastal together with core.async?

15:54 xeqi: dnolen: hmm, I think I might have the wrong granularity for my messages in my toy examples. I see in your example's the selector doesn't care about the original input, just the "state update" message from the highlighter

15:55 I have a feeling this would work out better, time more exploration later

15:55 bja: I I found tailrecursion/javelin fascinating wrt reactive programming

15:56 dnolen: xeqi: yep, easy bit to miss

15:56 TimMc: &(format "lib-%04d" (rand-int 1e4))

15:56 lazybot: ⇒ "lib-6927"

15:56 ro_st: squidz: i can't remember, i'm afraid. brenton does talk about it a bit in http://thinkrelevance.com/blog/2013/08/13/brenton-ashworth-podcast-episode-037

15:57 i remember that derives were going to expose channels somehow

15:57 squidz: yeah I heard that podcast, that's why i'm interested but I guess the plans are under wraps for now. Can't wait to hear what they come up with though

15:58 ro_st: not under wraps, just not nicely documented somewhere :-) you can read through the commits in the branch here https://github.com/pedestal/pedestal/tree/with-core-async

15:58 good luck, though. quite a lot going on there!

15:59 i know that tim ewald has had success rewiring the interceptor stuff in services with core.async. pausing and resuming http requests from different threads of control is a great fit for CSP

16:01 squidz: cool thanks ill take a look

16:25 brianwong: i am writing a command line tool in clojure. some of the functions call (System/exit 1) in specific situations. How do I test for these situations? `lein test` considers these failures when in fact i want to verify them.

16:26 technomancy: brianwong: you can't do anything about System/exit calls

16:26 ro_st: (not (is …)) -shoots from the hip-

16:26 -grin-

16:26 technomancy: you need to wrap it in a clojure function and call with-redefs on that

16:26 SegFaultAX: Well you could wrap System/exit in your own fucntion

16:26 Yea.

16:27 Essentially you need to mock out the exit call.

16:27 technomancy: clojure really needs an exit function so there's a standard way to do that

16:27 brianwong: so i can mock out System/exit in my deftest?

16:27 and just check for whatever my mock returns?

16:28 technomancy: brianwong: no, you have to replace a clojure function that wraps System/exit

16:28 you can't replace Java methods =(

16:28 brianwong: derp

16:28 i see

16:28 so in my app code i replace all system exits with a function that just wraps it

16:28 then mock that new function in my deftests

16:28 gotcha

16:29 technomancy: FSVO "mock"

16:29 brianwong: FSVO?

16:29 Phil_D: dnolen: Oh no. I hope I sleep tonight. Core.async has sucked me in for good.

16:29 nDuff: "for some value of"

16:29 technomancy: I don't like to use the term because some TDD people get annoyed if you're not using their particular definition

16:29 brianwong: ok with-redefs

16:29 ill try that

16:30 thanks for the advice

16:30 technomancy: np

16:33 glosoli: How could one jump into interop method source code ?

16:33 technomancy: glosoli: I think you have to be using ritz for that

16:33 glosoli: technomancy: Hm nice, you answered two questions, (was gonna ask another, no need anymore)

16:34 SegFaultAX: technomancy: Meh, it's a mock. Screw TDD evangelicals.

16:34 technomancy: SegFaultAX: I think with-redefs is more general, but in this case it's probably a mock

16:36 glosoli: Hmm is there some way to destroy the binding? i.e. I have server function which executes http kit to run, and later I want to destroy it without restarting nrepl ?

16:37 SegFaultAX: technomancy: Agreed. with-redefs alone is much more powerful. But the pattern brianwong is implementing with it is mocky.

16:39 technomancy: glosoli: with jetty you just call .stop on the return value of run-jetty

16:39 no idea about http-kit

16:58 TimMc: Well, this is infuriating. tools.namespace will give you a list of namespace names for a directory, *or* it will give you a list of ns declaration blocks from namespaces therein, but it doesn't provide any mechanism for converting between the two.

17:00 If you give it a file, it will give you the ns-decl... but it won't take ns symbol -> File.

17:00 And if you give it an ns-decl, it won't tell you what the namespace symbol is!

17:11 futile: Dear friends, why are we fighting amongst ourselves? Don't you see, this is what they want? Let us not give in to their dastardly plans, let us remember we're on the same team, Team Clojuriana!

17:13 technomancy: I thought we were on Team Lisp?

17:13 or possibly Team FP

17:14 joegallo: oh god, it's still here

17:14 futile: No, it's Team Clojuriana.

17:15 technomancy: you can be VP of Marketing, that last guy had an existential accident.

17:16 technomancy: I think you have to use Windows to be VP of Marketing

17:16 futile: (I mean he no longer exists now. Wiped from history. Was never born. What, who? I don't know who you're talking about.)

17:18 technomancy: that's just an urban legend

17:20 SegFaultAX: The number of dynamic vars in this code is too damn high! :(

17:23 ozzloy: rent is too damn high!

17:23 glosoli: yeah ;/

17:23 ozzloy: i'm on team edward, myself

17:24 on a more serious note, i think i'm more on team continuous unit testing than i am on team lisp or fp

17:26 SegFaultAX: ozzloy: You just named three entirely orthogonal things.

17:26 ozzloy: yes

17:27 agreed

17:27 SegFaultAX: So, why not all three?

17:27 coventry: SegFaultAX: You've gotta focus to succeed. :-)

17:27 ozzloy: oh, i'm in favor of continuous unit testing in FP style lisp

17:27 SegFaultAX: ozzloy: There you go. ;)

17:27 ozzloy: but of the three, i think the first is most important

17:28 perhaps that was a better way to express it?

17:29 SegFaultAX: ozzloy: As I said, they're orthogonal concerns.

17:29 justin_smith: team tastes great vs. team edward, winner takes on team sparkle motion

17:29 SegFaultAX: Code can be more or less functional, but it can't be more or less functional /as a function of how unit tested it is/

17:29 Raynes: ozzloy: Team Damon.

17:31 ozzloy: SegFaultAX, we're in agreement on that

17:31 Raynes, matt damon?

17:31 Raynes: ozzloy: The Vampire Diaries.

17:32 seangrov`: ,(let [wrapper #(apply identity %&)] (wrapper [1 2 3]))

17:32 clojurebot: [1 2 3]

17:32 ozzloy: oh... uh... i don't actually know more than "team edward" is a thing i heard somewhere and it has to do with vampires and werewolves

17:32 futile: ,(third [1 2 3])

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

17:32 futile: pfft

17:33 ,(let [[_ _ x] [1 2 3]] x)

17:33 clojurebot: 3

17:33 futile: wooo

17:33 s4muel: ,(doc nth)

17:33 clojurebot: "([coll index] [coll index not-found]); Returns the value at the index. get returns nil if index out of bounds, nth throws an exception unless not-found is supplied. nth also works for strings, Java arrays, regex Matchers and Lists, and, in O(n) time, for sequences."

17:33 SegFaultAX: I also thought Matt Damon.

17:34 s4muel: also team Raynes, I discovered laser while trying to do... well, the exact same thing laser does with hickory zippers, thankee for saving me a boatload of time

17:34 futile: s4muel: that takes too many args

17:34 (Can someone please explain the latest http://buttersafe.com/ ?)

17:34 seangrov`: No one must be using anon fn shorthand with %& in clojurescript, it seems like it's been broken for awhile

17:34 Raynes: s4muel: Sent gifts to Los Angeles.

17:34 send*

17:35 TimMc: futile: (def third #(`[~@%](+(*)(*))))

17:35 &(#(`[~@%](+(*)(*))) [:a :b :c :d :e])

17:35 lazybot: ⇒ :c

17:36 SegFaultAX: TimMc: Swearjure?

17:36 futile: TimMc: noooooo!!!!!!

17:36 TimMc: What else? :-D

17:36 futile: "whyyyyy!!!!!????"

17:36 SegFaultAX: no its just ascii art

17:36 btw i found a great ascii art bed: "hmmm"

17:37 ozzloy: futile, the two coins decided to have same location in relation to each other. coincide sounds like suicide. one jumped off the table, so the other had to too

17:37 SegFaultAX: futile: http://hypirion.com/musings/swearjure

17:37 ozzloy: that's the joke. -mcbain

17:37 coventry: TimMc: Where do you come up with this stuff? I'm still not sure about all the details of your "out of order" example from yesterday. How come you can put the first "do" where you do?

17:37 ozzloy: although from the drawings, it looks like they weren't actually coincident during this event

17:38 futile: ozzloy: oh. thanks.

17:38 SegFaultAX: coventry: That's an easy one. They can get far more complex.

17:38 futile: well i think ive done enough to bring this channel off topic, time to work again

17:39 ozzloy: futile, "you suck, mcbain!"

17:39 futile: ozzloy: im just disappointed. all the other buttersafes were funny.

17:39 ozzloy: but its not your fault. you're just the messager

17:40 ozzloy: at least i messaged you well!

17:40 TimMc: coventry: The "do" thing actually exploits a Clojure bug, and isn't Swearjure.

17:40 futile: ozzloy: well except for that one lost packet

17:41 (of ketchup?)

17:41 java.lang.RuntimeException: Unable to resolve symbol: of in this context

17:41 * futile sighs

17:41 futile: what the hell have you guys done to me >:|

17:41 ozzloy: is swearjure still going on?

17:41 TimMc: coventry: http://dev.clojure.org/jira/browse/CLJ-1184 and then I rely on hash order to make the reader see the 'do as the first item.

17:41 ozzloy: Not actively, I think.

17:42 coventry: TimMc: Thanks.

17:42 TimMc: coventry: All those spurious keywords in there are to get the hashes to come out right. I did it by hand, and probably never again. :-P

17:43 coventry: TimMc: Yeah, I figured out the role of the keywords.

17:44 TimMc: &'#{(println "of") do (do :z/h283r (println "order")) (do :b121 (println "out"))} ;; here is what the reader sees

17:44 lazybot: ⇒ #{do (do :b121 (println "out")) (println "of") (do :z/h283r (println "order"))}

17:45 TimMc: Theoretically, one could write a program to generate these programs by balancing the hashes correctly.

17:46 coventry: "You can write brainfuck in any language."

17:47 Didn't know that even with a quote, the order of entries in a set could change. Hmm.

17:48 TimMc: They don't actually change.

17:50 Sets don't really have an order, but they need to serialize and deserialize in *some* (arbitrary) order. The reader doesn't care what order the items are in when it constructs the set, so #{1 2 3} and #{3 2 1} are the same.

17:51 However, when you ask for (first some-set), the set has to pick *something*. That's what the compiler is asking for when it special-cases 'do, and if you arrange the contents of the set correctly, 'do will be picked as the first element.

17:51 coventry: Oh, yeah, I meant in the reader representation. I have been thinking about things in terms of the reader representation, recently.

17:52 TimMc: I don't know if that example will work on different JVMs or Clojure versions, since the set's seq output might be different.

17:53 coventry: I'm interested in implementing a heuristic for mapping the (macroexpand)ed form back to the source form. I don't think this issue messes with my heuristic, though.

17:56 Bronsa: seangrove: what's broken with cljs' %&?

17:56 TimMc: coventry: Well, the reader should attach :line metadata, and I think there's :col support coming soon.

17:57 Bronsa: TimMc: tools.reader already attaches :column and I believe LispReader.java too?

17:57 coventry: TimMc: Fortunately, Bronsa's tools.reader has already implemented column information.

17:58 (Oh, well, I needed to use tools.reader for other reasons, anyway.)

17:58 Bronsa: yes, LispReader.java does too, tools.reader just attaches the info in more places

17:59 seangrov`: Bronsa: Just finished doing a git bisect, one second...

18:00 coventry: Bronsa: I have a patch for changing the behavior of tools.reader/{dispatch-,}macros. I will wait and see whether it gives me everything I need before submitting a pull request, though.

18:00 Bronsa: seangrov` are you sure you upgraded tools.reader to 0.7.6? there was a bug in that

18:01 seangrov`: Bronsa: This is working off of clojurescript master

18:01 I'll check what version it's using

18:01 Bronsa: coventry: sure, just keep in mind that tools.reader is a clojure contrib project, this means that (unfortunately) I can't accept pull requests, only patches from registerd contributors

18:01 seangrov` right, bit if you're running clojurescript from script/repljs you need to ensure you grabbed the last tools.reader from script/bootstrap

18:02 seangrov`: Bronsa: re-running script/bootstrap

18:02 Bronsa: but*

18:02 seangrov`: Would be an poor use of time on my part if that turns out to be it

18:02 Still, hope that is it ;)

18:03 coventry: Bronsa: Oh, that's interesting. Would that mean I have to get a registered contributor to vet a patch? (Worst case, I can probably just work with my patched library.)

18:03 Bronsa: coventry: yeah

18:03 I'm sorry :(

18:03 seangrov`: Bronsa: Seems like the same error

18:04 coventry: Bronsa: No, not a real problem. FWIW, the current patch moves the current tools.reader/{dispatch-,}macros to macros* and dispatch-macros*, and makes macros and dispatch-macros dynamic defs referring to them. It also makes tools.reader/wrapping-reader a public function. Does that sound workable?

18:04 seangrov`: Bronsa: Mind applying a test and running the test suite?

18:04 Bronsa: seangrov` sure

18:07 coventry: sure, I can do that myself if you really need it, but what's the rationale of renaming macros to macros*? We can just make macros :dynamic

18:08 coventry: Bronsa: That allows me to do things like this: https://www.refheap.com/18121

18:09 Bronsa: coventry: I'll make wrapping reader public right now, still have to think about making {dispatch-}macros :dynamic, I have to find a good use case (as stuartsierra and tbaldridge mentioned some day ago, we don't really want to make the read-table extensible)

18:09 seangrov`: Bronsa: https://gist.github.com/sgrove/6371745

18:09 It literally seems to be the %& causing the problem

18:10 Bronsa: The actualy stack trace https://www.refheap.com/45fd544bac82e81745a19fad5

18:11 Bronsa: mmh

18:11 user=> (read-string "#(apply identity %&)")

18:11 (fn* [& rest__1632#] (apply identity rest__1632#))

18:11 looks all right to me

18:11 (this is tools.reader)

18:11 seangrov`: Yeah, works in the repl

18:11 Somehow it chokes when running the test

18:12 Bronsa: seangrov` last thing before I try to check it out any better, are you sure you don't have tools-reader-0.7.5.jar in lib/ ?

18:12 seangrov`: Let me doubly-verify that I'm running 0.7.6

18:12 I have it there next to tools-reader-0.7.6

18:12 Bronsa: that should be it

18:12 try removing it and re run the tests

18:13 seangrov`: Yeah, that seems to be it

18:13 Bronsa: (and this is why I'd like to see clojurescript deps managed by leiningen)

18:13 seangrov`: So I should blow away lib/ every time I run script/bootstrap?

18:13 Bronsa: looks like it doesn't do any cleanup

18:14 seangrov` I'm happy it wasn't a bug though, you had me panicking a bit :P

18:14 seangrov`: Yeah, all things considered, that is a better outcome

18:14 Still, frustrating to spend 30min on it

18:16 Bronsa: seangrov` next time there's a problem that might be caused by the reader, ping me and I'll try to help

18:17 dnolen: seangrov`: Bronsa: if somebody wants to give me a patch adding project.clj for development use I'll take it.

18:18 Bronsa: dnolen: will do

18:19 (hoping that all the dependencies can be found in maven)

18:23 dnolen: Bronsa: wasn't true in the past since we didn't package everything, we do now

18:35 Bronsa: dnolen: is there a reason why pom.xml isn't fetching the last available com.google.javascript/closure-compiler or it just didn't get updated?

18:36 `cbp: yogthos: grats! I'll buy your book asap :D

18:36 dnolen: Bronsa: we don't like doing that, we try make sure everything works together at a specific revision

18:36 yogthos: `cbp: hey thanks :)

18:36 `cbp: let me know what you think

18:36 `cbp: sure thing

18:37 Bronsa: dnolen: I wasn't saying "why it doesn't automatically fetch the last version" rather "why did't it get updated to the lastest version"

18:37 didn't*

18:37 dnolen: Bronsa: it was the latest version whenever we decided to bump it.

18:37 Bronsa: ok.

18:38 callen: I am having a dumb with Compojure - https://www.refheap.com/18125 - any advice for getting at what I want?

18:40 pbostrom: callen: get rid of the trailing slash?

18:40 callen: what? that's never broken it before.

18:40 pbostrom: just guessing

18:41 callen: the URL in the link (href) has a trailing slash.

18:41 I'll try it anyway, but :|

18:42 amalloy: callen: i'd say check what params is in the request "around" this one; it doesn't seem likely that using context is relevant

18:42 callen: amalloy: I am dumping params in all the handlers.

18:42 I just bumped into something else that I think is promising though.

18:43 hrm, no. boned.

18:45 do url parameters not get merged into params or what?

18:46 alexbaranosky_: I want to access a package level variable on a Java object. What is the best way to do this?

18:49 cored: hi

18:49 is there something equivalent to Scala School for Clojure?

18:50 justin_smith: cored: 4clojure has some similar stuff

18:50 with an interactive interface more question / find answer oriented

18:50 cored: justin_smith: talking about this http://twitter.github.io/scala_school/

18:50 callen: I don't think it's nearly as general.

18:51 cored: perhaps one of the various clojure koan projects?

18:51 cored: Scala School looks more like some sort of specific overview for the language

18:51 justin_smith: cored: I know what you meant, just saying that individual problems on 4clojure have similar contents to the examples in scala school

18:51 coventry: The early parts of Joy of Clojure or Programming Clojure give such an overview.

18:51 alexbaranosky_: anyone know how to access package level fields on java objects from Clojure?

18:52 cored: justin_smith: I see

18:52 justin_smith: will try to check 4clojure and follow along with Scala School content

18:52 callen: alexbaranosky_: what does package level mean? Are you referring to restricted access?

18:52 like, "this field is private to the package" ?

18:52 cored: justin_smith: want to learn both things to compare

18:52 justin_smith: cored: for example https://www.4clojure.com/problem/1

18:53 mostly that just has some intro info, and then you try to apply it

18:53 then it leads you to the next one etc.

18:53 callen: justin_smith: it doesn't serve the same need.

18:53 coventry: justin_smith: I wouldn't want to work through 4clojure without the kind of overview cored is asking for.

18:53 callen: I'm with coventry, Scala School gives a nice overview.

18:53 the Clojure Koan projects I've seen are much closer to that than 4clojure.

18:54 4clojure is puzzle grinding and "how can I abuse Seqs?"

18:55 ambrosebs: core.typed is "production ready" https://groups.google.com/forum/#!topic/clojure/U_aA_Ce3qWg

18:55 cored: agree with both of you

18:55 tried first problem and failed :-P

18:55 callen: alexbaranosky_: I can potentially help you, but I need an answer first. If it's what I think it is, you can use reflection to bypass.

18:55 coventry: 4clojure is great for someone coming from an imperative programming background who wants to learn fp. (Like me. I'm about halfway through it.)

18:55 callen: cored: you're supposed to fail.

18:55 cored: maybe it can be a good idea to create a Clojure School same thing as in Scala School but translate it to Clojure

18:55 callen: cored: you don't pick up a guitar and start hammering out licks.

18:55 cored: callen: yes, sure :-)

18:55 muhoo: callen: speak for yourself :-)

18:55 callen: cored: creating a Clojure School equivalent to Scala School is already on my to-do list, thanks for bringing to my attention.

18:55 brehaut: ambrosebs: nice!

18:56 callen: muhoo: blah blah. show off.

18:56 muhoo: farthest I got was grab-bag.

18:56 ambrosebs: brehaut: :)

18:56 callen: ambrosebs: really? how fast is the type-checker?

18:56 muhoo: callen: no, i mean guitar. musical instruments are a natural for me. clojure, i have to work hard at.

18:56 ambrosebs: callen: slow.

18:56 cored: callen: I'm planning to fork that project and just change everything to match Clojure's :-P

18:56 callen: ambrosebs: any particular plan of attack for addressing that?

18:57 cored: uh...it'd be best if somebody that knew Clojure did that.

18:57 coventry: cored: Those books I mentioned will give you a running start, though.

18:57 callen: I don't know about "cloning" either. Clojure is different and merits a somewhat differently structured overview.

18:58 ambrosebs: callen: lots of caching? :)

18:58 cored: coventry: I see

18:58 callen: ambrosebs: :|

18:58 ambrosebs: callen: but it's certainly a priority for the next reelases

18:58 cored: callen: got it

18:58 callen: ambrosebs: is there anything to be learned here from say - GHC?

18:58 cored: will start checking Scala School until I get the book

18:58 callen: cored: wat

18:59 cored: callen: I want to check both languages, out of curiosity, I'm a Ruby developer ;-)

18:59 ambrosebs: callen: there's still some Typed Racket optimisations that I haven't stolen yet. Plus I'm sure some of my code is just really slow. I haven't put a large effort into speeding it up.

18:59 just a minor effort.

18:59 callen: cored: well, I'll put it this way. You'll find a lot more people moving from Scala to Clojure than vice versa. I'll leave my own experiences out of it.

19:00 ambrosebs: hum. I hope you like rewrites :)

19:00 cored: callen: and why is that?

19:00 callen: ambrosebs: excellent work all in all :)

19:00 cored: lots of reasons, but sbt is a good place to start.

19:00 clojurebot: Alles klar

19:00 cored: callen: I notice something in #scala at least, there's less people there than in here

19:00 ambrosebs: callen: hehe you get used it :) thanks!

19:00 callen: cored: that might be a demographic thing, I wouldn't rely on that *too* much.

19:00 but it might be indicative :)

19:00 I think Scala is - for now - more popular in the "enterprise"

19:01 but Clojure is eating up marketshare from the "bottom up" from startups, OSS, and SMBs.

19:01 cored: callen: would like to know what is it that make it so

19:01 justin_smith: what I would avoid is a language that mostly gathers around AIM

19:01 callen: cored: frankly, a smaller percentage of Scala users are active and doing any OSS.

19:01 cored: callen: where I live there's just one company using Scala that I know of, none is using Clojure

19:01 callen: right, like I said, Scala is currently more popular in the "enterprise"

19:01 but far fewer people in Scala are writing code at home, OSS, etc.

19:01 cored: justin_smith: AIM?

19:02 callen: so the tools are kinda languishing without Typesafe to shove them along.

19:02 in Clojure you'll find more people scratching their own itches and contributing.

19:02 cored: callen: that's weird

19:02 callen: that's an important sign of health.

19:02 Nah, it makes sense to me :)

19:02 cored: weird in this context, mostly what I work on are web applications

19:02 justin_smith: cored: some languages will pull more people together on IRC than others

19:02 callen: cored: great news, so do a lot of other Clojure users :P

19:02 bbloom: ambrosebs: good stuff!

19:02 cored: I was trying to find some sort of web framework in Clojure too; find just compujure and the other day pedestal

19:02 justin_smith: cored: a language that pulls more people together on IRC may or may not be better than another

19:03 ambrosebs: bbloom: cheers!

19:03 callen: cored: Luminus pulls together "good defaults" for web apps in Clojure.

19:03 justin_smith: cored: a language that mostly pulled people together on AIM on the other hand, I would not touch with a ten foot pole

19:03 bbloom: ambrosebs: have you found any bugs in popular libraries yet? :-)

19:03 cored: justin_smith: probably that's because is harder to learn

19:03 justin_smith: and people come here to ask questions

19:03 ambrosebs: bbloom: only in core.typed ;)

19:03 callen: cored: you might consider looking into that. It's not a full blown "web framework" necessarily, unless you want to use it for the nice "ready-to-go" project templates.

19:03 bbloom: ambrosebs: you should totally just fork projects, add type annotations, and report bugs, then brag about it :-)

19:03 callen: cored: it's all just components you can swap out at your leisure.

19:03 ambrosebs: bbloom: aww can't someone else do that? :)

19:04 I just build the type systems around here

19:04 callen: ambrosebs: nope, your job to market your baby :)

19:04 ambrosebs: :P

19:04 yes it's true

19:04 cored: callen: Relevance is the closest thing as Typesafe that I found giving stuff to Clojure

19:04 callen: not a bad comparison, but Clojure doesn't need the shove-along nearly as much as Scala.

19:05 were it not for the Play community, Scala would be in a very sad state for web stuff. Comparable to Haskell.

19:05 justin_smith: cored: clojure has a much simpler semantics and syntax than scala; scala has the advantage of looking more like other popular languages

19:06 cored: callen: shove-along?

19:06 callen: Writing Clojure code and pushing out Clojure projects is more fun and pleasant - no need to get into nitty-gritty.

19:06 cored: justin_smith: yes, I saw that

19:06 justin_smith: also Play framework :-)

19:06 yogthos: Scala feels enterprisey :)

19:07 so I suspect it does better in shops that use Java today

19:07 cored: yogthos: how does Clojure feels?

19:07 yogthos: they even look superficially similar

19:07 callen: cored: fun, powerful, simple.

19:07 yogthos: it feels awesome, but it's a sisyphean task to get it going in enterprise I think :)

19:07 callen: it provides a good, safe default path for clean semantics but lets me monkey with stuff when I need/want to :)

19:07 yogthos: you've had great success, be more fair :)

19:07 yogthos: it's much more likely to succeed in startup environments

19:08 callen: alexbaranosky: https://github.com/arohner/clj-wallhack

19:08 yogthos: took me 2 years :)

19:08 bbloom: cored: isn't the guy who made Play now chilling on the clojure mailing list? :-)

19:08 callen: yogthos: you work in gubbermint :P

19:08 technomancy: bbloom: that's Lift

19:08 yogthos: I sure do

19:08 cored: yogthos: :-)

19:08 callen: technomancy: I'd run for the hills if I made Lift too.

19:08 cored: bbloom: yes, where?

19:08 bbloom: ah ok Lift, heh

19:08 technomancy: from what I can tell Play is more accessible to Java folks

19:08 cored: bbloom: :-P

19:08 jkkramer: as someone whose done a fair amount of both scala/play and clojure web dev, i vastly prefer clojure

19:09 callen: Play is considerably better designed than Lift, but I still prefer Clojure to Scala/Play.

19:09 yogthos: I think most people do

19:09 bbloom: i think the scala people are publishing some great, practical research papers

19:09 yogthos: problem is most people don't give clojure a chance :)

19:09 cored: bbloom: another weird thng, I remember that guy running away from Ruby and saying why strong typed languages are better going to Scala and building Lift, now he is using Clojure

19:09 yogthos: and part of it is lack of polish

19:09 and that's changing nowadays

19:09 callen: bbloom: I tried running a research PDF with `/usr/bin/env scala` once, didn't work. Not very practical :(

19:10 scottj: arohner: you have you written any blog posts or such about circleci's experience using core.typed?

19:10 cored: jkkramer: why is that?

19:10 yogthos: I think tooling is a really big part though

19:10 arohner: scottj: not yet. I mean to

19:10 callen: yogthos: well, it's huge when your tooling is as bad as sbt.

19:10 yogthos: again from enterprise perspective people use stuff like eclipse and intellij

19:10 jkkramer: tooling is big, yeah. leiningen is awesome

19:10 (inc technomancy)

19:10 lazybot: ⇒ 73

19:10 yogthos: so working with scala feels very natural to them

19:10 bbloom: sbt and lein would probably feel like a really great case study on the typed and untyped approaches

19:10 callen: yogthos: CCW is fine though.

19:11 jkkramer: also, play uses a lot of questionable design choices

19:11 yogthos: that's what I use :)

19:11 cored: yogthos: well, I was trying Clojure with Eclipse and clockwise

19:11 callen: bbloom: I don't see how they're indicative of either side of the fence.

19:11 yogthos: gets my seal of approval

19:11 arohner: scottj: it's worked well though. it's something of a pain to start using with 'legacy' code, because in general your type signatures are more gnarly w/o core.typed

19:11 bbloom: callen: sbt's configuration is operator overloading EXPLOSION

19:11 callen: yogthos: I didn't know you used CCW, thought you were an Emacs user.

19:11 yogthos: but it would be nice to have a good alternative to eclipse that's not emacs :)

19:11 callen: bbloom: oh yeah THAT. That shit is insane.

19:11 cored: jkkramer: I built an application on Play was the best thing I've ever use in a Java env, for web development. Before that I was using Structs/JSF both things I hate with all my heart

19:11 bbloom: meanwhile, lein is just a bag of data

19:11 cored: s/Structs/Struts

19:11 arohner: where if you're using core.typed when you design the code, you say "wait, do I really want that gnarly signature? no. simplify"

19:11 yogthos: I think lein is a real winner for clojure

19:11 arohner: and in general, that's a good thing

19:12 yogthos: especially with lein templates

19:12 callen: bbloom: but that's data vs. executing operators against representations of data. Is that really indicative of typed vs. untyped?

19:12 yogthos: the other thing that needs to shake out is some standard ways to do stuff

19:12 callen: arohner: you use core.typed at your startup?

19:12 yogthos: our philosophy is not to do frameworks and prefer libraries

19:12 but that's a big problem for new people

19:12 because they don't know what libraries to use, or how to structure projects, and so on

19:12 callen: to that end, Luminus is a roll-up of current best practices and libraries - not a reified framework unto itself.

19:13 yogthos: a lot of basic stuff can be frustrating to find

19:13 bbloom: callen: you *need* types in order to make the operator overloading work

19:13 yogthos: that's the plan :)

19:13 jkkramer: cored: developing clojure web apps is much simpler (in the hickey sense of simple) - responses are simply functions of requests. that's sorta-kinda the case in play, but with awkward typing and implicit gunk getting in the way

19:13 callen: bbloom: necessary sure, but I don't see the other side of the mirror where you could use the abuse thereof to compare type systems.

19:13 yogthos: jkkramer: that's what I'm trying to convey with the book as well

19:13 callen: bbloom: maybe more of a cultural note?

19:13 bbloom: callen: yeah, it's clearly cultural

19:13 callen: That makes sense.

19:14 bbloom: although i guess you could use the Rep or Expr or whatever type they have

19:14 yogthos: I think that if there's a decent book describing the ecosystem people can get the basics nailed down

19:14 bbloom: and just get an AST and call that data

19:14 callen: yogthos: just...gotta stop using thread-locals in lib-noir man... :P

19:14 yogthos: then they can jump start into doing stuff that makes sense for them :)

19:14 callen: patches accepted :P

19:14 callen: yogthos: you won't like this nihilist's solution to it, that's why I haven't PR.d

19:14 and no, I don't mean just deleting it.

19:15 yogthos: lol

19:15 callen: yogthos: my solution would be request scope contract enforcement, surely you know that.

19:15 yogthos: you know you can't do that in lib-noir without user education.

19:15 yogthos: yeah would be a big change

19:15 callen: well? that's why you don't have my dirty dirty DIRTY macros in lib-noir.

19:15 yogthos: the main thing is sessions

19:15 callen: but I needed http-kit to work - so here we are.

19:15 yogthos: same solution.

19:15 (seriously)

19:16 it's all just implicit request context scoping.

19:16 cored: jkkramer: have to re-watch that talk, probably

19:16 yogthos: and to be fair you don't want to make it a straight jacket either

19:16 for lots of apps jetty is perfectly fine

19:16 even with current setup if you use db sessions you're fine

19:16 cored: maybe Clojure needs some sort of killing tool, like Rails or even Play

19:16 callen: yogthos: I'm not saying, "rm -rf / # if using jetty", I'm just saying, make it implementation agnostic, and the deeper magic requires obeying the scoping contract.

19:16 cored: don't you guys think?

19:16 callen: cored: no, we just got done explaining libraries > frameworks.

19:17 jkkramer: yogthos: i have some middleware i use a lot - interested in PRs for the generic ones? https://github.com/jkk/sundry/blob/master/src/sundry/ring.clj

19:17 callen: cored: libraries > frameworks means, you don't throw away the whole car when the alternator needs replaced.

19:17 hiredman: cored: no

19:17 yogthos: jkkramer: absolutely :)

19:17 callen: ambrosebs: does arohner use core.typed at CCI?

19:17 ambrosebs: callen: yep

19:17 cored: callen: well that's what helped Rails in a way, even when Rails is kinda well not suited for doing big things

19:17 ambrosebs: callen: for a few months now

19:17 callen: cored: you need to learn the "why" of how we do things first.

19:18 ambrosebs: sounds like an endorsement to me.

19:18 ambrosebs: callen: it's *the* endorsement ;)

19:18 callen: jkkramer: I like that wrap-failsafe.

19:19 ambrosebs: one of the more prominent "product" startups using Clojure. Very cool :)

19:19 jkkramer: yogthos: cool. happy to move these into community libs so i can shirk maintenance responsibilities ;)

19:19 ambrosebs: callen: arohner seems happy with it.

19:19 hiredman: cored: that assumes a goal of growing the language user base very quickly

19:19 callen: jkkramer: yeah uhh...I'm just going to steal all of this code. kthxbai.

19:19 cored: to roughly quote Rich Hickey - "we're happy being the BMW or Mercedes of programming langauges"

19:20 cored: hiredman: ?

19:20 jkkramer: callen: they could use some docs but yeah, they have come in handy

19:20 cored: callen: what does that mean ? :-)

19:20 callen: cored: look at my quote, it explains what hiredman said.

19:20 cored: we don't need a lot of users to be successful, as long as we're productive and happy.

19:20 cored: callen: I was watching the Neal Ford presentation on Clojure Master Plan

19:20 he suggested somethings that the Clojure community needs

19:20 callen: cored: such as?

19:20 cored: callen: wait

19:20 callen: cored: Neal Ford is ThoughtWorks, not Relevance.

19:21 cored: callen: yes, I know :-)

19:21 yogthos: jkkramer: and it makes it easier to find the stuff too

19:21 for common utils I think it makes sense to have one lib

19:21 callen: cored: the more subtle point being that people are more likely to take advice/ideas from those who actually use Clojure and understand the culture/aesthetic.

19:21 yogthos: I like his stuff a lot.

19:22 yogthos: I'm stealing the multi-arity wrap-failsafe immediately.

19:22 yogthos: nice :)

19:22 alexbaranosky_: callen: sorry was in a a meeting. I mean a field defined in a JAva class that has no private or public term in front of it

19:22 callen: alexbaranosky_: clj-wallhack?

19:23 if you can't access it by default, surely clj-wallhack can.

19:23 hiredman: cored: I don't know that I would want something that did for clojure what rails did for ruby to exist

19:23 callen: cored: you'll find more than one person here that doesn

19:23 doesn't like the way Rails or frameworks like it are designed either.

19:23 alexbaranosky_: callen: thanks!

19:24 mgaare: Neal Ford tells this funny story about a consultancy that uses clojure (and often sells it in terms of 'java with an extensions library'). They only have 4 people, so to make companies take them more seriousy, they made fake linkedin profiles for 16 more employees. The feedback from customers is, "wow you guys must have the 20 best programmers in the industry"

19:24 callen: mgaare: :P:

19:24 er, mgaare: LOL

19:26 Raynes: ambrosebs: Awesome work with typed clojure. :3

19:26 ambrosebs: Raynes: thx!

19:27 `cbp: hah websockets are so cool. I feel like I might be doing something wrong with my approach of 'websocket on every page!'

19:29 cored: mgaare: yes, heard that on a podcast

19:29 callen: well he talks about an abstraction layer for jdbc

19:30 callen: also something like the pogniant ruby book for clojure

19:31 akurilin: yogthos, ping. Really tempted to buy your book in beta. How far along is it as of right now, if you don't mind me asking?

19:31 yogthos: akurilin: all the core content is there and code samples are all working

19:31 akurilin: there's probably some typos and stuff along the way :)

19:32 akurilin: yogthos, Why is it 8 months away from being done then?

19:32 callen: cored: the abstraction layer for jdbc is c.j.j, and there are higher level layers than that.

19:32 yogthos: akurilin: oh that's probably just standard boilerplate, it should be releasing in mid september

19:32 akurilin: yogthos, oooh well that's a completely different story then.

19:33 yogthos: akurilin: I'll ask the editor why that date is there :)

19:34 akurilin: yogthos, Is the book mostly based on your experience making Luminus?

19:35 yogthos: akurilin: mostly my experience using it at work for the last couple of years

19:36 akurilin: yogthos, awesome. I'm glad someone stepped up to write a book about that specific topic, it's super relevant to my day to day work.

19:36 so gratz :)

19:36 yogthos: akurilin: luminus is spawned from that too so a lot of it is similar just explored deeper

19:36 alexyakushev: I need to force Clojure reader to read a map literal with uneven number of forms. Is there a simple way to do this?

19:36 akurilin: Also nice to have it written by someone whose name is well known in our circles.

19:36 yogthos: finding out how to do simple stuff was my big frustration :)

19:36 I'd end up googling this and that and then going oh well that makes sense

19:36 but if you don't have anywhere to start it's definitely frustrating

19:37 ddellacosta: if anyone writes a version of the poignant guide for Clojure I will hurt them

19:37 just sayin'

19:37 callen: ddellacosta: haha, why?

19:37 yogthos: my whole philosophy on this is that I love clojure and I want more people to use it :)

19:37 akurilin: yogthos, yeah that's what I've been doing for a while now, so it'd be good to learn from others who have gone through the process for much longer.

19:37 yogthos: once people have a good initial experience the language really sells itself I think ;)

19:38 akurilin: and I'm definitely open to feedback as it's mostly my own experience, so different angle is always good

19:38 I'm sure some stuff I do might not work for others

19:38 ddellacosta: callen: I shouldn't get too deep into it, but as a Ruby/Rails dropout I have really conflicted feelings about "why" and think we should not emulate that approach to thinking about software and development.

19:39 hiredman: alexyakushev: I've used a patched(not public) version of tools.reader to do that

19:39 ddellacosta: callen: but, you know, if someone really wants to do that, of course I won't *really* say anything, I'll just grumble away in my corner

19:39 callen: ddellacosta: I'll just say it - I think _why is overrated - but I think a blend of Clojure's philosophy and code in some format could be very cool :)

19:39 alexyakushev: hiredman: Thank you, perhaps that's the only way

19:40 hiredman: alexyakushev: did you accidentally print a map with *print-length* bound?

19:40 ddellacosta: callen: that is not at all the same thing, that sounds like it could be coherent, educational, useful, and all-around a good thing. I thought we were talking about why's poignant guide

19:40 technomancy: Learn You some Clojure for Great Good

19:40 callen: ddellacosta: no no, you're right. It's very different, I'm just thinking of different solutions to similar problems.

19:40 hyPiRion: I wish there was one

19:41 alexyakushev: hiredman: Not really, I need to grab a top level form from Emacs in which user is currently in, and he may be in a process of writing a map

19:41 ddellacosta: I kind of feel like 4clojure is a pretty awesome way to learn Clojure, but I'm biased 'cause that's how I started

19:41 akurilin: yogthos, ok that's cool, I'll let you know if I spot anything :)

19:41 brehaut: technomancy: im now imagining a clojure book made entirely out of repurposed wondermark and achewood

19:41 cored: callen: I should list the things that he said exactly

19:41 callen: wait

19:42 ddellacosta: technomancy: I didn't get far through it, but I recall Learn You a Haskell for Great Good being not-too-bad

19:42 * ddellacosta makes another note to actually sit down and learn Haskell this time

19:43 technomancy: brehaut: tempted

19:43 akurilin: yogthos, happen to have any coupons I should know about? :P

19:43 technomancy: ddellacosta: I work with the guy who wrote the Erlang one

19:43 yogthos: akurilin: none that I know :)

19:43 akurilin: yogthos, fair enough, was worth the try :)

19:44 ddellacosta: technomancy: very cool. Gotta dig into Erlang too one of these days

19:44 * ddellacosta makes another note to actually sit down and learn Erlang tho stime

19:44 yogthos: akurilin: indeed, I get like 5 free hard copies to give out when it's realeased and that's it I think :)

19:44 hyPiRion: technomancy: Wha, are there only awesome people working at Heroku?

19:44 technomancy: hyPiRion: well the FP nerds at heroku have to band together

19:44 fend off the node onslaught

19:45 hyPiRion: ah, good

19:45 hopefully there aren't that few over there. For your sake, I mean

19:46 yogthos: and afk here

19:50 [Neurotic]: Anyone interested in testing out a fix for the leiningan plugin for IntelliJ 13 EAP? Looks like I have it working

19:50 callen: [Neurotic]: LaClojure?

19:50 [Neurotic]: Yah, works with La Clojure

19:51 La Clojure has nightly builds for the EAP (finally have nREPL support), but the Leiningan plugin wasn't supported for 13 yet

19:56 seangrov`: callen: Interesting, I suppose that'd make Haskell the Tesla of programming languages

19:57 With Tesla showing more signs of industry momentum...

19:57 callen: seangrov`: I beg your pardon?

19:57 what did I say to make you think that?

19:57 seangrov`: "to roughly quote Rich Hickey - "we're happy being the BMW or Mercedes of programming langauges"

19:58 callen: I don't see Haskell's traction that you're talking about.

19:58 last I checked, there are still singular libraries that can still cause cabal to die from conflicts even if nothing else is installed.

19:58 seangrov`: Alright, let's say Tesla 10 years ago - brimming with potential to show the rest of the industry how it's done

19:58 technomancy: like elm?

19:58 callen: even if you use cabal-dev (irrelevant if you haven't installed anything else)

19:58 seangrov`: Alright, let's say a fisker then

19:58 callen: seangrov`: fisker is failing/failed, I'm okay with that comparison.

19:59 seangrov`: Great ideas and good design, just not quite enough to push it to success

19:59 callen: Bingo.

20:00 seangrov`: technomancy: Played with elm at all? cljs is still eating up all my "new language" quota these days

20:00 callen: so who else loves that destructuring is recursive? :D

20:00 technomancy: seangrov`: I tried last year but literally couldn't get past `cabal install elm`

20:01 seangrov`: just as well; I don't have any need for web frontend stuff ATM

20:04 callen: technomancy: re: literally couldn't get past `cabal install elm` - I keep trying to tell the Haskell users I know to take that problem more seriously and they don't listen.

20:05 technomancy: "The longer you have been working around a problem, the harder it is for you to see it as a problem." - Some Guy

20:06 I got notified via github issues that "cabal install elm should work now, give it a try" like two weeks ago

20:07 (on a bug I filed after last year's strangeloop)

20:07 hyPiRion: heh

20:09 callen: technomancy: that's called 'schlep blindness' in the HN community.

20:12 zachoakes: technomancy: i have a project that relies on two different libraries, one that relies on net.cgrand.parsley and one that relies on org.lpetit/net.cgrand.parsley (a fork).

20:12 Bronsa: dnolen: would you accept this? http://sprunge.us/XjQP?diff

20:12 zachoakes: since they have the same name, it seems to conflict, and leiningen uses the first exclusively, thus causing an error. is there a way to avoid the conflict?

20:13 technomancy: zachoakes: it's easy enough to get it to prefer one over the other using :exclusions, but having both loaded into the same JVM is hard

20:13 unfortunately aether doesn't have any notion of provides/requires or replacing one package with another

20:13 but those kinds of problems can be worked around manually usually

20:14 hiredman: technomancy: I doubt he is describing a lein issue, I imagine both libraries provide the same clojure namespaces

20:14 zachoakes: right, it's not lein specific, i'm just wondering what the normal way of solving it is

20:15 hiredman: there isn't one

20:15 technomancy: hiredman: yeah, by provide/require I was thinking more about apt-get

20:15 hiredman: zachoakes: you need to not depend on one or the other

20:15 they cannot both be loaded in to the same clojure runtime

20:16 technomancy: zachoakes: what do you really want?

20:16 is the lpetit one just the same as the original plus bugfixes?

20:16 hiredman: you can fiddle around with classloaders to load multiple clojure runtimes in the same jvm, but it is almost certainly not what you want

20:16 zachoakes: it's a fork but i don't know how substantial the changes are

20:18 i believe i tried adding net.cgrand.parsley to :exclusions at the top level of project.clj

20:19 dnolen: Bronsa: I would rather that the patch leave the current stuff alone, this way people can transition. Best if it's just a project.clj and nothing more.

20:22 Bronsa: dnolen: understandable, but that defeats entirely my rationale for having a project.clj at all: having lein automatically fetch and use new dependency as they get added instead of having to scrip/clean && script/bootstrap

20:23 dnolen: Bronsa: I don't see how a project.clj is conflict with the other scripts

20:23 hyPiRion: zachoakes: it should be placed inside the dependency I believe, see sample.project.clj for an example

20:23 dnolen: Bronsa: if you run lein instead of the other scripts you're good.

20:24 Bronsa: dnolen: certainly, but then you have to interactively launch the test suite instead of script/test

20:25 dnolen: Bronsa: I still don't see the conflict, lein test, instead of script/test

20:26 Bronsa: unless there's something about lein I don't know about

20:26 Bronsa: dnolen: lein test is not going to work, script/test calls cljsc test and then invokes the output with various js engines

20:27 dnolen: Bronsa: er I mean test-compile the on your changes

20:27 s/on/one

20:28 Bronsa: dnolen: there is no test-compile on my changes, I only removed a script that was useless/not usable anymore if that patch is merged

20:29 dnolen: Bronsa: you're not explaining yourself very well :) why do you need to change anything besides adding a project.clj?

20:31 Bronsa: dnolen: I'm sorry. if you followed the discussion I had before with seangrove, he spent 30 minutes trying to find a bug that was caused by him not running lein clean && lein bootstrap to update to the new tools.reader dependency.

20:32 zachoakes: hyPiRion: i did try :exclusions inside the dependency as well but no luck. if there was a way to make both dependencies use the same copy of parsley i think it may work.

20:32 Bronsa: dnolen: if we let leiningen handle dependency updates/classpath generation, once we bump a version in there, calling a script will automatically use the updated version without requiring us to script/clean && script/bootsrap every time

20:33 dnolen: the clojurescript test suite is not invokable by leiningen since it requires clojurescript compilation && running the compiled code with a js engine

20:34 (script/clean && script/bootstrap not lein)

20:34 dnolen: Bronsa: yes I follow your reasoning, I guess I wasn't clear earlier. I think it's better to do just one thing at a time. Add a project.clj let people know about it. Transition off the scripts in some later release.

20:35 Bronsa: dnolen: ok, fair enough. two separate tickets then?

20:35 dnolen: Bronsa: sure thing.

20:36 Bronsa: thanks much!

20:36 Bronsa: dnolen: no problem, sorry for the misunderstanding :)

20:47 dnolen: Bronsa: my fault really :)

20:49 bbloom: ping

20:49 bbloom: dnolen: pong

20:50 dnolen: bbloom: Bob Nystrom's comments about limitations of CLJS core.async / Generators + channels go me thinking

20:50 bbloom: tldr; you can't actually hide asynchrony

20:50 bbloom: link?

20:50 dnolen: bbloom: no link just a twitter convo

20:51 bbloom: anyways I realized that part of Rich's ideas is that go is kind of like loop/recur

20:51 bbloom: in Erlang and Go like you lie and be unexplicit, but you run into the unbounded problem.

20:51 bbloom: http://gist.github.com/swannodette/6373022

20:52 callen: dnolen: 'unbounded problem' ?

20:52 bbloom: dnolen: i'm looking at the tweets now

20:52 dnolen: bbloom: f pretends to provide a sync interface, it does not

20:52 bbloom: dnolen: "poison the entire callstack" is true, which is why go dispatches at the infinity point: it forks the process off as a top-level resource, to use the algebraic effect parlance

20:53 dnolen: bbloom: yes, but my point is that it's a lie, anywhere a function is aync but present a sync interface is an unbounded queue

20:54 bbloom: dnolen: f IS a sync interface. you're making it async by writing "go"

20:54 dnolen: bbloom: but it's equally poisoned in the other directly :)

20:55 direciton

20:55 callen: could someone explain the unbounded problem dnolen is referring to?

20:55 dnolen: bbloom: if I put this in a go block, I'm screwed

20:55 bbloom: callen: he's talking about how you can create unbounded queues by using asynchronous send

20:55 callen: and asycnhronous send is trivial: you just wrap a send in a go and then ignore it

20:55 or use put! directly

20:56 dnolen: bbloom: this is a trivial relation really, but I don't think I ever really understood the limitations of lightweight process model.

20:56 callen: bbloom: more to the point, lazily allocated channels?

20:56 dnolen: anywhere where you pretend the sync and async world can just transparently talk to each other - it's simply not true

20:56 bbloom: callen: no

20:56 dnolen: s/relation/realization

20:57 bbloom: dnolen: i don't follow how this doesn't also apply to core.async

20:57 dnolen: bbloom: oh no, of course it does :)

20:57 bbloom: oh lol ok then

20:57 callen: that was part of what confused me.

20:57 bbloom: yeah, it's totally like recur

20:57 dnolen: bbloom: exactly!

20:57 bbloom: recur == "tail call elimination is not an optimization, it's a feature"

20:58 go == "heap allocated stacks are not an optimization, they are a feature"

20:59 so it turns out that Algebraic Effect handlers addresses *both* of these problems!

20:59 you can treat a tail call as an "effect" just as you can treat spawning a goroutine as an effect

20:59 and you install an effect handler in your stack & if you try to use an effect that isn't in your dynamic extent, you fail

20:59 this way you can prove a program never spawns a process or makes an unoptimized tail call

21:00 dnolen: bbloom: seems worthy of blog post :)

21:00 bbloom: you gonna write it? :-P

21:00 dnolen: bbloom: haha, no

21:00 bbloom: you should write a post about recur & go

21:00 i'll follow up about effects ;-)

21:01 dnolen: bbloom: but I might write something up about the unbounded queues where async and sync worlds meet

21:01 seangrov`: dnolen: I've been very interested in the boundary between async and sync, would definitely be interested in reading it

21:02 bbloom: dnolen: i have so many comments/corrections/challenges to tha ttwitter thread

21:02 but i don't feel like explaining any of them in 140 chars

21:02 nightmare.

21:03 dnolen: seangrov`: well in some sense this isn't a problem with CLJS core.async since you can't lie, if you really want to talk to async world, you need to lift yourself up into it via go.

21:03 callen: bbloom: which?

21:03 bbloom: all of it. :-P

21:03 callen: bbloom: if you drop a name I could use as an entrypoint to the thread, I'd appreciate it.

21:03 dnolen: bbloom: hehe, would happy to hear your thoughts, but yeah not a good twitter convo.

21:04 bbloom: callen: https://twitter.com/munificentbob/status/372164340457041920

21:04 seangrov`: dnolen: Sure, but I've been wondering about the "infectious" nature of go-routines, callbacks, and sync-code, and the fact that none of them can seamlessly interop

21:04 bbloom: dnolen: but yeah, that's the thing about "go" is it says "spawn this to the top level"

21:04 you actually *can* do non-top-level goroutines, etc, but it's not truly asynchronous. you only have one thread of execution

21:04 which would actually be useful to do in a game setting

21:05 callen: bbloom: thank you.

21:05 dnolen: bbloom: I haven't heard of that, how can you do this?

21:05 bbloom: if you go check out that paper on Eff, you'll see the distinction is one of whether or not you have a "resource" which is a top-level object from the outside world

21:05 seangrov`: If you have async code, sync code can no longer (meaningfully) interact with it without a very explicit understanding (or common patter), and the same for go channels and callbacks

21:05 dnolen: bbloom: do you mean in golang you can do this, or in genearl?

21:05 general

21:05 bbloom: dnolen: no, not in Go

21:05 dnolen: bbloom: k

21:06 seangrov`: I think the core problem is that "return" is made meaningless with callbacks and go channels/routines

21:06 bbloom: dnolen: imagine you have a variable with a top level "system" for your go routines, channels, etc

21:07 dnolen: every channel would have a pointer to this top-level system thing

21:07 seangrov`: The same thing effectively happens in twisted python - you have to resort to patterns (like the standard node callback signatures) because you no longer have a common way of communicating return values

21:07 bbloom: if it's the true top level, you don't really care what's in that pointer. it's global, so it's not important

21:07 but let's say you wanted to create a mini little world w/ a particular scheduler & determinism and all that

21:07 dnolen: seangrov`: yeah, but part of my argument which I think is true, when you think of processes you don't really have a sensible return value outside of a channel anyway.

21:07 bbloom: you could create a protocol for "effects" which are basically messages you send up the call stack like exceptions

21:08 dnolen: seangrov`: this is much messier if the async model is task oriented (i.e. one-off)

21:08 bbloom: and then "handlers" like catch blocks, can dispatch on those messages & continue at the point where the message was raised

21:08 so you could just implement the channel protocols & dispatch to that implementation for some sub-tree of your dynamic extent

21:09 dnolen: bbloom: but inside the sub-tree are you saying you're not really async?

21:09 bbloom: dnolen: right

21:09 dnolen: bbloom: hrm

21:09 bbloom: dnolen: it would just be round robin or whatever

21:09 this would be super useful to do in general, b/c you could mock the outside world to test your goroutines

21:09 you could reify their execution state however you like & inspect it

21:09 seangrov`: dnolen: Yeah, I think yield is an interesting subset of channel-communication - it lets you give multiple "return values". But if you have multiple return values, you're sending messages

21:09 bbloom: see http://math.andrej.com/wp-content/uploads/2012/03/eff.pdf

21:10 example 6.10

21:10 on page 22

21:10 the protocol there is yield (not generator yield) and fork

21:10 they create a trivial round robin scheduler w/ a list & install it in the dynamic extent

21:11 you could create an effect with the following operations: new-channel, send, recv, alt

21:11 oh and go

21:11 i think that's the effect protocol: channel/send/recv/alt

21:12 and i guess technically, send/recv can be implemented in terms of alt

21:13 in addition to Cleff, which is lexical extent only still, i have a working interpreter w/ this stuff :-)

21:15 dnolen: bbloom: hrm, this model still seems broken even if you can do this in your world, it has a global side effect at the top.

21:15 bbloom: how does the whole thing get unscheduled for some other top level process?

21:17 bbloom: dnolen: so there is this notion of a "resource" which is a top-level thing

21:18 dnolen: everything is single threaded & if you want real threads & real asynchrony, you use a resource, which must be provided by the runtime

21:18 the idea is that you'll have very few top-level resources & anything else will wrap those as needed or just create local "pure" effects

21:19 the two most obvious resources are the store and IO

21:19 think of it like a kernel call

21:19 whenever you make a kernel call in C, your program suspends

21:19 the kernel does something, then resumes your program

21:19 any time you send an "effect" and it bubbles all the way up to the top w/o being intercepted, then that's like a kernel call

21:20 dnolen: bbloom: feel like pushing the problem around but ok. I do like the effect handler bit - though I'm not convinced yet it's any better than core.async preventing unbounded queues.

21:20 bbloom: so your kernel API needs to have load/store memory, plus spawn/kill threads, etc

21:20 dnolen: bbloom: you would want the system to know that you're ok if the queue gets to a certain size, but this sounds like undecideable problem.

21:20 bbloom: yeah that's totally orthoginal

21:21 you can implement core.async with a cheap-threads resource

21:21 or system threads

21:21 core.async is a stylized use of effects

21:21 a good stylized use!

21:21 anyway, gotta run. ttyl

21:21 dnolen: bbloom: what I mean is you don't often want to prevent crossing the bounday

21:21 bbloom: you want to specify some condition by which it is allowed

21:21 but maybe that's really hard to verify :)

21:52 gdev: dnolen, have you emblogenated all this? I'm trying to piece together the whole thing and I'm not following it very well =o

22:28 dnolen, nevermind, now that I've read the whole twitter conversation, previous blog posts, and Tony Hoar's book, I understand

22:28 *Hoare

22:35 futile: Is the Clojure compiler very complicated?

22:36 brehaut: on the scale of compilers? not so much

22:36 and it depends waht you think of whitesmith style

22:37 futile: Would it be hard to write a parser for Clojure syntax in another language?

22:38 brehaut: no

22:38 gdev: hard for who?

22:39 futile: Me.

22:39 I'm considering a very stupid idea.

22:39 jimrthy: The parser wouldn't be that hard...but actually running it would probably be pretty difficult

22:40 I'm a fan of stupid ideas

22:40 hiredman: the clojure compiler?

22:40 futile: I'm thinking of creating a Clojure IDE where the front-end is written in ObjC + Cocoa, and to do the integration features would communicate to a running Clojure process for that Lein project.

22:41 hiredman: the clojure compiler is hard to make changes to

22:41 jimrthy: (Sorry for interrupting, brehaut...sometimes I can't keep my mouth shut when I should)

22:41 futile: Mainly because I'm much more proficient at Cocoa than Seesaw.

22:42 gdev: clojure IDE? like emacs?

22:42 brehaut: futile: writing a parser for clojure for a text editor his relatively straight forward, likewise nrepl shouldnt cause any major problems

22:43 futile: brehaut: good to hear

22:43 brehaut: i wrote a simple recursive descent one in javascript in a relatively short space of time

22:43 futile: Is there a definitive place to know all the syntax it supports?

22:44 brehaut: the implementation and clojure.org

22:44 the reader page on clojure.org is relatively comprehensive

22:44 gdev: futile, https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/Compiler.java

22:44 futile: Actually better question: are there any surprise aspects to the syntax that aren't commonly used?

22:44 Because I think I know the syntax well enough right now.

22:45 brehaut: the parser is more permissive than it officially supports

22:45 and #_ might trip you up

22:45 futile: brehaut: nah, it just expects a valid form afterwords right?

22:45 brehaut: right

22:45 futile: easy enough.

22:46 brehaut: but you probably have to special case it because its removed from the parsed form

22:46 ivan: futile: people use all kinds of characters in keywords that clojure.org says aren't allowed

22:46 futile: So I suppose all I need to do is build up an AST where each node includes the line/char coords, and what type it is. Then I can use that to decorate an existing text view.

22:47 So it sounds like this first part will be straight-forward. But integrating with a Lein project might not be.

22:48 seangrov`: Parsing will probably take up plenty of time

22:48 futile: Like, a few hours? Days? Weeks?

22:48 I can't imagine it taking more than a weekend or two.

22:49 seangrov`: Few days to get something reasonable, probably

22:49 futile: Reasonable in terms of performance, or actually working?

22:49 seangrov`: Actually working

22:49 futile: :/

22:49 brehaut: from memory it took me a week all up to write a syntax highlighter including the shenanigans to hook into the javascript library i was using

22:49 and performance tuning it

22:50 xeqi: I feel like a reference to https://github.com/cgrand/sjacket might be appropriate here

22:51 seangrov`: Wow, very cool

22:51 futile: xeqi: that was my first thought, thank to trptcolin pointing it out to me

22:51 xeqi: also possibly https://github.com/laurentpetit/ccw/tree/master/paredit.clj

22:51 futile: xeqi: but I can't help but think I should do the parsing on the ObjC side to minimize the things needed to be communicated between ObjC and Clojure

22:52 xeqi: true, these are better for a clojure based ide

22:52 like say http://nightcode.info/

22:53 futile: The only things I want to talk to Clojure about are the actual structure of the current project, things like jump-to-symbol etc

22:53 xeqi: ah, then you want an nrepl frontend

22:55 futile: xeqi: frontend in what way?

22:56 I figured I would have an ObjC GUI app that talks to a Clojure instance of [something] which sits inside the given project and can tell my ObjC all about its structure.

22:56 I'm not sure if [something] is nrepl or not.

22:57 Whatever it is, it needs to house several custom functions I create in Clojure.

22:58 brehaut: nrepl perhaps with middlewares or whatever it has that ive forgotten

22:58 xeqi: futile: I would expect nrepl would be a good starting point

22:59 possibly with custom middleware for your custom functions

22:59 ala the completion middleware, or ritz

22:59 futile: sounds good.

22:59 thanks guys :)

22:59 ok ill start on the objc frontend with proper syntax highlighting

22:59 woot, exciting times

23:00 i suddenly have lots of confidence in my ability to do things after the success of zephyros

23:00 hopefully not overconfidence :)

23:00 xeqi: cause I can associate your previous sentence with: have a C app (emacs, vim) that talks to a clojure instance of (nrepl running the project) and can tell the program all about the structure

23:01 futile: xeqi: well at first I had this vague feeling that it was *only* using nrepl, and nothing custom on top of it, and everything it needed was built *into* nrepl. In which case it wouldn't be a good fit. But if it has middlewares as you say, then that seems reasonable.

23:08 ddellacosta: are people interested in fixture/scaffolding kind of libs for clojure? I feel like I'm always writing ridiculous amount of setup/teardown crap. I'm not sure if my testing strategies suck (probably), but it seems like it would be handy to have a bunch of helpers which would let you spec out default fixtures in some way kinda like FactoryGirl/Machinist/etc. in Ruby-land. Does anything like this exist?

23:09 along those lines, I'd like something that makes it easy to sketch out DOM fixtures in CLJS-land.

23:09 mgaare: ddellacosta: do you think like FactoryGirl buys you anything that isn't already there thanks to clojure's richer syntactical offerings?

23:10 clj_newb_2345: http://www.ymacs.org/ <-- is there anyting like this, but written in clojurescript?

23:10 I'd love to have something emacs-like, running in the browser, and instead of elisp, uses clojurescript

23:11 ddellacosta: mgaare: it's a good question. I'm not sure it built in clojure using an abstraction that would solve problems for people, but I'm imagining something that would like you specify simple keyword args and reasonable defaults and then handle the setup/teardown, if you merely plugged in a database config. I do a lot of that manually now, and it takes me time to build out helpers, always.

23:11 mgaare: so, I mean, I don't know. Maybe?

23:12 SegFaultAX: 'ello boyos and girlos.

23:13 ddellacosta: mgaare: I should be specific, I'm talking about targeting DB-driven apps, especially web-apps. But even with this there is a lot of variation with what folks are using, it seems…Datomic to Mongo to Postgres...

23:13 'ello SegFaultAX.

23:13 mgaare: ddellacosta: the other thing I've found working with idiomatic(ish) clojure is that doing tests that actually the railsey style of actually setting up a test db

23:13 rather, I've found that I haven't needed to do that.

23:14 all of the clojure database libs I've come across work in terms of maps. So I tend to prefer to just fake the database layer

23:15 rhg135: https://www.refheap.com/18133 can i make the tracer module close over the value of comp-num at the time? (comp-num is supposed to be a unique id)

23:15 tracer function*

23:16 SegFaultAX: I have mixed emotions about that. For a lot of stuff it totally doesn't matter, so decoupling from the database is a good thing. But other times you really do want to see how the code interacts with the database.

23:16 ddellacosta: mgaare: interesting. The thing is, my schema is complex enough that faking this in and of itself would take just as much time. And another thing I've struggled with lately is how coupled our DB layer should be with the "model" layer. I find that I enforce a lot less separation in Clojure-land, and rely on the DB more.

23:16 SegFaultAX: Since it's easily the most crucial component of your site.

23:16 (Even the site itself isn't as important in the grand scheme as the database)

23:16 ddellacosta: yeah, I mean, I've really had to rethink my strategy for interacting with the DB since I started building apps in Clojure. It's turned a lot of my previous assumptions upside-down.

23:17 SegFaultAX: ddellacosta: That's a feature!

23:17 clj_newb_2345: let's start a kickstarter for a emacs-writtten-in-clojure

23:17 ddellacosta: SegFaultAX: most definitely, I'm thankful for it! But it means I can't be lazy...haha

23:18 SegFaultAX: clj_newb_2345: Let's not.

23:18 jack_rabbit: clj_newb_2345, and never speak of this again.

23:18 SegFaultAX: There should be a Greenspun-like law for editors relative to emacs.

23:18 rhg135: agreed

23:18 clj_newb_2345: jack_rabbit: are you an op here?

23:19 SegFaultAX: I think rhickey is the only op.

23:19 You can get chan info from chanserv though.

23:19 jack_rabbit: clj_newb_2345, no.

23:19 clj_newb_2345, I was just joking.

23:19 clj_newb_2345: given the option, why would anyone prefer scripting their editor in elisp rather than clojure?

23:20 SegFaultAX: Oh no, technomancy, chouser and a few other are also ops.

23:20 amalloy: SegFaultAX: chouser is an op, and i think technomancy became one too

23:20 mgaare: ddellacosta: there are definitely some style issues that I don't think have gotten entirely settled in clojure yet when it comes to db use

23:20 SegFaultAX: amalloy: Yea. /msg chanserv access #clojure list

23:20 clj_newb_2345: if you write some [piece of software, say lein, that every clojure user users, you deserve to be an op

23:20 jack_rabbit: clj_newb_2345, not sure. But I don't think re-writing the millions of lines of elisp is really feasible.

23:21 clj_newb_2345: if I wrote lein, my resumee would be "does your companay use clojure? hire me, bitches"

23:21 SegFaultAX: clj_newb_2345: If you wrote lein, all your resume would have to have on it is your name and email. Eg, hand them a business card

23:21 Hired.

23:22 clj_newb_2345: right right, when you write lein, you don't apply for jobs; jobs apply for you

23:22 amalloy: i think technomancy's resume is more like "does your company use github? no? don't hire me then"

23:22 jack_rabbit: sounds about right.

23:22 SegFaultAX: "Oh and also, I wrote lein"

23:23 brehaut: nah, its a single frame form a webcomic

23:23 ddellacosta: mgaare: yeah…but I think that they point to a larger problem in software engineering in general, wrt databases. Coming from a Rails background myself, I feel like I had a lot of faulty assumptions based on the cardinal law that databases were some sort of "dumb store" and you need to enforce de-coupling…of course, this is not in any way a new thing:

23:23 http://www.codinghorror.com/blog/2006/06/object-relational-mapping-is-the-vietnam-of-computer-science.html

23:23 tim: ddellacosta: I like Rich Hickey's take in one of his talks: ORM == OGM

23:24 *ORM == OMG

23:24 clj_newb_2345: btw, is there actually any _book_ on datalog? I hear that it's got the both of the relation model and prolog, but can't seem to find any structured infroamtion on datalog

23:24 mgaare: clj_newb_2345: there would need to be some big style changes with emacs to make it in line with idiomatic clojure. Almost all elisp assumes that there are mutable lists everywhere

23:24 ddellacosta: mgaare: what clojure does, for me at least, is exposes the lazy assumptions I had for years and has forced me to think about what persistence means and what de-coupling means and etc.

23:24 tim: clj_newb_2345: you have to define datalog, there are many flavours, do you mean the Datomic datalog?

23:25 ddellacosta: tim: ha, I remember that, it gave me a chuckle. He always has some funny, pointed moments in his talks like that

23:25 jack_rabbit: ddellacosta, that's the beauty of true functional programming.

23:25 mgaare: ddellacosta: Rails migrations are a crime against humanity ;)

23:25 ddellacosta: jack_rabbit: yah. heh

23:25 SegFaultAX: tim: TimMc?

23:25 ddellacosta: mgaare: I didn't used to think so, which is more evidence to prove your point. :-)

23:26 tim: SegFaultAX: nah sorry, tbaldridge

23:26 SegFaultAX: tbaldridge: Oh cool. Just wondering :)

23:26 gdev: clj_newb_2345, http://www.infoq.com/presentations/Datalog is a good place to start

23:26 mgaare: ddellacosta: Another thing to bear in mind is that in clojure, the cool kids tend to like to use datomic as the db for new projects

23:26 SegFaultAX: Rails migrations are one of the more useful things about Rails. There is a /lot/ of shit I hate about Rails, but migrations isn't one of them.

23:27 ddellacosta: mgaare: I don't have the cash to use it. ;-(

23:27 tbaldridge: ddellacosta: the free version is well....free. And I know several companies who get along just fine with it.

23:27 mgaare: ddellacosta: the free storage is actually pretty good

23:28 depends on what you're doing

23:28 SegFaultAX: One transactor can take you pretty far from what I understand. Especially on super read-heavy apps (which a lot of apps tend to be anyway.

23:28 mgaare: if you're doing something that you would use mysql in a somewhat standard railsey way, then datomic's free storage should be awesome

23:29 ddellacosta: SegFaultAX: I feel mixed wrt Rails migrations. They can be handy. But I no longer trust down-migrations like I used to.

23:29 SegFaultAX: ddellacosta: When using #change?

23:29 ddellacosta: tbaldridge, mgaare: okay, I guess it's probably more accurate to say that I can't legitimately evaluate datomic right now because of other obligations, and I use price as an excuse. ;-)

23:30 mgaare: I've come to think that if you're doing a lot of rails migrations, then maybe a relational database isn't really what you want

23:30 callen: SegFaultAX: hypothetically 8.2 million transactions per second.

23:30 SegFaultAX: mgaare: What?

23:31 gdev: datomic is only free if your time is worth nothing, ;0

23:31 callen: mgaare: what?

23:31 gdev: to repurpose a quote about linux

23:31 callen: Datomic is about to save me a ton of time and hassle at work, it's a win for me and my company anyway.

23:31 ddellacosta: SegFaultAX: generally speaking I mean. I agree with this: http://flywaydb.org/documentation/faq.html#downgrade

23:32 tbaldridge: gdev: learning anything takes time. Nice thing is, learning datomic too me way less than most DBs

23:32 SegFaultAX: ddellacosta: Yea #change is shit. Just stick with explicit ups and downs.

23:32 It's better that way.

23:32 callen: I don't think anybody is saying Datomic should be used for everything under the sun, but I think it's pretty straightforward to learn and it has more niceties and broader applicability than many may think.

23:32 mgaare: if you are making that many schema changes where rails migrations are solving a big problem for you, maybe a nosql database would be a better option

23:32 ddellacosta: yeah, I can't say I wouldn't be using Datomic if I didn't have the option, I'm definitely interested.

23:32 callen: mgaare: ick, no.

23:33 tbaldridge: gdev: and if you get tasked with a project (like I was) where you need to do a 3 way compare on update with partial merging of data, Datomic is pretty much the only correct answer. SQL is a ugly hack in that case.

23:33 SegFaultAX: mgaare: Dude, just no.

23:33 callen: mgaare: migrations aren't nearly as painful as corrupted data.

23:34 mgaare: I've happily used "NoSQL" data stores in the past, but you shouldn't abandon an RDBMS where its use is commended just because you're finding a migration sticky.

23:34 SegFaultAX: And rapid iteration and changing business requirements doesn't mean we should throw schema out the window.

23:34 callen: That's like saying because stop signs are painful, we should just charge through and plow pedestrians over.

23:34 ddellacosta: tbaldridge: oh god, I've done something like that 3-way compare in Ruby + SQL and it was hell

23:34 callen: I mean, don't get me wrong, I'm all for culling the herd - but that's not a good reason for doing it.

23:34 SegFaultAX: callen: This is the sort of dribble I expect to hear from "webscale" type people. Not the fine upstanding citizens of #clojure

23:34 * SegFaultAX ducks

23:34 ddellacosta: heh

23:35 gdev: okay, so when I do winky o-face ;0 that means I'm kidding

23:35 ddellacosta: I got yer webscale right heah

23:35 SegFaultAX: s/dribble/drivel (don't know what my fingers were typing there)

23:35 callen: SegFaultAX: clearly your inputs needed validation...

23:36 * callen WINK WINK NUDGE NUDGE

23:36 gdev: I'm the guy trying to get Simulant as an approved testing framework at my job...Clojure Datomic and Datalog on the approved technologies list in one swoop, =D

23:36 SegFaultAX: gdev: Well done!

23:37 There's a really hardcore process for adopting new tech at my job...

23:37 "Hey guys, I'm going to write this in Clojure. If you don't like that, please forward your complaints to /dev/null"

23:37 mgaare: callen: one hard migration in an app that works well with rdbms, no problem. I think a big pile of migrations can be cause for concern though

23:37 SegFaultAX: Then I slam my macbook air on the ground and walk to blue bottle.

23:37 callen: the process for getting Clojure + Datomic at my company involved explaining it to the project manager. PMs are often hackers, so it wasn't hard. That was about it.

23:37 mgaare: I don't thin kso.

23:38 SegFaultAX: macbook air? pleb laptop.

23:38 SegFaultAX: only non-programmers have MBAs at my company. :P

23:38 gdev: SegFaultAX, I like it, are you guys accepting resumes?

23:38 SegFaultAX: callen: Remember, it's pairing environment.

23:38 callen: ...hrm. that's a truism.

23:38 SegFaultAX: oh right, with that kind of efficiency you might as well code on chalkboards. Proceed.

23:38 SegFaultAX: callen: Primary development is on beefy desktops.

23:39 callen: screeeeech, "def get", scraaaaaaaaape

23:39 SegFaultAX: Well not beefy, but at least they're 486's!

23:39 callen: *chalk breaks* fuck it, lets scrum.

23:39 SegFaultAX: gdev: Why yes, yes we are.

23:39 callen: SegFaultAX: with the turbo button?

23:39 mgaare: I think nosql gets a bad rap because mongo sucks

23:39 SegFaultAX: callen: Don't get crazy dude. We don't need that kind of speed.

23:40 callen: mgaare: Mongo sucks, but NoSQL is not a general purpose persistence solution - period.

23:40 SegFaultAX: mgaare: I think nosql is about as useful of a term as "OOP" or "FP"

23:40 callen: gdev: don't let him fool you, they're a rails shop. No Clojure in sight :P

23:40 SegFaultAX: Not true!

23:40 callen: mgaare: NoSQL as a "term" and a VERY rough grouping fell out of the need for super high scale specialized persistence layers.

23:40 SegFaultAX: Well, the rails part is. But the Clojure part isn't!

23:41 callen: SegFaultAX: where's the beef?

23:41 mgaare: note that none of what I just said includes, "dinky internal dashboard for SMB"

23:41 SegFaultAX: callen: In your mums trousers! Oooooooh

23:41 * SegFaultAX c-walks away

23:42 callen: SegFaultAX: no but 5realz. Where the parens at?

23:42 we've upgraded to (inc :4realz) so truth me.

23:42 mgaare: I'm no new-db expert, to be sure. My "nosql" experience has mostly been with couchbase

23:42 callen: mgaare: that's not a general purpose persistence solution either.

23:43 I bet it'd make a hell of a caching layer though.

23:43 SegFaultAX: callen: Right now just internal stuff. But as we migrate more towards SOA/uSOA I'm hoping it will play a larger role.

23:43 mgaare: That's sort of how we're using it now, on top of cassandra for the "raw" data

23:44 callen: SegFaultAX: yisssss

23:44 mgaare: I'm sorry to hear that.

23:44 mgaare: cassandra has gotten much nicer this year

23:44 callen: I wasn't saying that re: Cassandra.

23:44 Cassandra has improved a lot.

23:44 gdev: I'm trying to use datomic to store all my repl history

23:45 callen: gdev: any...particular reason?

23:45 futile: ♫ this is the tale / of captain jack sparrow ♫

23:45 mgaare: callen: saying it re: couchbase?

23:46 gdev: so when I get an error I can see if I've made the same mistake before

23:46 SegFaultAX: futile: Hhheheh

23:46 callen: futile: dare I ask what the prompt was?

23:46 futile: ♫ michael bolton we're really gonna need you to focus up ♫

23:47 callen: you haven't seen it?

23:47 callen: I assumed there was a more specific prompt than merely watching the movie.

23:47 futile: callen: http://www.youtube.com/watch?v=GI6CfKcMhjY

23:47 `cbp: what's the patrician's preferred laptop? :P

23:47 gdev: callen, its also part of the functionality for a project I'm trying to hack together

23:48 callen: `cbp: retina MBP or thinkpad, but I was being facetious :)

23:48 gdev: that being?

23:49 although Lenovo is doing a really good job of incrementally ruining the thinkpad series.

23:49 I'm like two bottles of scotch away from doing a Kickstarter for a "hacker's laptop" product line.

23:50 futile: "Now I'm back to the good part!"

23:50 gdev: callen, clojure-quest

23:50 futile: "not better"

23:50 callen: :D

23:56 ddellacosta: anyone around who is doing repl-based CLJS testing?

23:56 mgaare: callen: that would be great. keep it simple. massive hi res display, tons of ram, fast processor, 1 ssd and 1 spinner, lots of ports. boom done :D

23:56 tbaldridge: anyone know where the fn to greek lambda converstion code is in emacs live?

23:57 callen: ddellacosta: sometimes I think you intentionally pick stuff that won't get answered in here.

23:57 ddellacosta: might I suggest Saint Jude?

23:57 ddellacosta: callen: haha, yeah, that was kind of a shot in the dark. I want to figure out a better CLJS testing flow than the one I have now, and I would like it to be repp-based (rather than the compiling via lein cljsbuild I am doing over-and-over these days…*sigh*)

23:58 repp = repl

23:58 if that wasn't obvious

23:58 callen: I've only used lein-cljsbuild :(

23:58 ddellacosta: I think some people do a browser repl based thing, and experiment in that.

23:58 I don't know that they necessarily run unit tests from it though.

23:58 xeqi: ddellacosta: https://github.com/cemerick/austin and https://github.com/cemerick/clojurescript.test might be of interest

23:59 callen: xeqi: good call :)

23:59 ddellacosta: xeqi: I've got a browser-based repl loaded up, and I am using clojurescript.test. The problem is that I have a good flow for writing a test in a file and having it get loaded quickly into my repl so that I can iterate through solving a test in "realtime."

Logging service provided by n01se.net