#clojure log - Jun 21 2013

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

0:00 tomjack: mdeboard: reify is good

0:00 I wouldn't camel-case my fn names..

0:01 mdeboard: Yeah, holdover from my first 15 stabs at this tonight. Transliterating a tutorial from java to clojure :)

0:04 muhoo: nice, i've got spyscope, nrepl-discover, and possibly even nrepl-ritz to try out

0:04 amalloy: mdeboard: the (. obj method) syntax looks *very* awkward

0:05 noonian: (.get matrix 4)

0:05 callen: I really could've used spyscope a long time ago.

0:06 mdeboard: amalloy: I'm ok with awkward-looking for now, more concerned with logic than style atm

0:07 Unless there's a clojure styleguide somewhere in which case that would be great too

0:08 malyn_: mdeboard: Clojure style guide -- https://github.com/bbatsov/clojure-style-guide

0:08 mdeboard: Awesome.

0:10 amalloy: mdeboard: if i were going to edit this and make only cosmetic changes, my version would look like https://gist.github.com/amalloy/5828691

0:10 haha whoops, except i introduced a new local named coords, which stomps on the "hidden" global coords. so call mine something else

0:11 also i strongly suspect you don't want coords to have "keywordized" integers as keys, like :2. just make it the integer 2

0:11 mdeboard: ok so here's method invocation syntax "fixed" https://gist.github.com/mattdeboard/5828696

0:11 n_b: I recall someone in here mentioning they had a Whirldwind Tour of Clojure slide deck - anyone recall who it was or where I might find it?

0:12 amalloy: $google Whirlwind Tour of Clojure slide deck

0:12 lazybot: [Building Web Apps with Clojure / Open Source Bridge: The ...] http://opensourcebridge.org/sessions/836

0:13 mdeboard: amalloy: Yeah, I have questions about that (``coords`` ref) too. Since this java method I'm invoking doesn't actually return anything I guess I have to resort to mutable state; that said I'd rather not pollute namespace scope with refs but I can't pass that ref to the MatrixRenderListener

0:13 What I SHOULd do is extend the PdfReaderContentParser and add a new method. Good idea

0:13 tomjack: does #spy/p really work as advertised?

0:13 I don't get it

0:13 amalloy: mdeboard: right, you probably can't do without it in the context of the larger problem. although it also is very likely that an atom would be fine and there's no need for a ref

0:14 * mdeboard tries to remember cemerick's grid of stateful types

0:14 mdeboard: atom is... uncoordinated and something?

0:14 tomjack: #spy/d makes sense I guess, but seems kinda nuts..

0:15 amalloy: tomjack: doesn't it just expand to code that prints the given thing and thenn returns it?

0:15 like, it's a macro for "wrapping" a value in printing, except that it works for devs whose keyboards lack () keys

0:16 mdeboard: amalloy: In what sense is a ref overkill but an atom isn't?

0:16 amalloy: mdeboard: well, you need some global state, but you don't need to coordinate across multiple stateful things

0:16 tomjack: that's what seems kinda nuts

0:17 amalloy: tomjack: i agree it's stupid

0:17 tomjack: #spy/p just seems impossible t ome

0:17 or useless

0:17 amalloy: i mean, i'm totally in favor of a macro like (? (x)) which prints "(x) is 5" and returns 5; i wrote one myself and use it all the time

0:17 but making a reader macro out of it because you can't figure out how to use paredit? it's stupid

0:18 tomjack: ah that is a reason that makes (some) sense at least

0:18 didn't occur to me that it would be easier for some people to type a reader macro

0:18 er. data reader.

0:19 amalloy: now, there is one actual benefit of doing it that way

0:19 ie, you can use #spy/p in a namespace that doesn't (require 'spy.whatever)

0:19 since reader macros are global

0:20 tomjack: ah, yeah, it occurred to me but I explained it away too easily with "well you have to require it anyway"

0:28 switching to nrepl and tmux today. /me crosses fingers

0:29 muhoo: nrepl is great

0:34 wastrel: nrepl you say

0:37 noonian: im trying out light table right now as an alternative to emacs

0:52 muhoo: ah, i think my PermGen errors are triggerd by trying to run alembic

0:52 seems to be what causes the breakage, pretty reliably.

1:05 somewhat mitigating nrepl's awesomeness, is trying to use C-c C-e with tools.trace or spyscope, in which case, the trace output goes nowhere

1:21 bluegator: hello all

1:21 is there a way to query at runtime if lein is running with a particular profile?

1:46 mjc: &(byte 120)

1:46 lazybot: ⇒ 120

1:46 mjc: &(byte 129)

1:46 lazybot: java.lang.IllegalArgumentException: Value out of range for byte: 129

1:57 amalloy: &(doc unchecked-byte)

1:57 lazybot: ⇒ "([x]); Coerce to byte. Subject to rounding or truncation."

2:40 mjc: amalloy: that is indeed what I'm looking for, thanks!

2:41 doing some analysis type stuffs on xor "encrypted" data

