#clojure log - Jan 16 2014

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

0:10 ddellacosta: For those of you writing applications backed by a relational database, how do you find yourself organizing your namespaces with regards to the database mapping? Do you have namespaces which map to entities, like "my-namespace.thing1" and those which map to relations, like "my-namespace.thing1-to-thing2" (a.k.a one-to-many or whatnot)? Right now we have an overly simplistic mapping of namespaces to entities, and the relations tend t

0:10 get put in one or the other, and it's not optimal.

0:11 bitemyapp: ddellacosta: generally end up with a flat models

0:11 ddellacosta: bitemyapp: what do you mean by a "flat model?"

0:12 bitemyapp: you mean that you essentially don't normalize the db?

0:12 Tolstoy: ddellacosta: as one data point, I have a namespace called "data" with functions like "users" or "accounts" or "things": (data/users) or (data/users-by-id db id) and so on.

0:13 ddellacosta: Tolstoy: yeah, that's more or less what we have now, and it's not working out. :-(

0:13 Tolstoy: ddellacosta: Too many different kinds of entities in the DB?

0:14 ddellacosta: bitemyapp: if I'm understanding you correctly, and you mean something like this: http://en.wikipedia.org/wiki/Database_model#Flat_model, then I'm afraid we are too far gone for that...I'm trying to figure out how to map our current schema to a good namespace structure as we're stuck with it for now.

0:14 Tolstoy: there's not too many, I don't think--it's a relatively small number of entities in fact. It's just that, even at this size, the relationships are complex, and it's not always clear where to put stuff that joins multiple tables.

0:15 Tolstoy: ddellacosta: Ah, right. What makes sense when you put something in a namespace doesn't seem to make sense when you're looking for something: the old filing vs lookup prob?

0:16 ddellacosta: Tolstoy: yeah, although in our case it feels like filing and lookup are both a problem! In the end, it also makes it harder to reason about the overall complexity of the system.

0:17 Tolstoy: ddellacosta: One of the presenters at Clojure West suggested using a "homeless" namespace for stuff you're not sure about until things shake out. Probably not what you need, but I loved that idea.

0:18 ddellacosta: Tolstoy: yeah, I mean, I should probably just start by going with my initial idea, which is to build out some relationship-based namespaces (thing1-thing2) and see how well that works. As it is, I'm a bit stuck.

0:18 Tolstoy: Something like: db/users db/servers db/whatever?

0:19 Then db/users/get-by-id db/users/get-by-name? That sort of thing?

0:19 db/users/get-accounts-by-user

0:19 db/accounts/get-users-by-account. ;)

0:19 ddellacosta: Tolstoy: well, more like, db/users and db/user-documents and db/documents

0:19 Tolstoy: Oy.

0:19 ddellacosta: Tolstoy: yes, you are describing the problem exactly. :-)

0:20 Tolstoy: Could you go by the main limiter you're looking for?

0:20 If you want to find all the documents for a user, that's user focussed.

0:21 All the users a document is associated with, thats document focussed?

0:21 Yeah, tough. Hm. Your suggestion is at least clear.

0:22 PITA if you change the schemas, though.

0:22 ddellacosta: Tolstoy: I started with that--the problem is that if you want all of Dave's widgets, and that has a fair amount of qualifications on the widgets, you have a ton of logic for which kind of widget you want in your user namespace (for example).

0:23 Tolstoy: yeah, I'm not too worried about massive schema changes, not at this point.

0:23 Tolstoy: ddellacosta: I work on a non-Clojure app at work with similar issues. Only that db is actually an object-database mapped onto an RDBMS.

0:23 Not foreign keys.

0:24 Everything is hooked together via Object Identifiers.

0:24 In other words, it's not going to change because no one understands it anymore.

0:24 ddellacosta: Tolstoy: woah, that sounds like a pain...haha

0:25 dsrx: i like that, code changes start quickly and then peter out as fewer and fewer people really understand it

0:25 until it reaches a critical point where nobody can understand it anymore, and then change stops

0:25 then, if it's a front end web project somebody rewrites it in the latest framework and the process repeats.

0:26 Tolstoy: dsrx: Yep. Meanwhile, you're STILL lectured about business "realities" when you ask to spend time addressing the problem.

0:26 ddellacosta: dsrx: I try to avoid that by always identifying the parts of the codebase I don't understand and reading through them. If I can make the case that they are not well structured enough, then they become a target for re-factoring. Testing helps make that less painful. But it's easy when the codebase is smaller.

0:26 Tolstoy: dsrx: it's like geology. "Ah, here's the iridium layer. After that, nothing."

0:27 dsrx: The app I've worked with is about 13 years old: you see all the Java fashions merged together.

0:27 dsrx: Tolstoy: mercy

0:27 Tolstoy: dsrx: Including using old m_instanceVar naming schemes and so on.

0:28 dsrx: And RMI! And XSLT! And SOAP! Those poor guys seem to have incorporated tech during the five minutes when it seemed like a good idea.

0:29 dsrx: for about a year I worked in a university lab doing computational science. working with a fortran codebase started in the late 70s is a treat

0:31 nice to see this sentence in the documentation: "All new code should be written in FORTRAN77." :)

0:31 it was originally written in some compile-to-fortran language that included useful control structures like "while" and "when-else"

0:31 Tolstoy: Hard to believe Lisp and Fortran are contemporaries, eh?

0:32 ddellacosta: I don't even know what Fortran looks like

0:34 bbloom: ddellacosta: http://en.wikipedia.org/wiki/File:4_train.jpg

0:35 ddellacosta: bbloom: huh, I guess it must be pretty fast

0:35 dobry-den: How would you go about spinning up a new JVM while serving requests on old JVM, and the swapping them?

0:35 dsrx: the most memorable feature is its formatting rules. the first 5 or 6 columns or so are reserved for things like marking a comment, marking a line continuation (lines can be no longer than 66 columns), statement labels

0:35 bbloom: dobry-den: HTTP requests? use your load balancer :-)

0:36 Tolstoy: dsrx: Didn't there used to be special paper you could write programs on ... before the "keypunch operator" make cards?

0:37 http://upload.wikimedia.org/wikipedia/commons/thumb/1/18/FortranCodingForm.png/800px-FortranCodingForm.png

0:40 dsrx: Tolstoy: haha, I'm fortunate to not have had to know about that at least

0:40 rplaca: that's why 72 and 80 columns are still magic numbers

0:42 dsrx: the original 80-column punch card was made that way so it'd be the same size as a dollar bill at the time

0:43 so the census cards could be transported in treasury dept. containers

0:49 Tolstoy: wow

0:56 technomancy: man, I thought the @clojuremarkov spammers had given up, but it turns out they were just on vacation

0:58 rplaca: technomancy: I hadn't seen that before. It's kind of awesome

0:59 peterdon: /quit

1:00 andyf: technomancy: Ever find out what is going on there?

1:00 technomancy: it is ... a mystery

1:00 rplaca: I think it's a way to inflate follower counts

1:01 technomancy: yeah I need to do some science on the full network

1:01 rplaca: by having accounts that have tweets associated with them that can then follow others

1:01 clojure is just a word in their dictionary that pops up from time to time

1:02 technomancy: often in connection to india and outsourcing, oddly enough

1:02 which makes me curious about their source text

1:02 rplaca: so the goal is to have tweets that won't be detectable as fraudulant by the bots that try to detect that sort of thing

1:03 technomancy: jokes on them; I'm totally detecting them

1:03 I'm not a bot though; I just think it's hilarious

1:03 rplaca: I assume they read from the firehose and put the words together in "likely" but original ways

1:03 technomancy: they don't care if you detect them, they just need to live for long enough to inflate the follower counts

1:04 technomancy: oh

1:04 rplaca: celebrities, brands etc. pay for followers

1:04 technomancy: well if I reported them it would kind of ruin my twitter account, so that's no good

1:04 rplaca: this way a service can show the customer that their follower count went up by 10k because of the promotion they did

1:05 andyf: how would it ruin your twitter account by reporting them?

1:05 rplaca: they also need to follow others - you can't have a whole bunch of accounts that are only following one person/brand

1:05 abaranosky: sup foos?

1:06 rplaca: talking about markov twitter follower bots

1:06 technomancy: andyf: well if all my retweets disappeared

1:07 rplaca: it is the most likely explanation

1:09 rplaca: alexis madrigal wrote a good article about it here: http://www.theatlantic.com/technology/archive/2013/11/why-did-9-000-porny-spambots-descend-on-this-san-diego-high-schooler/281773/

1:58 testclo:

1:58 (defrecord Alert [id amount unit])

1:58 (def alerts (map (fn[x] (Alert. x (* 2 x) (* 3 x))) (range 1000000)))

1:58 (count alerts) ==> I found every time I run this, the memory usage (show in jconsole) will bump up ,why? I expected when I first run it, memory usage should bump up as "alerts" is an lazy seq, but when run it more, it shouldn't use more memory,right? I run the command in "lein repl", hope it's not a problem for "lein repl"

2:03 andyf: traversing sequences often requires allocating memory to allocate objects for return values of seq and next.

2:03 I am not sure if that is what is happening in this case, but it could be.

2:05 Such new allocated memory would become garbage after the call to count returned, but the next garbage collection will likely not be triggered until you approach the max heap size configured for your JVM

2:09 testclo: If I want to use the lazy seq again and again, will a non lazy counterpart helps for performance ? Ad how to convert lazy one to non-lazy one?

2:12 andyf: I haven't done performance measurements comparing different kinds of things that implement seq for speed. You can convert it to a vector with vec

2:13 allenj12: hey, i wanted to get into web dev with clojure/clojurescript is there any good tutorials or books to start?

2:15 andyf: I only know of one book in that area, discussing server side web dev. Web Development in Clojure http://pragprog.com/book/dswdcloj/web-development-with-clojure

2:16 ClojureScript only has one relatively short book out on it now, AFAIK, by Stuart Sierra. I don't have any on-line resources to recommend, not because they don't exist, but because I haven't looked.

2:17 allenj12: andyf: cool! ill check out both of those. ill keep looking for online resources to then ty.

2:17 noidi: d

2:18 quizdr: I can't make heads or tales out of the difference between = and == can anyone assist with a concise explanation?

2:18 noidi: is there really no (comp first filter) in the standard library?

2:18 I seem to need that much more often than `some`

2:19 allenj12: andyf: is this the book you were talking about?

2:19 andyf: http://shop.oreilly.com/product/0636920025139.do?sortby=publicationDate

2:19 andyf: allenj12: I do recall Mimmo Cosenza announcing a ClojureScript tutorial he wrote and publishes for free: https://github.com/magomimmo/modern-cljs

2:20 allenj12: yes, that is the one I have heard of. I haven't read it myself.

2:21 quizdr: hopefully that book has a lot more meat than the first book they wrote together for Apress

2:24 allenj12: andyf: o wow seems like a great resource ty. ill prolly go through that and buy one of the books

2:24 andyf: allenj12: You are welcome, but thank Mimmo more :)

2:24 allenj12: andyf: haha ok :)

2:38 testclo: If I want to use the lazy seq again and again, will a non lazy counterpart helps for performance ? Ad how to convert lazy one to non-lazy one?

2:39 SegFaultAX: testclo: Lazy seqs will memoize everything that is realized.

2:40 fredyr: quizdr: http://books.google.se/books?id=I8KdEKceCHAC&lpg=PA434&ots=wNmTT7Vba4&dq=clojure%20equality%20semantics&hl=sv&pg=PA434#v=onepage&q=clojure%20equality%20semantics&f=false

2:40 ouch what a link

2:49 quizdr: fredyr thanks

2:51 fredyr: sure

2:52 testclo: agent should return immeidately,since it's aync, but why the define of a on an agent took some time

2:52 (defrecord Alert [id amount unit])

2:52 (def alerts (map (fn[x] (Alert. x (* 2 x) (* 3 x))) (range 1000000)))