3:35 Zamarok: &(assrt (= (conj '(false) true) (conj [false] true)))

3:35 lazybot: java.lang.RuntimeException: Unable to resolve symbol: assrt in this context

3:35 Zamarok: &(assert (= (conj '(false) true) (conj [false] true)))

3:35 lazybot: java.lang.AssertionError: Assert failed: (= (conj (quote (false)) true) (conj [false] true))

3:35 Zamarok: why does conj work differently for '() and []?

3:36 [(conj '(false) true) (conj [false] true)]

3:36 &[(conj '(false) true) (conj [false] true)]

3:36 lazybot: ⇒ [(true false) [false true]]

3:49 mjc: Zamarok: I believe it's due to how the data structures are implemented under the hood, i.e. head vs tail insertion

3:50 Zamarok: That was a very disrupting bug to work out, and the docs aren't helpful

3:51 &(doc conj)

3:51 lazybot: ⇒ "([coll x] [coll x & xs]); conj[oin]. Returns a new collection with the xs 'added'. (conj nil item) returns (item). The 'addition' may happen at different 'places' depending on the concrete type."

3:51 Zamarok: Which concrete types? Which "different 'places'"? Why is 'places' in suspicious quotes?

3:52 mjc: http://clojure.org/data_structures has more detail

3:53 callen: Zamarok: where's your book?

3:54 Zamarok: Book? I have 'Programming Clojure'...

3:54 callen: That's not a good one.

3:54 Zamarok: okay we'll do this the old fashioned way.

3:54 Zamarok: in Clojure, what is a []?

3:54 Zamarok: A vector

3:54 callen: Zamarok: and, approximately, how is it implemented?

3:55 Zamarok: Some sort of Java array, I'm guessing?

3:55 callen: Zamarok: if you don't know, just say you don't know. Don't google. Just talk to me.

3:55 Zamarok: wrongo!

3:55 Zamarok: okay, what's a '()?

3:55 Zamarok: PersistentSequence

3:56 Not sure how they're implemented either

3:56 callen: hrm, less concretely.

3:56 Zamarok: how are traditional Lisp lists implemented?

3:56 Zamarok: no idea. just got into lisp a few days ago

3:57 callen: Zamarok: you should be using your book more. Lets speak in broad terms.

3:57 Zamarok: what is orthogonality?

3:57 mthvedt: zamarok: 'places' and 'addition' are in quotes because clojure data structures are persistent, or follow the link mjc gave

3:58 Zamarok: dunno about orthogonality either

3:58 callen: Zamarok: https://en.wikipedia.org/wiki/Orthogonality_(programming)

3:58 Zamarok: mthvedt: that makes sense, thanks

3:59 Oh, as in "clojure code is just clojure data"

3:59 callen: Zamarok: does it sound better to have a bunch of data structures with the same weaknesses and strengths or to have a set of data structures that have a mix of strengths and weaknesses?

3:59 Zamarok: A mix, so you can choose the right one for the right job

4:00 callen: Zamarok: if there's a mix, does that mean adding values to them is going to be equally performant in all cases?

4:00 adding values in a particular fashion, anyway.

4:01 Zamarok: I guess not.. I know adding to beginning of an array is expensive in many languages, if it's even possible

4:02 callen: Zamarok: so a vector looks like this: http://blog.higher-order.net/2009/02/01/understanding-clojures-persistentvector-implementation/

4:02 Zamarok: but easy to add a new head to the beginning of a linked list

4:02 mjc: interesting. I'd always heard orthogonal to describe the abilities of pieces of a system to be modifiable in isolation.

4:03 callen: mjc: that's something else.

4:03 Zamarok: okay, so if conj isn't making any promises about "where", but rather, "what", why do you suppose the behavior is different?

4:05 Zamarok: also when I said '(), I was asking for IPersistentList. Behaves more or less like a standard Lisp list with the stacky cons/conj characteristics

4:06 Zamarok: Seq is the generic collections abstraction that sits atop Clojure collections.

4:06 Zamarok: although it's not a fantastic book, you do have a book. You should read it.

4:09 Blkt: good day everyone

4:09 callen: Blkt: good evening.

4:09 Zamarok: So, if I understand correctly, conj is different for vectors because Clojure wants to add nodes to the tree in a balanced way, rather than inserting nodes in awkward places.. yes?

4:09 callen: Zamarok: no. Read your book.

4:09 katratxo: hehehe

4:16 amalloy: that's not far from true, really. conj goes last for vectors because that's where it's efficient to put them. who cares about "balanced" and "awkward"?

4:17 mthvedt: i think starting socratic inquiry, only to terminate it with "no, read your book" is an anti-pattern

4:17 callen: mthvedt: I gave him a link that demonstrated visually exactly why it is the way it is

4:17 mthvedt: the "read your book" was a reaction to the evident laziness.

4:18 mthvedt: Beginner mind? no problem. Lazy mind? not my problem.

4:18 but anti-pattern is a delightful way to say "I don't like this". I'll have to use that to describe somebody's cooking tomorrow.

4:20 Zamarok: I read quick ;) thought I got the gist, wanted to confirm so I can move on, research it later

4:20 amalloy: callen: he asked why tea is so popular in england, and you sent him a diagram of the structure of a taste bud. asking for clarification by rephrasing what he thought he'd learned was pretty reasonable

4:20 Zamarok: but thanks for the cryptic assistance

4:20 callen: Zamarok: nobody ever said lazy meant slow.

4:21 amalloy: I think that's a fair characterization. But if he's in such a hurry, he has no time to wait for anybody in IRC to respond to anything. So godspeed.

4:21 mthvedt: callen: i think not understanding unnecessary details of persistent data structures is not proper evidence of a "lazy mind", particularly when it's obvious he attempted to understand them

4:22 callen: why aren't you helping him instead of spending time discussing how I helped him?

4:22 mthvedt: callen: tu quoque

4:22 callen: I had an epiphany - then shared it.

4:22 don't be a bore.

4:23 People that wait for an excuse to toss out latinate nouns for acts of sophistry are terrible conversation partners.

4:24 mthvedt: i also actually tried to help, so that's both wrong and fallacious.

4:30 callen: ddellacosta: what joke?

4:30 ddellacosta: has lein changed how it handles checkouts recently? I thought that you merely had to put something in checkouts, then remove the dependency in projects.clj, and it would pick it up. I could swear I've done it that way many times in the past.

4:30 callen: what?

4:30 callen: ddellacosta: your twitter. What joke did you try to tell?

4:31 ddellacosta: haha, that?

4:31 callen: ddellacosta: American jokes told to Japanese people. You said they weren't ever funny.

4:31 ddellacosta: what joke did you try to tell? Or were you simply witness to it?

4:31 ddellacosta: I was in Starbucks, and the cashier gave me a free sample

4:31 and I said, "are you trying to make me fat?" and she just looked at me, and I was like, right, not funny...

4:31 of course, it's not really funny anyways

4:32 but it *is* a very American thing to say

4:32 callen: ddellacosta: I kinda feel for her. I tend to stare blankly when people are insincere.

4:32 ddellacosta: what does lein classpath say?

4:32 ddellacosta: I was sincere! Always sincere. In my desire to get her to chuckle at least…*sigh*

4:32 callen: lein classpath says it's there.

4:33 callen: hmm, wonder if it's cause my repl is loaded with-profile test?

4:34 callen: ddellacosta: well you have a good candidate for a testable hypothesis now.

4:34 ddellacosta: callen: regarding the joke thing, I guess it's more just that I suck at Japanese small talk--it's all about knowing the thing that makes them smile. I can do it in the states, I can't do it here. Don't have the cultural depth yet.

4:34 callen: yeah, I'll try that.

4:35 callen: ddellacosta: could be worse. I can't make anybody smile unless you count winces.

4:35 ddellacosta: I wonder what Japanese small talk sounds like? I don't think I've ever heard it before.

4:35 ddellacosta: callen: haha…seriously? I'd be surprised if that were really true.

4:35 callen: ddellacosta: I've only heard conversations in shows.

4:36 ddellacosta: callen: like I said, if I could manage it, I would have made my cashier chuckle…maybe.

4:36 callen: ddellacosta: did flipping the profile to dev or user change the behavior?

4:36 ddellacosta: callen: well, the thing I realized is that because I am testing, I can't really do that without essentially making it a moot point. Hmm.

4:37 callen: ddellacosta: I think part of the problem is that it's a transactional conversation and it's hard to do small talk in Japanese without pre-established information or to use as a prelude to further conversation.

4:37 ddellacosta: passing one-liners is a very American thing, I think.

4:37 ddellacosta: let me re-state the issue: how do I mock ring's anti-forgery-token in a routing test?

4:37 callen: did you just xy my ass?

4:37 ddellacosta: callen: I think you're absolutely correct.

4:37 xy?

4:37 clojurebot: xy is http://mywiki.wooledge.org/XyProblem

4:37 callen: thank you clojurebot.

4:37 ~botsnack

4:37 sigh. god dammit.

4:37 clojurebot: botsnack is scoobysnack

4:38 callen: ,scoobysnack

4:38 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: scoobysnack in this context, compiling:(NO_SOURCE_PATH:0:0)>

4:38 callen: ~scoobysnack

4:38 clojurebot: scoobysnack is botsnack

4:38 callen: ...the bot is fucking with me now.

4:38 ddellacosta: callen: yeah, I guess I may have….I'm sorry though, it was my own fault for going too far down the wrong road before I realized I should back it up and try asking the *real* question. My apologies!

4:39 callen: oh it's okay, I probably earned the torment earlier

4:39 ddellacosta: yeah, I mean, this all came from me trying to test a post action which I have wrapped in ring-anti-forgery middleware

4:40 callen: ddellacosta: in terms of mocking it, what exactly do you want it to do? you could just monkeypatch the middleware.

4:40 ddellacosta: if you want it to stop validating the token, write a no-op ring middleware and swap it out.

4:40 ddellacosta: callen: yeah, I *was* trying to stub out the actual *anti-forgery-token*, but I may just go and try stubbing the middleware itself

4:41 callen: ddellacosta: well nothing happens but by the grace of god - or in this case, middleware.

4:41 ddellacosta: better to smash the arm swinging the hammer rather than try to stop it hitting the anvil.

4:41 ddellacosta: callen: and while it may be a better practice conceptually, I don't like pulling the specific routes out and just testing against those--I often end up missing something because my environment is different

4:42 callen: haha, interesting metaphor

4:42 callen: ddellacosta: I generally write tests for the complicated bits and for API QA. I don't feel compelled to TDD things like you do.

4:43 ddellacosta: callen: I mean, I think sometimes I get too caught up in it. I'm still trying to find a good balance. But usually when I've gotten to this point, it means I'm doing something wrong.

4:43 callen: ddellacosta: so now I'm an enabler.

4:43 ddellacosta: callen: haha, no--but you've given me good food for thought (as always).

4:44 although, I have to say, you didn't help me at all with my Japanese smalltalk. *sigh*

4:44 callen: ddellacosta: you could say Amerika kara desu, but that'd be painfully obvious and out of place.

4:44 ddellacosta: having a prop might help.

4:44 ddellacosta: callen: yeah, I look different enough that no one needs me to call *that* out...

4:46 alright, gonna try to get this working. Thanks callen, and sorry for the xy-ing earlier…

4:46 callen: ddellacosta: I'm a big fan of doing quasi-evil things with (binding...) when I need to monkeypatch.

4:46 ddellacosta: good luck :)

4:46 ddellacosta: callen: another interesting idea, will try it. thanks :-)

4:46 callen: ddellacosta: it at least scopes the evil.

4:46 failing that, just smash the fuckin' var.

4:47 ddellacosta: haha…HULK MOCK/SMASH

4:47 callen: I should pass that one on to Raynes for his next testing library.

4:47 Raynes: callen: wat

4:47 callen: Raynes: I've had a lot of tea.

4:54 ddellacosta: callen: ring.middleware.anti-forgery/valid-request? (constantly true)

4:54 in with-redefs


4:54 callen: ddellacosta: handy if you still want the token floating around.

4:54 ddellacosta: nice :)

4:55 ddellacosta: callen: thanks for helping me think outside the box. ;-)

4:55 Raynes: callen: I managed to break the dash and interior gauge light dimmer housing before actually buying the car, btw. At least the dimmer breaking loose was not my fault, I barely touched it. Breaking the dash loose on the left, on the other hand, was my fault while I was trying to fix it.

4:55 callen: ddellacosta: you're always welcome to my padded cell.

4:56 ddellacosta: heh

4:56 callen: Raynes: stop hulk-smashing your future car.

4:56 Raynes: I'm not even sure how to get something like that fixed.

4:56 I mean, I can't find the dash online anywhere, so I'm not sure how a mechanic would either.

4:56 callen: mechanics have resources.

4:56 also, junkyards.

4:56 Raynes: Yeah, but if it's this hard to find it I'm going to end up paying a fortune.

4:57 callen: I don't think that's an epistemologically valid statement.

4:57 Raynes: I don't think I know what that word means.

4:57 callen: easy to test hypothesis though.

4:57 * Raynes three finger taps

4:57 callen: why not call a mechanic and maybe a few junkyards?

4:57 Raynes: Well, I will.

4:57 callen: then why the distress? you already know what to do. :)

4:57 Raynes: Going to talk to Alex about it tomorrow and see if he has any suggestions on what we should do.

4:58 Because it sucks, man.

4:58 * callen rubs chin

4:58 Raynes: I've still got to get my CA license. Going to the DMV tomorrow, crossing my fingers that they don't force me to do a behind-the-wheel test and waste another day of my time.

4:58 callen: Raynes: well I hope the problem unravels inexpensively.

4:59 Raynes: Luckily i didn't break anything on the car that would make it unusable for testing.

5:02 callen: ddellacosta: I really need to pick ring-anti-forgery apart. Way too tightly bound together.

5:02 ddellacosta: callen: I mean, there's not that much to it in the end

5:03 callen: but it would be nice if it was a bit more configurable I think

5:03 callen: ddellacosta: quite right, but it locks off the whole ring app.

5:03 maleghast: Anyone in here used / using Compojure, I have an odd question...

5:03 If I wanted to define a POST route, with a URL pattern like this -> /:country/payment/submit/:type.:format - how would I assign / bind :country, :type and :format as well as get hold of the POST Body (which is going to be JSON, EDN or XML)

5:03 ?

5:03 (All the examples I can find on the web seem to assume that you don't need to bind anything from the URL if you're handling a POST)

5:03 ddellacosta: callen: yes

5:03 callen: ddellacosta: that's uh, unacceptable for my purposes :P

5:03 maleghast: (sorry about the copy/paste - I originally posted in wrong room - d'oh!)

5:03 ddellacosta: callen: for mine too, it turns out…I learned the hard way today

5:04 callen: you've been having a grand time lately it seems.

5:04 ddellacosta: heh, dunno if I would say "grand..."

5:07 echo-area: Is Compojure deprecated or not?

5:07 maleghast: echo-area: Not that i'm aware of, no

5:08 echo-area: I mean weave jester (James) hasn't made any commits or integrated any pull-requests for a month, but I don't think it's dead or anything

5:08 echo-area: Why?

5:08 callen: echo-area: Noir is the web framework that got deprecated, Compojure is still very popular and maintained.

5:09 maleghast: compojure is pretty close to not really needing much changed unless the mission statement or requirements change.

5:09 maleghast: callen: I figured - I have found it excellent, apart from my confusion above ^^ and one other Q I have

5:09 echo-area: callen: That's it. Is Noir deprecated because its design is not simple in the sense in Rich's presentation? I recall I read it somewhere saying so.

5:10 maleghast: Never mind, it's just I was trying to recall what I saw.

5:11 callen: Noir is deprecated because the creator found better things to do and the community wasn't interested in maintaining that kind of web framework.

5:11 the more useful bits live on in lib-noir

5:11 Raynes: callen: http://www.youtube.com/watch?v=Vw5MYv-5xZE

5:11 callen: I recently discovered how much I love this band.

5:11 maleghast: echo-area: ??

5:11 lazybot: maleghast: Definitely not.

5:11 Raynes: Just throwing that out there.

5:12 maleghast: Raynes: Interesting… I will check it out later - work does not currently lend itself to video consumption ;-)

5:13 callen: Raynes: this is pretty good. I'm hella tired though.

5:13 Raynes: callen: The band fills a hole left by the departure of My Chemical Romance for me, which is dark rock.

5:14 callen: Raynes: you need to be filling your holes with black metal.

5:14 Raynes: They remind me of The White Stripes crossed with MCR. I'm particularly excited to see a young female lead not doing bubblegum pop.

5:14 She was 17 in that video, fwiw.

5:14 clgv: echo-area: arguments against noir mainly criticised its global variabls as far as I remember. you are encouraged to use lib-noir though if you need some of its features

5:14 callen: There are females in black metal.

5:14 ddellacosta: got booted and now you guys are talking about metal

5:15 callen: ddellacosta: somebody was asking about Noir (again) and raynes is still musical.

5:15 ddellacosta: maleghast: did you find a solution? I was about to say, I have routes which are like that, and they are basically like GET in terms of destructuring and whatnot

5:15 callen: Noir…? Is there a metal-band called Noir?

5:15 maleghast: echo-area: Here's the announcement about Noir -> http://blog.raynes.me/blog/2012/12/13/moving-away-from-noir/

5:16 ddellacosta: Not as yet - can you give me an e.g., please?

5:16 ddellacosta: hmm, lemme see, one sec

5:16 echo-area: maleghast: I read somewhere complaining about some web framework being deprecated because of not implemented with composite functions, or not being simple. I forgot its name (actually the many web frameworks written in Clojure is a little confusing to me), and tried to recall its name.

5:16 callen: ddellacosta: Noir web framework. It was the daily, "is Noir deprecated?" conversation.

5:16 ddellacosta: callen: haha, oh, that. Just not sure what it has to do w/music

5:16 echo-area: maleghast: Okay, thanks

5:16 clgv: Good to know, thanks.

5:17 maleghast: I think I read it on ycombinator or somewhere.

5:17 callen: ddellacosta: nothing. I wasn't framing a causal relationship, just rattling off isolate conversations.

5:17 echo-area: be careful, those ycombinator folk are tricksy.

5:17 maleghast: echo-area: You might want to consider Compojure + lib-noir, or Liberator + Compojure for an API and finally you could always give Pedestal a try...

5:17 ddellacosta: callen: ah, gotcha…now I see.

5:18 callen: echo-area: use compojure and lib-noir. See Luminus or bitemyapp/neubite for examples.

5:18 clgv: echo-area: you get pretty far with ring, compojure and friend...

5:18 callen: echo-area: don't use Friend either.

5:18 clgv: callen: huh, why?

5:18 maleghast: callen: Yeah, why no Friend usage?

5:18 callen: pain, irrelevancies that will confuse noobies just trying to learn and maybe get something done.

5:18 echo-area: See, that's why I'm confused. Currently I use only Ring, for I don't need to rend complex web pages.

5:18 callen: writing their own auth middleware will be a good exercise.

5:19 maleghast: callen: Fair point

5:19 callen: every single time a noobie gets told to use Friend, they're invariably in here for hours trying to bash it into place to make it work.

5:20 why not eliminate the tire spinning and let them focus on the parts that matter? it's bad pedagogy to recommend something like Friend to anybody who isn't already "together" in other respects.

5:20 ddellacosta: maleghast: I can't copy and paste the code I'm using or my boss would be mad, but here is a rough idea of how we did it…no guarantees on this working as is though, of course: https://www.refheap.com/15978

5:21 maleghast: ddellacosta: Cheers mon ami - 'sis appreciated :-)

5:21 ddellacosta: re Friend questions, you can throw them my way, but I can understand where Callen is coming from. Not really n00b-friendly lib

5:21 maleghast: hope it helps!

5:21 callen: it's just a low value thing for them to fight

5:22 it's added complexity that has nothing to do with learning Clojure or making a web app. They'll know later on when/if Friend makes sense for them.

5:22 ddellacosta: yah, I think that's probably reasonable

5:22 callen: and I still think writing auth middleware is a good exercise for learning Ring.

5:22 * maleghast is enjoying the idea that he might no longer be a total n00b as he found Friend really easy to quickly use and get value from

5:22 clgv: callen: ah learning clojure was echo-area's main goal? I read it as being building a webapp... ;)

5:22 callen: maleghast: nope.

5:22 ddellacosta: I think it's definitely a "once you get comfortable with Ring/Compojure and maybe a template lib, then give it a shot" kind of thing

5:23 callen: I'm starting to suspect nobody reads anything I say and just looks for keywords like #clojure #friend and #bad

5:23 clgv: reread what I said.

5:23 clgv: "or making a web app."

5:24 ddellacosta: maleghast: one note on what I gave you, I don't think there's any need for the context in there--it's just how we have it structured. Presumably you could use that path in the POST call directly.

5:24 maleghast: callen: FWIW I got what you meant, and you're not wrong.

5:24 ddellacosta:

5:24 ddellacosta: OK, cool - thanks :-)

5:24 clgv: callen: well if I want to make a web app and am not a clojure beginner and need authentication+authorization why shouldnt I use friend?

5:24 irctc081: callen, I am looking what you said. lol

5:25 callen: clgv: that's not what I was talking about.

5:25 clgv: callen: well, then your repetition of "or making a web app" was pointless for me ...

5:26 callen: the universal, perpetual, and exclusive qualifier was "noobie"

5:26 maybe my sentences need to be structured like clojure macros.

5:27 (defnoobie [(or (making-web-app :use-friend?) ; returns nil (learning-clojure :use-friend?) ; also returns nil)])

5:27 clgv: callen: then my question whether echo-area's main goal is learning was totally valid ;)

5:27 callen: clgv: top level is a macro scoping it to noobies.

5:28 clgv: possible predicate applicators are making a web app or learning clojure.

5:28 clgv: in either case, there's not much cause to use Friend.

5:28 whether your goal is to make a web app (as a noobie. Remember the defnoobie?) or to learn Clojure (as a noobie. Remember the defnoobie?)

5:28 I'm starting to see why XML was so popular.

5:28 * maleghast *headdesk*

5:28 clgv: callen: I found it pretty useful in setting up access control for a web ui to control a computation

5:29 callen: clgv: that's wonderful but also maximally irrelevant to what I was talking about.

5:29 clgv: one of the very first sentences I wrote on the subject was that it was, "bad pedagogy" to recommend Friend.

5:29 clgv: do you know what pedagogy is?

5:30 clgv: callen: ok, short answer would have been "echo-area just wants to learn how to make web apps in clojure"

5:31 maleghast: I love the word pedagogue, in fact it's even better if you enhance it with the adjective peripatetic...

5:31 …you get alliteration and "clever words" as a combo bonus. ;-)

5:31 callen: clgv: but the deeper answer?

5:32 it's kind of sad that you can't alliterate alliteration. Only assonance.

5:32 mthvedt: maleghast, i think what we have here is a pair o pathetic peripatetics.

5:33 maleghast: mthvedt: I couldn't begin to comment - but I do love that this channel often surfaces fantastic vocabulary as well as helpful insights into its supposed subject / purpose.

5:35 mthvedt: maleghast: tbh my comment was partially motivated by the desire to use "pair o pathetic peripatetics" in a sentence

5:35 * callen whistles at clgv

5:36 maleghast: mthvedt: Entirely reasonable in my not-even-remotely-humble opinion… ;-)

5:37 echo-area: callen: What do you think the main problem of Friend is?

5:37 noncom: hi, i want to split my single cljs file into several cljs files. do i simply do this like with clj files? i mean the namespace stuff, :use and :require things

5:37 callen: echo-area: I was talking about pedagogy.

5:37 echo-area: Hmm

5:38 To be honest, I still don't get the key to decide by reading your discussions earlier.

5:39 I'll check them later, when I need one of them.

5:39 callen: echo-area: use compojure + lib-noir, look at Luminus or bitemyapp/neubite for examples.

5:40 echo-area: callen: The reason behind your recommendation is?

5:43 noncom: is there no condp in cljs?

5:51 supersym: ola

6:16 clgv: echo-area: just start developing your web app and defer adding authorization/authentication until you really need it

6:22 Zamarok: What's the best Clojure book? For someone who's been programming a few years, functional programming maybe one year

6:22 echo-area: clgv: Let things grow spontaneously is the normal way.

6:22 *Letting

6:22 callen: Zamarok: Clojure Programming, Chas Emerick's book.

6:22 echo-area: Zamarok: Yes, that one.

6:22 Zamarok: Ok. Is the Clojure Cookbook any good?

6:22 clgv: echo-area: well you can plan ahead a bit by grouping together the potential routes that may need authorization

6:23 echo-area: clgv: I don't know if authorization is needed, I don't do web development now :)

6:23 callen: Zamarok: Clojure Cookbook just got started getting written...

6:24 Zamarok: oh, saw it referenced somewhere.. love the Python one

6:26 Pupnik: 3rd on clojure programming, it's the only programming book ive ever read, but I liked it

6:27 ddellacosta: Zamarok: I would check that one (Clojure Programming) out as well as Joy of Clojure, but I think Clojure Programming is a bit more accessible at first. I like them both. There are others too, like Programming Clojure by Stuart Halloway et al.

6:27 …which I've only skimmed, but seemed solid enough.

6:28 Zamarok: Clojure Programming must be damn good then..

6:28 I have the Stuart Holloway one, it's decent

6:28 maleghast: Zamarok: FWIW I learned Clojure from Stuart Halloway's book published by Pragmatic; I found it to be an excellent book, and I still refer to it form time to time.

6:29 xecycle: Hi. Can I ask CLR here?

6:29 echo-area: xecycle: Maybe you could just ask

6:29 maleghast: Zamarok: I would also recommend the O'Reilly video(s) that Stuart Halloway did recently, "Clojure Inside OUt"

6:29 vijaykiran: ~anyone

6:29 clojurebot: Just a heads up, you're more likely to get some help if you ask the question you really want the answer to, instead of "does anyone ..."

6:30 Zamarok: maleghast: ooh, I like videos.. can code and learn at the same time

6:30 xecycle: Okay. Why does the binary distribution for .NET 3.5 failed to launch on my Windows 7? I have .NET 4.0 installed on it, but I assume a proper backwards compatibility here.

6:30 Zamarok: maleghast: did you do the 'lancet' project in Holloway's book?

6:31 xecycle: The one for 4.0 runs fine.

6:31 maleghast: Zamarok: Also, try to get to a Clojure event near you if you possibly can - learning in person from other programmers is the best. The London Clojure Dojo really helped me - I wish I could still attend more often, but babies happened… I'm not complaining; my kids are awesome, but...

6:31 Zamarok: xecycle: if someone here can't help you, try asking in a C# channel

6:31 xecycle: Zamarok: :/ Thank you but how can C# be relevant...?

6:31 maleghast: Zamarok: yes I did work through that project

6:31 Zamarok: Long time ago now though...

6:32 Zamarok: xecycle: well, those guys deal with .NET more than most other types of programmers, and they're usually helpful over there

6:32 ddellacosta: xecycle: seems like it's more relevant than closure, if we are just talking about .NET generically

6:32 maleghast: xecycle: Ask away, the worse you're gonna get is "huh?"

6:32 ddellacosta: jinx

6:32 Zamarok: >_<

6:32 ddellacosta: closure -> clojure *#$!spellcheck

6:32 xecycle: Okay. Anyway I am talking about ClojureCLR.

6:32 ddellacosta: ;-)

6:32 Zamarok: maleghast: just wondering if the project is worth doing along with the book.. would you say?

6:33 maleghast: Zamarok: IMHO it's better to find something that you want to do and do that as a "learning by doing" project, but I still did the follow-along project in the book, so whadda I know? ;-)

6:34 Zamarok: Just did the first ten Project Euler problems to start.. looking for more programmer-y, less math-y stuff to practice on

6:34 maleghast: Zamarok: *nods*

6:35 clgv: Zamarok: try 4clojure

6:35 maleghast: Zamarok: Have you considered building a Roman Numeral Calculator? *snigger*

6:36 hyPiRion: Roman Numeral Calculator?

6:36 Zamarok: clgv: oh, this site will keep me busy for a while O_O

6:36 hyPiRion: Oh right.

6:36 Zamarok: maleghast: that was an /r/dailyprogrammer project a few months back

6:37 hyPiRion: ,(require '[clojure.pprint :refer [cl-format]])

6:37 clojurebot: nil

6:37 hyPiRion: ,(for [n (range 1 11)] (cl-format nil "~@R" n))

6:38 clojurebot: ("I" "II" "III" "IV" "V" ...)

6:38 maleghast: Zamarok: Fair enough - I was trying to see if Bruce was lurking in here today

6:41 Zamarok: maybe I'll clone clojurebot ... such an awesome tool

7:08 noncom: in ClojureScript I cant use update-in to descend JavaScript objects?

7:08 is it recommended to use the dot-notation and set! ???

7:08 lazybot: noncom: Yes, 100% for sure.

7:09 noncom: lazybot: heeey

7:09 hyPiRion: noncom: it's a bot. It automatically responds to two and three question marks at the end of a message

7:09 what??

7:09 lazybot: hyPiRion: What are you, crazy? Of course not!

7:10 noncom: yeah i know :D just testing the AI

7:10 hyPiRion: heh

7:10 noncom: wow

7:10 hyPiRion: ~the door

7:10 clojurebot: the door will show you what jars (including the clojure jar) leiningen is using

7:10 callen: it's not AI

7:10 noncom: i thought lisps and AI go hand in hand

7:10 joke :)

7:11 heh the door seems to be a secret

7:11 ,(println "wow")

7:11 clojurebot: wow\n

7:11 noncom: ,(print "wow")

7:11 clojurebot: wow

7:11 noncom: ,(print "hyPiRion: check")

7:11 clojurebot: hyPiRion: check

7:13 noncom: ,(ns test)

7:13 clojurebot: nil

7:13 noncom: ,*ns*

7:13 clojurebot: #<Namespace sandbox>

7:13 noncom: eh

7:13 ,(do (ns test) *ns*)

7:13 clojurebot: #<Namespace test>

7:14 noncom: ,js/console

7:14 clojurebot: #<CompilerException java.lang.RuntimeException: No such namespace: js, compiling:(NO_SOURCE_PATH:0:0)>

7:14 noncom: in ClojureScript I cant use update-in to descend JavaScript objects? is it recommended to use the dot-notation and set! ???

7:14 lazybot: noncom: How could that be wrong?

7:14 noncom: doh

7:15 *out*

7:15 ,*out*

7:15 clojurebot: #<StringWriter >

7:15 noncom: ,*in*

7:15 clojurebot: #<LineNumberingPushbackReader clojure.lang.LineNumberingPushbackReader@1ebf6ed>

7:17 supersym: someone who knows a bit more about def-memo, its hardly mentioned and I'm updating/learning from this forked project

7:17 https://github.com/clojens/slice/blob/master/src/slice/core.clj#L211

7:18 defn-memo it is,... has a null pointer exception that I just can't seem to figure out

7:18 probably in the head (since all the code before that just properly compiles to a function, but after head it gets the null ptr

7:21 noncom: ,(.write *out* "check" 0 5)

7:21 clojurebot: check

7:23 noncom: ,(ns-map)

7:23 clojurebot: #<ArityException clojure.lang.ArityException: Wrong number of args (0) passed to: core$ns-map>

7:23 hyPiRion: ,(.write *out* "\000 hey what")

7:23 noncom: ,(ns-map *ns*)

7:23 clojurebot: {sorted-map #'clojure.core/sorted-map, read-line #'clojure.core/read-line, re-pattern #'clojure.core/re-pattern, cond->> #'clojure.core/cond->>, keyword? #'clojure.core/keyword?, ...}

7:24 romain_1p: Hi everyone, could someone help me with an xml-zip parsing problem ?

7:24 This http://pastebin.com/9UD6rthh always result in an empty sequence

7:25 noncom: ,(map println (range 0 2))

7:25 clojurebot: (0\n1\nnil nil)

7:26 romain_1p: (and yes, my document has a "en-export" root :) )

7:26 jtoy: how should I go about finfing an error if the only stacktrace i get is: NullPointerException clojure.lang.Numbers.ops (Numbers.java:942)

7:26 hyPiRion: noncom: you know, /msg clojurebot also gives you back results from evaluating clojure code

7:27 noncom: hyPiRion: you mean, personally, so other don't see?

7:27 hyPiRion: yeah

7:27 jtoy: You can do (pst) and get the complete stack trace usually

7:27 noncom: or many thanx, i did not know... i think its an irc feature, but i do not know irc

7:28 hyPiRion: jtoy: If that's not working, I tend to throw prns around everywhere.

7:32 supersym: nvm got it

7:44 jtoy: hyPiRion: i didnt know about pst,thanks

7:45 hyPiRion: np

7:47 jtoy: does try not catch "NullPointerException clojure.lang.Numbers.ops (Numbers.java:942)" ? I have atry/catch on the line it references

7:48 gfredericks: jtoy: it looks like (try (/ 3 0) (catch Exception e ...))?

7:51 jtoy: gfredericks: this is the line it dies on:

7:51 (fn[x] (== 0 (try (predictor model (x :data)) (catch Exception e (do (println x) (println e) nil)))))

7:51 hyPiRion: jtoy: When you catch the exception, you return null/nil.

7:52 Is that what you'd like?

7:52 jtoy: hyPiRion: yes, the error is happening inside there though

7:52 hyPiRion: uh

7:52 ,(== 0 nil)

7:52 clojurebot: #<NullPointerException java.lang.NullPointerException>

7:52 hyPiRion: ,(= 0 nil)

7:52 clojurebot: false

7:52 hyPiRion: Return 1 instead or something

7:53 jtoy: I mean I can return anything and i will still get that errore, i will tes tit now

7:55 yes, I sitll get the same error, the error is happenning inside the try block

7:57 i see something weird though, still testing

7:59 hmm, im not sure why, i cant compare 1 == nil, but 1 = nil works

7:59 wtf

8:00 hyPiRion: yes, i didnt understand what you were saying earlier, is that expected behavior?

8:02 hyPiRion: jtoy: yeah

8:02 ,(doc ==)

8:02 clojurebot: "([x] [x y] [x y & more]); Returns non-nil if nums all have the equivalent value (type-independent), otherwise false"

8:02 hyPiRion: nums mean in this case any number

8:03 ,(doc =)

8:03 clojurebot: "([x] [x y] [x y & more]); Equality. Returns true if x equals y, false if not. Same as Java x.equals(y) except it also works for nil, and compares numbers and collections in a type-independent manner. Clojure's immutable data structures define equals() (and thus =) as a value, not an identity, comparison."

8:04 jtoy: thx

8:04 sometimes i really hate programming :)

8:05 hyPiRion: jtoy: yeah, sometimes it's really horrible. That single character destroying all your hopes and dreams =/

8:28 jtoy: this looks fun to debug; OutOfMemoryError Java heap space [trace missing]

8:28 this machine has tons of memory also, wtf

8:28 clgv: jtoy: heap space? buy some more 4GB ram sticks ;)

8:29 jtoy: do you process large data in a lazy way?

8:29 Blkt: jtoy: how do you start your JVM? -Xmx?

8:29 jtoy: I just startjvm with lein clojure

8:30 I am processing some data in memory, but is only ~10k rows of data from sqlite3

8:30 Zamarok: jtoy: :javac-options ["-Xlint:unchecked"

8:30 Blkt: mmm, I suppose it gives the standard maximum heap size

8:30 Zamarok: add that to project.clj

8:30 oh wait, wrong option

8:30 the option is "-Xmx4096m"

8:31 Blkt: still, you may be loading too much stuff eagerly

8:31 you can probably flip a few functions to flush elaborated data earlier in your loop

8:31 clgv: jtoy: do you have the sql result in map-form in your program?

8:33 jtoy: clgv I am using sql korma, i think it is in map form, here i the funciton that reads from sql: https://www.refheap.com/15983

8:35 Zamarok: Ihave the same options when I added: :javac-options ["-Xmx4096m"]

8:36 i think its jvm-options though

8:36 clgv: jtoy: you could request less line say 100 to measure memory consuption (profiler ...) and calculate if the 10k lines should fit into your ram. if not you will have to split up the result data in chunks you can handle

8:36 Zamarok: https://github.com/antoniogarrote/lein-javac/blob/master/README#L25

8:36 Definitely :javac-options

8:37 clgv: definitely not! https://github.com/technomancy/leiningen/blob/stable/sample.project.clj#L295

8:37 jtoy: Zamarok: :jvm-opts change fixed it

8:37 Zamarok: Oh, does :javac-options only apply to actual Java code?

8:38 jtoy: that sucks i need to deal with memory issues like this, why doesnt it just "autoscale" in use

8:38 hyPiRion: jtoy: :jvm-opts ^:replace [] should fix that too

8:38 The issue is that the jvm optimizations lein shut off for some strange reason removes stack traces after some time

8:38 clgv: Zamarok: you linked to a former plugin. java compilation is built into leiningen since a while. :javac-options are for the java compiler

8:39 hyPiRion: yeah, javac is for javac, jvm is the java virtual machine options

8:40 Zamarok: ah I see.. my use case was actual java code

9:01 clgv: Zamarok: but your use case must have been compilation, not running java code ;)

9:04 jtoy: is there a simple way to do something like: ({:car "test"} "car" :car 11) I have data that comes into a function that somtimes uses strings or keywords as the key for maps

9:05 or how can i write code that grabs the value whether it is as tring or keyword?

9:17 aroemers: jtoy: clojure.walk/keywordize-keys may be of help? Depends on how large the data is.

9:20 Zamarok: what happened to clojure.contrib.repl-utils/show ?