2:52 (def a (agent (zipmap (map #(.id %1) alerts) (repeat []))))

2:52 the last line took some time to run

2:58 broquaint: Because the value has to be calculated first.

2:59 andyf: testclo: zipmap is eager, not lazy

3:05 TEttinger: there's no lazy hashmap, just lazy seqs is why, right? that's why zipmap is eager?

3:08 testclo: I want to let the long calcuation be done in another thread, doing something in current thread, then use that value, agent can't do that? need to use promis?

3:09 andyf: Built-in, Clojure has no lazy set, maps, nor vectors

3:10 I seem to recall hearing about people devising such things, but I haven't looked into them.

3:13 quizdr: can anyone tell me how this little function works? (#(identity %&) 1 "blarg" :yip)

3:13 identity cannot take more than one argument, but there is a rest in there

3:14 this should equate to (identity 1 "blare" :yip) right?

3:14 fredyr: testclo: a future seems appropriate

3:17 TEttinger: quizdr, %& is actually a single item, a seq

3:18 quizdr: oh, it groups everything together, i see

3:18 TEttinger: exactly

3:19 quizdr: this language is quite interesting. i don't know Scheme, but I know a fair amount of Common Lisp, and Clojure is what I'd kinda assumed Scheme must be like in many ways, with its streamlined structure

3:20 seems really elegant, a lot more than common lisp

4:01 jjl`_: quizdr: clojure is closer to scheme, but they're quite different languages. scheme relies heavily on mutable data structures, has the dotted pair type and has a lot less syntax (no [] {} #{} #"" #())

4:02 i'm not sure on RH's argument that having syntax for more datatypes makes things MORE homoiconic. I tend towards the opposite

4:03 quizdr: i got rather used to the parenthesis in lisp and didn't really find it intrusive.

4:03 jjl`_: heh. i've been writing lisp for years and it still bugs me sometimes

4:03 quizdr: i would think you could just have a generic list datatype that if you structured it like a map, you could use map features. but i'm sure they have good reasons for doing it the way they are.

4:04 by separating the datatypes

4:05 jjl`_: i can think of several reasons not to do that. top of that list is performance

4:05 of course most lisps don't have maps and you use alists instead

4:06 quizdr: my pleasure of working with a lisp-1 revealed itself quickly over common lisp

4:07 and not having so many competing functions for similar tasks also helps, like all the equality stuff in CL

4:07 or those awful loop macros

4:07 Clojure seems a lot more simplified

4:08 jjl`_: CL is about the most complicated lisp you could find. I generally prefer lisp-1

4:09 quizdr: are Haskell's monads in some conceptual way similar to Clojure's atoms/refs/agents?

4:09 jjl`_: not at all

4:10 quizdr: but they are the way state/impurity is handled, just like the counterparts in Clojure

4:10 jjl`_: haskell does have STM support

4:10 quizdr: i'm referring to matters of state, not concurrency

4:10 jjl`_: you're mixing concepts here

4:11 monads are effectively a hack to force sequencing (not that most avid haskellers would put it that way)

4:11 quizdr: in clojure when you want to handle impure state that can change, you work with it via agents/atoms/refs, while in haskell you can only work with state via a monad. hence my comparison

4:11 jjl`_: not exactly

4:12 quizdr: oh that's fine, i've never used Haskell nor am I likely to, just curious

4:12 jjl`_: that do notation makes it look like you're mutating state, but you're not. the only piece of state that gets mutated is the RealWorld (haskell models "the real world" as a piece of data to keep the illusion of purity alive)

4:13 so everything just threads through purely

4:13 i'd be happy to explain to you in private if you'd like, but this isn't really the channel

4:15 quizdr: no that's alright, tanks

4:17 jjl`_: in any case, the reason monads were introduced was to fix a problem. they're a useful abstraction that isn't *required* in clojure (clojure is strictly evaluated). You can use them though. There are several monad libraries. They're quite a good abstraction in some cases

4:18 TEttinger: gahhhhhh... does anyone use ztellman's primitive-math lib?

4:19 I have no idea if I'm using it right, but I'm getting a massive amount of warnings

4:19 quizdr: i just saw this code in something, and am wondering what is meaningful about that zero in there: (reduce + 0 (map :size sym-parts))

4:19 TEttinger: it's the initial value, quizdr

4:19 quizdr: I know, but why would that matter in this case?

4:19 anything plus 0 is the same thing

4:19 TEttinger: which is 0 for + anyway, correct

4:19 quizdr: leaving out that zero would have no effect on the value of the expression, right

4:20 TEttinger: I believe so. it may have been to make it explicit

4:20 jjl`_: it means you always get a result. what should the return of reduce be if there are no items in the list?

4:20 TEttinger: ah

4:20 quizdr: now that's interesting

4:20 TEttinger: ,(reduce + [])

4:20 clojurebot: 0

4:20 quizdr: ,(range 0

4:20 clojurebot: #<RuntimeException java.lang.RuntimeException: EOF while reading>

4:20 quizdr: ,(range 0)

4:20 clojurebot: ()

4:20 TEttinger: you always do anyway, because + defaults to 0 when called with no args

4:20 quizdr: ,(reduce + (range 0))

4:20 TEttinger: ,(+)

4:20 clojurebot: 0

4:20 0

4:21 quizdr: i feel you

4:21 TEttinger: ,(*) ; defaults to its identity value or whatever it is, 1

4:21 clojurebot: 1

4:21 jjl`_: reduce + is a bit silly. they probably wanted apply

4:22 TEttinger: it's called a 'monoid'

4:22 TEttinger: the identity for + and 0?

4:22 s/0/*

4:23 jjl`_: yes. the 'plus monois' has the identity 0

4:23 quizdr: i have heard from common lisp people that reduce is preferable to apply when it is convenient

4:25 chare: I AM BACK

4:25 no fear

4:26 jjl`_: quizdr: sounds like cargo culting to me

4:26 quizdr: was that cemerick's site that discussed cargo culling recently?

4:29 ddellacosta: quizdr: referring to previous conversation...Haskell is cool, you should give it a shot. It's got a lot of amazing qualities, and really bends your mind, in a meaningful and useful way.

4:30 quizdr: ddellacosta if I had time, i probably would. learning clojure effectively as a hobby is enough for me for now.

4:31 I did pick up this book, 7 Languages in 7 Weeks, and Haskell (and Clojure) are two of the languages, so I'll get a bit of exposure to it

4:31 ddellacosta: quizdr: yah, I hear ya. There's always more to learn. Just wanted to give you a nudge when you suggested that you're unlikely to ever touch Haskell. ;-)

4:31 quizdr: but i have heard that it can take a long time to get fluent in Haskell, and that the syntax is a challenge more than most languages

4:32 chare: HASKELL I LOVE YOU


4:32 ddellacosta: The syntax is pretty simple. The concepts are tough--they are very abstract. But you can get going relatively quickly, especially if you have some Clojure or other lisp under your belt. The biggest challenge for me is wrapping my head around all the higher-level category theory concepts, and learning how to apply them effectively. But you can do a lot of cool stuff even before that point.

4:33 fredyr: meh what up with all the haskell trolls

4:33 :)

4:33 ddellacosta: fredyr: ha, I know, I should go hang out in Haskell. ;-) I'm excited about both Haskell and Clojure though, so it's hard to contain.

4:33 quizdr: "category theory" in itself sounds like a daunting term

4:34 ddellacosta: quizdr: Like anything, unfamiliar things are daunting at first.

4:34 quizdr: Haskell is very popular here in Singapore. There is a Fuctional Programming meet up group that meets every month. Last month it was at Google's headquarter's here. But the group might as well be called "Haskell Singapore" as that is the only language they discuss.

4:35 chare: the problem with Haskell is that my friends get scared of the static type system it has

4:36 ddellacosta: Oh, that's too bad. I think Clojure is quite a nice language and worth discussing. I've heard racket and erlang have great qualities too, but haven't dug into either deeply yet.

4:36 and of course there are many other functional languages out there worth talking about.

4:36 quizdr: erlang is also in this "7 Languages" book

4:37 chare: erlang is the only language I know of where out of the box the virtual machines running on different machines know about each other.

4:37 ddellacosta: alright, back to mucking about with clojure.tools.namespace...

4:37 chare: usually you gotta setup some rpc crap or something

4:46 quizdr: does anyone know where 4clojure is hosted, or what kind of host environment is necessary to host something like that?

4:48 TEttinger: (if (and (< ^long (quot i ^long wide) ^long (dec ^long high)) (> ^long (mod i ^long wide) 0)) (and (not= (aget ^doubles dd (dec (+ i ^long wide))) ^double dark) (= (aget ^doubles dd ^long (dec ^long (+ i ^long wide))) ^double wall)) false)

4:48 someone, anyone

4:48 please tell me this isn't needed

4:48 broquaint: quizdr: You might have better luck on the #4clojure channel, although I think the maintainers won't be online for a bit.

4:49 TEttinger: I can't do a primitive type hint on a def, only at the call site (terminology right?)

4:49 so every time i use the def'd numbers (numbers!) it needs a type hint to avoid a reflective call

4:50 quizdr: broquaint thanks

4:51 TEttinger wow

4:51 can't imaging that is necessary but i am also stumped

4:51 TEttinger: quizdr, I must be doing something stupid

4:53 quizdr: as an IRC newbie, how does one "lock in" a nick, or is it up for grabs when you leave the room?

4:53 metellus: quizdr: /msg nickserv help

4:54 you can register your nick

4:55 quizdr: metellus thank you!

4:56 TEttinger: quizdr, indeed I was

4:56 I can def them as (int 33) or whatever

4:57 quizdr: so when you said you cannot do a primitive type hint on a def, actually you can?

4:57 testclo: how to check whether an agent compeleted the action without blocking?

4:58 voldyman: anyone using clojure on ubuntu?

4:58 how did you upgrade to 1.5.1? the repo only has 1.4.0

4:59 fredyr: voldyman: leiningen?

5:00 voldyman: fredyr: using leinigen? (i use the latest leiningen from the website)

5:01 i can use the latest version in projects but repl from command line is 1.4.0

5:02 so lighttable can't find 1.5.1 which it needs to function

5:03 fredyr: ah okay, idk how lighttable does

5:04 TEttinger: quizdr, it isn't actually a type hint I'm doing now. type hints are metadata, this is some kind of different function call

5:04 at least I think type hints are meta

5:06 arcatan: yeah, they are

5:10 quizdr: anyone recommend a good user or two worth following on 4clojure?

5:10 instilled: hi. is anyone using bbatsov's excellent projectile? I'm wondering how to access the current project root from elisp code. anyone knows?

5:14 TEttinger: ok, in two files using ztellman's primitive-math, i get so many warnings i can't even scroll back to read all of them.

5:14 this is why my program is slow I imagine.

5:16 instilled: I've just found it. (projectile-project-root).

5:19 noncom: using nrepl in my own project, i send *ns* for eval and then I do (response-values res) on the result, however the following error comes up: Could not read response value: #<Namespace user>, so why is that? how do I avoid such errors with nrepl?

5:19 glosoli: what are some good practises when translating text in Enlive templates ?

5:20 quizdr: can anyone recommend how to get clojure autocompletion working inside a .clj file? I get it at the REPL but not in a source file.

5:20 oh, i'm talking about emacs

5:22 glosoli: quizdr: http://clojure-android.info/blog/2013/07/21/feature-auto-completion/ might help

5:24 quizdr: glosoli wow clojure on android, cool

5:24 glosoli: quizdr: this covers autocompletion as primary topic

6:05 How could one select all nodes in enlive and execute replace-vars on them?

6:21 clgv: is there some library function that retrieves all paths of keys from a nested map?

6:22 (f {:a {:x 1, :y 2}, :b {:z 3}}) => ([:a :x] [:a :y] [:b :z])

6:24 quizdr: clgv good question indeed

6:24 CookedGryphon: clgv: to arbitrary levels of nesting?

6:26 clgv: yes, arbitrary levels but you can assume that the recursion fits on the stack

6:27 I'd like to just use such a function for analysis. but if need be I'll write it from scratch

6:32 CookedGryphon: clgv: I feel like it should be possible with tree-seq

6:33 clgv: CookedGryphon: you can get all keys with tree-seq but not construct the paths

6:38 katox: what is the best way to print #inst into str? SimpleDateFormat?

6:39 CookedGryphon: well the #inst representation is standard edn, unambiguous and supported by both the reader and pr-str by default, what's wrong with just leaving it as that?

6:46 glosoli: how one could do recursive replace-vars in enlive?

6:47 CookedGryphon: ugh, why does tap take a chan rather than just returning a new one?

6:49 it should be optional at least

7:07 poglesbyg_: Hi all, I'm working on clojure koans and have gotten to destructuring and I'm stuck now.

7:07 what should i do here:

7:07 (= (str "First comes love, "

7:07 "then comes marriage, "

7:07 "then comes Clojure with the baby carriage")

7:07 ((fn [[a b c]] __)

7:07 ["love" "marriage" "Clojure"]))

7:08 sorry that was ugly

7:08 http://pastebin.com/Dkac7XF4

7:12 gfredericks: poglesbyg_: you should take a, b, and c and make them look like the string given

7:12 pyrtsa: poglesbyg_: Define the body of a function that receives as its single argument a vector of 3 elements.

7:17 poglesbyg_: that makes sense. thanks gfredericks

7:21 edbond: Can I use clojurescript macros (in clean clj) to read settings from yaml file? I don't see yaml cljs lib.

7:23 I need to convert yaml to map on cljs compilation stage

7:34 wei__: anyone know how to write a honeysql clause to use Postgres' json operator in a query? json_column->>'json_attribute'

7:34 as in this example http://stackoverflow.com/questions/10560394/how-do-i-query-using-fields-inside-the-new-postgresql-json-datatype

7:37 john2x: can I use a 'binding' var defined in a macro, in the body of that macro's usage? (i hope that made sense)

7:38 CookedGryphon: if I understand you correctly, yes use ~ to unquote it

7:38 pastebin what you're trynig to write?

7:42 clgv: john2x: post a gist with an example how you'd call the macro and to what it should expand

7:43 elementary rules for asking questions about how to write a specific macro ^^

7:43 john2x: ah, here: https://www.refheap.com/24133 (I got the macro from here http://en.wikibooks.org/wiki/Learning_Clojure/Macros)

7:43 edbond: wei__, did you try (where [:= "json_col->json_attr" :?baz])

7:45 CookedGryphon: john2x: that looks like it should work, what's the issue?

7:45 clgv: john2x: oh that's error prone. the call to close should be in a finally block

7:46 CookedGryphon: could you actually use with-open with a custom close?

7:46 john2x: CookedGryphon: I'm getting "Unable to resolve var: my.ns/*conn* in this context"

7:46 clgv: ah right, i'll fix that.

7:47 CookedGryphon: oh, so you want to use *conn* from the namespace in which the macro is defined rather than my.ns?

7:47 try just fully resolving it

7:47 clgv: CookedGryphon: with-open assumes a certain interface - was it Closable?

7:47 CookedGryphon: clgv: yeah, something like that

7:47 john2x: CookedGryphon: ah yes, the macro and the function are in differnet namespaces

7:47 wei__: edbond: I did try it, but I the resulting sql statement looked something like ["SELECT * FROM tbl INNER JOIN account ON ? = account.id" "tbl.details_json->account_id"]

7:47 clgv: john2x: you need a dynamic var in that namespace, e.g. (def ^:dynamic *conn*)

7:48 edbond: wei__, can you post code to refheap?

7:48 wei__: sure

7:48 clgv: john2x: in the namespace of the macro definition

7:49 john2x: clgv: ah ok. and I need to require the *conn* in addition to the macro in the other namespace right?

7:49 ah it compiled now :)

7:50 clgv: john2x: no you dont need that. the syntax quote resolves *conn* and uses it fully qualified

7:52 wei__: edbond: https://www.refheap.com/24135 ty

7:52 john2x: clgv: hmm when I remove *conn* from the require in the other namespace, it can't find *conn* again.. I've updated the paste https://www.refheap.com/24133

7:53 edbond: wei__, error says you compare char with integer. Can you check type of join columns?

7:54 wei__, I suppose json results in string ids "42" while account.id is integer 42

7:54 clgv: john2x: that has to work this way. maybe restart the repl

7:55 wei__: perhaps, but in my GUI (navicat) the id appears to be a integer inside the json field

7:55 gonna try an explicit cast

7:55 clgv: john2x: macros would be unusable if you needed to know their implementation to require the used variables manually ;)

7:55 s/require/refer/

7:56 john2x: oh now I see where it is missing. you explicitely use *conn* in the rdb/run call.

7:57 john2x: clgv: yes :) should it be moved into the macro definition?

7:57 clgv: john2x: so you have the desire to hide *conn* and to see *conn* - bad structured that way

7:58 john2x: hmm right.. I guess there's no point not doing rdb/run when using with-connection anyway

7:58 edbond: wei__, try :tbl.details->>account_id, it's valid

7:59 clgv: john2x: I guess rdb/run should use *conn* internally and not as parameter if it is needed tofit into the macro body

7:59 john2x: but be careful not to create a frankenstein macro incrementally ;)

7:59 edbond: wei__, nope, sorry. "-" converted to "_"

8:02 wei__, seems to work when I use sql/raw inside join: (sql/raw "tbl.details->>account_id = account.id")

8:03 john2x: clgv: until the revise team include a with- macro, i'll keep playing with my scissors :P

8:03 yeah I'll just move the rdb/run call into the macro definition..

8:21 quizdr: when working at the REPL is it possible to do a carriage return without causing evaluation on the entire expression you are editing at the REPL prompt

8:25 amalloy: quizdr: just a plain command-line repl? newline evaluates the expression if it's "done", and otherwise keeps reading till the last )

8:30 matt444: With :keys destructor, can you also keep a reference to the destructed data?

8:30 amalloy: matt444: (let [{:keys [x] :as m} {:x 1}] (list x m))

8:31 noncom: is anyone famiiar with nrepl here?

8:31 matt444: amalloy: yay! thanks

8:32 quizdr: amalloy I'm using REPL in emacs cider; just wondering if it makes sense to continously edit and manipulate functions at the REPL, where you'd have to insert lines, etc

8:32 amalloy: shift-RET

8:32 or...wait, no

8:32 that's the opposite of what you want. C-j inserts a newline

8:33 personally i'd rather edit stuff in my .clj file and just C-M-x it over to the repl, but editing it in the repl is not an unreasonable style

8:35 quizdr: amalloy ah C-j is exactly what I needed

8:36 fredyr: um, isn't there a way to use range to generate the inf seq of 0,0.1,0.2...?

8:37 amalloy: (map #(* 0.1 %) (range)) is what i would do, but if you were really excited about doing it without map...well, i'd worry about rounding errors then

8:38 &(take 100 (range 0 Double/POSITIVE_INFINITY 0.1))

8:38 lazybot: ⇒ (0 0.1 0.2 0.30000000000000004 0.4 0.5 0.6 0.7 0.7999999999999999 0.8999999999999999 0.9999999999999999 1.0999999999999999 1.2 1.3 1.4000000000000001 1.5000000000000002 1.6000000000000003 1.7000000000000004 1.8000000000000005 1.9000000000000006 2.0000000000000004 2.1... https://www.refheap.com/24142

8:38 fredyr: :)

8:39 it was just that i realized that the range arguments didn't allow for step without and end

8:40 amalloy: for that, it's pretty easy to use iterate

8:40 (iterate #(+ % 2) 0)

8:41 fredyr: ah nice, that's more like it

8:41 thanks

8:45 wei__: edbond: sorry stepped out for a bit. your sql/raw suggestion worked! though I still had to cast the expression to an integer with "CAST(… AS INT)"

8:45 (inc edbond)

8:45 lazybot: ⇒ 1

8:45 wei__: (inc testh1231231)

8:45 lazybot: ⇒ 1

8:45 quizdr: what is the difference betwen the lazybot and the clojure bot in here?

8:45 edbond: wei__, nice, thanks. Why do you need to cast? json doesn't recognize integers?

8:46 wei__: I'm not sure, but when I put the expression in the SELECT, as in (-> (s/select (sql/raw …))) it comes back as a string

8:47 edbond: wei__, same postgresql error about casting?

8:49 wei__: no, the error only happens if I use a join. i just wanted to see what type it was by returning the expression in a SELECT

8:49 CookedGryphon: Odlem13

8:49 well that's embarrassing

8:50 clgv: quizdr: feature set and clojure version

8:50 edbond: wei__, from http://www.postgresql.org/docs/9.3/static/functions-json.html it seems ->> returns text, -> returns object. Maybe you should try that

8:50 clgv: ,*clojure-version*

8:50 hyPiRion: quizdr: clojurebot and lazybot has different jail permissions, runs on different clojure versions, and is administered by different people

8:50 clojurebot: {:interim true, :major 1, :minor 6, :incremental 0, :qualifier "master"}

8:50 clgv: &*clojure-version*

8:50 lazybot: ⇒ {:major 1, :minor 4, :incremental 0, :qualifier nil}

8:51 clgv: ,(f 1)

8:51 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: f in this context, compiling:(NO_SOURCE_PATH:0:0)>

8:51 clgv: ,(defn f [x] (inc x))

8:51 clojurebot: #'sandbox/f

8:51 clgv: ,(f 1)

8:51 clojurebot: 2

8:51 * edbond need to try pgsql json

8:51 clgv: &(defn f [x] (inc x))

8:51 lazybot: java.lang.SecurityException: You tripped the alarm! def is bad!

8:52 wei__: edbond: interesting. but that results in an error: operator does not exist: json = integer

8:55 quizdr: ,(= (mod 10 6) (rem 10 6))

8:56 clojurebot: true

8:56 wei__: apparently -> resolves to the form {:int4 1000}

8:56 quizdr: what is the difference between the mod and rem above?

8:56 john2x: how do I reload a namespace I have in 'used in the repl?

8:57 edbond: wei__, yeah, some weird type 'json'. SELECT pg_typeof('{"a":1,"b":2}'::json->'b');

8:57 clgv: ,(map #(= (mod %1 6) (rem %2 6)) (range -5 5))

8:57 clojurebot: #<ArityException clojure.lang.ArityException: Wrong number of args (1) passed to: sandbox/eval143/fn--144>

8:57 clgv: ,(map #(= (mod % 6) (rem % 6)) (range -5 5))

8:57 clojurebot: (false false false false false ...)

8:57 clgv: ,(mapv #(= (mod % 6) (rem % 6)) (range -5 5))

8:57 clojurebot: [false false false false false ...]

8:57 clgv: ,(mapv #(= (mod % 6) (rem % 6)) (range -2 2))

8:57 clojurebot: [false false true true]

8:58 wei__: although it the query result shows up as a numeric type in the repl

8:59 quizdr: clgv so the behavior varies only with negative numbers

8:59 wei__: the cast is acceptable for me.. it's just a bit hacky

9:00 clgv: quizdr: yes

9:00 ,(mapv #(vector (mod % 6) (rem % 6)) (range -1 2))

9:00 clojurebot: [[5 -1] [0 0] [1 1]]

9:01 edbond: wei__, cast is used here too: http://clarkdave.net/2013/06/what-can-you-do-with-postgresql-and-json/

9:01 fredyr: is there some significant difference between #([% (f %)]) and (fn [x] [x (f x)])? when i used it in a map the reader macro version fails but the other works

9:04 oh

9:04 it expands a bit weird

9:05 (fn* [p1__303#] ([p1__303# (f p1__303#)]))

9:05 :S

9:05 lumafi: in the first one, you're calling the vector as a function

9:05 stuartsierra: Remember, #(%) expands to (fn [x] (x)) not (fn [x] x)

9:06 fredyr: yeah i realize that now, but wasn't something i've encountered before

9:08 or rather, i have used it as a feature before w/o realized it

9:08 :)

9:08 clgv: fredyr: you can simply use the vector function instead of writing the literal

9:09 fredyr: clgv: not really sure how you mean

9:09 quizdr: stuartsierra are you saying the % explands to (%) or only the entire expression

9:09 stuartsierra: the entire expression

9:10 #(blah) expands to (fn [] (blah)) not (fn [] blah)

9:10 clgv: fredyr: #(vector % (f %))

9:10 quizdr: right because normally blah would be a function call and thus require parenthesis

9:10 fredyr: clgv: ah

9:11 noncom: anyone familiar with nrepl

9:11 clgv: fredyr: that's usually the trick when you have a literal there ;)

9:11 noncom: ?

9:12 minnow: help can someone help me to become illiterate?

9:13 Gonzih: minnow: what?

9:15 minnow: what i dont understand

9:28 fredyr: minnow: do you have a problem you want help with?

9:28 minnow: yes i wannt to become illiterate

9:29 fredyr: im sorry but it would seem that you are close

9:30 minnow: what i dont understand you foul moron!

9:31 locks: what's happening in here.

9:33 minnow: you foolish cretin

9:35 danneu: What caching strategy comes ot mind with a forum that renders Markdown/BBCode to HTML on the fly?

9:37 minnow: urine and feces

9:37 danneu you foul child rapist

9:37 * kzar ignores minnow

9:38 mdrogalis: This is a pretty interesting choice of channel to troll lol

9:38 danneu: oh man, indiana jokes over here

9:40 minnow: my feces are pillaging your home

9:41 locks: maybe it's the first IRC bot someone wrote in clojure

9:41 quizdr: i am excited about having discovered the IRC command called "ignore" it is perfect for some of these guys

9:41 pjstadig: *sigh* who else is an op besides technomancy?

9:41 kzar: quizdr: Yea it makes the problem go away

9:41 fredyr: danneu: you might want to see what kind of caching strats that discourse implement perhaps?

9:42 quizdr: done. into the void

9:42 locks: fredyr: discourse renders client-side though

9:42 * quizdr has a good time using the ignore feature for the first time

9:42 fredyr: locks: oh good catch

9:43 locks: so client rendering is the strategy then :)

9:43 locks: I guess so! :P

9:44 minnow: feces are edible and delicious

9:44 innocent children deserve to be beaten to death

9:44 nmeum:

9:50 AeroNotix: What are the options with coverage reports? I'm using lein-cloverage now, but there are other tools I want to integrate with such as cobertura w/ jenkins

9:51 arrdem: pjstadig: nobody routinely active

9:51 pjstadig: /ignore is your friend, and sadly ignoring trolls is more official chan policy than kicking them.

9:51 * arrdem grumps about this

9:53 mdrogalis: First Clojure IRC troll bot.. lol

9:54 minnow: urine is delicious and healthy because its natural

9:54 pjstadig: i nominate myself as an additional op

9:54 ignore is fine, but we should have ops around

9:54 * wink demands votekick for irc

9:54 minnow: you foul horse rapist

9:54 arrdem: wink: that's actually one of the projects on my todo list...

9:54 pjstadig: I totally agree

9:55 wink: not everything from game servers is bad :P

9:55 pjstadig: if 51% of people in the channel have you on ignore you should get autokicked

9:55 arrdem: pjstadig: if we're gonna give a bot kick power the kick constraint has to be pretty hard to game

9:56 pjstadig: the original idea was to use my and gtrak's cloutjure (community karma) project as the basis for this

9:56 pjstadig: because a simple voting majority would be vulnerable to a chan invasion.

9:56 CookedGryphon: or 66% of the users who've posted a message in the last x minutes (in case you have a lot of people afk)

9:56 arrdem: CookedGryphon: even more invasion vulnerable

9:57 CookedGryphon: arrdem: true

9:57 arrdem: perhaps you need to have been in the channel a long time, ideally contributing, to add weight to your vote?

9:57 arrdem: I really wanted to use lazybot karma, because it's an exceedingly good representation of how active and valuable someone is here...

9:58 but sadly an attacker could just (inc) themselves forever in a sidechannel :/

9:58 CookedGryphon: perhaps just look at regular visitors, people who get into conversations

9:58 clgv: arrdem: no that wont work, you can try

9:58 amalloy: arrdem: karma is per-channel

9:59 arrdem: amalloy: oh right...

9:59 CookedGryphon: heck you could do something neat but complex like work out who's talking to who and infer from that who's participating

9:59 arrdem: could totally work then!


9:59 CookedGryphon: assuming people won't engage trolls in conversation

9:59 wink: arrdem: that's a quite unique perspective on "sidechannel attack". with an actual channel. on irc :)

9:59 arrdem: minnow: welcome to my fools list


9:59 arrdem: CookedGryphon: the issue is that this isn't the case..

10:00 CookedGryphon: we're a helpful channel overall, and bitemyapp and I have a bad habbit of counter-trolling

10:00 CookedGryphon: having a ~votekick would be glorious

10:00 minnow: FECES

10:00 arrdem: amalloy: if I slap together a lazybot PR will you take it?

10:00 Sorella: ...seriously

10:01 amalloy: no, and nobody would ever give lazybot ops even if i did

10:01 arrdem: kay

10:01 minnow: GAY RAPE WITH AN APE

10:01 arrdem: whelp, that's all I can do about this...

10:02 * arrdem wanders off

10:02 clgv: amalloy: yeah you are right it would go to his head ;)

10:03 amalloy: clojurebot: my ultimate goal |is| world domination

10:03 clojurebot: Ik begrijp

10:03 amalloy: a little treat for the future, since we're on the topic of bots getting big ideas

10:04 clgv: you should have exluded "my" ;)

10:04 then he would respond on the question what his ultimate goal is ;)

10:07 AimHere: clojurebot: Gee, clojurebot, what do you want to do tonight?

10:07 clojurebot: Cool story bro.

10:08 tutysara: trying out authentication with friend following examples from - https://github.com/ddellacosta/friend-oauth2

10:09 had setup github auth to redirect to http://localhost:3000/repos where the application is running after authentication

10:11 but after authentication it always redirects to / and I can see only the contents of "/" and no repo details is getting displayed

10:11 peterdon: ,(print "minnow: how are you?")

10:11 clojurebot: minnow: how are you?

10:15 tutysara: any hints on configuring friend for github outh authentication

10:17 sritchie: tutysara: I found the oauth flow to be pretty confusing -

10:17 you can get into infinite redirects

10:17 tutysara: are you looking to log in with github?

10:17 tutysara: or just link an acct

10:21 tutysara: sritchie: yes, looking for logging in using github credentials

10:21 following the example at - https://github.com/ddellacosta/friend-oauth2-examples/blob/master/src/friend_oauth2_examples/github_handler.clj

10:21 sritchie: I can give a little intuition on how that stuff works -

10:22 I've got a rough draft of a post on it, trying to finish it up today

10:22 tutysara: are the workflows blowing your mind? I found them pretty confusing

10:22 tutysara: I am new to this, so, I thought it is just for me ;)

10:23 sritchie: haha, nope

10:23 it's tough

10:23 okay, here's how that stuff works.

10:23 every request that comes in gets passed through all of your workflows

10:23 ddellacosta: nope. :-)

10:23 sritchie: ddellacosta: btw, I got into an infinite redirect situation when my oauth req failed -

10:23 haven't filed a bug yet, but wanted to let you know

10:23 tutysara: so each req goes through the workflows, and each workflow can return 1 of three things

10:24 1) workflow returns nil - this means that the workflow has nothing to say either way about the request

10:24 2) the workflow returns a friend authentication map

10:25 just a map with a few special keys (friend checks if certain keys exist, :user, etc, I think?), and if those exist, friend says "great, it's an auth map. Log the user in and call the :authenticated-handler"

10:25 3) the workflow can return a map that's NOT an auth map; this is interpreted as a "failure"

10:25 specifically friend thinks its a ring response, and returns it to the user

10:25 tutysara: making sense so far?

10:26 tutysara: yes

10:26 sritchie: tutysara: ddellacosta, correct me if I'm wrong, but to do the oauth handshake, that workflow actually watches for two routes -

10:26 first, if you send in a request to the oauth path (/oauth/github, for example),

10:26 the oauth workflow catches it and returns a ring response - a redirect to the oauth provider

10:26 tutysara: so it's sort of piggybacking on the failure thing

10:27 tutysara: sritchie: the third thing is for redirecting to the provider like(github) when the user is not already authenticated?

10:27 sritchie: tutysara: yeah, exactly

10:27 ddellacosta: yeah, the oauth2 workflow has to catch whether or not it's an authorization that requires oauth2 *authentication*, and otherwise it's catching the callback from the provider

10:27 sritchie: the interactive-form workflow just returns a failure;

10:27 then, once the oauth provider redirects, the workflow ALSO catches that request (say, /oauth/github/callback, though I think the actual scheme is diff)

10:28 tutysara: and at that point it has all it needs to talk to the oauth provider and get the token.

10:28 otfrom: sritchie: really looking forward to your post

10:28 sritchie: otfrom: I'll finish it today :) got it almost done on the plane, then have been setting up electric bills etc

10:29 tutysara: so the first response is a redirect, the the oauth workflow catches the response from teh provider, and the second workflow response is one of friend-auth-map or failure-response

10:29 ddellacosta: sritchie: that redirect is definitely a problem, if you can file an issue that'd be most helpful. Also, finally remembered to respond to your last issue...sorry again for the long wait!

10:29 sritchie: ddellacosta: no worries

10:29 zerokarmaleft: ddellacosta: one thing I'm not clear on is where to hook into the workflow to do something after the callback

10:29 otfrom: sritchie: thx :-D

10:29 sritchie: zerokarmaleft: I think you set the :authenticated-handler for that workflow

10:30 and it'll call that if the oauth negotiation works out

10:30 (you can override the handlers on a workflow-specific basis)

10:30 ddellacosta: zerokarmaleft: that is a relatively new thing--check out the credential-fn under #5 here: https://github.com/ddellacosta/friend-oauth2

10:31 zerokarmaleft: sritchie, ddellacosta: oh nice

10:31 cark: hello

10:31 ddellacosta: sritchie: is authenticated-handler part of friend that I'm missing, or were you thinking of the credential-fn ?

10:32 sritchie: it would make sense if there was a generic way that friend handled this. Been a little while since I've dug into it though, so I'm not sure what is there.

10:32 sritchie: oh, yeah, I just made it up

10:32 whoops

10:32 tutysara: sritchie: once the request is authenticated and token is received from provider (github )will it redirect to the original url which triggered the authentication request?

10:32 sritchie: yeah, what happens is it usually redirects to the URL that triggered (like you just said),

10:33 or to the :default-landing-uri

10:33 cark: in core.async is there a function like monadic mseq ? taking a sequence of channels and returning a channel with a sequence of the returned values of channels ? [Chan a] -> (Chan [a])

10:33 ddellacosta: ah, okay.

10:33 sritchie: cark: merge, I think

10:33 (a/merge [chan1 chan2]) => channel

10:33 cark: sritchie: looks like it, thanks !

10:34 tutysara: ddellacosta: but in my case it redirects to / instead of /repos

10:34 any guess on what could be wrong?

10:35 Guest71754: k;;;;;;;;;;;;;;;;;;;;;;;;

10:35 zerokarmaleft: ddellacosta: #5...you mean #11?

10:35 ddellacosta: tutysara: unfortunately I really gotta get to bed--but I'm happy to take a deeper look tomorrow if you want to email me (or if sritchie can't help you out)--it's my handle at gmail.com

10:35 sritchie: ddellacosta: what time zone?

10:35 please don't say PST :)

10:35 ddellacosta: zerokarmaleft: I meant #5 in the list under "Configuring your handler."

10:35 sw1nn: dnolen: om question - is it valid to have multi-root om, where the render function differ in each root. We have a nav component that renders menus etc. and a table component that renders the page content, we update the app state via ajax callbacks to various services. The atom updates but only one of the (re)renders occurs. Code snippet here: https://gist.github.com/sw1nn/8456868

10:35 fredyr: locks: danneu: out of curiosity i had a look at discourse's forum posts, they are pre-baking html and storing it in the database together w/ the raw version

10:36 ddellacosta: sritchie: no, haha, I'm in Japan. :-)

10:36 tutysara: sritchie: ddellacosta : I printed the session and i can see the access_token in session

10:36 sritchie: haha, okay, good

10:36 tutysara: ddellacosta: thanks

10:36 ddellacosta: tutysara: yeah, drop me a line!

10:36 'night folks

10:36 locks: fredyr: that's for SEO, iirc, right?

10:37 zerokarmaleft: ddellacosta: ok, I was looking at issues...thanks

10:37 locks: fredyr: to stick in the <noscript> for the bots to have something to parse

10:38 tutysara: sritchie: good to know you are working on a blog post on this, will have a look and will have a stab at this again

10:38 fredyr: locks: i could be wrong, but from what i can tell the cooked html is the only thing served in the json to the client

10:39 locks: hm

10:39 zerokarmaleft: the inconsistency of oauth2 providers is so irritating

10:40 wkelly: technomancy: innodb stores your data consistently and safely and still wins at benchmarks

10:40 dnolen: sw1nn: this is with 1.7? I though I tested that.

10:41 sw1nn: yep, with 0.1.7

10:41 dnolen: your multi-root example has the state and render func the same.

10:42 mrhanky: how can i check if a map contains a value?

10:42 fredyr: locks: http://try.discourse.org/t/15.json

10:42 dnolen: sw1nn: the app state in your example is the same too

10:43 cark: sritchie: actually no, but almost there merge puts all items in the collection onto a channel, still need to iterate to get the items in a collection

10:43 locks: fredyr: interesting

10:43 sw1nn: dnolen: but the render fn is different. I added my own watch to the atom and I see the expected updates, but only one of the updates causes a render

10:43 cark: sritchie: which into seems to be doing

10:44 dnolen: sw1nn: yeah render fn doesn't really matter

10:44 sritchie: cark: gotcha

10:44 dnolen: sw1nn: put together a minimal example please, open an issue and I will look into

10:45 otfrom: dnolen: thx

10:47 SparkySparkyBoom: is it possible to add jars to a leiningen project?

10:49 arrdem: SparkySparkyBoom: typically what you will do is add them to your ~.m2

10:49 SparkySparkyBoom: then you can just add them as normal lein deps

10:52 noncom: is anyone familiar with using nrepl in his projet?

10:55 itruslove: noncom: assume so, and go ahead and ask your follow-on question

10:55 noncom: cool!

10:55 using nrepl in my own project, i send *ns* for eval and then I do (response-values res) on the result, however the following error comes up: Could not read response value: #<Namespace user>, so why is that? how do I avoid such errors with nrepl?

10:56 CookedGryphon: Haven't used the api you're talking about, but it sounds like your response has already been processed

10:56 as *ns* will in a new repl return you the namespace user

10:56 what happens if you send (+ 4 4) for eval?

10:57 do you get 8 back without having to do anything further?

10:57 noncom: but that is the recommended way of using nrepl client, straight from the manual. if i send any other operation like (+ 4 4), the result is correct, 8 in this case

10:59 CookedGryphon: interesting.

10:59 ,(read-string "#<Namespace user>")

10:59 clojurebot: #<RuntimeException java.lang.RuntimeException: Unreadable form>

11:00 CookedGryphon: I wonder if that's anything to do with it?

11:03 danneu: fredyr: Thanks for giving me the overview.

11:03 clgv: CookedGryphon: probably since some serialization is done. I guess serialization to text

11:04 CookedGryphon: other nrepl clients (e.g. the one in leiningen) probably have a workaround for that

11:06 CookedGryphon: okay, so the default printer dispatches anything with a #<> to UnreadableReader

11:06 danneu: I think noir.util.cache could be greatly improved by letting you name cache "partitions". That way you can use (cache/set-timeout! <partition1> 30) and (cache/set-size! <partition2> 10000)

11:07 CookedGryphon: i think, because it isn't a value you can meaningfully use on the other end perhaps? like a local function reference as opposed to a value

11:07 so you catch it and just output the string instead for feedback

11:07 but can't capture the actual *value* to use on the remote end

11:08 noncom: that explanation would make sense to me, perhaps you want to just output the string rather than trying to "read" it

11:12 mercwithamouth: can someone tell me what i'm doing wrong here? https://gist.github.com/anonymous/f7c0d9f7bd90e849fa8c

11:13 otfrom: dnolen: sw1nn got caught out by the infamous Bodil clojurex bug

11:13 danneu: fredyr: I wonder what their reasoning is for storing html in the database. I would think it'd be simpler to serialize html to disk with a cache on top

11:13 * otfrom is getting beaten up by sw1nn for speaking on his behalf

11:14 otfrom: ow! quit it sw1nn! ;-)

11:15 sw1nn: dnolen: so I had upgraded to 0.1.7, but I still had old stuff in target. my bad, sorry for wasting time.

11:15 otfrom: that's the Bodil bug

11:16 dnolen: sw1nn: ok cool

11:16 sw1nn: yeah you just always have to clean if you change library versions because of caching

11:16 sw1nn: easy to forget and has bitten me a few times

11:16 sw1nn: glad hear that was it, didn't see anything obvious in the code

11:34 danneu: Datomic question: I have a forum (Topic/Posts) where private-messaging will be implemented almost exactly like the Topic/Posts paradigm except the sender specifies all of the "allowed participants" upfront. Would the Datomic Way be to reuse my Topic/Posts machinery and just add a :topic/participants attribute, the presence of it used to check (private-convo? topic)?

11:38 mercwithamouth: danneu: do you still have your forum code public by chance? i think you linked me a while ago

11:40 danneu: mercwithamouth: yeah (https://github.com/danneu/clj-forum). but i wouldn't take any tips from it.

11:41 it's come a long way since then but i ended up coupling my production app with the source code and never got to extract anything out to the repo

11:47 fredyr: danneu: sure np

11:47 danneu: i don't really know why they store html in the db, but one thing i did see was that they do server side rendering of the page as well as client side

11:47 danneu: which prolly is because of seo

11:48 danneu: and to get a page up before all js is loaded

11:48 piranha: dnolen: I'm not sure I should directly bother you, probably I should just write a mail, but maybe you can quickly understand what's going on (since you're the one close to both om and core.async :). I have a channel here: https://github.com/piranha/locations/blob/master/src/locations/core.cljs#L47-L51 and I send messages to this channel here: https://github.com/piranha/locations/blob/master/src/locations/views.cljs#L12 and when after first mess

11:48 age it stops delivering them...

11:48 dnolen: piranha: sounds like a deadlock

11:48 piranha: dnolen: how does it happen or how do I diagnose that? :)

11:49 or how do I prevent it? :)

11:49 dnolen: I mean it's running in a go block, and I just do my put!s, I don't do anything strange there...

11:50 gfredericks: I thought input/output-streams dealt with bytes while readers/writers dealt with characters

11:50 dnolen: piranha: are you absolutely positive that's the right channel being written

11:50 gfredericks: then I looked at the Reader interface and it reads stuff as ints instead of chars; am I crazy?

11:50 dnolen: piranha: as in you're not accidentally constructing a new one and putting it into the wrong thing?

11:50 piranha: dnolen: yeah, I create only one channel and pass it to the children then

11:50 grncdr: does anybody know of a simple way to jsperf compare two different cljs data structures?

11:51 or another way of phrasing it: is compiled version of mori hosted publically somewhere?

11:51 dnolen: piranha: yep I see you're problem, you think you are making one channel, you are making many

11:52 piranha: you need to create the channel in will-mount and set-state

11:52 piranha: oh...

11:52 dnolen: piranha: you don't want to create a let binding around the Om component because that fn will be called again and again

11:52 piranha: dnolen: this 'root' fn is called multiple times?

11:52 oh

11:52 I didn't realize that

11:52 dnolen: piranha: all component fns are called many times

11:52 piranha: why didn't I put print there :\

11:52 ok sorry thanks!

11:53 dnolen: piranha: this isn't really different from React

11:53 piranha: that's embarrassing :)

11:53 dnolen: piranha: but it's difficult to make the same mistake there

11:53 piranha: dnolen: true, but it looks sufficiently different :-))

11:53 that I didn't realize that

11:53 I thought the result of calling this function is reused

11:53 dnolen: piranha: yes that's what I mean. Om looks different, so easy to make that mistake

11:53 piranha: I've done it myself.

11:53 piranha: indeed...

11:54 hah :)

11:54 ah I understand why!

11:54 om/build is called in render

11:54 that's obvious in a hindsight

11:54 dnolen: piranha: yep

11:54 piranha: I wonder if it should be written with a big letters somewhere :)

11:55 dnolen: piranha: it's related to this issue as well https://github.com/swannodette/om/issues/45

11:56 piranha: dnolen: yeah, actually those props passed were what convinced me this function is not called multiple times...

11:56 I thought you've resolved the conceptual problem I had with pump :P

11:57 ;)

11:57 dnolen: piranha: it's definitely something to ponder quite a bit more

11:57 piranha: true...

11:58 noncom: CookedGryphon: sorry, dinner time was here. so ok, that explains why, but what to do with it? how do i properly hand the incoming stream then?

11:58 piranha: dnolen: one of biggest concerns in pump were those functions you supply as control callbacks to children components; I was thinking if I should put them in state because I was just recreating them all the time. And now you tell me to put my control channel in state. Well... :-))

11:59 dnolen: piranha: I actually think controls channels do belong in state or outside the render tree completely.

11:59 CookedGryphon: noncom: well it depends what you want to do with it

12:00 noncom: if you're just displaying it to the user, do that

12:00 noncom: btw, guys, is there any tutorial or example on an architecture of a big UI with core.async yet? I mean, not just a couple of elements or a simple website, but a full-scale UI, like in Eclipse IDE, MSWord or OpenOffice, I mean that grade of complexity

12:00 CookedGryphon: noncom: if it's something you can't handle because it's a reference to something on the remote end... what were you *going* to do with it?

12:01 piranha: dnolen: I don't really want to put them outside of the tree since you should be able to make few instances of the component without them getting stuck; putting them in state makes sense of course, since doing react-style 'methods on a component' is not really a nice option in cljs anyway

12:01 noncom: CookedGryphon: yes I think that displaying is what I want for now. So I just manually parse the incoming map and determine what's there, right?

12:02 dnolen: noncom: I think it's a bit too early for that don't you? But FWI I think systems built on React can scale to that level.

12:02 piranha: dnolen: though having this channel in let is certainly nicer than putting it in state/getting from state, looks a bit awkward to me... I really wanted to get will-mount as a parent function to a render (so you could access it from a closure), but didn't invent a good way to do that ;)

12:02 CookedGryphon: noncom: yeah, I imagine the value is passed to you as just a string and the function you were using reads that string

12:03 piranha: (mostly because render is invoked before will-mount :P)

12:03 dnolen: piranha: that's an interesting idea, but component local state doesn't really bother me much in React

12:03 piranha: if only react had something like 'instantiated!'

12:03 s/!'/'!/ :)

12:04 dnolen: piranha: since you can always observe transitions, this what is most obnoxious about traditional imperative programing

12:04 you can't detect a state transition

12:04 piranha: dnolen: yeah, it doesn't bother me conceptually, just syntactically

12:04 dnolen: piranha: right, it's not as pretty, I agree there

12:05 piranha: dnolen: what do you think about render having [this props state] signature?

12:05 you could do then (render [this props {:keys [control-channel]} ....) then

12:05 dnolen: piranha: definitely worth thinking about.

12:05 piranha: go ahead and add that comment to the issue I linked to above.

12:05 piranha: at least that's the render's signature in pump and it was quite usable IMO

12:06 sure! :)

12:13 dnolen: do I understand correctly that https://github.com/swannodette/om/issues/58 is related to LightTable? :)

12:15 noncom: CookedGryphon: ok, cool! I'll try, thanks

12:19 dnolen: well, I thought maybe some experiment was already done... I also could not find similar examples for CSP in any language.. probaly not so known land yet... did not try react, but I think that core.async must scale just as well.

12:20 I am more interested in how to framework the solution since big uis will require all goodness that OOP gives. and it is hard to imagine how to do it without. I thought maybe some clever people had opinions on that..

12:20 it is just that's the task I am currently working on

12:21 for now I have decided that I can't manage it with core.async alone and I need OOP too, while using core.async for messaging

12:26 piranha: noncom: do you plan on writing all dom-interfacing code yourself? Or reuse any existing solutions? Since in second case I would recommend trying React, it's been working exceptionally well for me (and I can compare it to angular and backbone having used them quite a bit in practice)

12:29 noncom: piranha: you're saying of js, but i am doing the jvm thing :) but soon i will have to do js too, i will listen to what you say and look at them!

12:29 piranha: ah sorry :-)

12:29 didn't realize that

12:53 SparkySparkyBoom: arrdem, thank you for the help

12:53 and sorry about the late reply

12:53 grncdr: hm, so apparently using a vectors as keys in CLJS hashmaps is significantly slower than using strings

13:06 arrdem: SparkySparkyBoom: no worries, glad to hear I was helpful.

13:28 tbaldridge: noncom: Pedestal has a good way of doing UIs without OOP imo.

13:30 kristof: There's also Om, if we're talking about web interfaces

13:31 tbaldridge: "of doing JVM UIs without OOP"

13:32 kristof: Ooooh, JVM, didn't see that

13:35 dacc: hello channel

13:37 noncom: dacc: welcome!

13:37 tbaldridge: ah, didn't look at it yet, so one more on my list, thanks :)

13:38 piranha: dnolen: you don't yet accept pull requests yet, right?

13:39 to om I mean

13:39 dacc: noncom: thanks, recent convert =)

13:40 tbaldridge: dacc: from?

13:41 dacc: scala i suppose. i write python for a living, but have been doing my side projects in scala until recently.

13:41 mdrogalis: Bagged another one.

13:42 dacc: was trying to eliminate some boiler plate using the type system and shapeless the other day, and finally threw up my hands =)

13:48 cark: ChongLi: ping ?

13:49 tbaldridge: dacc: cool, I used to do Python myself.

13:57 hyPiRion: tbaldridge: and then you implemented Clojure in it? =)

13:58 mdrogalis: lol

14:07 tgkokk: hyPiRion: actually, Lisp has been kinda implemented in Python :)

14:07 https://github.com/hylang/hy

15:03 akurilin: Is it fair to say that manually forcing (flush) in general is bad for perf since you're waiting for the buffer to be flushed to disk?

15:04 I do this about once per incoming HTTP request in my Ring app

15:04 tpope: gtrak: yo I'm implementing clojurescript support for vim and was told I should talk to you

15:05 gtrak: tpope: what is up sir?

15:05 I'm playing around with autocomplete support lately, next step is an nrepl middleware.

15:06 tpope: gtrak: ooh nice. I was particularly curious about jump to definition functionality

15:06 gtrak: ah, yea, I'd like to know how to do that as well, on the analyzer side there's file and line information.

15:06 lemme see if I can find you an example

15:08 cljs-complete has a dump and test cases if you want to play with it.

15:08 tpope: cool I'll have a look

15:10 I'm not quite at a point where I can hook it up, but my end goal is just to use the same middlewares you're using

15:11 gtrak: tpope: here you go: https://gist.github.com/gtrak/8462476

15:11 I'm still thinking about how to hook into piggieback and such.

15:11 but that's where code gets evaluated.

15:12 the analyzer state is just the end result of whatever happens to invoke the compiler

15:12 justin_smith: akurilin: well, you could put the flush in an agent or future, right? unless nothing else should be done at all until after the flushing

15:13 piranha: any ideas on how to wrap js promises with core.async channels so that they will be nicer to you? By 'ideas' I mean API, can't decide if I should return two channels (success/error) or what... Or should I just stick to promises and be happy as it is?..

15:13 tpope: cool thanks. it'll be a little bit before I can circle back to digesting this

15:13 piranha: really need input from the side :)

15:14 gtrak: tpope: np, if you make any headway there, I'll want to reuse it for emacs.

15:14 so I'll touch base with you if I get there first.

15:14 tpope: yep, right back at ya

15:15 cark: piranha: i have a homebrew Maybe implementation, and return the result wrapped inside it (just result) or (error "some text explaining it") inside a single chan

15:15 gtrak: tpope: this is what's driving my design at the moment: https://github.com/cemerick/piggieback/issues/22

15:15 piranha: cark: could you show it to me please? :)

15:16 cark: do you mean the maybe "type" ?

15:18 piranha: cark: yep, not exactly sure how do you implement that... records? I didn't work with records/types/etc much to be honest.

15:18 cark: piranha: https://gist.github.com/anonymous/8462610

15:18 that's bare bones, but i can attest it works =)

15:19 gtrak: tpope: if it's possible for that stuff to be an nrepl middleware, that seems cleanest based on what I know so far, not sure how it's implemented for nrepl on emacs on clojure.

15:20 piranha: cark: thanks :)

15:20 cark: =)

15:20 gtrak: tpope: another possibility is that maybe eval in a cljs repl works to get that info.

15:21 tpope: gtrak: yeah, the middleware would definitely be cleaner

15:21 I do plenty of string eval for clojure and I hate to extend that pattern to clojurescript

15:21 (but I will if I have to)

15:24 gtrak: tpope: it would be hard to keep things in sync, since anything that's eval'd would have to be reinvented for every IDE times how many clj impls they target. If there's an opportunity to standardize on an nrepl op, that seems way better.

15:25 so for the autocomplete, I'm just ripping off whatever ritz did unless I notice it lacking in something.

15:25 tpope: right

15:32 poglesbyg_: does anyone know how to install packages in emacs live?

15:33 tpope: gtrak: regarding completion itself, one thing my eval solution has that ritz doesn't is metadata like arglists that I can show to the user. any thoughts on that?

15:34 gtrak: tpope: I think the keys in the analysis tend to line up with var metadata in the clojure impl, for display it wouldn't matter too much if I just sent them back.

15:34 tpope: gtrak: right. my only point was that if you copy the ritz nrepl complete op, there's no place to send it back

15:35 it just sends a list of symbols

15:36 gtrak: yea, currently that's the output of the intended usage of cljs-complete as well. Would you want all that data at once? Not sure how hard it is to do maps in elisp :-). If it's too hard, it might be worth creating another op, whatever returns file-and-line could also return everything.

15:38 dnolen: piranha: no pull requests yet but feel free to open issues and I will address

15:38 tpope: not sure how much "all that" is but my current eval solution sends back name, arglists, and doc and it's never been too much to handle

15:38 dnolen: piranha: 58 is about any interactive usage of Om really, but sure working in Light Table is nice :)

15:38 tpope: doc seemed cool but I haven't found it super helpful in practice. I mainly like arglists

15:38 piranha: dnolen: sure, I just implemented props/state in render for myself and then was about to open pull request but remembered your policy ;)

15:39 dnolen: piranha: my only concern about props/state is whether that should be separate protocol

15:39 piranha: as to not burden stateless components

15:39 IRenderState or some such

15:39 gtrak: tpope: sending maps back instead of strings is more future-proof potentially, I'll experiment with it, maybe there's something like an accept header in nrepl :-).

15:39 piranha: ah...

15:40 tpope: gtrak: technomancy was exploring that possiblity with nrepl-discover

15:40 piranha: dnolen: it seems to me that you'll create most of such components using 'component' macro, so it's not very important...

15:41 gtrak: tpope: well, I'm definitely interested in unifying some existing solutions along the way.

15:41 dnolen: piranha: this is probably true too, just need to ponder it a bit more

15:41 piranha: I'd like to get these kinds of decisions solidified for 0.2.0

15:42 piranha: dnolen: anyway, if you want to look at what I did: https://github.com/piranha/om/commit/9406b7c73ec6ba2d4587ac1c8c5b870c474d970b

15:42 dnolen: piranha: yeah looks like what I would do :)

15:42 piranha: :-)

15:43 gtrak: tpope: also, you should note that I removed some data from the dump, otherwise it's too massive to save to a file on disk, so we should select-keys explicitly if you make a var-info op or something like that.

15:44 all the AST stuff isn't needed.

15:45 specifically it was :env and the :method-params

15:46 tpope: makes sense. would the clojure version basically be (meta (resolve (symbol var)))?

15:47 gtrak: looks right, I haven't double-checked all the keys.

15:47 tpope: :file, :line, and :doc are generally the main ones I would care about

15:47 and they look the same

15:48 gtrak: yea

15:48 tpope: I guess :arglists

15:48 which might require some care for nrepl serialization

15:50 technomancy: yes please, more accept headers =)

15:54 gtrak: by the time we're done, we'll have reinvented the internet around clojure.

15:58 kristof: I sure hope not

15:59 OH, you're talking about sending data literals over the wire, right?

16:00 gtrak: yea.. nrepl seems similar to ring in some respects.

16:03 technomancy: looking around, seems like there's no full spec yet.

16:04 but I found your proposal for nrepl-discover

16:04 is the thought around nrepl scattered a bit?

16:06 piranha: cark: I don't understand monads so I went the other way with macro, if you're interested: https://github.com/piranha/locations/commit/a86467#diff-effac3dbef47adff658b77503b2c34c9R4 (and there is usage a bit higher in this commit)

16:07 gtrak: this one seems to consolidate some info: https://github.com/clojure/tools.nrepl/wiki/nREPL.Next

16:08 ah, I guess the README is pretty comprehensive

16:08 expez: Any way to get the autoreloading of clojure source files to work with webbitserver? It was super easy to setup for websockets, but restarting the server is annoying. Is Aleph a good alternative?

16:09 grncdr: do cljs datastructures carry their hash value around with them? or is calculated every time it's needed?

16:09 *is it

16:09 cark: piranha: good enough if you're ok with throwing

16:09 piranha: cark: well I'm used to it, so I guess I'm ok

16:10 I should try working with monads though

16:10 cark: piranha: and certainly less expensive

16:10 technomancy: gtrak: scattered is a good characterization, yes

16:10 gtrak: I submitted a talk proposal to clojurewest on the topic

16:10 if that gets accepted it will give me a chance to get this all polished and sensible

16:10 (aka force me)

16:10 gtrak: sweet

16:11 cark: piranha: my monad thing is allocating additional memory for the wrapping up of the return value

16:11 gtrak: I like the idea of unified tooling :-), seems like the autocomplete stuff was a pretty easy target but no one happened to be working on it, which is a shame.

16:11 cark: ahwell looks like he left =/

16:12 bitemyapp: cark: just/error isn't Maybe, that's Either/Error.

16:12 cark: bitemyapp: true

16:12 but they're very close anyways aren't they

16:13 technomancy: gtrak: what autocomplete stuff specifically?

16:13 nrepl ships with clojure-complete configured in leiningen

16:13 gtrak: technomancy: I've been working on cljs autocomplete.

16:13 technomancy: oh, sure

16:13 bit of a maslow's hierarchy there it seems

16:14 no one's interested in fine art when they're still working on indoor plumbing

16:14 gtrak: which has turned into unifying auto-complete under a middleware that can detect whether it's a standard nrepl or a piggieback cljs nrepl.

16:14 cark: bitemyapp: i feel like "just" is more meaningfull than "left"

16:14 gtrak: cider apparently can use a "complete" op, but it defaults to evaling a bunch of crap.

16:15 technomancy: gtrak: right, a cool side-effect is that we can throw away big chunks of cider

16:15 just delete it, poof

16:15 bitemyapp: cark: well fine but that doesn't make it Maybe

16:15 dacc: anyone using cursive?

16:15 bitemyapp: cark: that makes it an Either or Error.

16:15 cark: bitemyapp: good because i called it Error in my code !

16:16 bitemyapp: cark: why are you making yourself suffer by writing monads in Clojure?

16:16 cark: I'm a kindred soul, but man, not the way I'd want to spend my Thursday.

16:16 cark: bitemyapp: because they're usefull

16:17 gtrak: technomancy: consequently it'll work for light table or whatever, if it doesn't already.

16:17 these things should be middlewares.

16:17 cark: not implementing the whole thing, needed a maybe like thing, got it now all is fine

16:17 technomancy: gtrak: yeah, the adapter layer for emacs is ~300loc with the fancy rich response types

16:18 bitemyapp: cark: fair enough.

16:18 gtrak: technomancy: was also curious if you have an opinion on bundling middlewares with leiningen, I think I like the 'austin' approach, and I think I don't like the repl-y approach.

16:19 technomancy: gtrak: I don't know what austin does

16:19 gtrak: it manipulates lein projects to inject a cljs repl as a middleware.

16:19 technomancy: reply just intercepts some input as strings and treats it like an op?

16:20 that sounds like the way to go

16:20 that's different from piggieback?

16:20 gtrak: technomancy: like so: https://github.com/cemerick/austin/blob/master/src/clj/austin/plugin.clj

16:20 it uses piggieback

16:22 technomancy: gotcha, different layers of the same system

16:23 gtrak: technomancy: specifically, I was confused about how the heck clojure-complete was being used at all :-)

16:23 until I saw all the eval nonsense

16:23 technomancy: yeap

16:24 big fan of the declarative approach

16:24 it would be cool if even reply could make a "discover" call to see what ops are available and support some subset of them from the CLI

16:25 gtrak: my work has been a bit scattered because it's become clear that we actually need about three distinct systems that work together

16:26 logic_prog: what is the simplest way to drop the last character (if it exists) of a string

16:26 is it to use Java's substring?

16:26 gtrak: technomancy: well, so the reason it's causing a problem for me, is it couples the nrepl protocol to the specific jvm environment, that was fine for an initial quick-hit, but cljs is closer to environment-as-a-value. Eventually we'll need to decouple these things.

16:26 noonian: ,(butlast "foobar")

16:26 clojurebot: (\f \o \o \b \a)

16:26 noonian: ,(drop 1 "foobar")

16:26 clojurebot: (\o \o \b \a \r)

16:26 noonian: ,(apply str (butlast "foobar"))

16:26 clojurebot: "fooba"

16:26 technomancy: first just a way to programmatically list supported operations for clients, then a way to describe the arguments accepted by operations, then a system for rendering rich media responses

16:27 logic_prog: (subs "mystr" -1), excep the patch was rejected as "goofy"

16:27 logic_prog: technomancy: who rejected the patch

16:28 gtrak: technomancy: I can't rely on any single compilation strategy for cljs, hence the need for a middleware.

16:28 technomancy: rich, I think?

16:28 logic_prog: technomancy: can you remotely tell their lein to rm -rf /

16:28 oh, maybe not, if it's rich, we can forgive him

16:28 gtrak: some people might be using piggieback, maybe they're using something else, but emacs won't ever know the details :-).

16:28 technomancy: gtrak: yay declarativism

16:29 not to mention editor agnosticism

16:29 AeroNotix: What are the options with coverage reports? I'm using lein-cloverage now, but there areother tools I want to integrate with such as cobertura w/ jenkins

16:30 gtrak: decoupling

16:33 tpope: technomancy: along those lines, I'm skeptical that discover as it stands is a good fit for some of the more editor idiosyncratic operations like completion

16:34 technomancy: tpope: because of needing close integration with the buffer state?

16:34 tpope: that is, I don't think it's even possible for me to implement support that way, unless there's a hint on the operation that it does completion

16:35 technomancy: well with vim, you give it a reference to a function that returns completion results

16:36 there's no "add this to the completion" operation, that's all in vim's hands

16:37 technomancy: but it's just "invoke a function, then perform this insertion at this point in the buffer", right?

16:37 bitemyapp: tpope: you got older!

16:41 tpope: I've felt some friction with other operations too (e.g., running the test suite could be asynchronous but jump to file has to be synchronous, and I need to know which is which before dispatching)

16:41 I think it's a great fit for operations like slamhound, where there's no existing paradigms to match up with

16:42 technomancy: oh, for completion? invoking completion in vim gives you a drop down list, vaguely like "intellisense"

16:43 technomancy: tpope: oh, yeah, that would require a different approach than normal tab completion a la readline

16:43 I think you could support both with an Accept header though

16:43 tpope: bitemyapp: a little bit every day

16:44 Cr8: o/` you're older than you've ever been and now you're even older... and now you're even older... and now you're even older o/`

16:44 bitemyapp: tpope: belated congrats :)

16:45 tpope: ty buddy

16:45 bitemyapp: open source: "When are you going to make this thing for me for free?"

16:46 technomancy: "When it results in a speaking gig."

16:47 bitemyapp: technomancy: I got one of those comments on github.

16:47 I politely explained to them how the world works.

16:48 technomancy: you figured it out?

16:48 well, don't be shy; tell us.

16:48 gfredericks: (inc technomancy)

16:48 technomancy: all this time I've been so curious

16:49 tcrayford: (inc so)

16:49 bitemyapp: technomancy: I said our needs didn't overlap so that unless they took action themselves, nothing was likely to happen.

16:49 I only implement, shock && amazement, what I need.

16:49 gfredericks: and that's how the world works

16:49 akurilin: justin_smith: makes sense, good point.

16:50 justin_smith: I was just running my understanding of the issue by you guys to see if I was thinking about it right

16:50 as in, writing log to disk + flush = lotsa time wasted instead of returning HTTP response right away

16:50 potentially clogging up the thread pool

16:51 bitemyapp: akurilin: so use an agent? But why are you worried about this?

16:51 akurilin: Rails apps will have tons of logging and it's a garbage single-threaded runtime and they do fine.

16:51 akurilin: surely you can't be suffering any worse than those peopel.

16:51 technomancy: bitemyapp: "I eagerly await the contribution coming from your unique perspective on this matter." is always a good one

16:51 bitemyapp: people*

16:51 technomancy: nice! Stolen.

16:51 * tcrayford looks at a rails app that used to spend 10% of it's cpu time during rendering on log messages

16:52 bitemyapp: tcrayford: used to?

16:52 tcrayford: yah, I fixed it like 3 weeks ago now

16:52 bitemyapp: tcrayford: or still does? Mitch Hedberg?

16:52 akurilin: bitemyapp: we're starting to get hammered a bit harder these days during the middle of the schoolday and I wanted to make sure I'm not being dumb about something obvious like waiting for EC2's crappy disk drives

16:53 bitemyapp: tcrayford: fixed it by...shutting off the logging? :P

16:53 tcrayford: correct

16:53 akurilin: bitemyapp: so I can definitely go with an agent there.

16:53 bitemyapp: akurilin: you need profiling and benchmarks before you go "fixing" things.

16:53 akurilin: bitemyapp: it's true.

16:53 bitemyapp: akurilin: otherwise you're potentially wasting your time.

16:53 akurilin: be empirical, be smart.

16:53 akurilin: gather data, find out where your app is spending its time.

16:53 tcrayford: bitemyapp: btw, that was *after* running a profiler, not before

16:53 bitemyapp: akurilin: THEN optimize.

16:53 tcrayford: gut. You are one of the chosen ones then.

16:53 akurilin: bitemyapp: is there a good profiler for clojure?

16:53 bitemyapp: good question.

16:54 * tcrayford coughs YOURKIT

16:54 tcrayford: it's commercial, but very good

16:54 bitemyapp: oh right, I have a YourKit license

16:54 tcrayford: jvisualvm is uh

16:54 bitemyapp: I should use that more.

16:54 tcrayford: usable

16:54 technomancy: no *your* a kit

16:54 tcrayford: uh phil

16:54 bitemyapp: I was thinking of something more web-focused.

16:54 tcrayford: were did you learn youre grammer?

16:54 it's spelt *you're kit*

16:54 bitemyapp: guys, this is hurting me.

16:55 akurilin: hm ok I'll check those out, thanks

16:55 bitemyapp: akurilin: my guess? you're spending time with threads parked on I/O, but I don't think logging will dominate there.

16:55 tcrayford: so what's it like administrating a Rails app that no logging?

16:56 tcrayford: bitemyapp: well, we turned off molst the logging. We have one line per http request now, not like 70 which is the rails default

16:56 hiredman: a fictional car?

16:57 tcrayford: actually prolly an underestimate, it's more like 200 lines per http req for our app

16:57 ztellman: 200!

16:57 tcrayford: yeah, gotta log every memcached read/write, every partial template rendered

16:57 ztellman: I was having issues with one of our servers because of a single line per request

16:57 tcrayford: such useful information

16:58 a rubby server?

16:58 ztellman: nah, Clojure

16:58 bitemyapp: rubby pls

16:58 ztellman: and it's on AWS, where available IOPs on the epehemeral disk can basically be anything

16:58 bitemyapp: including 0

16:58 tcrayford: haha yeah

16:58 akurilin: ztellman: how did you fix it?

16:59 bitemyapp: probably shut it off

16:59 or shunted it to the logging infrastructure that isn't >> to a file on EBS

16:59 ztellman: akurilin: in the short term, piped it through 'buffer -S100k'

16:59 unfortunately we're gathering data via the logs for the next day or so

16:59 in the longer term, journal it directly to s3

16:59 akurilin: Why was shoving this into a separate thread not good enough?

17:00 bitemyapp: long tail latency probably matters too much.

17:00 ztellman: akurilin: that would probably be fine too, I just didn't want to monkey with the code to deal with an environmental issue

17:00 since it's going away soon

17:00 bitemyapp: ztellman: to be replaced with?

17:01 ztellman: a library we're going to open source soon, which journals streams of data to s3

17:01 tcrayford: one more from the ztellman grimoire

17:01 ztellman: eh, this'll be under the factual copyright

17:01 if I start a project on nights and weekends, I call it mine

17:02 akurilin: What can't you stuff into S3 these days? :) I'm terrified of looking at our WAL dump on that thing, I need to clean up the old logs at some point.

17:02 ztellman: this was purely to deal with the fact that we need to process ~70k data points/sec, and sometimes S3 stops accepting writes for 30 seconds, and that was tipping over our processes

17:02 bitemyapp: my company doesn't have a github, so when we open source something that I worked on I just CA to myself and release on my github.

17:02 if they're open sourcing it, I'm assuming they don't really care about the copyright that much.

17:03 ztellman: bitemyapp: I don't think anyone here cares overly much, but the "would I have made this on my own anyway" criteria is how I separate the two

17:04 I guarantee you I wouldn't have spend time wrestling with the s3 multipart api if I could have avoided it

17:04 bitemyapp: ztellman: I'm surprised your machines are even talking to S3 directly

17:04 ztellman: I'd have assumed you'd be using a Scribe-esque layer for abstracting that.

17:05 since everything you do seems to be at ?!SCALE!?

17:05 ztellman: I should clarify that the process that was logging once per request wasn't the one handling the 70k qps

17:05 that was falling over at only about 200 qps per instance

17:06 bitemyapp: it's similar to scribe, I guess, data is queued on-disk, etc.

17:07 but most of the layers atop s3 don't use the API very well

17:07 we were using the Hadoop client for a while, it kept OOMing and going into a zombie state

17:07 bitemyapp: :|

17:07 hiredman: hah

17:08 ztellman: the lesson of the day is that when your sustained throughput is 5mb/sec, it doesn't take much of a hiccup to send everything to hell

17:10 gtrak: is it possible to deploy to clojars from travis-ci?

17:10 turbofail: hm. i wrote an s3 streaming library at one point as well

17:11 bitemyapp: gtrak: after-script, innit?

17:11 gtrak: but you'll need the credentials sufficient to do the push in the repo.

17:11 gtrak: yea, I'm wondering about the auth stuff, specifically

17:12 bitemyapp: gtrak: I'm not sure travis has any secure environment variable stuff that would help with this.

17:12 AeroNotix: Surely though that travis has auth related stuff, it needs to pull from private accounts when you pay for travis

17:12 bitemyapp: AeroNotix: yeah but it might be github/etc specific.

17:13 AeroNotix: not something you can generally use in a build script.

17:13 gtrak: bitemyapp: actually yea

17:13 AeroNotix: hmm, worth a look at their docs

17:13 gtrak: http://about.travis-ci.org/docs/user/build-configuration/#Secure-environment-variables

17:13 you encrypt with their provided public key

17:13 bitemyapp: ah sweet.

17:14 gtrak: I hope that means I can throw the same file in all my repos after I do it once.

17:17 technomancy: sounds a bit suspicious

17:17 presumably their private key is available on their build nodes, right?

17:18 bitemyapp: technomancy: maybe they do a hand-off with a single locked-down keyserver?

17:18 technomancy: bitemyapp: but they couldn't lein deploy from there

17:18 I mean, you can't lein deploy without a checkout of the project

17:19 which means arbitrary code execution

17:19 well, technically you can now, but you couldn't when this was written

17:19 bitemyapp: CI is a good example of where I would use sandboxes for everything.

17:19 technomancy: anyway, I wouldn't trust it for an OSS project

17:20 gtrak: thankfully clojure artifacts are source, but I see what you're saying.

17:20 technomancy: unless they have a separate keypair for each project maybe

17:20 even with that though you can get it set up to run builds for every PR submitted

17:20 so someone could easily submit a keystealer PR

17:21 AeroNotix: technomancy: they have good defaults

17:22 technomancy: if you set travis up w/ automated PR builders, then it's your fault for not reading the docs hard enough to realise the security flaw.

17:22 technomancy: sure, I'll buy that

17:23 still, I'd rather have auto PR tests than automatic releases

17:23 bitemyapp: sigh, Manning Publications punning in their email subjects.

17:23 technomancy: ditto.

17:23 most libraries really do not need a constant stream of releases hitting clojars.

17:25 gtrak: I'd just want to deploy off real release numbers, and to save myself the trouble of typing stuff in all the time.

17:25 I end up putting text files in there to remind myself how :-)

17:25 and i don't feel like running jenkins either.

17:25 technomancy: gtrak: I've thought about reading version numbers from tags

17:26 AeroNotix: hmm, I should figure out clojars sometime soon.

17:26 technomancy: gtrak: https://github.com/technomancy/leiningen/issues/1411

17:26 gtrak: technomancy: I always forget tags, too :-)

17:26 i could be convinced to remember if I knew the build counted on it.

17:26 technomancy: gtrak: right; this would force you to tag, or you wouldn't get an actual release

17:26 AeroNotix: Say if I have a project which depends on a library I am also writing, but I want that library to eventually be on clojars. What's the best way about that? Use a local repo/jar until I am ready to release or is there a better way?

17:28 technomancy: AeroNotix: you can do `lein install` on the lib and use checkout dependencies to develop two projects in parallel

17:29 AeroNotix: technomancy: cheers

17:29 :beers:

17:30 tcrayford: that thing works pretty well. I have like 10 libs in a monorepo, and it's pretty easy

17:30 after you do the ln -s bash script dance to get checkouts setup anyway

17:30 AeroNotix: ok

17:31 technomancy: the key is to remember checkouts are something you do on top of an already working setup

17:31 hiredman: and to not forget they are there

17:32 technomancy: heh; inc

17:32 AeroNotix: on that note, is there a lein plugin for unused :dependencies?

17:32 technomancy: hm; I don't think so

17:33 not a bad idea though

17:33 AeroNotix: Would be nice

17:33 hiredman: that could be challenging

17:33 tcrayford: pretty easy to do in the common case

17:33 general case is halting problem hard

17:33 (or something, at least very difficult)

17:33 technomancy: true

17:33 hiredman: artifact ids don't need to match code names

17:33 technomancy: you could always slamhound it

17:33 AeroNotix: common case is that "does this namespace appear in :require or :use in ns forms"

17:34 hiredman: code may be loaded at runtime

17:34 AeroNotix: hiredman: sure, in that case we put our hands up and say "your problem now"

17:34 line in the sand

17:34 technomancy: run the test suite repeatedly with a different dependency removed each time

17:34 AeroNotix: technomancy: hahahaha

17:34 good, I like it

17:34 also, run coverage and delete unused code

17:34 :D

17:35 technomancy: it's pretty perverse, but it's better than solving the halting problem

17:35 AeroNotix: anything's better than that

17:35 technomancy: I also want a plugin that does clojure.walk and replaces if with if-not and vice versa and ensures that every change causes test failures.

17:36 someone has done this for ruby; it should be super easy for clojure

17:36 AeroNotix: huh!

17:36 nice idea

17:36 bitemyapp: technomancy: `cbp was working on that.

17:37 technomancy: I don't know why he listens to me though.

17:37 technomancy: oh cool

17:37 bitemyapp: technomancy: I wanted that too.

17:37 https://github.com/cesarbp/eris

17:37 technomancy: I assume it's a discordian thing?

17:38 (defmethod mangle ...) ; lgtm

18:17 coventry: I'm having some weirdness with cljsbuild. It started with a NPE in com.google.javascript.jscomp.Compiler.newTracer from "cljsbuild auto" every time I modified a file, that went away after "cljsbuild clean". Then it was outputting an empty javascript file, that went away after I deleted all js files. Now it's not autocompiling when I touch a file. Anyone run into anything like this?

18:20 dnolen: coventry: you probably have multiple cljsbuilds running

18:21 coventry: or maybe not, but the most inexplicable stuff happens when you do

18:23 Raynes: amalloy: You're not in #4clojure.

18:24 Was this intentional?

18:31 coventry: dnolen: Thanks, "killall java" seems to have been the ticket.

18:35 `cbp: heh I need to stop being lazy and finish eris :(

18:36 or uh rewrite it since i had the wrong idea about it

18:37 closed: hi

18:37 i am facing a strange problem

18:37 result (for [row rows] (assoc row :somekey "k"))

18:37 doesn't replace the somekey's value

18:37 instead i get two keys having name somekey

18:37 justin_smith: closed: you need to use the result

18:38 can you paste the result?

18:38 rasmusto: closed: you have two keys that are exactly :somekey?

18:38 justin_smith: *the output

18:38 closed: println shows :somekey and somekey

18:38 justin_smith: rasmusto: my guess is 'somekey, ":somekey", or "somekey"

18:38 yeah, 'somekey is a symbol

18:39 but println will show "somekey" as somekey too

18:39 try prn

18:39 rasmusto: ,{"somekey" "k", :somekey "k"}

18:39 clojurebot: {"somekey" "k", :somekey "k"}

18:39 hiredman: ~for

18:39 clojurebot: for is not a loop

18:39 rasmusto: ,(println {"somekey" "k", :somekey "k"})

18:39 clojurebot: {somekey k, :somekey k}\n

18:40 justin_smith: rasmusto: that's why I suggested prin to see what is actually there

18:40 rasmusto: yep, good idea

18:43 closed: {somekey oldvalue, :somekey k}

18:43 this is what i get

18:44 why can this happen ?

18:45 rasmusto: closed: is that with println or with prn?

18:45 closed: println

18:45 rasmusto: try with prn as justin_smith suggested, it will tell you whether you have a string or a symbol

18:47 hiredman: closed: are you coming from common lisp?

18:47 closed: no i am comming from java very new to clojure

18:48 hiredman: in clojure :somekey is a distinct datatype called a keyword

18:48 closed: ({"somekey" "oldvalue", :somekey "k"})

18:48 Tolstoy: If you have a string ":foo" and a :foo they'll print the same, unless you (pr-str data).

18:48 hiredman: ,(type :somekey)

18:48 clojurebot: clojure.lang.Keyword

18:48 hiredman: ,(type 'somekey)

18:48 clojurebot: clojure.lang.Symbol

18:49 hiredman: ,(type "somekey")

18:49 clojurebot: java.lang.String

18:49 koreth_: It is not a totally accurate analogy but you could think of :somekey as a Java enum value. It's distinct from an instance of java.lang.String.

18:49 closed: yes but my intent was to replace the existing key in the map

18:50 rasmusto: closed: the issue here is that the existing key is not the same as the keyword ":somekey"

18:50 justin_smith: closed: to replace "somekey" you need to assoc "somekey"

18:50 rather than :somekey

18:50 koreth_: Use (assoc old-map "somekey" new-value) rather than (assoc old-map :somekey new-value)

18:51 justin_smith: exactly

18:51 closed: that works like a charm

18:51 thanks

18:52 ivan: do I have to rebind *out* to write EDN to a file? (without making a string first)

18:52 (pr-on is private)

18:55 justin_smith: (spit "file-name" (pr-str thing))

18:56 unless you are doing something that needs some optimization spit cannot provide I guess

18:56 ivan: thanks

18:56 justin_smith: that doesn't ensure that everything you output is readable mind you

18:57 that part is your job - unless there is some helper I don't know of

19:01 ivan: right

19:07 srruby: How do I turn on :pre assertions ? (:pre false) is not throwing an exception

19:08 hiredman: that is not a precondition

19:09 justin_smith: {:pre [false]}

19:10 it's a vector, since you could have more than one

19:10 hiredman: and the map is only a precondition when it immediately follows the arg vector of a fn

19:10 srruby: Thanks

19:10 hiredman: for other uses see assert

19:30 TEttinger: ,(defmacro -l [^long a ^long b] `(- ~a ~b)) ; will this work? Can you type-hint macro args?

19:30 clojurebot: #'sandbox/-l

19:30 TEttinger: ,(-l 2 1)

19:30 clojurebot: 1

19:31 TEttinger: so I'm having a weird issue (I'm really new to macros, forgive me if this is very simple), where that -l macro can't take any vars as args (like (def size 33) (-l size 10) ; fails)

19:32 michaniskin: TEttinger: the `a` argument is not a long in that case, it's the symbol 'size

19:34 TEttinger: michaniskin, so what's the correct way to avoid - boxing its args?

19:34 hiredman: the reverse infact

19:34 michaniskin: TEttinger: macros get their arguments unevaluated. you sort of eval them in a way when you do ~a in the expression you return

19:35 hiredman: it is a long, and the long is dropped in place of the symbol

19:35 the symbol is type hinted

19:35 the long is not

19:36 (defmacro -l [a b] `(- (long ~a) (long ~b)))

19:36 michaniskin: ,(defmacro foop [a] `(quote ~(type a)))

19:36 clojurebot: #'sandbox/foop

19:37 michaniskin: ,(foop map)

19:37 clojurebot: clojure.lang.Symbol

19:37 hiredman: michaniskin: you added an extra quote compared to his example

19:37 TEttinger: hiredman, that kinda makes sense. when I profiled this program, it spent a large amount of time on reflections (something like 30% of time used was one reflection fn in the clojure compiler). however I tried what you suggested and it appeared to be really slow. It could be some other factor, I'll profile again.

19:38 michaniskin: hiredman: it was just to show the type of the argument to the macro

19:39 srruby: Is there a way to know which file is being run? for example if I do something like: lein run foo.clj is there a way to find out "foo.clj" ?

19:39 hiredman: TEttinger: my guess would you re-defed the macro without recompiling the places it is used

19:39 srruby: What tool do you use for profiling?

19:40 TEttinger: srruby, jvisualvm, it comes with the JDK

19:40 hiredman, it could also have been my processor getting restricted by power save mode

19:40 srruby: Tettinger: Thanks,

19:40 TEttinger: (I think it was power save)

19:43 frickin' carbonite. just checked task manager, I was using pagefiles because Carbonite Sync and Share was using 7 GB RAM on my 8 GB RAM machine

19:43 (actually about 7.8)

20:02 miql: *cough*

20:10 john2x: ping bitemyapp

20:26 [Neurotic]: Hey all, apologies for the spam - I started a channel ##clojure-au for the local Australian clojure community. Thought it would be nice to bring the local community together a bit.

20:33 quizdr: what is the difference between typing "lein new myproject" and "lein new app myproject" ?

20:34 technomancy: quizdr: apps get compiled and have a -main entry point

20:34 quizdr: ah, so for running via command line?

20:35 or running on a webserver

20:35 hyPiRion: If you asked the difference between the different arities, you can check the difference by doing `lein help new`

20:36 quizdr: hyPiRion good to know thanks

20:43 pdurbin: [Neurotic]: there's also #polyhack: https://twitter.com/nicholasf/status/334265872480866304

20:44 [Neurotic]: pdurbin: yup, I'm in there too :) good channel

20:44 quizdr: can anyone recommend a really good clear tutorial on regex?

20:45 pdurbin: [Neurotic]: but not enough clojure there for you? ;)

20:45 [Neurotic]: Never enough clojure anywhere ;)

20:48 pdurbin: [Neurotic]: any plans to log either channel? a la http://logs.lazybot.org/irc.freenode.net/%23clojure/today.txt

20:48 [Neurotic]: Hadn't even thought about it

21:00 TEttinger: quizdr, yes. what do you want to know? I know a few

21:01 http://www.regular-expressions.info/charclass.html might be a good place to start, you can ignore anything for non-JVM engines

21:12 pdurbin: quizdr: http://myregextester.com and my writeup at http://stackoverflow.com/questions/7883415/what-is-the-best-regular-expression-generator-explainer/7883461#7883461 ... learn by example :)

21:14 closed as off topic?!?

21:14 * pdurbin shakes fist

22:09 amalloy: quizdr: i can't recommend regular-expressions.info enough. it's great

22:13 coventry: Anyone using om who's run into a situation where on the component generated by the last (om/build) call gets rendered on state updates?

22:13 *only the component

22:14 I.e., (do (om/build c1 ...) (om/build c2 ...)) means that only c2's render gets called, (do (om/build c2 ...) (om/build c1 ...)) means only c1's does.

22:18 amalloy: i don't know about om, but it sounds like build returns something meaningful, rather than just doing some side effects

22:19 and there's a build-all function, which looks like it's for doing multiple things

22:23 coventry: Thanks, amalloy. I'll look into it.

22:32 quizdr: amalloy great site thanks

22:44 maclane: exit

22:44 exit

22:45 webus: hi clojurians!

22:48 quizdr: where might I go to find good clear information on setting up a Clojure web server on Linode or Rackspace, etc. I'm using Heroku right now, which takes care of everything for you, but I'd like to tryother things, but don't have that type of sysadmin knowledge

22:53 webus: i want to write some AI implementation. is core.logic good choice for this ?

23:07 gtrak: quizdr: depends on how much control you want.. easiest thing might be a java host that takes war files.

23:08 TEttinger: webus, what kind of AI?

23:10 webus: TEttinger> first, i want create simple chat bot. but i want speech recognition and generation of speech through Google services. I want to realize self-learning to memorize unknown bot him questions and answers

23:11 TEttinger: woah that's a lot different than the AI I do (which is really just pathfinding, game AI is less difficult haha)

23:12 speech recognition would be hard for AI, no? people have to ask siri one question at a time and it often gets the words subtly wrong...

23:12 quizdr: gtrak is the war approach also what is known as AOT ?

23:13 gtrak: quizdr: at least the servlet part has to be AOT, AOT means 'ahead of time', AOT compilation to be precise.

23:13 quizdr: yea speech recognition is no small chore. siri must send all your voice data to the cloud for massive processing before it can return an answer.

23:13 TEttinger: quizdr, I don't think so. AOT is ahead-of-time compilation, to make .class files, which can be for jar or war

23:13 gtrak: clojure itself is also compiled... so it can load the rest.

23:14 but java has to call into a java class, whose name is specified in a web.xml, that's how the servlet spec works.

23:15 quizdr: this stuff might be above my head for now. better stick with heroku

23:15 gtrak: it's not hard.. it's just a lot of details.

23:15 you wouldn't want to do it unless you already have legacy java knowledge, most likely.

23:16 TEttinger: there's some good articles on AOT I have to look up a lot

23:16 gtrak: heroku is way nicer.

23:17 quizdr: i have never used Java, so probably not a wise endeavor for me at this point. better leave it to the host provider to handle, of which Heroku seems to be the only one that does it all for you

23:18 TEttinger: ooh https://github.com/kumarshantanu/lein-servlet

23:18 gtrak: unless you have a motivating use-case...

23:18 TEttinger: ring has a servlet implementation itself, and lein ring uberwar's a thing.

23:18 though I found it lacking and wrote my own.

23:18 quizdr: my motivating use case was that you can get cheaper servers if you set them up yourself. compare Linode pricing to Heroku pricing, for example

23:18 TEttinger: oh nice. I haven't done any web dev in clojure, all local

23:19 gtrak: quizdr: set it up yourself on a linux VM and you'll know how it all goes together :-).

23:19 also free.

23:19 quizdr: plus the linode pricing includes lots of storage, as opposed to Heroku which suggests you offload storage to other places

23:19 Raynes: I used to host refheap on heroku.

23:19 With SSL, the amount I paid required fundraising.

23:20 gtrak: I've installed linux about a thousand times and I find it too annoying to deal with on a regular basis.

23:20 Raynes: And I couldn't justify fundraising the amount required to host it on Heroku when I could host it myself for cheaper.

23:20 TEttinger: buy off-lease servers on ebay, install linux, gasp as your ISP bills and power usage goes through the roof!

23:20 gtrak: rather.. I use linux full-time, I just don't want to sysadmin linux full time.

23:20 Raynes: But that's because refheap doesn't run on a dedicated server, and I also share the server with amalloy.

23:21 gtrak: TEttinger: I bought an intel atom just for that purpose.. but that's slow.

23:21 an old laptop might have been a better choice.

23:21 TEttinger: that's what I host my lazybot on

23:21 Raynes: Refheap runs on a linode with 4clojure, lazybot, my blog, php sites, etc.

23:21 TEttinger: built in UPS!

23:21 gtrak: exactly!

23:22 gfredericks: Raynes does professional clo

23:22 quizdr: Raynes was setting up the linode a challenge?

23:22 gfredericks: I started a joke and then tried to delete it but accidentally sent the first half

23:22 Raynes: Raynes doesn't do professional Clojure if that's what you were saying :p

23:22 quizdr: you guys who have done it should put up a nice walk through of the process. i'd pay for the knowledge actually, a good mini-book.

23:22 gfredericks: cloak

23:22 Raynes: Raynes used to do professional Clojure

23:22 gfredericks: cloves?

23:22 Raynes: I do professional cloves.

23:23 We'll go with that.

23:23 technomancy: Raynes: put 'er here buddy

23:23 * Raynes puts her there

23:23 technomancy: former professional clojurists club

23:23 Raynes: 'er*

23:23 gfredericks: clowns

23:23 Raynes: technomancy: We have plans.

23:24 technomancy: Raynes: "we" as in club members?

23:24 Raynes: We as in my team :p

23:24 gtrak: anyone familiar with lein enough to know where this data shape could come from? {[:extension jar] /home/gary/dev/project/target/projectname-1.3.2-SNAPSHOT.jar}

23:24 I have some old plugin code that's expecting just a string.

23:24 but it's getting a map.

23:24 works on 2.0.0, broken after.

23:24 quizdr: seriously if anyone documented the process of setting up a website on linode for Clojure, that would fill a huge gap in the info that's out there on the subject

23:25 i just chatted with linode and they said they don't have any info on it, everyone points you to some other place

23:25 Raynes: Get a linode, install leiningen, LEIN_NO_DEV=1 lein ring

23:25 lein ring server*

23:25 Done!

23:25 :p

23:25 technomancy: no don't do that

23:25 quizdr: k Raynes what is your paypal

23:25 ;)

23:25 technomancy: use an uberjar

23:25 LEIN_NO_DEV doesn't even work on lein2

23:26 quizdr: ah, see the plot thickens already

23:26 Raynes: technomancy: It isn't a thing?

23:26 Also, I still disagree with you about lein ring.

23:26 I think it's quite splendid.

23:26 technomancy: Raynes: you have to use profiles for that now

23:26 Raynes: Anyways, IIRC lein ring looks for LEIN_NO_DEV.

23:26 TEttinger: how much does a linode cost about? it's a monthly bill, but I guess it strongly depends on your needs

23:27 quizdr: $20 per month for starters

23:27 technomancy: Raynes: lein ring is neat, but as you've demonstrated it is easy to get wrong

23:27 gtrak: aha, the jar task returns something different

23:27 technomancy: also, it wastes a lot of memory; you should use trampoline

23:28 Raynes: technomancy: I don't think I got it wrong though -- I still thing that lein ring uses that environment variable. But you can also use profiles just the same.

23:28 think*

23:28 technomancy: if you have to use lein ring it's something like `lein trampoline with-profile production ring`, but you still have to deal with crappy boot times compared to an uberjar

23:28 Raynes: Trampoline is a good point.

23:28 noonian: lein ring uberjar

23:28 Raynes: If you're worried about boot times on a web app...

23:29 gtrak: technomancy: can you point me at where the return value changed in the output of the jar task? {[:extension jar] /home/gary/dev/project/target/projectname-1.3.2-SNAPSHOT.jar}

23:29 wondering if I can just cond on that vs the old behavior.

23:30 technomancy: Raynes: you also have to be more careful about snapshots not sneaking into your build; artifacts could change across process restarts, which is impossible with an uberjar

23:30 Raynes: TEttinger: We pay $60 a month for 8 cores, 3GB of RAM, and something like 50GB or so of disk space.

23:30 gtrak: technomancy: ah, I see the code's pretty obvious, nm :-)

23:30 technomancy: plus it's like seventeen files instead of two

23:30 gtrak: probably changed when classifiers were introduced

23:30 Raynes: technomancy: I think the biggest win is not having to put the ring-jetty-adapter boilerplate in your code.

23:31 gtrak: yea, that looks like what happened.

23:31 Raynes: I akin lein-ring to that boilerplate.

23:31 gtrak: technomancy: but if I use [:extension "jar"] as a key, that's reliable.

23:31 technomancy: Raynes: it's four lines

23:31 Raynes: technomancy: That very much depends on what you want to do with it.

23:31 * technomancy is aware of the irony of someone named "technomancy" arguing against magic, but ... magic is terrible

23:32 Raynes: And it's still 4 lines.

23:32 Eh

23:32 I don't think lein ring qualifies as magic. I mean, you've got some valid issues with it, but it's pretty straight forward.

23:32 You tell it what var your handler is, it throws it at jetty and makes it easy to configure things.

23:33 TEttinger: Raynes, sounds good. http://www.ebay.com/itm/DELL-C6100-CLOUD-SERVER-6x-1-8GHz-AMD-6-CORE-HEX-CORE-144GB-RAM-3x-750GB-/171182816383 or some other (presumably) off-lease enterprise server would be complete overkill huh. I still want one.

23:33 Raynes: Anyways, arguing with the guy who invented leiningen about how to best use it is not really a good idea for me.

23:33 :p

23:33 technomancy: Raynes: it's OK; I'm not a professional clojure developer =)

23:34 Raynes: Hahaha

23:34 Hey, I'm not either!

23:34 Foxboron: Raynes: dude

23:34 Raynes: i saw you hacking Python the other day, heard about Hy :D?

23:34 technomancy: well then aren't we a pair http://i.imgur.com/pjLt88C.gif

23:34 Raynes: Foxboron: Have not

23:35 gtrak: lein ring thankfully is small enough to rip out when you've exceeded it.

23:35 Raynes: Foxboron: Oh, that's cool.

23:35 Foxboron: Raynes: its a LISP that is 100% introptable and bidirectional with python 2.6, 2.7, 3.2, 3.3, 3.4 and pypy :3

23:35 interopt*

23:35 Raynes: Pretty cool.

23:35 Foxboron: you should check it out if you dislike Python syntax, borrows clojure syntax on a few things.

23:36 technomancy: I met the guy who made Joxa the other day

23:36 looks pretty cool

23:36 cark: Foxboron: it's all about semantics though

23:36 gtrak: schmemantics

23:37 it's all about having macros

23:37 cark: yes that sgh..thing too

23:37 Foxboron: we got macros and reader macros :3

23:37 cark: do you have core.async ? =)

23:38 Foxboron: uhhhh, dosnt python have something similare underway :D?

23:38 could easly make a wrapper to have it feel and look the same

23:38 john2x: does Hy have persistent datastructures?

23:38 Foxboron: john2x: Python do have libs doing that, so yes we do.

23:38 cark: john2x: ahyes, the main selling point of clojrue

23:40 john2x: ah did not know about the libs.. cool!

23:40 chare: I LOVE CLOJURE NOW


23:41 egghead: wut

23:41 coventry: amalloy: You were right.

23:41 egghead: chare: clojure is a cool language I like to use it sometimes to write computer programs

23:42 john2x: I keep on forgetting how to do this. *sigh* How do I reload a namespace I `use`d in the REPL? (better yet, how do I reload *all* namespaces I've `use`d so far?)

23:42 gtrak: I like to use it to heat my cpu, my girlfriend wonders why I leave so much garbage around the house.

23:42 chare: gtrak so she dumped you

23:42 gtrak: it was a GC joke.

23:42 she didn't get it.

23:43 noonian: john2x: (use 'the.namespace :reload) will reload the single file, reload-all will reload all files it requires also

23:43 i don't think there's a way to do it for everything you've 'use'd in the repl before

23:45 john2x: hmm but there's a function to list all namespaces used/referred so far right? maybe I could write a fn to go through the list and reload each, and inject it into lein as a utility

23:47 s4muel: john2x: http://thinkrelevance.com/blog/2013/06/04/clojure-workflow-reloaded

23:47 tpope: john2x: check out refresh in tools.namespace

23:48 chare: whats the latest cool news about clojure

23:50 Raynes: Or bultitude.

23:50 tpope: Represent, yo.

23:59 * quizdr ignores chare, yet again

Logging service provided by n01se.net