9:21 aroemers: ,(let [data {:foo 'bar}] (or (data :foo) (data "foo") 'baz))

9:21 clojurebot: bar

9:21 aroemers: jtoy: ^

9:22 clgv: Zamarok: it vanished

9:27 jweiss: amalloy_: hiredman: thanks for the hint about that xml parser loading behavior yesterday. i turned on some debugging and it seems like both "behaviors" are using the same class of TransformerFactory: org.apache.xalan.processor.TransformerFactoryImpl https://www.refheap.com/15985

9:40 noncom: how do i get a JavaScript array element in ClojureScript? if I excersize (type) on the array, it says "function Array() { [native code] } "

9:41 how do I get inside this one?

9:44 jcromartie: noncom: how about nth

9:45 just a guess

9:47 noncom: jcromartie: ok, it worked, but there is another trouble now :(

9:48 jcromartie: noncom?

9:48 noncom: jcomartie: i got my array with (clj->js [[0 1] [2 3]]) and now that I get what should be [0 1], using (nth % 0), that type is now Object... no access inside.... same if I do plain array [0 1 2 3], (nth % 0) typeis Object

9:49 why is that...

9:49 jcromartie: hmm, let me fire up my cljs

9:51 noncom: it works fine for me

9:51 noncom: hmmmm

9:51 jcromartie: (-> [[1 2] 3] clj->js (nth 0))

9:51 #<Array [1, 2]>

9:52 jtoy: aroemers: thanks

9:53 noncom: so where have i missed...

9:55 jcromartie: i have "function Number() { [native code] } ", "function Object() { [native code] } " and "function Array() { [native code] } " all over the place..l don't you know how could that happen? looks like i did not do anything special to get that.. maybe you have some idea?

9:55 jcromartie: well let's see your actual code

9:56 can you paste it (Gist or refheap)

9:56 noncom: also, if you're not already using a REPL I'd highly recommend it

9:56 just to be able to bang out this sort of thing

9:57 noncom: jcromarite: i'll try to factor a reafhep case now.. wait..

10:02 cmajor7: "https://github.com/flatland/https://github.com/flatland/clojure-protobuf": is there a reason why "flatland.protobuf.PersistentProtocolBufferMap$Def" is not serializable?

10:03 (https://github.com/flatland/clojure-protobuf/blob/develop/src/flatland/protobuf/PersistentProtocolBufferMap.java#L60)

10:06 noncom: jcromartie: here: https://www.refheap.com/15986 it'snot a perfectcase though..

10:08 jcromartie: noncom: so where is your issue coming up

10:09 noncom: is it mk-line?

10:09 noncom: jcromartie: i have updated the snippet, check it out. tehre is the ; <<< comment

10:09 clojurebot: You don't have to tell me twice.

10:10 noncom: jcromartie: basically i just try to update the coordinates of the line, which are stored in the array "points" of the object "attrs" of the object of type Kinetic.Line.

10:10 all these are plain javascript..

10:10 at least should be

10:13 jcromartie: noncom: what is attr??

10:13 lazybot: jcromartie: What are you, crazy? Of course not!

10:13 jcromartie: the bots are being awfully snarky today

10:14 noncom: jcromartie: attrs is a JSON

10:14 jcromartie: it simply stores the properties of a KineticJS object

10:15 jcromartie: noncom: I just don't know what "attr??" is

10:15 (attr?? ti-cursor :cursor-position)

10:15 noncom: jcromartie: (defn attr?? [elem k] (.getAttr elem (name k))) ; same as (k (.-attr elem))

10:16 jcromartie: alrighty then

10:16 I figured but I'm not sure why you'd call it that

10:16 noncom: jcromartie: here is the spec: http://kineticjs.com/docs/Kinetic.Node.html

10:16 jcromartie: simply a wrapper for handling the JSON which stores the props

10:17 jcromartie: i try to use the Kinetic idiomaticy..

10:17 jcromartie: sorry if it all is a little cumbersome..

10:17 jcromartie: I'm still not sure where the actual problem is

10:17 noncom: would you recommend something?

10:17 jcromartie: cur-y-1 (type (attr?? ti-cursor :cursor-position)) ; <<< function Number() { [native code] } WTF

10:18 noncom: ehh.. me too.

10:18 jcromartie: that's fine

10:18 noncom: well,i guess,i'll try to check everything again..

10:18 jcromartie: it's a number

10:18 noncom: but why function Number() { [native code] }

10:18 immutability?

10:18 jcromartie: no

10:19 just try (type 1)

10:19 it's the prototype of the object

10:19 noncom: in javascript "typeof 5" would be"number" or not?

10:20 jcromartie: yes but Clojurescript's "type" is not Javascript's "typeof"

10:20 "type" returns the constructor of the object

10:20 you can do it in a JS console: (42).constructor

10:21 returns "function Number() { [native code] }"

10:21 noncom: well, anyway, in case of [ [] [] ] the code (nth external (nth internal 0) 0) returns error because (type (nth external 0)) is function Array() { [native code] } and not #<Array >..

10:22 i'm lost.. i guess you're wasting time, and i just have to do a refactoring iof my code and more study on the language

10:22 jcromartie: that is a JavaScript array

10:22 it's fine

10:23 BTW use aget to get at JavaScript objects

10:23 noncom: i'll try aget

10:24 jcromartie: like, (aget some-obj "attribute-name")

10:24 or (aget js-array 0)

10:25 anyway, good luck

10:26 I'm a CLJS noob myself… lots to learn

10:27 atyz: Hey guys, my team is about to start a new project, I'm trying to convince them to do it in clojure (which they aren't particularly against as we just built a small webservice) but it seems like they're leaning more towards ruby. Their reasoning for this is that they think it will be more familiar in the case of hiring people. They also feel like the ruby tooling is better. I've already said that the clojure tooling is pretty good. Are there any a

10:27 and you can deploy compiled code

10:27 and that there is the whole java ecosystem to pull from

10:27 noncom: jcromartie: thanks! :)

10:28 jcromartie: atyz: your first message was cut off at "Are there any"

10:28 atyz: Are there any arguments for clojure over ruby, other than that its the jvm, and you can deploy compiled code and that there is the whole java ecosystem to pull from

10:28 thanks jcromartie

10:29 vijaykiran: atyz: is your team familiar with Java ?

10:29 jcromartie: I think that in terms of hiring, yeah, Rails is going to be easier

10:29 atyz: vijaykiran: they have used java, I'm the only member with significant ruby experience

10:29 jcromartie: wow, today is the day: when you choose Rails because it is easier to hire for

10:29 maleghast: atyz: Immutable State makes for more reliable predictable testing and code, and smaller codebase(s) - that's a plus

10:29 atyz: jchauncey: we would definitely not choose rails

10:29 jcromartie: atyz: what kind of project?

10:30 atyz: jcromartie: it's probably going to be a backend with a frontend in angular

10:30 so all interaction would be through apis

10:30 jcromartie: well since Angular has no opinion on backend APIs, I'd say you could easily go with Clojure

10:30 but again it depends on what the system does

10:30 atyz: jcromartie: i know, the trick is convincing them to go with clojure over ruby

10:31 cmajor7: atyz: why do _you_ think clojure is a better fit over ruby?

10:31 jcromartie: what kind of data model?

10:31 maleghast: atyz: What jcromartie said, though you could argue for Pedestal and have a single language front and back (isn)

10:31 jcromartie: honestly ActiveRecord is a huge time saver if you have anything like a normal CRUD app with nested models

10:31 atyz: cmajor7: I personally feel that all the ruby tools are a little bloated - I like the simplicity that comes with clojure

10:32 cmajor7: atyz: ok, so here is your first point for clojure

10:32 maleghast: ActiveRecord is a lame dog in terms of performance, though… Productivity win, but final result is poor.

10:32 jcromartie: yes

10:32 atyz: I've mentioned that, but they feel that our lack of experience with the language (I have the most and I'm sitting at about 3 months)

10:32 would hinder us more in a functional language than an imperative one

10:32 jcromartie: atyz: experience with Clojure or Ruby?

10:33 atyz: I have 4.5 years of ruby and 3 months or clojure

10:33 jcromartie: sure it's easier to hack out a solution in Ruby

10:33 if you don't know Clojure

10:33 cmajor7: ruby as a language is also quite simple, but I agree tooling and a heavy weight Rails and inflexible ActiveRecord hide most of the Ruby simplicity, whereas in Clojure it is not the case => language primitives come first..

10:33 jcromartie: atyz: so what kind of data model? what kind of app?

10:33 atyz: The rest of the team doesn't have much ruby experience either

10:34 cmajor7: Clojure culture (over Ruby) is "libraries vs. frameworks" which comes from functionality (things are composable)

10:34 maleghast: The classic case-study is U-Switch, right..? They ported to Clojure with sub 6 month hobbyist Clojurians and had massive wins in productivity, code clarity, low line count and maintainability, not to mentions stability and quality.

10:34 atyz: jcromartie: its mostly going to be leveraging apis from other content providers and putting a mapping over the data we receive from them

10:34 jcromartie: atyz: sounds like Clojure would be quite pleasant for that

10:34 atyz: (content providers as in things like salesforce content)

10:34 maleghast: atyz: If that's the case then Clojure all the way

10:34 atyz: maleghast, jcromartie why over ruby?

10:35 jcromartie: you can do everything from a single Clojure process

10:36 atyz: jcromartie: I'm not entirely sure what you mean by that

10:36 jcromartie: Clojure's concurrency will make it a snap to go out and fetch a bunch of data and map over it and turn it into a canonical representation and then provide further functions on that

10:36 I've done this sort of thing :)

10:36 cmajor7: atyz: can you just write a simple prototype for a single content type in Clojure and discuss with the team? this would be the best, since you would know "what it takes" for this problem in Clojure, at the same time I don't foresee more than 100 lines of code to show to the team

10:36 jcromartie: an RSS/Atom feed aggregator in both Clojure and in Rails

10:36 but you said not Rails

10:37 and if not Rails, then I don't really imagine why you'd got with Ruby for it

10:37 atyz: cmajor7: i did that with the last webservice, thats why it's done in clojure :)

10:37 cmajor7: atyz: so what are their reservations?

10:37 atyz: jcromartie: ruby has lots of other tooling which is also honestly quite great

10:37 cmajor7: besides hiring, which is a valid one

10:37 jcromartie: atyz: do you mean gems?

10:37 atyz: jcromartie: yes

10:38 jcromartie: atyz: how much data are you talking about BTW?

10:38 atyz: so grape - for writing apis

10:38 jcromartie: potentially quite a lot

10:38 maleghast: atyz: Really? Re Grape I mean..?

10:38 jcromartie: atyz: if you're storing everything forever and you need a database, then the Ruby solution would push concurrency and state to the DB

10:39 maleghast: Clojure + Compojure will give you a lot more power and more importantly performance than ruby + grape

10:39 atyz: maleghast: i basically meant that - there are well written librarys for anything you could want to do in ruby

10:39 maleghast: There are in Clojure

10:39 jcromartie: Clojure + Java

10:39 atyz: maleghast: yes, but the issue is that nobody is familiar with it

10:39 maleghast: http://www.clojure-toolbox.com/

10:39 jcromartie: libs(Clojure + Java) > libs(Ruby)

10:39 maleghast: also true

10:40 jcromartie: but Clojure doesn't have any libraries like "trollop" or "tranny" or "girlfriend"

10:40 maleghast: (though I love the fact that other, better engineers have already wrapped up a lot of powerful Java libraries in Clojure so that I don;t have to do Interop)

10:40 I use Ruby for my job and I don't know what they are, jcromartie

10:40 atyz: maleghast: i have explained to them that they can leverage the java ecosystem

10:40 and thats rather attractive

10:41 maleghast: It should be

10:42 If you're building a RESTful API, Clojure, using Liberator and Compojure will more than get the job done, it will be fast, flexible and easy to test.

10:43 atyz: maleghast: our last webservice was exactly that, and we have all enjoyed working on it, but i think the fear of unfamiliarity with conventions is the primary motivator for this insecurity

10:43 well conventions and the tools

10:44 maleghast: Well, all I can offer is that I banged on about Clojure until people finally gave in - I am building our first bit of Production Clojure at the moment, and it's built on Compjure and HTTP-Kit

10:44 Just grind 'em down until all they want to do is say "yes" so you'll stop talking about Clojure ;-)

10:45 atyz: maleghast: I basically did the same thing and just built our last webservice - but the next service we're building is a lot bigger and i think they're nervous about doing it in a functional language that they don't know a lot about and there aren't as many resources available

10:46 maleghast: atyz: Just tell them:

10:46 "“I must not fear. Fear is the mind-killer. Fear is the little-death that brings total obliteration. I will face my fear. I will permit it to pass over me and through me. And when it has gone past I will turn the inner eye to see its path. Where the fear has gone there will be nothing. Only I will remain.”"

10:46 noncom: +1

10:46 atyz: Hah

10:47 zerokarmaleft: might as well use the Voice to compel them if you already have the prerequisite Bene Gesserit training

10:47 maleghast: If things weren't hard and / or scary sometimes they wouldn't be worth doing, but in general I have heard no horror stories about failed projects in Clojure - all I have heard is "we worried it would be hard, but we did it anyway and now we use Clojure for everything"

10:48 atyz: Good Luck!

10:48 zerokarmaleft: The wyrding way is beyond my level of skill, I am sorry to say.

10:48 atyz: thanks maleghast, jcromartie, cmajor7

10:48 My motivation is that I'm really bored of ruby and I like clojure and feel it would be a good fit

10:49 jcromartie: "I have heard no horror stories about failed projects in Clojure"

10:49 maleghast: atyz: I think you are right about the fit, so cling to that and your enthusiasm and evangelise...

10:49 jcromartie: maleghast: I had a "failed" project in Clojure

10:50 maleghast: jcromartie: Well I haven't - if you want to tell me some then I'l be able to offer a more balanced outlook, but as of now I haven't heard any.

10:50 jcromartie: well :)

10:50 atyz: what are somw big clojure projects though?

10:51 jcromartie: the Clojure project was good, but I rewrote it in Rails because other people needed to work on it

10:51 maleghast: atyz: Deutsche Bank has some Production Clojure Code, there is U-Switch - that's all Clojure on the backend, handling the provider tariffs etc.

10:51 jcromartie: to be a team player

10:51 oh, and THEN I lost my job there…

10:51 maleghast: jcromartie: You are too nice

10:51 jcromartie: so much for thoughtfulness

10:51 antares_: atyz: https://groups.google.com/forum/#!topic/clojure/a4Dp8gdHev8

10:51 atyz: there are banks known to have over 2M lines of Clojure (and that's probably dated by a year)

10:51 jcromartie: this one? http://www.uswitch.com/

10:52 antares_: but "I'm bored with Ruby" is not a good enough reason to choose Clojure

10:52 atyz: antares_: i agree, like i said earlier, I prefer the flexibility that comes with clojure,

10:53 antares_: on the other hand, "I hate Ruby because it's terrible at X and I primarily do X" is a different story

10:53 Ruby can be really flexible, in fact, too much so :D

10:53 atyz: most ruby tools/frameworks all seem to be too full featured

10:53 futile: Is ClojureScript actually way awesome?

10:53 jcromartie: futile: it could use better documentation

10:53 antares_: atyz: are you a Web developer?

10:54 futile: Yes, that part of it terrifies me.

10:54 But is it so awesome in itself that it's worth such a hassle of having lacking documentation?

10:54 jcromartie: people say that Ruby is good at DSLs because the syntax is so flexible, but that's not really what's going on… they just mean they like method_missing and blocks

10:54 atyz: antares_ yes

10:54 antares_: atyz: if so, Clojure would work OK for you but don't expect wonders. I'd probably just use JavaScript or Play with Scala for Web apps

10:54 jcromartie: futile: if you can read the sources instead of docs, then yes

10:54 futile: jcromartie: oh! good idea for a blog!

10:54 antares_: Clojure is excellent and data processing and APIs but not Web apps with templates

10:55 jcromartie: (inc antares_)

10:55 lazybot: ⇒ 2

10:55 jcromartie: that's exactly it

10:55 atyz: antares_: it would be a cllojjure api with an angular frontend

10:55 jcromartie: if you have a bog-standard web app with a login page and user profiles and pages with content and CRUD, then just go use Rails

10:55 futile: atyz: do not listen to antares_, Clojure is excellent for web apps, using compojure and hiccup and ring.

10:55 antares_: *and => at

10:55 futile: (dec antares_)

10:55 lazybot: ⇒ 1

10:55 atyz: the api would be pure data processing

10:56 futile: We use Clojure + ring + compojure + hiccup at work, and the results are amazingly better than any other web framework I've ever used in any language.

10:56 antares_: atyz: ok, that's better

10:56 atyz: the reason, of course, is not technical but a social one

10:57 you will have a hell of a time convincing good frontend engineers to use Hiccup and stuff

10:57 atyz: our "frontend" devs are full stack

10:57 antares_: even though they may have strong interest in Clojure and FP, it's just too inconvenient for many

10:57 even so

10:57 jcromartie: futile: where is "work"?

10:57 futile: I'd love to believe you :)

10:57 antares_: but single page apps that only need an API and HTML can use anything

10:57 atyz: they won't have trouble with hiccup/lazer/whatever

10:57 maleghast: futile: Yes, where is your work and do you want more Clojurians...

10:57 ?

10:58 jcromartie: maleghast: no! me first!

10:58 futile: maleghast: we're not hiring right now

10:58 maleghast: futile: Fair enough - I do get to do some Clojure where I am so really I'm just being greedy ;-)

10:59 robewald: technomancy: Forked your nrepl-proposal on github and added some notes: https://github.com/robewald/nrepl-discover/blob/master/notes-bob.md

11:01 noncom: jcromartie: FYI: the problemwas with KineticJS. It transforms the passed object in a hidden way: http://stackoverflow.com/questions/13732758/kineticjs-how-to-get-points-from-a-line and http://stackoverflow.com/questions/15893697/cant-get-transformed-points-out-of-a-kinetic-js-line

11:01 just in case you ever stumbleupon the case

11:02 jcromartie: noncom: mutable state strikes again

11:02 noncom: yeah :)

11:09 manutter: atyz: http://www.infoq.com/presentations/Clojure-powered-Startups

11:10 noncom: if I want to break my cljs file into several files - do i do this just the same way as in clj? I mean the :use and L:require things?

11:11 jtoy: is there debugging support? I want to inspect the elements of a hash at a certain point in my code im not sure exactly how to inspec the data

11:14 edw: Has anyone used Carmine to talk to a Redis server? It's getting connection errors for params that redis-cli takes happily.

11:18 Rogach: Q: Is it possible to use clojure compiler programmatically, for example, from java code? I tried something along the lines of `clojure.lang.Compiler.load(new StringReader("(println 1)"));`, but that failed with NPE.

11:19 hyPiRion: fairly certain load attempts to read the file "(println 1)" with that incantation

11:21 Rogach: hyPiRion: Woah. That's not good. Out of curiosity, why somebody would pass a file name parameter as a Reader?

11:21 hyPiRion: wait

11:22 trptcolin: ,(* -9223372036854775808 -1)

11:22 clojurebot: -9223372036854775808

11:22 trptcolin: (+ -9223372036854775808 -1)

11:22 ,(+ -9223372036854775808 -1)

11:22 clojurebot: #<ArithmeticException java.lang.ArithmeticException: integer overflow>

11:22 trptcolin: does the multiplication seem like it ought to throw as well?

11:23 hyPiRion: Rogach: I thought Compiler.load mapped to clojure.core/load, but that's not right.

11:24 ,(*' -9223372036854775808 -1)

11:24 clojurebot: -9223372036854775808

11:24 hyPiRion: whah.

11:25 trptcolin: whoa, it gets worse

11:25 ,(* -1N -9223372036854775808N)

11:25 clojurebot: 9223372036854775808N

11:25 trptcolin: ,(* -9223372036854775808N -1N)

11:25 clojurebot: -9223372036854775808N

11:25 Rogach: hyPiRion: Looking at the source of Compiler.java, it accepts a reader, and it seems that it should try to execute that as a code.

11:25 hyPiRion: Rogach: yeah, I'm looking into it now

11:26 Rogach: hyPiRion: But the NPE is thrown during Compiler static init, on line 47.

11:27 hyPiRion: Rogach: do you have Clojure on the classpath?

11:27 Rogach: hyPiRion: Sure.

11:27 hyPiRion: (when I don't, java executable complains about failing to find class file)

11:27 hyPiRion: Yeah, you should've gotten some LinkingError or something if that weren't the case I suppose.

11:28 Rogach: could you inspect the stack trace of that NPE?

11:28 Rogach: Actually, I want to do two things: 1) I want to be able to interpret/run arbitrary string of clojure code at runtime, 2) I want to be able to compile some code to standard classfiles and execute them afterwards (so I will be able to amortize costs of compilation)

11:28 hyPiRion: I'll paste it.

11:29 hyPiRion: Ok, great.

11:29 Rogach: hyPiRion: http://pastie.org/8066786

11:29 hyPiRion: And here's the code: http://pastie.org/8066791

11:35 hyPiRion: Ah, seems it's a known issue (with a workaround): http://dev.clojure.org/jira/browse/CLJ-1172

11:35 hyPiRion: ah

11:36 Oh well, good it has a workaround

11:37 Rogach: hyPiRion: No, it's hilarious.

11:38 hyPiRion: I applied the workaround, it worked, but here's what gets printed to output: "No need to call RT.init() anymore"

11:38 hyPiRion: whaat

11:38 From the issue: Doing this: RT.load("clojure/core"); at the top works avoids the message from RT.init()

11:39 Rogach: hyPiRion: No it doesn't :)

11:39 hyPiRion: I tried that already.

11:39 hyPiRion: oh dumm

11:39 Rogach: hyPiRion: Same message gets printed. (I'm using 1.5.1)

11:40 hyPiRion: I'll update the ticket to at least include that information

11:41 Rogach: hyPiRion: Thanks!

11:42 hyPiRion: Actually, it's already awesome that I can run arbitrary strings of clojure (modulo that warning).

11:42 atyz: So I've just run into something where my tests are about to be run on a CI. However it seems to want a database connection on boot of lein test

11:43 is there anyway to prevent this?

11:43 it's a compojure / ring app

11:43 hyPiRion: Rogach: what a strange thing though. If you want to avoid that warning, you can probably replace System.err and swap it back after calling RT.init();

11:43 (Seems like hassle though)

11:43 Rogach: hyPiRion: Yes, that will work, as a temp workaround.

11:44 hyPiRion: Is there some similarly simple method to compile some clojure file to classfiles?

11:45 hyPiRion: I want my app to use clojure files as some sort of "programmable configuration", so it would be nice if I could recompile those class files only when needed - it would shave ~1 sec on most runs.

11:45 hyPiRion: Rogach: At runtime I suppose?

11:45 Rogach: hyPiRion: Yes.

11:46 hyPiRion: Currently, I keep config as scala file, but compiling it is *very slow* - around 8 seconds on each run.

11:46 hyPiRion: I hope that clojure will compile faster.

11:47 hyPiRion: Rogach: I think http://clojure.org/compilation should have sufficient information about this

11:47 have a look at Compiler.compile.

11:49 Rogach: hyPiRion: Hm. It compiles a java class. But it is possible to compile a heap of clojure code into classfiles?

11:53 hyPiRion: Humm, it should in theory compile it down to a classfile, but I've not done runtime loading from java, soo..

11:54 Rogach: hyPiRion: Runtime loading is not a problem ;)

11:55 hyPiRion: Compiler.compile takes three args - `superName`, `interfaceNames`, `oneTimeUse`. How do I specify which code I actually want compiled?

11:56 hyPiRion: You're reading at the wrong compile: https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/Compiler.java#L7162 <--

11:56 Rogach: well, Compiler.compile() should dump out a classfile in `*compile-path*`, which is by default "target/classes"

11:58 ak5: hey guys, I have been looking at clojure, thinking about learning lisp finally - and now there is lisp made for the web kinda. However, Java scares me, I dislike it and don't want to touch it if possible - how much Java do i need to know to start with clojure?

11:58 hyPiRion: So e.g. if you attempt to compile a file through Compile.compile(reader, "source/name",

11:58 oops.

11:59 ak5: You have to know how to run `java` to set up your server, and that should be it :)

11:59 ak5: hyPiRion: sounds good enough for me

11:59 thanks

11:59 Rogach: ak5: What's so wrong with java per se?

11:59 ak5: what about standard libs? Which are the java essential libs that end up being used often in clojure?

12:00 Rogach: call it a personal preference?

12:00 Rogach: ak5: "Personal preference" also has some reasons.

12:00 hyPiRion: ak5: the string class has some functions, but they are very easy to invoke. Apart from that, I haven't had the need to use any Java yet.

12:01 So for instance, you would sometimes like to do ##(.indexOf "Hello world!" \w)

12:01 lazybot: java.lang.IllegalArgumentException: No matching method found: indexOf for class java.lang.String

12:01 ak5: Rogach: I feel like it's sucking my soul out through my fingers when I type java

12:01 it's just a feeling

12:01 hyPiRion: (See, I don't know how to do that and I'm still fine)

12:01 Rogach: ak5: Well, you mean the verbosity?

12:01 ak5: Rogach: yes

12:01 Rogach: ak5: You can try scala ;)

12:02 hyPiRion: ,(.indexOf "Hello world" "w") ; << ak5, that's probably the most java you have to understand for a web app.

12:02 clojurebot: 6

12:03 VFe: ak5: Clojure's ecosystem has matured a lot, unless you're specifically writing a wrapper or some library to interact with a java client, I haven't had to use actual java for anything at all.

12:03 hyPiRion: (the .indexOf is a java call)

12:03 ak5: VFe: thanks

12:03 hyPiRion: good :) thanks

12:04 Rogach: I haven't ever looked at scala, its like clojure in that in runs on the JVM, right? but it's not lisp-like?

12:04 VFe: I think not lisp-like is…a very under-stated way of putting it XD

12:04 Rogach: ak5: Something like it.

12:04 ak5: It's very different, but still runs on jvm.

12:05 ak5: yeah, I see. It seems to be super object oriented

12:05 Rogach: ak5: But I wouldn't compare it to clojure - both languages have their place.

12:05 ak5: Yes, that's true.

12:06 noncom: ,(take "hello" 3)

12:06 ak5: well I just want to know WTF this deal with macros is, everyone says they're "the shit". I'm a javascript kinda guy, have been for a while. Think it's time to step up my game, you know? xD

12:06 clojurebot: #<ClassCastException java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Number>

12:06 noncom: ,(take 3 "hello")

12:06 clojurebot: (\h \e \l)

12:06 noncom: how do I make the result of (take 3 "hello") to be "hel" and not a list?

12:06 Rogach: hyPiRion: I tried loading a string of clojure code with `ns` and `gen-class`, and then loading a string that called `compile`, but it seems that `compile` requires source file.

12:06 ak5: and since the web is my home, why not learn a dialect of lisp that does that well <-- is that a good enough reason to look into clojure?

12:07 hyPiRion: noncom: subs

12:07 noncom: oh

12:07 thanks

12:07 hyPiRion: ,(subs "hello" 3)

12:07 clojurebot: "lo"

12:07 hyPiRion: ,(subs "hello" 0 3)

12:07 clojurebot: "hel"

12:07 VFe: ak5: imho yes, that's one of primary reasons I got into clojure as well

12:08 noncom: ,(str (subs "what is where" 4) (subs ("what is where" 5))

12:08 clojurebot: #<RuntimeException java.lang.RuntimeException: EOF while reading>

12:08 noncom: ,(str (subs "what is where" 4) (subs ("what is where" 5)))

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

12:08 noncom: ,(str (subs "what is where" 4) (subs "what is where" 5))

12:08 clojurebot: " is whereis where"

12:08 noncom: ,(str (subs "what is where" 0 4) (subs "what is where" 5))

12:08 clojurebot: "whatis where"

12:09 noncom: nice

12:10 ak5: VFe: cool, whats a good place to get started? I just got leiningen cause I like the logo :P

12:11 VFe: ak5 I'd start at luminusweb.net , it's a "framework"(more a collection of libs) thats incredibly beginner friendly

12:11 hyPiRion: Also, to get familiar with clojure, check out 4clojure.

12:11 VFe: and the site guides you through a lot of the basics of creating a simple web app in clojure/clojurescript

12:12 and yeah, 4clojures a great place to just try problems to get familiar with lisp style programming

12:13 ak5: I like to get the syntax in project euler or something, but i'll check that last one out too

12:16 VFe: Anyone have thoughts on Mailer vs Postal?

12:17 ohpauleez: VFe: Depends on the goal you're looking to achieve, I dislike them both for different reasons, but have used both

12:18 I haven't taken a look at them in a year or so though

12:18 VFe: I'm just looking at sending out validation and password reset kind of emails

12:23 jtoy: what am I doign wrong with this reduce: (reduce (comp + :precision) [{:precision 0.3} {:precision 0.5} ])

12:24 ohpauleez: VFe: I would use Mailer - the metadata abuse in Postal always seemed to be annoying

12:24 jtoy: reduce fns take two args, the accumulator and the new value

12:25 you probably want something like (fn [accum newv] (+ accum (:precision newv)))

12:25 hyPiRion: ohpauleez: or even better, (reduce + (map :precision [...]))

12:25 VFe: Thanks, appreciate the input before I bothered learning one or the other =0

12:26 ohpauleez: hyPiRion: yes, that's even better

12:26 and change the reduce to apply there, to get a call-site cache hit

12:26 jtoy: hyPiRion: why doesnt your version take seperatevalues?

12:26 hyPiRion: jtoy: what do you mean?

12:26 ,(reduce + (map :precision [{:precision 0.3} {:precision 0.5}]))

12:26 clojurebot: 0.8

12:27 jtoy: hyPiRion: yours doesnt have accum and newv, just + as the function

12:27 hyPiRion: ,(map :precision [{:precision 0.3} {:precision 0.5}])

12:27 clojurebot: (0.3 0.5)

12:27 ohpauleez: because + takes as many args as you pass it

12:27 hyPiRion: oh right

12:27 that's what you meant, sorry

12:28 ohpauleez: in your example before, your accumulator doesn't have the key, :precision, so the comp fails

12:28 jtoy: So the solution is to get a seq of all your values (with map), and then sum them up

12:29 jtoy: ohpauleez: im not 100% clear on waht that means, but i can follow that

12:29 ohpauleez: jtoy: Play with `reductions` a little to see how reduce is working

12:30 dnolen_: a simple reason why your version doesn't work

12:30 ((comp + :precision) {:precision 0.3} {:precision 0.5})

12:30 this makes no sense

12:31 but that's what you've written

12:32 ,(:precision {:precision 0.3} {:precision 0.5})

12:32 clojurebot: 0.3

12:32 dnolen_: ,(+ 0.3)

12:32 clojurebot: 0.3

12:32 dnolen_: ,(reduce (comp + :precision) [{:precision 0.3} {:precision 0.5}])

12:32 clojurebot: 0.3

12:34 jtoy: thx

12:35 dnolen_: I thought the use case for comp was to add funtions together

12:37 dnolen_: jtoy: it does add two functions together

12:37 jtoy: but your composition does not make sense when used with reduce

12:38 jtoy: or rather, it doesn't work as you intend because of the examples I showed above

12:39 jtoy: hyPiRion's answer is the correct one, you want to first *extract* :precision via map, and then reduce the resulting seq of numbers with +

12:58 jtoy: dnolen_: yup, im using that now, thanks guys

13:01 mhooge: I'm new to Clojure. Is this the proper IRC channel to ask general questions, style, functionality, and the like?

13:02 TimMc: Yep.

13:04 hyPiRion: lazybot: it's true, right???

13:04 lazybot: hyPiRion: How could that be wrong?

13:05 mhooge: Sweet. So I've been spending some of my free time writing up some Clojure for our API. Is there a preference to :pre conditions or exceptions?

13:09 aroemers: mhooge: we use assert, which is another option, and you can turn them off.

13:10 hyPiRion: I think it kind of depends on the system. preconditions are nice when speed is not critical.

13:11 Hmm, I think The Joy of Clojure has a discussion on preconditions, but I don't remember exactly what they concluded with.

13:12 llasram: There's also the pretty common idiom of just GIGO. Instead of throwing an explicit exception for invalid input, just return undefined results or `nil`

13:12 technomancy: mhooge: preconditions are for "if this ever happens, it's a bug". for the kind of problems that are unavoidable in the real world (out of disk space, network goes down, input got garbled, etc) you should use exceptions

13:15 mhooge: thank you for all the response. In our case, invalid input would just result in the server kicking back an error response. So the asserts would just help developers debug.

13:20 dnolen_: cemerick: fwiw, I don't really understand what you're saying in the ticket 527 at all :)

14:29 aphyr: ,(* -1 Long/MIN_VALUE)

14:29 clojurebot: #<ArithmeticException java.lang.ArithmeticException: integer overflow>

14:29 aphyr: ,(* Long/MIN_VALUE -1)

14:29 clojurebot: -9223372036854775808

14:33 aphyr: what you know about multiplication?

14:34 llasram: Well, we can infer from this example that it is not commutative

14:34 mmitchell: Anyone have tips on deploying a jar file to s3? This is not a clojure project, but a java project. It has an ant build file, no pom.

14:37 amalloy: &(*' Long/MIN_VALUE -1)

14:37 lazybot: ⇒ -9223372036854775808

14:37 justin_smith: mmitchell: lein ring uberwar will create the thing beanstalk would use

14:37 (or tomcat on ec2)

14:38 llasram: &(*' (inc Long/MIN_VALUE) -1)

14:38 lazybot: ⇒ 9223372036854775807

14:38 llasram: Cool!

14:38 tomjack: mmitchell: there is s3-wagon-private

14:39 oh, nevermind

14:39 mmitchell: justin_smith: oh this is just a regular java lib that i'd like my clojure project to use from s3

14:39 technomancy: mmitchell: you can deploy it to a directory on disk and then use s3cmd to upload that directory

14:39 mmitchell: interesting, maybe that's the simplest approach

14:39 justin_smith: mmitchell: ahh, in that situation I would push it to clojars

14:40 amalloy: aphyr: that's funny. c.l.Numbers/multiply does: "multiply the two numbers; if dividing the result by y doesn't give you back x, then throw an exception"

14:40 in the case of (* Long/MIN_VALUE -1), the overflow-check itself suffers the same overflow, and no exception is thrown

14:42 Bronsa: ,[(== 4.0 4) (== 4.0 4.0M) (== 4 4.0M)]

14:42 clojurebot: [true true false]

14:44 tomjack: I guess even haskell has trouble with floats :(

14:45 Bronsa: the fix is really simple https://github.com/Bronsa/clojure/commit/f0082056c2470420fd16067b23bd7b210305d509

14:48 tomjack: I see, that seems pretty nuts

14:50 why (== 4.0 4.000M) now?

14:51 well that makes sense maybe, but also (== 4.000M 4.0)?

14:52 oh, yeah

14:52 &(== 4.0000000000000000000001M 4.0000000000000000000001M 4.0)

14:52 lazybot: ⇒ true

14:54 moquist_: seancorfield: do you mind a PM to talk about clojure.java.jdbc.ddl ?

14:54 aphyr: amalloy: jesus

14:56 TimMc: &(* Long/MIN_VALUE -0.99999999)

14:56 lazybot: ⇒ 9.223371944621055E18

14:58 seancorfield: moquist: fire away!

14:59 TimMc: &(= (*' -1 Long/MIN_VALUE) (*' Long/MIN_VALUE -1))

14:59 lazybot: ⇒ false

14:59 Bronsa: feels good to have a locally patched clojure where everything is working fine

15:02 trptcolin: aphyr / amalloy / TimMc: patch attached to http://dev.clojure.org/jira/browse/CLJ-1222

15:07 aphyr: trptcolin: http://aphyr.com/media/dancing.gif

15:08 hyPiRion: I very frequently multiply Long/MIN_VALUE with -1, so it is good that this is fixed

15:09 trptcolin: hehe

15:11 it's funny, there are actually bunches of generative tests for math, including commutative multiplication. alas, 2^64 is a big space to hope we get all the cases

15:11 surely there's some smart way generative tests could be made to seek out edgy cases (MAX_VALUE, 0, 1, MIN_VALUE, ...)

15:11 [not with full generality of course, i get that]

15:13 stuartsierra: dnolen: ping

15:13 dnolen_: stuartsierra: what's up?

15:14 stuartsierra: dnolen_: Working on ClojureScript release. Can you test something for me?

15:14 dnolen_: stuartsierra: sure

15:14 stuartsierra: dnolen_: OK. Add a :repository for "https://oss.sonatype.org/content/repositories/orgclojure-1017/&quot;

15:14 Then try a dependency [org.clojure/clojurescript "0.0-1834"]

15:14 And see if everything works.

15:15 TimMc: trptcolin: Generative tests usually *do* focus on the edge cases.

15:15 dnolen_: stuartsierra: like in an empty project?

15:16 stuartsierra: dnolen_: Any Lein project will do.

15:16 trptcolin: TimMc: oh. cool, maybe it's just underusing what's available then

15:16 stuartsierra: dnolen_: Preferably something that uses ClojureScript somewhere. :)

15:17 amalloy: trptcolin: 2^128, really, since you need to find pairs of numbers

15:17 trptcolin: ah, good point.

15:17 amalloy: but i think it would be better to talk to a mathematician

15:17 trptcolin: i was considering being sly and citing the birthday paradox, but that is totally irrelevant.

15:17 dnolen_: stuartsierra: how do I add that repository?

15:18 :repository [...] doesn't work

15:18 in my project.clj

15:18 stuartsierra: Sorry, meant :repositories {"clojurescript" "that URL"}

15:18 (This is a temporary staging repository.)

15:20 dnolen_: stuartsierra: thx testing now

15:20 stuartsierra: seems to work

15:21 stuartsierra: dnolen_: Great, thanks. I'll commit these changes and get a real release out this afternoon.

15:21 dnolen_: stuartsierra: thx!

15:22 stuartsierra: dnolen_: Hopefully this will make it *actually* automated instead of sort-of-automated.

15:24 dnolen_: stuartsierra: excellent

15:35 stuartsierra: dnolen_: ClojureScript 0.0-1835 released to Sonatype.


15:35 dnolen_: stuartsierra: thank you!

15:35 rkneufeld: ^

15:36 rkneufeld: the namespace aliased keyword patch is in there

15:42 bbloom: dnolen_: I love git. I wanted to know what that patch was about, so I did `git show :/alias` and poof the most recent relevant commit came up :-)

15:43 dnolen_: did we break this when we made the related fix? or was this already broken?

15:44 dnolen_: bbloom: was always broken

15:44 bbloom: dnolen_: k

15:44 anything having to do w/ the reader is pretty tricky to get right

15:44 dnolen_: bbloom: someone had committed a half fix at one point which I applied

15:44 bbloom: removed what they did and did the correct thing, it was simple in the end

15:45 bbloom: cool

15:45 dnolen_: https://github.com/clojure/clojurescript/commit/4a04114aedbd1073c4a7c58cee122fcfd0ef1eb4

15:46 form-seq wasn't lazy enough, and there was pointless dynamic var, should have just used *cljs-ns*

15:46 bbloom: read

15:47 * bbloom was in the wrong buffer

15:51 * futile just wrote a new blog: https://gist.github.com/evanescence/5833792

15:52 futile: and it's all thanks to callen

15:57 not really Clojure-specific, i know, but its something i really wish everybody knew

16:02 That sounds arrogant, doesn't it? But really that's the only reason people write blogs..

16:04 bbloom: futile: personally, i write my blog primarily for myself. teaching is an excellent way to learn. polishing up the spelling, grammar, and formatting for consumption is basically because it's free publicity after i've paid the price of tuition

16:05 hyPiRion: futile: nah, I agree with the statement somewhat, but I limit it to what I want to publish for others to see

16:05 futile: hyPiRion: which statement

16:06 hyPiRion: futile: oh right, the statment you made in the post

16:06 So e.g. I find it justifiable to "hack 'till it works" in programming competitions for instance.

16:08 And I may implement X on the side for fun, curiosity and/or to learn how to make a good X.

16:09 futile: hyPiRion: oh, yeah.

16:10 hyPiRion: I'd agree.

16:10 hyPiRion: hence that last paragraph about polishing up abandoned sw as good practice

16:11 tomjack: every time I try to write a blog post it just makes me realize I still need to think more :)

16:12 robewald: technomancy: thanks for your comments on my notes on github.

16:14 mhooge: I've noticed that my preconditions with the :pre keyword don't always trigger an Assertion error, even though an actual (assert something) will. Is there something I'm missing? I've check that *assert* has not been set to false

16:15 *checked

16:17 avishai: hi

16:18 can lein fetch pom dependencies? e.g. multi module dependency

16:25 robewald: mhooge: do you have an example to look at?

16:25 mhooge: Sure, where would you like me to put it? Gist?

16:26 robewald: As long as I get a link it should be fine :)

16:28 mhooge: robewald https://gist.github.com/mhooge/5834051

16:30 futile: bbloom: To further explain my point from the other day:

16:30 https://gist.github.com/evanescence/5833954

16:32 bbloom: futile: your first example uses 7 commas and your second example uses 6

16:32 futile: bbloom: think you're missing the point

16:33 or maybe I just explained it wrong, but I think it's the former

16:33 It's not about the commas, it's about all of it, the commas are just one part.

16:33 bbloom: futile: did you write both of those examples?

16:33 futile: yes

16:33 why

16:34 bbloom: just curious

16:34 futile: i used to write in the first style, now i write in the second style

16:34 mainly because i wouldnt read the first one if someone else wrote it, but id read the second one

16:34 bbloom: your first example includes several run-on sentences that can easily be broken up and it would be much clearer than the second paragraph

16:34 futile: bbloom: meh

16:35 bbloom: they also contain different content, so it's not really a reasonable comparison

16:35 futile: bbloom: look I'm not saying my point is well made, just that it's right.

16:35 bbloom: yea, it is.

16:35 the content is an integral part of the sentence.

16:35 bbloom: futile: lol ok well, since you know you're right, i'll just leave you alone to be right then

16:35 futile: it's a perfect comparison, apples and oranges.

16:36 * futile won the conversation!

16:38 robewald: mhooge: It works for me an breaks with a IllegalArgumentException. You don't catch that at another place, do you?

16:38 futile: ha, i /knew/ i'd win if only i said enough nonsense bbloom

16:38 :D

16:39 bbloom: futile: and knowing that you view this as a winnable game means that i know it's not worth discussing with you

16:39 mhooge: robewald interesting. No, I'm not catching it anywhere else. I'm just testing it with the repl

16:39 futile: bbloom: assuming I wasn't joking, sure

16:40 bbloom: I think you're taking a pointless IRC conversation and a couple empty blog posts way too seriously

16:41 technically the word is vain, from Latin vanus, meaning "empty", i.e. void of real substance or purpose or meaning

16:41 but yeah, empty and pointless work too

16:46 mhooge: robewald how are you executing the code, if you don't mind me asking?

16:48 robewald: mhooge: wrong, i just noticed... The pre doesn't get triggered for me either

16:52 mhooge: the docstring is in the wrong position. take it away and it works.

16:54 mhooge: yes, the docstring goes after the :pre, :post map

16:54 mhooge: robewald ooohhhh. Sweet, good to know. Thank you.

16:55 and there it is.

16:56 robewald I appreciate your help, thank you.

16:59 robewald: mhooge: my pleasure.

17:35 futile: bbloom: sorry for being kind of rude earlier

17:36 bbloom: futile: no worries

17:40 callen: I really wish he would stop attributing those posts to me.

17:40 r0bgleeson: he reminded me of 'Sebastian' from Kitchen Nightmares.

17:40 callen: parade of narcissists.

17:41 mdeboard: a phrase I never thought I'dsee in #clojure

17:43 wastrel: i decided to write a clojure program

17:45 r0bgleeson: is clojure being used to write web applications?

17:46 callen: r0bgleeson: nope never.

17:46 wastrel: i think it is likely the case

17:46 callen: r0bgleeson: totally impossible.

17:46 wastrel: that people are using it to write web applications but i don't know any examples because i'm not really a clojure person

17:46 bbloom: callen: seriously. please don't be sarcastic with the newcomers

17:46 patchwork: r0bgleeson: I have several in production

17:47 r0bgleeson: patchwork: did you use a framework?

17:47 mdeboard: wastrel: Yes, getprismatic.com is written entirely in Clojure.

17:47 For example.

17:47 callen: r0bgleeson: you want to use Luminus.

17:47 r0bgleeson: bbloom: its fine, question was sort of stupid and open-ended :)

17:47 callen: r0bgleeson: http://www.luminusweb.net/

17:47 r0bgleeson: thanks

17:47 technomancy: HTML uses angle brackets and Clojure uses parentheses, so they are clearly incompatible.

17:47 mdeboard: Er, sorry, r0bgleeson, getprismatic.com is written entirely in Clojure, for example.

17:47 callen: r0bgleeson: example app based on Luminus: github.com/bitemyapp/neubite/

17:47 technomancy: oh so you're allowed to be sarcastic and I'm not?

17:48 technomancy: watch out, bbloom will scold you.

17:48 mdeboard: eternal junetember

17:48 callen: ^^

17:48 r0bgleeson: mdeboard: fast as hell, too :)

17:49 mdeboard: did you use luminus?

17:49 mdeboard: r0bgleeson: Yeah, seeveral very very very smart people working on it.

17:51 wastrel: i set up clojure on my laptop

17:51 callen: wastrel: you mean Leiningen?

17:51 r0bgleeson: hum interesting, clojure might be a great fit for a project i have, I need to talk to MS-SQL but i'm not good enough to do a project of that size in a language i dont know

17:51 id love to though

17:52 wastrel: callen: no i just downloaded the clojure zip

17:52 callen: r0bgleeson: most Clojure apps sit atop existing Java tooling like JDBC either via cjj or Korma so database compatibility isn't a "problem"

17:52 wastrel: that's a bad idea. Use Leiningen.

17:52 wastrel: i haven't read about lenanignen yet

17:52 i set up a clj script that uses rlwrap

17:52 callen: wastrel: it's like a one or two line installation. I'd hop to it.

17:52 wastrel: and vimclojure

17:52 r0bgleeson: callen: yup, as soon as I saw JDBC I wanted to use clojure :p

17:52 callen: I don't think I've heard of anybody actually liking JDBC, but okay.

17:53 it's useful as mortar I guess.

17:53 r0bgleeson: well, it has good MS SQL support doesn't it?

17:53 that's not that easy to find in open source (ruby at least)

17:53 wastrel: i'm going to start writing scripts in clojure

17:53 callen: Ruby isn't a community known for having an ecumenical attitude towards technology.

17:54 r0bgleeson: I think it has more to do with not a lot of people choosing an MS stack and also using open source.

17:55 interest isn't there to work on it

17:55 callen: I personally left the .NET world very purposefully, I'm not sure I blame them.

17:55 mdeboard: r0bgleeson: Last I looked Clojure-CLR is up to date with 1.4 :)

17:55 Just throwing it out there

17:56 So if you're coming from C# or whatever, there's that.

17:56 up to date with clojure 1.4, that is.

17:56 r0bgleeson: mdeboard: not a C# guy myself, but got to integrate with a .NET stack

17:56 mdeboard: Might be worth a look.

17:56 r0bgleeson: ill check it out, thanks

18:25 wastrel: it seems lanenign is very popular

18:25 ToxicFrog: leiningen, you mean??

18:25 lazybot: ToxicFrog: Uh, no. Why would you even ask?

18:25 justin_smith: (dec lazybot)

18:25 lazybot: ⇒ 17

18:45 kyled2: (inc lazybot)

18:45 lazybot: ⇒ 18

18:58 gt`: hi getting this erro when starting joodo server using lein joodo server .. here is the error java.lang.IllegalArgumentException: No implementation of method: :make-writer of protocol: #'clojure.java.io/IOFactory found for class: nil

18:58 any help appreciated

19:05 justin_smith: gt`: can you put the stack trace on refheap or pastebin or something? - there are lots of places something may want to call make-writer on something that is accidentally nil

19:08 gt`: thanks will try that

19:12 justin_smith: https://www.refheap.com/15996

19:14 justin_smith: i am just new to clojure

19:14 justin_smith: what is your code's namespace?

19:16 my guess, just looking at the stacktrace is that joodo.kuzushi.comands.server/execute is expencting something that it can make a writer out of

19:16 gt`: justin_smith: just downloaded joodo a frame work for herouku and starting the server

19:16 justin_smith: oh, so no code of your own in there at all?

19:16 gt`: I am no even coding anything

19:16 justin_smith: there may be an arg or config missing there

19:17 gt`: I am just following the instructions i downloaded

19:17 justin_smith: so did you create a project?

19:17 hyPiRion: gt`: may I guess that you do `lein joodo` or something?

19:17 gt`: yes i did

19:17 justin_smith: ok, when you create a project, that creates your namespace

19:17 gt`: yes lein joodo new

19:17 justin_smith: that gets loaded when you run

19:18 gt`: it creates the directory skeleton and project.clj

19:18 hyPiRion: gt`: did you follow these instructions? https://github.com/slagyr/joodo/blob/master/README.md

19:18 justin_smith: so the answer to my question "what is your code's namespace" is what joodo generated for you when you did lein judo new

19:18 gt`: yes that is the instructions i am following

19:18 justin_smith: I ask because knowing which code is yours helps me narrow down where a problem likely is in a stacktrace

19:19 hyPiRion: hm, that's strange. Let me just quickly set it up myself.

19:19 gt`: I guess yes

19:19 what ever namespace joodo creates

19:19 justin_smith: well new usually takes an argument

19:19 and after joodo creates it, it is your code from that point on :)

19:19 technomancy: is there something specifically in joodoo you need? if you just want to put a web app together there are simpler ways =)

19:20 hyPiRion: gt`: I can confirm that I get the same error as you do, so fear not. (well, at least I can reproduce it)

19:20 gt`: justine_smith: I guess but i don't feel like i own it yet :)

19:21 hyPiRion: thats great I am not alone

19:30 hyPiRion: gt`: ok, I figured it out

19:30 gt`: when you specified the plugin in your config.clj, change the version number to "1.2.0" and it should work

19:30 *profiles.clj

19:31 I would also delete the old project and make a new one, in case the project has changed on the default setup somehow.

19:31 tomjack: yes, delete the old project, then abandon joodo :)

19:34 gt`: hyPiRion : thanks will try that

19:35 tomjack: :) I will when i can't get an app running on herouku hahaha

19:36 technomancy: `lein new heroku myapp`

19:43 gt`: HyPiRion: thanks alot now the server is working I am able to load the page on my browser

19:43 hyPiRion: great!

19:44 gt`: hyPiRion: now the next step is to deploy wots working on herouku

19:44 so that i get a sense of deployment

20:05 sevengraff: clojure is for smelly nerds.

20:05 im a nerd. i smell. teach me clojure

20:05 bbloom: callen: you can be sarcastic to this one

20:07 sevengraff: no but for real im taking a Clojure class tomorrow https://workshopweekend.net/oakland/catalog#workshop-clojure

20:07 and im pretty excited so i thought i'd chill with the cool kids in the irc room

20:07 what does a noob need to know about clojure?

20:09 technomancy: bbloom: haha nice

20:09 hyPiRion: sevengraff: The parens may seem scary in the beginning, but you'll like them after you've played around with clojure for some time

20:10 sevengraff: im ok with the parens, we did scheme for a few days in a class at university

20:10 but ive seen some clojure code with square brackets. whats [ and ] all about?

20:12 noonian: unlike scheme, clojure has more than 1 built-in types with syntax for literals of those types

20:12 so a collection that uses square brackets instead of parens is a vector

20:12 amalloy: noonian: you're claiming scheme only has one literal type?!

20:13 sevengraff: woah a vector, this sounds cool

20:13 noonian: amalloy: not claiming anything, which types are available in scheme other than the pair? I think there are vectors actually I'm remembering but I never see them used much

20:14 amalloy: numbers, strings, symbols, lists, booleans...just off the top of my head

20:14 noonian: er, maybe composite types is a better term for what I'm getting at?

20:14 technomancy: meh; numbers are just an optimization over church numerals

20:15 amalloy: technomancy: same for cons cells :P

20:15 hyPiRion: technomancy: couldn't that be said for vectors, maps and sets as well? :p

20:16 noonian: anyway, i'm not trying to bash scheme, I love scheme actually :P

20:17 technomancy: hyPiRion: the secret twist ending of all computer science

20:17 hyPiRion: heh

20:18 noonian: I was despairing that I'd have to wait until r7rs large language was ratified to find a lisp with decent library support, but then I found Clojure

20:19 technomancy: isn't r7rs large just a standardization of all the stuff the racket guys couldn't get in r6rs?

20:20 noonian: my understanding is it will be a large set of standard libraries to do useful stuff like http and it will be part of the language standard so that implementations that want to say they support it will have to support all of it

20:20 bbloom: technomancy: i got the impression that racket isn't a direct superset of scheme, it's the language that those guys implemetned several schemes with :-P

20:20 noonian: but toy implementations and research ones can opt to only implement the 'small' language

20:20 bbloom: technomancy: i mean, if you're gonna go meta, you might as well go meta meta and iterate until a fixed point

20:21 noonian: yeah, the racket languages that they teach to people don't conform to any of the scheme standards anyway

20:26 gt`: to those who deploy on heroku can one deploy through some other port other than port 22. I am sitting behind a firewall trying to git push

20:34 noonian: gt`: I don't have much experience with circumventing heroku restrictions, but this (heroku plugin?) might help with what you are trying to do. I found it through stack overflow where he says it uses https

20:34 https://github.com/ddollar/heroku-push

20:39 gt`: noonian: thanks looking at it now

20:41 technomancy: gt`: you can use port 2222 on gitproxy-default.herokussl.com, though it's not officially supported

20:42 wait, your firewall blocks 22 specifically but lets any other through?

20:42 what kind of company does that? =\

20:43 muhoo: the kind of company who knows how easy it is to tunnel out of the firewall with ssh?

20:44 ken_barber: one can tunnel on any port really.

20:47 technomancy: tunneling out on other ports is arguably easier since it doesn't require root

20:48 wastrel: hi candy canes ♥

20:57 i downloaded the leaningen

21:01 i think i prefer the rlwrap repl

21:06 my main question about leningean - what's a project and why do i want one

21:08 TimMc: Leiningen projects allow you to have dependencies and have versioned releases.

21:12 noonian: a lot of useful development tasks for specific libraries and technologies have been implemented as leiningen plugins, think rake tasks for rails and the like

21:13 gt`: noonian: hmm i was able to deploy but not to the app i just created it is deploying to one of the default app created by heroku called still-castle-3461. There must be a way around it some how :)





21:14 r0bgleeson: noonian: it's more like bundler.

21:15 gt`: noonian: here is the deployed site http://still-castle-3461.herokuapp.com/

21:16 i wanted to deploy to this http://mexams.herokuapp.com

21:18 noonian: gt`: hmm, I think there is an --app-name flag you can pass into heroku calls to specify which of your apps you're targeting

21:18 r0bgleeson: yeah, bundler + rake combined :)

21:19 gt`: noonian: mmm i think so too i will have a look thanks for the help so far

21:19 noonian: gt`: no problem, good luck

21:21 seangrove: Hey all, wondering how I can make this more idiomatic

21:21 https://www.refheap.com/3076119d0daf6d917de7518b5

21:21 There are a few places that state is changed, though they're all at the top at least, and the whole function just look ugly... that may be a consequence of dealing with streaming http api's async, but it's still a bit sad

21:22 Anywya, idiomatic/better code suggestions readily welcome

21:23 noonian: well, instead of using swap I might do some sort of accumulation with reduce or use loop/recur

21:23 I'm very new to clojure also so take my advice with a grain of salt

21:28 seangrove: That might work, but then I need to keep track of when to kill the connection

21:28 I feel like I'm going to end up introducing state and tying everything together in an ugly way

21:33 gt`: noonian: found out how to add the app name one is deploying too .. in the .git/config file add app name there. I added this url = git@heroku.com:mexams.git. and heroku push and it deploy to the app i specify . Thank you so much for the help i am getting

21:34 wastrel: vim clojure thing is spazzing about indenting

21:34 borkage

21:47 i think if it doesn't understand some keyword it doesn't indent properly :p

21:56 tomjack: "http.async.client"? wow

21:58 seangrove: tomjack: ?

21:59 tomjack: just seems crazy to claim http.*

21:59 seangrove: Ah, fair enough

21:59 That'd be like cemerick claiming cljs.test :)

22:00 tomjack: worse I think

22:00 no suggestions, I agree it is sad :(

22:00 seangrove: Ah well, thought there may be something obviously better I was missing

22:01 'course, the new async stuff hickey is working on might add some nice options

22:01 dnolen_: seangrove: sounds like it

22:01 tomjack: maybe

22:01 still going to be ugly, but not that ugly

22:04 dnolen_: seangrove: I'm honestly more excited about core.async for client side code

22:05 seangrove: dnolen_: I agree, could be some really cool stuff there. Just surprising how ugly concurrent code is currently

22:07 amalloy: seangrove: (.getTime (java.util.Date.)) is just a gross/expensive way to write (System/currentTimeMillis)

22:07 dnolen_: seangrove: yeah it's really little better than JS at the moment

22:07 seangrove: amalloy: Ah, well, that's good to know at least

22:08 amalloy: but i don't think you can avoid the atom, given that your http client only exposes a callback-based API

22:08 though honestly (atom "") that you keep concat-ing to is just an inefficient StringBuilder

22:09 tomjack: seangrove: do you even need async?

22:09 amalloy: i wouldn't unconditionally println in there

22:09 seangrove: tomjack: Not necessarily, but I wanted to explore using it

22:09 paultag: Anyone know how I might run a program and drop to a REPL with lein?

22:09 seangrove: amalloy: More concerned about the ugly nature of it, given the callback-based api

22:10 tomjack: since you're taking up a thread anyway seems it'd be a lot simpler to just use clj-http or whatever

22:10 seangrove: amalloy: If you were writing this async http api, how would you do it instead? Would you still use callbacks?

22:10 amalloy: i'd use lamina and aleph

22:11 seangrove: Alright, will play with those next time instead then

22:11 This was just for fun to play with a seemingly trivial problem

22:11 amalloy: which doesn't fundamentally change the process, but it does hide some of the state for you, and lets you build some things that look functional

22:13 tomjack: deceivingly so :)

22:13 can't decide whether that's better or worse than core.async's approach

22:15 with core.async I'd guess that code would turn into a loop inside go

22:16 which would be nice and somewhat clear

22:16 but do we just write new loops inside go every time?

22:17 amalloy: haha, https://github.com/clojure/core.async/blob/master/test/clojure/clojure/core/async/buffers_test.clj#L14 - a slap in the face to the claim that clojure.test/is is extensible

22:18 tomjack: lamina seems lax in that you pretend these non-values are values, which lets you use nice things like map/filter/etc

22:18 but they're not values. otoh writing (go (loop [])) all over doesn't sound fun :(

22:19 amalloy: i couldn't find any docs for core.async, and the tests don't mention this "go" thing, so i can't have a meaningful discussion with you about it

22:19 or, at least, not the two test files i chose based on my guess at whether they'd be interesting

22:19 tomjack: the go tests are https://github.com/clojure/core.async/blob/master/test/clojure/clojure/core/async/ioc_macros_test.clj

22:19 bbloom: amalloy: the doc strings are reasonable for a first cut in core.async

22:20 https://github.com/clojure/core.async/blob/master/src/clj/clojure/core/async.clj#L322

22:21 tomjack: (go (let [done (timeout 1000)] (loop [posts []] (alt! conn ([post] (recur (conj posts post))) done (do (close! conn) posts)))))

22:21 oslt

22:22 which, yeah, is clearly so much better than http.async :)

22:22 bbloom: dnolen_: tomjack: during QnA for my walk on wednesday, rich asked if i had considered the applicability of the core.async IOC macros to building generators

22:22 tomjack: I saw tbaldridge experimenting with that I think in the precursor to core.async

22:22 bbloom: since Fipp is basically a pipeline of communicating sequential processes

22:23 tomjack: yeah, i think one could directly use channels instead of generators, but i guess you could re-use the IOC macros if they are made extensible

22:23 tomjack: they are extensible already :)

22:23 bbloom: even better

22:23 :-)

22:24 tomjack: only extensibility problem is the alt thing

22:24 which bakes in async-chan-wrapper

22:24 but irrelevant if you don't want to support alt inside your go-like thing

22:24 bbloom: in Fipp, I used reducers to eliminate the lazy seq overhead for using mapcat to non-forking chain of communicating processes

22:24 ….to *simulate* non-forking… i mean

22:24 dnolen_: bbloom: yeah sad I couldn't make your talk, work thing. I caught up w/ Rich afterwards. somewhat related I mentioned I was very interested in seeing core.logic could use channels

22:25 he said on his machine he's been able to get a million events a second, which is promising

22:25 core.logic can only execute 200-300,000 goals a second

22:25 bbloom: wow. that's pretty good

22:25 how would core.logic utilize channels?

22:26 dnolen_: bbloom: parallel AND and OR

22:26 bbloom: dnolen_: hmmm excellent :-P

22:27 dnolen_: I looked into setTimeout performance today

22:27 it's pretty dismal if you want to handle a million events a second in JS

22:27 not gonna happen

22:27 but I toyed around with this https://gist.github.com/swannodette/5833247

22:27 bbloom: oh yeah, it's baad

22:27 it's tied to the UI look

22:27 loop*

22:27 dnolen_: if you use a queue, you can handle a million events a second

22:27 one of the fast events in the browser at least under OS X is mouse events

22:28 but that threshold is around 6ms

22:28 tomjack: there are a few tricks I've seen used for getting better perf than setTimeout

22:28 dnolen_: so you can set a event queue flush around that, and that seems like it might work

22:29 bbloom: dnolen_: have you tried post message on browsers that support it?

22:29 wastrel: is there an easy/quick way of finding dependency version numbers for project.clj?

22:29 bbloom: dnolen_: http://dbaron.org/log/20100309-faster-timeouts

22:29 wastrel: i'm looking at old tutorials and all their jazz is out of date

22:30 bbloom: wastrel: clojars.org ?

22:30 wastrel: or maven central or wherever the artifacts are

22:31 dnolen_: seems like postmessage is supported pretty much everywhere since IE 8. caveat is that IE 8 to 10 only allow string messages

22:31 http://caniuse.com/#search=postMessage

22:32 tomjack: http://caniuse.com/#search=mutationobserver :(

22:32 seangrove: tomjack: We rely on mutation observers, but don't support ie

22:33 Has worked out pretty well

22:33 dnolen_: seangrove: yeah not supporting ie is a non starter

22:33 bbloom: tomjack: agreed. that sucks. would be nice to be able to sync the dom w/ a virtual dom or something like that. but it's not a huge deal b/c you can just assume that external changes to the dom are made via inspector or by some extension that is likely trying (at least a little) not to break assumptions about the shape of the dom

22:33 dnolen_: bbloom: that does look interesting, should be measured against queue

22:34 seangrove: dnolen_: Depends on what you're talking about of course - I wouldn't expect anything in cljs core to touch mutation observers

22:34 bbloom: dnolen_: i assume that the actual solution would be some combination of a flag, a queue, and a message/timeout :-P

22:35 dnolen_: bbloom: yeah postMessage is unacceptable slow for 1000000 events

22:36 my solutions takes 200-300ms

22:36 to enqueue all events

22:36 and finishes 200ms or so later

22:36 bbloom: dnolen_: yeah, keep the queue, just swap out setTimeout with postMessage

22:36 dnolen_: postMessage takes 53 seconds for 1000000 events

22:37 bbloom: you're using queue+setTimout, try queue+postMessage

22:38 and don't post a function, i think that serializes the function

22:39 dnolen_: bbloom: oh oops that test is messed up anyhow you may be right

22:39 the events are not independent

22:40 they should be

22:45 tomjack: https://code.google.com/p/dart/codesearch#dart/trunk/dart/tools/dom/src/Microtask.dart

22:46 dnolen_: bbloom: yeah, even w/o queueing naive calls to setTimeout destroys postMessage

22:46 8s for setTimeout for independent events

22:46 60s for postMessage

22:46 bbloom: dnolen_: really? wow. that's strange.

22:46 dnolen_: the benchmark is flawed it's only testing events that depend on each other

22:46 e0 -> e1 -> e2

22:46 etc

22:47 bbloom: dnolen_: http://dbaron.org/mozilla/zero-timeout

22:47 what does that report for you?

22:47 dnolen_: bbloom: yes i just ran that and modified it to benchmark independent events

22:47 postMesage loses massively

22:48 bbloom: dnolen_: can i see your benchmark?

22:48 tomjack: i'm not positive, but i think dart is DOA

22:48 dnolen_: bbloom: http://gist.github.com/swannodette/5835632

22:49 tomjack: sure, I don't plan to ever touch dart, I just plan to steal the idea from Microtask.dart

22:50 dnolen_: bbloom: I commented out the setTimeout case if you have them both run browser goes haywire

22:52 tomjack: that implementation does looks like a pretty good approach, more fully fleshed out version of what I was considering

22:53 bbloom: dnolen_: https://gist.github.com/swannodette/5833247 why is this calling clearInterval?

22:54 don't you mean clearTimeout?

22:54 dnolen_: bbloom: oops yeah a typo

22:59 bbloom: dnolen_: i'm still confused by your code here

22:59 why are you setting a timeout if there is already one?

22:59 dnolen_: seangrove: definitely not against hybrid approach as pointed out by the Dart code ^

22:59 bbloom: because you may not fill the queue, i.e. mouse stops moving

23:00 bbloom: huh?

23:01 let me see if i understand the goal here

23:01 you want a callback to be fired

23:01 at some later time, so you can use setTimeout(aCallback)

23:01 but that's too slow, so you do: enqueue(theCallback); notifyQueueNoLongerEmpty()

23:01 dnolen_: bbloom: remember this is for core.async dispatch

23:01 bbloom: right?

23:01 clojurebot: flatten |is| rarely the right answer. What if your "base type" is a list

23:01 bbloom: yes, i remember

23:01 clojurebot: you are not helping.

23:01 clojurebot: Pardon?

23:03 dnolen_: bbloom: yes you could probably do it differently, I'm not sure which performs better but I how it did was this

23:03 bbloom: oh yeah, i'm just an idiot. you are checking (!fulsh_timer)

23:03 dnolen_: oh ok

23:06 bbloom: i mean it's some pretty silly imperative code just to demonstrate an idea :)

23:06 bbloom: dnolen_: yeah, i'm just confused why postMessage wins so much here http://dbaron.org/mozilla/zero-timeout

23:07 dnolen_: bbloom: yeah I tried to explain earlier those aren't independent events

23:07 bbloom: i don't know what you mean by that

23:07 dnolen_: the next increment doesn't get to run until the previous one

23:08 in my queue code 1000000 events actually get queued

23:08 none of them know about it each other at all

23:08 which more similar to what core.async needs I would think

23:12 seangrove: Anyone use cemerick's cemerick.cljs.test? I just get "ReferenceError: Can't find variable: cemerick"

23:12 mhr: Have any of you read this article: http://e-texteditor.com/blog/2010/beyond-vi ? Their website went down, and I can't find a mirror. I'm trying to find someone with a local copy. I'm trying to figure out why a Vim user would consider switching to an editor other than Emacs (http://stevelosh.com/blog/2010/09/coming-home-to-vim/#vims-feeling), but I can't figure out what that editor was about.

23:15 tomjack: what is the point of dispatch in cljs?

23:16 just 'make sure this happens AFTER the rest of the stuff I'm about to do synchronously' like process.nextTick?

23:17 dnolen_: tomjack: I don't see how core.async could work at all without it

23:18 tomjack: (defn run [f] (f))

23:18 that would break things?

23:18 dnolen_: think about it some more

23:18 core.logic is an obvious example

23:18 f may not terminate

23:18 but if it's work is broken apart by dispatch

23:18 it can't steal all the time

23:19 and in fact it can be closed if somebody else say we don't need your information anyway

23:20 bbloom: tomjack: setTimeout or some other form of dispatching allows for concurrency

23:20 tomjack: I see, yeah

23:20 bbloom: the IOC takes a task and breaks it into parts, so you need some strategy for breaking it up

23:20 tomjack: you'd still get concurrency without it, maybe

23:20 bbloom: but i'm not convinced setTimeout is the answer tho

23:20 tomjack: but only when you park

23:20 bbloom: i think you can just have a pseudo-random queue

23:20 tomjack: this way you can (go ..) (go ..) and have em both go

23:20 regardless of contents

23:21 bbloom: i think that when parking happens, you can just execute the next thing in the queue

23:22 tomjack: hmm of course they can't both go

23:22 so I'm back to the reason q.js has, that it's useful to know stuff isn't going to happen until after the current tick

23:22 bbloom: dnolen_: right? is timeout really necessary?

23:23 tomjack: I'm reminded of CurrentThreadScheduler

23:23 dnolen_: bbloom: you need something to say schedule this later. it could be many things - but setTimeout is widely available, with queue'ing it need not be slow

23:24 but I like tomjack's Dart link, picking the fastest option available is wise

23:24 bbloom: dnolen_: but what constitutes "later"? how much later?

23:25 dnolen_: bbloom: yeah in general you shouldn't care

23:25 obvious for stuff like mouse events or server calls

23:25 Rich has a neat thing called timeout channels

23:25 I'm very curious how this will port

23:25 bbloom: so i don't see why you can't just run all async code in an event loop off a queue and "later" == "later this tick, after i yield control to the task loop"

23:25 tomjack: I think that's what CurrentThreadScheduler is basically?

23:26 from Rx

23:26 dnolen_: bbloom: but that loop will need to ... call setTimeout

23:26 there no such thing as yielding control w/o some browser based async service

23:26 bbloom: dnolen_: only after it's timeslice is up, right?

23:27 i understand that you need setTimeout to say "OK, i'm not done with the queue, but i want to give the browser time to eexecute normal DOM stuff"

23:27 so yeah, setTimeout

23:27 but you don't need to setTimeout every time you call core.async/go

23:27 dnolen_: bbloom: in anycase, I think Rich's intuition is correct, browsers already do a bunch of work to figure out what the optimal time for JS to run is as setTimeout is a common pattern

23:28 he's pretty much against building a scheduler of any kind

23:28 and whatever we come up with needs to be very fast

23:28 bbloom: dnolen_: either i'm wildly confused or i'm not explaining myself clearly

23:28 dnolen_: or you're not listening :-P

23:29 is there a 1 to 1 mapping between setTimeout and core.async/go ?

23:29 tomjack: the clojure go always does a dispatch/run

23:29 dnolen_: bbloom: currently yes

23:29 bbloom: tomjack: yes, but they have threads :-P

23:29 dnolen_: bbloom: and in JS you have setTimeout

23:30 bbloom: dnolen_: so there is a little virtual machine that drives the IOC-ed code, yes?

23:30 like the thing that just calls the function slices on the queue is just a loop

23:30 and presumably, when your async code is running, you're already in that loop, right?

23:30 tomjack: so go inside go could use a queue?

23:31 bbloom: that's what i'm saying. if you're already async, you don't need to call setTimeout

23:31 tomjack: (again that's exactly CurrentThreadScheduler I think)

23:31 bbloom: you only need to cal setTimeout (or postMessage or whatever) if you're not in the dispatch loop already

23:31 but you do need to have a time limit on the dispatch loop

23:32 if you have async code that creates an infinite chain of async functions, the queue will never be empty

23:32 so you need to have a time limit ont hat loop & if you hit the time limit, you abort & setTimeout to come back and finish up

23:32 tomjack: would that ever be not a bug?

23:32 dnolen_: bbloom: which sounds pointlessly complicated

23:32 if you can use setTimeout and handle a million dispatches a second who cares?

23:33 bbloom: dnolen_: surely you can beat that by a lot if you dont' call setTimeout a few million times a second :-P plus it's not that complicated....

23:34 you've already got a queue, so you already have this problem where you might have an infinite chain of async calls

23:34 so you need a time limit on dequeue-ing anyway

23:34 dnolen_: bbloom: but you're just reinventing setTimeout

23:34 you pick some arbitrary time N to yield control

23:35 it maybe that some patterns maybe more efficient with that knob

23:35 or might turn out that setTimeout + queue'ing makes the different insignificant

23:35 bbloom: tomjack: i dunno if that would ever be sensible, but it seems like you certainly wouldn't want to kill the browser if you make an infinite loop like that even if it's just during development

23:35 dnolen_: difference

23:36 bbloom: dnolen_: even ignoring efficency, there's that infinite loop case

23:36 or not even infinite, just potentially long

23:36 tomjack: CurrentThreadScheduler.scheduleRelative used to block the vm :)

23:36 bbloom: it's quite possible for totally reasonable code to schedule enough stuff to make the app slow

23:36 a 100ms time limit would keep the app & dev tools responsive in that situtation

23:37 and once you build the time limit in, it's trivial to rely on it instead of always scheduling a timeout

23:37 it's one mroe if test :-P

23:37 dnolen_: bbloom: yeah I don't follow why that's an issue if the loop is in a go block

23:37 bbloom: I'm skeptical, but hey we're close to point where we can see for ourselves :D

23:37 tomjack: you don't mean (go (loop [] (recur)))?

23:37 dnolen_: tomjack: yes

23:37 tomjack: I'd expect that to still block everything

23:39 dnolen_: tomjack: I mean if there's a write or read from a channel in there of course

23:39 tomjack: ah yeah

23:44 bbloom: *shrug* basically my brain must be shot, soooo i'll pour myself a gin :-P

23:44 dnolen_: bbloom: haha

23:44 tomjack: shit

23:45 testing (go (loop [] (recur))) was a bad idea https://www.refheap.com/bd5fbcabc5dd3b41cab2c89ff

23:45 bbloom: guy at the liquor store sold me a bottle of http://www.brooklyngin.com/ -- sooo good. i might become an alcoholic, it's so yummy

23:45 tomjack: made it to the charger in time :)

23:45 callen: bbloom: tried bombay sapphire?

23:45 dnolen_: bbloom: nice

23:45 callen: that's my usual drinking gin, so trying to figure out if I have something new to look into.

23:46 dnolen_: tomjack: heh yeah, you need the read / write, but that of course will be given for core.async code

23:46 Raynes: callen: I drove. Nobody died. Good stuff.

23:46 dnolen_: a loop/recur in a go w/o read/write make no sense

23:46 callen: Raynes: congrats.

23:46 Raynes: LA drivers are unpredictable, but manageable so far.

23:46 tomjack: yeah, I expected it to do what it did

23:46 bbloom: callen: bombay is pretty good

23:46 tomjack: just didn't expect full cpu use to drain my battery down to nothing in 10s O_o

23:47 callen: tomjack: what other-worldly awful computer do you own?

23:47 bbloom: dnolen_: in theory, the compiler could trivially reject that :-P

23:47 callen: was the battery capacity getting sucked into another eldritch dimension?

23:47 tomjack: dunno if the computer is bad, but the battery has been severely mistreated

23:47 callen: tomjack: I genuinely want to know what make it is.

23:48 tomjack: I'm having battery troubles that are my fault atm, so it's a subject of present interest.

23:48 tomjack: toshiba tecra a11

23:48 bbloom: dnolen_: hey so cljs idea/question

23:48 tomjack: this is my second battery :( maybe I _should_ blame it on toshiba instead of feeling guilty for leaving it plugged in and on all night

23:49 bbloom: dnolen_: if i were to experiment with doing some of our own js-level analysis, what would you consider the best intermediate language to target?

23:49 dnolen_: interesting choices are ES > 5, TypeScript, and Google Closure's little type system stacked thing

23:49 callen: bbloom: typescript added generics recently, if you didn't catch that.

23:50 bbloom: which is information that is principally useful to me so that I can taunt Golangers more.

23:50 bbloom: callen: saw the announcement, but didn't dig in

23:51 tomjack: no activity on the chrome asm.js ticket :(

23:51 bbloom: callen: the golang generics thing is kinda odd…. i'm not sure what the rational is

23:51 tomjack: s/chrome/v8/

23:51 callen: bbloom: rationale* - they think they can't do generics without comprising performance or their version of simplicity.

23:51 bbloom: callen: yeah, but boxing to interface{} is the exact same loss of performance :-p

23:52 Qortzniv: Raynes, your name is so clsoe to Gayness

23:52 we must be made for each other

23:52 it's a sign from the gods.

23:52 callen: bbloom: the interface boxing and type-casting I think tells all that need be said. I think it's partly from their Suckless heritage that they take a bizarre version of minimialism into their aesthetic.

23:52 bbloom: they could add type checker support without changing the code generation or runtime

23:53 callen: bbloom: the concern is generics code generation if they really wanted to support it

23:53 bbloom: they're superstitious with regards to anything C++, so they're refusing to learn anything from what they did. Other alternatives "compromise performance" or implementation simplicity. So.

23:54 bbloom: callen: but i don't think that could possibly be it… b/c they already decided that boxing is fine… so they could just do boxing :-P i think that they realize average devs can't figure out co and contravariance, and so having generics at the type level would be pointless, hence interface{} is good enough

23:54 at the type CHECKER level, i mean

23:54 also the C# people called them "in" and "out" annotations & people seem to grasp that well enough, so who knpws :-P

23:54 callen: bbloom: Golang is an LCD language designed to facilitate Pharaonic project management styles. *shrug*

23:55 bbloom: callen: Go is the new Java & that's a very good thing

23:55 I think Go is absolutely brilliant for it's particular design criteria

23:55 callen: Qortzniv: may his merciful shadow fall upon you.

23:55 bbloom: personally, i hope that Go and the community takes off in a big way, such that the Go runtime replaces the JVM as the target of choice

23:55 callen: bbloom: I'd rather get a cleaned up Scala as a "java next"

23:56 bbloom: you're scaring kitty :(

23:56 wastrel: wi 10

23:56 bbloom: actually.. has anybody tried a clj->go yet? dnolen_ ?

23:59 hiredman: ugh

23:59 the jvm is so much better

Logging service provided by n01se.net