#clojure log - Jan 17 2014

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

0:00 chare: quizdr why do you always do that

0:06 gtrak: nrepl-complete drunk coding begins now.

0:13 quizdr: if cider uses nrepl, then why are things that are nrepl-based not always working in cider?

0:13 gtrak: quizdr: because suck

0:14 quizdr: because suck?

0:14 gtrak: well, what specifically? :-)

0:14 I'm just starting to dig into that stuff, it's a little messy.

0:15 but pretty neat at the same time.

0:16 quizdr: i see various "cider compatibility fixes" on mailing lists for emacs live, overtone, others.

0:16 gtrak: it seems like there's a loose spec but a lot of de-facto implementations of things.

0:16 it's just a young project.

0:16 we were all using swank a year ago.

0:17 hiredman: nrepl is a protocol, there was an an email nrepl client, called nrepl.el, which was renamed to cider

0:17 quizdr: yeah this the fastest moving dev tech i've encountered

0:18 hiredman: that rename broke things

0:18 quizdr: so it primarily a naming issue, not so much a major change in how things are done

0:18 gtrak: I'm noticing more cool than broken so far.

0:18 hiredman: it happend, I dunno, some time in the last six months

0:19 well, right after it was renamed, it was blown part in to a million files

0:19 gtrak: like it picks up the port from a file if you start a server outside of emacs.

0:19 hiredman: which definitely broke everything

0:19 and made to depend on some emacs packaging nonsense which depends on all kinds of other stuff and broke everyeones stuff

0:20 cark: an makes me type "cider clojure" instead of just "nrepl" in google

0:21 TEttinger: cark, you don't want yours "cider fix" from martinelli

0:23 hiredman: it is terrible, bbatsov(who is running nrepl now) seems to revel in maintaining things like style guides for clojure, without, as far as I can tell, having written any clojure

0:23 I mean cider

0:23 the (only?) nrepl server I know of is in contrib and the defactor standard of the protocol too

0:24 gtrak: they seem pretty friendly so far.

0:24 dsrx: hey now that's unfair hiredman https://github.com/bbatsov/praxis/blob/master/clojure/praxis/src/praxis/rot13.clj

0:24 cark: you can't tell if someone is doing lot's of clojure by just looking at github

0:25 dsrx: ^

0:25 hiredman: cark: "as far as I can tell"

0:26 dsrx: this 'richhickey' guy only has four original sources repos written in clojure on github, he's hardly an authority figure :P

0:26 hiredman: I write lots of clojure for work and for fun, and I have seen his stlye guide, and I was not impressed

0:26 gtrak: have you ever been impressed with a style guide?

0:26 hiredman: I just know some day someone is going to say to me "well the style guide says ..." and I am going to scream

0:26 seancorfield: Since this hot potato topic has come up, I'll side with hiredman and add my bitter complaints to the mess that bbatsov has created, IMO.

0:27 quizdr: take the google c++ style guide, for example. you'd think google knows a thing or two about writing software. but a lot of people disagree with their style points.

0:27 seancorfield: I have been extremely unimpressed with bbatsov's responses on the Clojure list about the stupid renaming of nrepl.el

0:27 dsrx: some of the google c++ style guide is there because of accidents of history at google specifically

0:27 gtrak: my company has a style guide too, I don't remember what's in it.

0:27 seancorfield: Basicually he says "Fuck you! - update your dev env!"

0:28 hiredman: never upgrade anything, never use anything that forces you to upgrade

0:28 quizdr: i'm sure this issue will be resolve at the next meeting of the clojure standards committee

0:28 seancorfield: Making a change that forces every single user to faff around like that is terrible

0:28 as hiredman says, it broke everything associated with nrepl.el

0:29 and it creates an unknown (non-zero) amount of work for every single user of nrepl.el for no good reason at all

0:29 dsrx: i guess i was lucky to have started with clojure just after it was renamed =)

0:29 seancorfield: The renaming was completely unjustified IMO

0:29 cark: i spent several hours completely redoing my emacs config

0:29 hiredman: I wonder if I can find the pr

0:29 cark: tho now it's working better than ever =)

0:29 hiredman: maybe it was an issue

0:30 seancorfield: Yeah, I don't want to migrate because it's not just me - it's my whole team

0:30 gtrak: it's always been pretty broken for me, but if I can figure it out within 30 minutes I don't blame anyone else, since I don't really care to learn elisp for real.

0:30 dsrx: hmm...

0:30 cark: btw is ritz fixed yet for cider ?

0:30 dsrx: if only emacs had some way of grouping functions and variables together into names, and then requiring those from some other code, but using them with a different name

0:31 quizdr: i just use other clojure devs emacs configs on github until i find one i like.

0:31 dsrx: you could call them 'namespaces'

0:31 gtrak: I'm still using the supposedly defunct 'starter kit'

0:31 quizdr: then i tweak it slightly to help my tired eyes with larger fonts

0:31 i think starter kit is in mine as well

0:31 seancorfield: cark: ritz works just fine with nrepl :)

0:31 cark: seancorfield: go ahead stab me some more

0:32 quizdr: i don't even know what starter kit supposedly is. i'm so lazy on IDE setup. Apple spoiled me with Xcode for many years.

0:33 cark: while we're bitching, what i don't like is the "war on" :use

0:33 and the fact it isn't available in clojurescript

0:33 gtrak: meh use is lame

0:33 Raynes: It isn't? Splendid!

0:33 hiredman: https://github.com/clojure-emacs/cider/issues/375

0:33 gtrak: it makes namespaces entirely incomprehensible if you didn't write themm.

0:33 hiredman: ugh

0:34 cark: there are many cases when you want to quickly model something, and use is very nice then

0:34 gtrak: when you work on a large codebase, you want to make 'explicit' easier.

0:34 :refer :all is still there.

0:34 you just have to know it's there.

0:34 hiredman: cark: :require :refer :all

0:34 cark: hah man, been working with clojrue for years now, and didn't know about that

0:34 Raynes: Yep.

0:35 gtrak: cark: good :-)

0:35 Raynes: If you want to purposely write bad code, Clojure lets you. Particularly because it's useful for tests.

0:35 gtrak: no one will yell at you for not using :refer :all

0:35 I will yell at you for using :use

0:35 hiredman: https://github.com/clojure-emacs/cider/issues/375#issuecomment-25488294

0:36 cark: well that's my point, sometimes you want to quickly throw something together to see if it will work, we're not always programming in the large

0:36 exploratory programming !

0:36 gtrak: mine has never suffered.

0:37 I'd rather use a one-letter alias than use

0:37 noonian: yeah, i use use from the repl all the time

0:38 gtrak: if I have a bunch of utils, I stuff them in a u/

0:38 cark: gtrak: hah ! now who's doing bad things !?

0:38 quizdr: hiredman that's an interesting thread, sheds light on both sides of the issue

0:38 gtrak: it's less bad, and it's explicit.

0:38 cark: =)

0:39 gtrak: cark: at least I know there's no chance of calling a function where I don't know where it came from.

0:39 if I have to move stuff out of the utility namespace, it's relatively easy to do so.

0:39 in practice, it doesn't get huge.

0:40 trying to learn some code where it has 20 namespaces 'used', even if 'only', is really really hard.

0:41 cark: my biggest clojure program uses only :use ... stopped updating it to new clojure version since the big contrib explosion

0:41 still works nice, but lein is frustratingly refusing to work like it used to !

0:41 gtrak: ah yea, I'm glad that happened though.

0:42 cark: funny thing is, the program compiles using ant, but i need lein to work with emacs =/

0:43 gtrak: the only trouble I've had since 1.3 is stupid tests relying on hashkey ordering.

0:43 because order of keys tends to be consistent, unless the algo changes.

0:43 cark: my old program is still on 1.2 =/

0:44 gtrak: if it's seq'd at some point... then order starts to matter.

0:45 hiredman: the first clojure program I ever "deployed" pre 1.0 is still out there cranking away, I don't even know if I still have the source, but the guy I wrote it for writes emails and complains if the server part goes offline

0:45 built using make

0:45 cark: haha make

0:45 ahwell true and tested =)

0:46 hiredman: technomancy did not release lein until sometime later

0:46 cark: my thing i started coding the day I managed to AOT compile a test program ...I think it was before 1.0 too ... not quite sure anymore

0:46 but i still have the source at least =) and maintain it still

0:48 tpope: omg at this nrepl.el rename thread

0:48 I thought the foreplay rename was contentious

0:48 chare: lets talk about making a game in clojure

0:50 cark: i don't think clojue is a good fit for games

0:50 quizdr: cark why not? have you read Land of Lisp? makes some neat examples of lisp for gaming

0:50 gtrak: what kind of games?

0:51 chare: what kind of game do you like

0:51 cark: clojure is quite fast, but there is nevertheless a penalty for using persistent data structures, you end up coding in a non idiomatic way

0:53 gtrak: I think it would be relatively easy to optimize immutable code

0:54 you wouldn't want to write a physics engine in it

0:54 cark: yes but there is a whole lot of hashing going on with clojure

0:54 chare: we aren't trying to make a super high end graphics game don't need full optimization

0:54 gtrak: cark: records?

0:55 cark: yes that works, but how about vectors ?

0:55 seancorfield: hmm, we have a couple of legacy :use clauses in some old tests but that's about it... and we have a handful of :require :refer :all clauses... but mostly we either :require :as or have a limited :require :refer

0:55 gtrak: arrays are there if you want them.

0:56 noonian: arrays and transients

0:56 cark: gtrak: exactly what i'm saying, non-idionatic =)

0:57 gtrak: cark: well, you can return a mutated array just fine, it's only if you pass the intermediate steps around that it gets to be a problem.

0:57 noonian: transients are pretty idiomatic i think

0:57 cark: noonian: sure

0:58 gtrak: I tried to do this in cljs, it didn't look too bad, but it was a little annoying.

0:58 cark: gtrak: still you can't go about cosning like crazy and expect to maintain a pristine 60fps

0:58 consing*

0:58 gtrak: cark: cons is probably not what you want ever.

0:58 cark: i mean allocating =)

0:58 gtrak: ah.

0:59 noonian: i use cons when i want to stick something on the front of a collection even if its a vector

0:59 gtrak: cache thrashing from linked lists is going to hurt in any language.

0:59 hiredman: in the lisp tradition "consing" is synonymous with "allocating memory"

1:00 cark: yes writing lisp is habit forming

1:01 i think sequences are "32 by 32" even for lists in clojure ?

1:01 hiredman: " still you can't go about [allocating] like crazy and expect to maintain a pristine 60fps"

1:01 which no one has ever argued with

1:01 gtrak: I've got a low-level background.. I would notice if I did something like that.

1:01 hiredman: cark: no, lists are linked lists

1:01 gtrak: that's a problem in java too.

1:01 cark: hiredman: was it seqs then ?

1:01 gtrak: but immutability just exacerbates it

1:02 cark: hiredman: i mean lazy seqs

1:02 hiredman: cark: seqs are an abstraction, there can be different implementions under the hood

1:02 by 32 by 32 you mean chunked seqs?

1:02 cark: that's the name

1:02 yes

1:03 hiredman: they can be, unfortunately

1:03 cark: i'm not a native english speaker, sometimes it's a bit hard to recall a word =)

1:03 gtrak: you probably don't want laziness either

1:04 cark: so yes there are many reasons to avoid clojure for games

1:04 gtrak: cark: I don't know man.. I'd use it for that.

1:04 I wouldn't force myself to write java for fear of writing myself into a corner in clojure.

1:04 hiredman: there are many reasons to avoid the jvm

1:05 gtrak: if that's the comparison.

1:06 cark: too bad though, because core.async would make for very readable code in a game (state machines everywhere)

1:07 quizdr: i can also think of many creative advantages to using clojure for games. but "games" is such a huge category. text games, high fps games, browser games, social games, turn-by-turn vs realtime, etc.

1:07 hiredman: a go ai

1:07 dnolen: quizdr: many of which Clojure(Script) would be perfectly fine for.

1:08 cark: well

1:08 dnolen: quizdr: playing around w/ React has made me realize you could probably be even make a ridiculous fast underlying engine that Clojure could idiomatically interact with

1:08 cark: there is more than the 60fps problem, there is also the huge memory footprint of clojure data

1:09 quizdr: assuming clojurescript has full HTML5 support, I can't see why you couldn't have very fast graphic performance in a browser with clojurescript, if you are targeting the web of course

1:09 gtrak: cark: I wouldn't use persistent data-structures for fast-changing state.

1:09 quizdr: after all the browser only sees javascript, right? so you get some major potential right there.

1:10 cark: is it you dnolen that showed me a long time ago a example of clojurescript doing a wolfenstein style labyrinth walk ?

1:10 quizdr: why would clojure data require more memory than any other program? it organizes memory differently, but why a larger footprint?

1:10 dnolen: cark: yes

1:10 cark: dnolen: that was pretty impressive, but if i recall you had to cram very much in a single function

1:10 dnolen: cark: just like the original JavaScript it was based on

1:11 quizdr: well clojure is very good at cramming a lot into a single function ;)

1:11 cark: haha macros upon macro ...to a 2Mb function

1:15 tutysara: tried the Facebook example in - https://github.com/ddellacosta/friend-oauth2-examples/blob/master/src/friend_oauth2_examples/facebook_handler.clj

1:17 It went to Facebook for auth and came back to http://localhost:3000/authlink, I had given access for the app in Facebook login, still getting - "Sorry, you do not have access to this resource"

1:18 what could have been wrong?

1:20 kakos: What is the best book for learning Clojure? I'm an experienced programmer with lots of experience with Lisp, Scheme, Haskell, Scala, and Java.

1:20 gtrak: kakos: joy of clojure

1:20 or clojure-programming if you want help with tooling and such

1:21 ddellacosta: tutysara: checking it out now, one sec.

1:21 quizdr: i've hit three clojure books, and the most accessible is by Stuart Halloway, a good balance between useful and beginner-friendly.

1:22 But the best i've seen for a truly deep look at the language is the OReilly book which could be a bit intimidating for some readers

1:23 kakos: quizdr: Well, beginner-friendly is not what I'm looking for. I've programmed CLisp for a couple of decades now, so I think I can advance beyond the beginner books. I want a book that is both a good and quick introduction to the language as well as one that can be a great reference down the road.

1:24 gtrak: kakos: joy of clojure is the most philosophical one

1:24 I've heard clojure programming is good otherwise

1:24 that's the o'reilly

1:24 quizdr: yes the oreilly is quite a book

1:25 kakos: Looks like a new version of JoC is coming out in Feb

1:25 quizdr: Joy of clojure and also clojure in action, and also Halloway's book, are all due out now or in the next couple months with second editions

1:25 gtrak: the manning MEAP on the first edition is how I learned

1:25 quizdr: the one book to definitely stay away from is the Apress book

1:26 testclo: r is an nested lazy seq like ( (...), (...)), it was got by map function which is compuation intensive, so I tried to use future to get the work done, and then combine the data, but the future doesn't work: after defind the following statement, upc is idle, when I use @r1 to defer, then it begins to work and upc is high, but I don't want it to calculated lazy, is that doable?

1:26 (def r1 (future (vec (first r))))

1:26 (def r2 (future (vec (second r))))

1:26 (def r3 (future (vec (take 3 r))))

1:26 kakos: What version does the O'Reilly book cover?

1:26 quizdr: the Oreilly book is about 1.5 years old

1:26 kakos: That's a shame. Apress has put out a few books I really liked

1:27 quizdr: it's very much hit or miss with Apress. they named it "practical clojure" trying to ride on the coatails of "practical common lisp" which was a runaway hit. but the clojure book is just a waste of time

1:27 kakos: PCL was an amzing book

1:28 quizdr: i agree

1:28 ddellacosta: tutysara: sorry, not sure what is up, I'm getting the same thing. May take me some time to figure out and I can't do so now--I'll put something in github issues and update it ASAP.

1:29 clojurebot: In Ordnung

1:30 tutysara: ddellacosta: okie, sure... was it working before with Facebook login?

1:31 kakos: Thanks for the info, gents.

1:31 quizdr: do I understand correclty that use of "recur" without use of "loop" still guarantees tail call optimization?

1:31 ddellacosta: tutysara: it was the last time I tried it, probably a few months ago. I suppose it's possible that something changed with Facebook, but not sure right now what it would be. Will investigate when I have time.

1:31 tpope: quizdr: correct

1:31 quizdr: tpope thanks

1:32 tutysara: ddellacosta: let me take a look at the google wf if that is working

1:32 ddellacosta: tutysara: okay

1:33 dnolen: kakos: O'Reilly book is pretty much up-to-date as far as language, it's changed little, perhaps some of the tooling and library stuff needs updating

1:34 quizdr: there are some examples in the oreilly book which kinda blew me away in terms of algorithm design

1:39 chare: does anyone know a list of all dynamically typed functional languages besides clojure

1:40 echo-area: I don't know a whole list, but Racket is one of them

1:41 http://docs.racket-lang.org/ts-guide/

1:42 chare: I'm wondering what other dynamically typed functional languages look like, racket is too similiar to clojure

1:44 TEttinger: http://altjs.org some of these are functional...

1:52 dnolen: chare: Racket is pretty multi-paradigm

1:52 chare: dnolen: i'm looking for what other dynamically typed functional languages look like not another lisp like language

1:52 tutysara: ddellacosta: same error with google authentication as well

1:52 ddellacosta: tutysara: okay, will take a look when I have time

1:53 gtrak: success...

1:53 ddellacosta: tutysara: probably some basic configuration I'm forgetting about right now

1:53 tutysara: and it works for you with other providers?

1:54 tutysara: ddellacosta: I tried with Facebook

1:54 ddellacosta: tutysara: weren't you using the github example yesterday?

1:54 tutysara: and google and got the same errors

1:55 ddellacosta: I had my own errors configuring Github, I will try that again and update you

1:55 ddellacosta: tutysara: okay

2:00 gtrak: tpope: progress, works in emacs with slight modifications.. https://github.com/gtrak/nrepl-complete/blob/master/src/nrepl_complete/middleware.clj

2:01 ddellacosta: tutysara: sorry I know the issue

2:01 gtrak: tpope: cljs is next, I'll let you know how I figure out piggieback detection.

2:01 tpope: gtrak: sweet

2:01 ddellacosta: you need to define a credential-fn to associate the role with the token

2:01 tutysara: ddellacosta: with github also same thing, i noticed it is not going to acces_token url

2:01 ddellacosta: ohh okie, great :)

2:02 ddellacosta: tutysara: take a look at the test app in the friend-oauth2 tests here: https://github.com/ddellacosta/friend-oauth2/blob/master/test/friend_oauth2/test_helpers.clj#L65-L67

2:03 tutysara: I'll update the examples with this ASAP. In the meantime that should get you going. Sorry I forgot that, and thanks for testing this out and exposing the issue!

2:04 tutysara: ddellacosta: thanks, yrw

2:45 ddellacosta: thanks everything started working

2:46 ddellacosta: tutysara: great.

2:46 tutysara: just saw you added a new pull request, had github changed some settings recently?

2:46 tutysara: ddellacosta: may i know what is the use of config-auth option for workflow

2:46 quizdr: in emacs how do i see the full path of the file i have open in a buffer?

2:47 tutysara: ddellacosta: not sure, but I had to change :access_token to :access-token and add a :identity key to extract the token

2:49 peterdon: quizdr: I use C-x C-v to see the full path

2:49 ddellacosta: tutysara: hmm, strange...I'll check it out. re: config-auth, deprecated as far as I know. Will update examples.

2:51 quizdr: I don't know how to get the file path but you can do M-x pwd for the working directory. The filename of course will be listed at the bottom above the mini-buffer.

2:52 peterdon: nice, didn't know that one...

2:52 quizdr: ddellacosta perfect, exactly what I needed

2:52 squidz: has anybody gotten om working with lighttable?

2:52 quizdr: the emacs channel ignored this rather basic question ;)

3:06 piranha: squidz: not yet, I suppose https://github.com/swannodette/om/issues/58 is a problem

3:16 logic_prog: core.async makes programming fun again

3:16 making every thing go "hmm, I should make this into a go process" is like learning how to program all over again

3:21 what's a good name for a global queue

3:21 that everything throws stuff on

3:21 i'm thinking of calling it "backbone"

3:22 TEttinger: "pile"

3:23 all praise ztellman! My game has excellent performance even on -client JVMs, thanks to primitive-math issuing at least 400 warnings about reflection in math

3:23 and fixing all of them by hand...

3:23 quizdr: i thought for sure I saw something once about the unless function, but I don't see it in the API docs, was I mistaken?

3:25 TEttinger: quizdr, that's like a (when (not condition) body) right?

3:25 quizdr: yeah

3:26 easy enough to implement on one's own but I thought it was in a book I read. maybe not

3:26 TEttinger: ,(defmacro unless [pred body] `(when (not ~pred) ~@body))

3:26 clojurebot: #'sandbox/unless

3:27 TEttinger: ,(unless (= 1 2) (str "whee"))

3:27 clojurebot: "whee"

3:27 quizdr: or (defmacro unless [test & branches] (conj (reverse branches) test 'if))

3:28 fredyr: ,(when-not (= 1 2) (str "wow" "such" "doge"))

3:28 clojurebot: "wowsuchdoge"

3:28 quizdr: ,(defmacro unless [test & branches] (conj (reverse branches) test 'if))

3:28 clojurebot: #'sandbox/unless

3:28 quizdr: whoops i just overwrote yours

3:28 ,(unless (= 1 2) (str "whee"))

3:28 clojurebot: nil

3:28 TEttinger: hm

3:29 quizdr: ,(macroexpand '(unless (= 1 2) (str "whee")))

3:29 clojurebot: (if (= 1 2) (str "whee"))

3:29 fredyr: ,(macroexpand-1 '(when-not (= 1 2) (str "wow" "such" "doge")))

3:29 clojurebot: (if (= 1 2) nil (do (str "wow" "such" "doge")))

3:30 quizdr: ,(unless (= 1 2) (str "yo") (str "not yo"))

3:30 clojurebot: "yo"

3:31 quizdr: two different interpretations of unless, i guess

3:32 amalloy: unless is just when-not

3:33 quizdr: ah ok

3:33 TEttinger: ,(def unless when-not)

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

3:33 TEttinger: :-(

3:36 quizdr: that's interesting

3:41 chare: does lisp and scheme have functional data structures like clojure does?

3:43 TEttinger: yes. not the same of course, it's never the same

3:43 chare: so how do their immutable data structures work?

3:43 compared to clojure

3:43 TEttinger: they don't have immutable one usually

3:44 clojure's pretty unique in the immutable persistent data types, except for stuff like haskell and maybe some ML variants

3:45 chare: but if you have a list A and you cons onto it to get a list B you can refer to both A and B, in that sense lisp and scheme have persistent data structures?

3:45 TEttinger: I've never used common lisp, from what I understand it has a lot of mutable data types

3:46 quizdr: yes common lisp is totally imperitive if you want to use it that way.

3:46 Raynes: TEttinger: https://www.youtube.com/watch?v=y9zp16GJeDY

3:46 quizdr: mutating data is the normal thing to do

3:46 in cl

3:47 in common lisp I found it very confusing, however, not that the data itself was mutable, as that is easy to understand, but rather, some core functions would mutate data and others would return new data, and it was never clear unless you just memorized which did which

3:48 Pupnik: TEttinger: popular languages usually have a lib with persistant data structures

3:48 quizdr: much easier when you know that all functions (except those with exclamation points) are returning new data, and all data is immutable unless you opt in with an agent or atom, etc

3:49 TEttinger: true, Pupnik

3:55 chare: ok so in lisp how do you do the equivalent of this haskell code foo :: [Int] -> ([Int], [Int]) foo list = (list, 5:list)

3:57 you guys know how to at least do that in clojure right?

3:59 ucb: so foo is a function that takes a collection of Int and returns a pair of two collections of Int, where the first element in the tuple is the original collection, and the second is the collection with the first items dropped?

4:00 chare: ^

4:00 chare: what no?

4:00 thats a cons not a drop

4:00 ucb: oh, right, sorry, haskell is not my strongest suit

4:00 I interpreted 5:list as pythons slice operator :)

4:01 in any case, this should do the trick (fn [coll] [coll (cons 5 coll)])

4:01 chare: and thats guaranteed not to create a copy of the list?

4:02 ucb: I'd think so

4:02 chare: what do you mean you "think"

4:03 ucb: I mean I'm not entirely sure but that I think that's the case.

4:04 chare: how can you not be a lisp expert!!!!

4:05 ucb: chare: have a good day.

4:05 fredyr: chare: it is a persistent structure

4:05 so if will share the list

4:05 and not copy it

4:06 chare: but it will let you edit the list unlike clojure right?

4:06 fredyr: unlike clojure?

4:07 if you mean unlike haskell, so no

4:07 kaw: Are you asking about Common Lisp?

4:07 chare: i mean clojure

4:07 clojure got immutable lists right

4:08 fredyr: so you're talking about common lisp?

4:08 chare: yes

4:08 fredyr: ok

4:08 so then it is mutable by default

4:08 but for cl questions there are better channels i would guess

4:11 quizdr: i was quite impressed with common lisp until i looked at clojure.

4:11 now i really do see what all the fuss was about with clojure.

4:12 Noinafara: Where can I read about clojure idioms for designing an application?

4:12 I worry that my application, when I get to writing it, might well be "classical Object Oriented" - probably some variant of MVC/MVP.

4:12 quizdr: Noinafara that's a rather broad question. the clojure "way" is well written about in several books.

4:13 Noinafara: quizdr: Any websites you can recommend?

4:13 quizdr: books, yes. depending on your background, the OReilly book or Halloway's book

4:15 Noinafara: My background is mostly python, C++ and delphi.

4:15 But $30 for a book is remarkably cheap - don't have the budget for one at the moment, but for $30, maybe...

4:15 amalloy: halloway's book is *really* old. i wouldn't recommend it to anyone picking up the language now

4:15 khaled: lol

4:15 quizdr: i'd recommend the Pragmatic Publisher's book by Halloway -- the second edition, not the first that amalloy mentions

4:16 the second edition was just released a few days ago actually

4:16 khaled: how can you be in the computing world and crying like a child for money you dont have

4:16 Noinafara: Hmm, THe O'reilly one is a beginner one.

4:16 khaled: No, it's just that this is far down the list of priorities at the moment.

4:16 khaled: lol, i dont give you the clue of how get every book you want

4:17 quizdr: OReilly is a deep read. If you are totally new to the language, you might get a bit further faster with the basics using Halloway's book.

4:17 khaled: because it's not fair for the wrtiter, and you have to grow up and be able to find resources on the big world of the internet

4:18 amalloy: quizdr: Programming Clojure 2e by halloway appears to be from 2012. where do you see it a few days old?

4:18 quizdr: amalloy i have it let me check

4:18 Noinafara: No, I mean, O'Reilly is more of a reference, I'm after _idioms_ and _design_.

4:18 amalloy: amusingly, http://www.amazon.com/Programming-Halloway-published-Pragmatic-Bookshelf/dp/B00E6TU47U thinks it is over 2000 years old

4:19 Raynes: amalloy: Wow, the only part of Stuart that has aged past 35 is his hair.

4:19 Noinafara: No, I think what I really want is a patterns book.

4:19 Raynes: Wouldn't think him to be 2000 years old.

4:20 khaled: Noinafara: go on youtube and type clojure you will find so much presentation and video tutorial by the author of books and clojure language inventor

4:20 Noinafara: I don't like videos.

4:21 quizdr: amalloy you are right, it is a different book by the same publishers about Clojure web development that was just released last week. the 2nd edition Halloway book is not that old though, same as the Oreilly, they cover the major additions to the language since the first edition

4:21 khaled: rick hickey in a vido it's not a video it's peace of geniuosity

4:22 amalloy: yeah, 2nd edition isn't *that* old. i didn't realize there was a second

4:22 Noinafara: khaled: Unless it's subtitled, the video isn't much use to me.

4:22 quizdr: Noinafara incidentally you'll read in these books about how "design patters" are not that useful as they are in object oriented programming, where design must be crafted a lot more around state considerations that are much better by default in clojure

4:23 the one book to steer clear of is the Apress book, but most others are in pretty good shape, and second editions of two well-known books (joy of clojure and clojurein action) are coming out in the next couple months

4:23 Noinafara: quizdr: Even so, one must organise the code.

4:23 khaled: just this video is a "chef d'oeuvre" of two big mind http://www.youtube.com/watch?v=wASCH_gPnDw

4:24 quizdr: well, do as you wish, but these are some good recommendations.

4:24 Noinafara: I'm taking note of their TOC's. :)

4:32 chare: I just got banned from #lisp for saying clojure > lisp

4:36 wedr: chare: dont start flamewars :-)

4:36 chare: you guys agree i'm right?

4:36 chavezgu: chare: clojure is a lisp.

4:36 clojure is not common lisp but, it is a lisp. "Clojure is a dialect of Lisp, and shares with Lisp the code-as-data philosophy and a powerful macro system."

4:37 chare: its lisp++

4:37 kzar: what's with the #clojure trolls recently? :(

4:38 * kzar uses /ignore again

4:41 khaled: can i use leiningen as a replacement of ant/maven/gradle even if my project is not composed by clojure codes?

4:43 chare: omg this is the thing i hate about java ecosystem, wtf is the difference between ant maven and gradle

4:43 quizdr: khaled it's a free country. just kidding. leiningen does automatically work with clojure dependencies, i wouldn't think it makes sense as the ideal tool if you're not using clojure

4:44 khaled: quizdr: ok, thanks for your advice

4:45 chare: lol, it seems you are not comming from the java world ;) anyway welcome to the jvm world

4:46 chare: khaled explain

4:48 khaled: chare: ant+ivy/maven/gradle are the defacto standard of the java build tools even if there are not standardized(by a jsr), and the fact you dont see see difference means you cannot comming from the java world that's all that's is

4:48 it

4:49 chare: so tell me about java world

4:49 john2x: ping bitemyapp.. got a question about revise

4:51 khaled: chare: what kind of story do you want to here, i could give you some "fable"(kids stories) like "Grimm Tales"

4:52 -here+ear

4:52 chare: JUST TELL

4:52 khaled: ansel and gretel ?

4:52 chare: be serious pleaz or specific to allow us to have a productive talks

4:54 warpy: khaled: why are projects moving from maven to gradle? how is it superior?

4:54 chare: so I come from haskell world khaled you gotta start from the beginnings of java world

4:55 warpy: chare: ant, maven, gradle are build tools like cabal

4:56 they are based on different philosphies and hence have different ways of working and different feel

4:56 khaled: warpy: some... only some, because the xml config is less hackable than a grooy dsl, and the build lifecycle is not seen in the same philosophy, in gradle everything turn around the task

4:56 warpy: but essentially they just compile the java code

4:56 chare: wtf how did it end up with 3 build tools

4:57 warpy: chare: because java has a big community and different people created different tools as per their own philosphies

4:57 khaled: chare: clear and simple because this had not been standardized by a jsr

4:57 warpy: khaled: so, gradle = ant + groovy?

4:58 khaled: warpy: to be simple when you target the jvm you see like this

4:59 +can

5:00 and each tools came at different time, some are evolution other are revolution

5:01 chare: ok so to setup what do I download i download eclipse, then somehow get clojure working????, then get which of ant maven and gradle?

5:02 khaled: chare: sorry i could not figure you was coming from other than the jvm world, cause in my mind every clojuriste of aprenti are a java programmer

5:02 chare: you can use simple text

5:02 warpy: chare: you dont *need* eclipse for clojure. and leiningen is the defacto build tool

5:03 khaled: chare: sorry not simple text , but sublime text

5:03 chare: i found it the best text editor, but if you are a emacs user , take emacs

5:04 quizdr: khaled clojure programmers are likely either java programmers or common lisp programmers. i fall into the latter groups. i've never written a line of java in my life.

5:05 warpy: chare: i also use sublime text + leiningen

5:05 fredyr: quizdr: i see a venn diagram joke opportunity with that partitioning :)

5:05 warpy: emacs is too complicated for me ...

5:05 khaled: chare: http://sublimerepl.readthedocs.org/en/latest/

5:06 warpy: he same for me

5:06 +t

5:07 fredyr: tbh i use to be the same

5:07 but paredit was what won me over to emacs

5:07 *used

5:07 warpy: maybe i wrote clojure professionally, i'd give emacs a try

5:08 fredyr: i went a weird route, sublime -> vim -> emacs -> emacs/evil

5:08 khaled: the probleme with emacs if you did not learned it at school or having a peer to surround you, the learning curv is too hard comparing to intellij+lacjure eclipse+plugin sublim+repl

5:09 the fact is that emacs is just a beast when you dompted this animal

5:10 warpy: true

5:10 i am yet to try eclipse + ccw

5:10 how does it compare

5:10 fredyr: its pretty good i would say

5:10 warpy: to other setups

5:10 khaled: warpy: you 'll gain nothing by moving from sublim to eclipse

5:11 warpy: thats what i feared and i stuck to subl

5:11 khaled: you 'll just lost 1go of ram and 2minutes every restarting

5:11 fredyr: lol

5:11 ior3k1: khaled: I'm not sure if I agree with your statement about Emacs' learning curve. I think the only "weird" thing is that you use the language (lisp) to configure the editor

5:11 warpy: well, i use eclipse all the time anyway ...

5:11 * warpy <- java programmer

5:11 ior3k1: coming from other editors, I expected there to be a dsl to configure emacs

5:12 clgv: warpy: I work with it since more than 3 years

5:12 fredyr: warpy: then you won't have problems with project setup and such, so i think eclipse might be an advantage then

5:12 also iirc the repl evaluation was a bit smoother in ccw

5:12 amalloy: ior3k1: you're arguing elisp isn't a dsl?

5:12 fredyr: than sublime-repl

5:13 ior3k1: amalloy: not at all, it didn't seem a dsl at the time... for example, if you compare it with how vim does it

5:13 amalloy: it's hard to explain... it feels more... down to the metal

5:13 khaled: eclipse is just a piece of ish in term of usability, even if its architecture/ecosystem is a wonderful

5:14 quizdr: i find emacs quite a joy to use, but its in the setup and config of emacs that i really lose patience. if you use an existing emacs config that works, that really helps. actually using emacs is not that hard, though.

5:14 khaled: intellij is just the IDE

5:14 intellij com ed+laclojure if for me better than eclipse

5:14 warpy: i am just used to eclipse

5:15 ior3k1: quizdr: I agree with the "joy" part. I have no problems configuring it as well

5:15 warpy: have nothing against intellij

5:15 khaled: i hace everyting against eclipse

5:15 lol

5:15 quizdr: configuring emacs with various dev packs, scripts, etc, can get a bit messy wrap your head around

5:16 clgv: warpy: you know that you can just download a CCW standalone to try it quickly

5:16 ior3k1: quizdr: interesting, I never felt that, once I got into the "right" mindset

5:16 I don't even use package.el

5:16 clgv: warpy: for integration in your current eclipse the plugin path is the way to go.

5:17 chare: wtf where is ubuntu ppa for latest eclipse

5:17 quizdr: putting all the moving pieces together, nrpel, various editing modes, paredit, etc, it's certainly more than most IDEs

5:17 khaled: chare: stop right now

5:17 chare: dont use any java thing from ppa

5:18 only openjdk

5:18 chare: dowload eclipse from the website

5:19 warpy: clgv: i'll check it out next time i do something in clojure

5:19 clgv: chare: eclipse is an easy manual download ;)

5:19 chare: why openjdk over oracle jdk

5:19 khaled: unpack and fix your .profile .bashrc to give the global env who could be need

5:19 clgv: chare: why the other way around?

5:21 khaled: chare: because oracle jdk is not distributed in default ppa

5:22 Southy: openjdk and oracle jdk are so similar now, from Java 8 they will be exactly the same as openjdk are developing project lambda

5:22 khaled: you'll only find openjdk who is the OSS project where oracle jdk is not OSS even if it's free

5:24 rohni: quizdr: Which is to be expected, emacs is an OS not an IDE and has various package managers to help you out, e.g. el-get ;)

5:27 clgv: rohni: yeah, emacs would be such a great OS if it only had a decent editor ;)

5:27 kzar: ...

5:28 khaled: definetly, the editor is coming from another age

5:28 Southy: Problem is that none of the other editors have the functionality. LightTable is probably mu best hope for a 'modern' clojure editor

5:28 khaled: the only text editor i can stand who run into the terminal is nano

5:29 chare: I WANT ECLIPSE NOW


5:29 clgv: chare: eclipse for clojure dev?

5:29 khaled: Southy: for me, the best clojure editor who will come is the intellij based ide

5:30 chare: what else would I need eclipse for?

5:30 khaled: http://cursiveclojure.com/

5:30 Southy: khaled: that will be nice, I use intellij for all my java development, but it will cost, where LightTable is now open source.

5:30 clgv: chare: windows/linux? 32/64Bit?

5:31 chare: anyway choose for yourself http://doc.ccw-ide.org/documentation.html#_install_counterclockwise

5:31 khaled: Southy: no it's based on the community edition so it's free as a free beer

5:32 Southy: khaled: what you mean next time it's my round? :P

5:33 Cursive will be available as an IntelliJ plugin for use with the Community or Ultimate editions, as well as a standalone Clojure-focused IDE. It will be a commercial product, at a similar price point to PyCharm or RubyMine.

5:33 ^ From the website you linked

5:33 so only free as the plugin version, not the standalon

5:33 e

5:34 khaled: have you used the EAP version?

5:35 khaled: Southy: yes

5:35 Southy: is it stable/usable?

5:35 khaled: Southy: very usable

5:35 Southy: I might give it a go

5:56 tutysara: can we use two workflows with friend say to allow outh login using either google or Facebook login?

5:57 ddellacosta: can we do something like use either Facebook or google outh to authenticate using friend-ouath2

6:01 katox: is it possible to use cljx with cider-test?

6:02 the tree structure is something like src/clj/ns1 src/cljs/ns2 src/cljx/ns3

6:02 I thought that if I mirror that in test dir, the mode would work but apparently not

6:02 ddellacosta: tutysara: I'm sure there's a way but I can't think of a simple method off the top of my head, unfortunately.

6:02 katox: does anyone know what to change in .el?

6:04 ddellacosta: tutysara: would be work building a demo to give it a shot though.

6:04 *worth

6:06 tutysara: ddellacosta: ;), I am thinking of passing multiple uriconfig to outh2/workflow function in a map and using the "GET /login" to show the different providers and set them in request before posting to "/login", then read the provider and use them in redirect-to-provider! and request-token functions

6:07 ddellacosta: just an initial thought, haven't gone through the code much

6:08 ddellacosta: tutysara: yeah, I'd have to dig into it again to give you a good answer, and I can't at the moment...your questions have provoked me to look at code I haven't thought about deeply in a few months. ;-)

6:09 tutysara: but I suspect it is possible.

6:11 tutysara: ddellacosta: agh great :). I can try doing this and see if it works, if you have some ideas on how this can be done please get back to me when you find some time

6:12 ddellacosta: tutysara: sure--add an issue to friend-oauth2 to keep it on my radar, will you?

6:12 tutysara: ddellacosta: sure will do that, thanks

6:12 ddellacosta: tutysara: thanks!

6:22 noidi: ,(java.nio.file.Paths/get (into-array ["lol"]))

6:22 clojurebot: #<ClassNotFoundException java.lang.ClassNotFoundException: java.nio.file.Paths>

6:22 noidi: ,(import 'java.nio.file.Paths)

6:22 clojurebot: #<ClassNotFoundException java.lang.ClassNotFoundException: java.nio.file.Paths>

6:22 noidi: anyway, that results in a ClassCastException [Ljava.lang.String; cannot be cast to java.net.URI

6:23 Paths has two arities, but for some reason Clojure picks the wrong one and then complains that the cast fails http://docs.oracle.com/javase/7/docs/api/java/nio/file/Paths.html

6:23 how can I make it call the right method?

6:27 clgv: ,(System/getProperty "java.version")

6:27 clojurebot: #<SecurityException java.lang.SecurityException: denied>

6:28 clgv: noidi: you need to give an explicit first argument there

6:31 noidi: that should work (defn paths [^String path & more] (Paths/get path ^"[Ljava.lang.String" (into-array String more)))

6:32 skip the type hints if you like since they are not needed

6:35 noidi: thanks

6:35 it's still strange that Clojure picks the wrong method when called with one argument

6:36 clgv: noidi: it does not. it picks the only available method with arity 1

6:36 noidi: the other one you intended to use has arity 2

6:36 noidi: the whole variable args in java is just compiler magic ;)

6:37 noidi: ah, right

6:37 makes sense

6:37 clgv: noidi: String... just means String[] on JVM level

6:37 ah not even that but Object[]

6:37 noidi: I misread the javadoc

6:37 as taking 0..n arguments

6:58 nicl: What does & {:as something} do in function parameters?

6:58 very-curious-pro: http://programmers.stackexchange.com/questions/224512/lisp-clojure-replace-parentheses-with-indents

6:58 nicl: I know that & allows binding all further arguments. And I know :as can bind a symbol to all parameters collectively. But what does it do within curly braces?1

6:58 !

7:00 rmrfchik: are there non-greedy regexps? now (re-seq (re-pattern "X.*Y") "XfY X6Y")

7:00 gives ("XfY X6Y"), and I want ("XfY" "X6Y")

7:03 peterdon`: ,(re-seq (re-pattern "X.*?Y") "XfY X6Y")

7:03 clojurebot: ("XfY" "X6Y")

7:06 peterdon`: rmrfchik: use .*? to make it non greedy

7:06 rmrfchik: peterdon`: thanks!!!

7:07 very-curious-pro: http://programmers.stackexchange.com/questions/224512/lisp-clojure-replace-parentheses-with-indents

7:10 progo: yeah. How about no :)

7:30 quizdr: if i pass a list or anything that isn't a vector to a destructuring form like [[a]] that clearly expects a vector, it works; does this mean that vec is implicityly getting called on the argument?

7:41 ro_st: dnolen: quick question - are om/transact! and om/update! meant to be used outside the root? or else can we mutate the atom directly and expect om to do the right thing?

7:45 rurumate_: ,"test"

7:45 clojurebot: "test"

7:46 jjcomer: nicl: The & {:as something} trick is use to group the extra params into a map. So (f :a 1 :b 2 :c 3) would bind the map {:a 1 :b 2 :c 3} to "something"

7:47 nicl: jjcomer: nice, thanks.

7:48 chare: quizdr do you eat at quiznos?

7:48 ro_st: so you can (fn [& {:as kwargs}] …) and kwargs will be a map?

7:48 jjcomer: ro_st: yup!

7:48 ro_st: that rocks

7:51 chare: someone buy me pepperoni pizza

7:51 i'm hungry

7:51 are you hungry?

7:51 quizdr: since we are talking about desturing, i'll repeat my question from earlier: if i pass a list or anything that isn't a vector to a destructuring form like [[a]] that clearly expects a vector, it works; does this mean that vec is implicityly getting called on the argument?

7:57 fredyr: ,(macroexpand-1 '(let [[a b] [1 2]] (+ a b)))

7:57 clojurebot: (let* [vec__27 [1 2] a (clojure.core/nth vec__27 0 nil) b ...] (+ a b))

7:58 fredyr: quizdr: ^^

7:58 quizdr: it just expands to nth

7:58 quizdr: ah, i see

7:59 sveri: hi, I am trying to figure out how to work with cheshire, when i use the "parse-string" function of it i get back a PersistentArrayMap and i dont really have a clue how to work with it, does someone have example code where i could look how to do it?

8:00 quizdr: fredyr that's a nice trick for understanding implemenations with macroexpand even if you arent writing a macro. i dig it

8:04 tcrayford: sveri: that's just a map, you work with it like any other map in clojure

8:04 If that's confusing to you, I guess you should go look at some beginner tutorials

8:06 jjcomer: sveri: I know one gotcha with cheshire is that it will parse json keys to strings unless you use (parse-string json-str true) which will use keywords

8:06 tcrayford: note that if you're parsing arbitrary user data, you always want to parse to strings

8:06 otherwise you can cause some "interesting" GC problems for your jvm

8:07 jjcomer: very true :)

8:07 sveri: jjcomer: thanks for the hint, thats one thing that bugged me

8:07 that i could not use keywords

8:08 fredyr: quizdr: yes it is :)

8:08 tcrayford: sveri: note 99% of the time, unless the json source is completely trusted, you want strings anyway

8:08 sveri: tcrayford: thank you too, i read a lot of tutorials and i am on my second book already, but without some hands on experience its hard to connect the dots

8:09 tcrayford: but isnt it easier to work with using keywords?

8:09 tcrayford: sure is, but it won't cause your JVM to crash

8:09 (as in, keywords can, strings won't)

8:10 sveri: tcrayford: ok, that makes sense, so to get soemthing out of it i have to use (get map "key"), right?

8:10 tcrayford: yeah

8:11 sveri: ok, thank you all very much :-)

8:11 tcrayford: or you could convert a safe set of the json keys to keywords (which is what I usually end up doing)

8:11 like, parse json, do select-keys, then just convert toplevel keys to keywords

8:12 sveri: tcrayford: ok, i may try that later :-)

8:13 jjcomer: sveri: Instead of 'true' you can pass in a function for key parsing, into which you could build in some defensive parsing

8:26 borkdude: what is the opposite of select-keys

8:27 tcrayford: borkdude: what do you mean?

8:27 borkdude: tcrayford I mean, remove keys from a map

8:27 key-vals

8:27 tcrayford: not sure there's an inbuilt for that specifically

8:27 guess you can just use filter though

8:28 borkdude: sure ok

8:28 cemerick: ,(dissoc {:a 5 :b 6 :c 7} :a :c) ; borkdude: what about this?<<

8:28 clojurebot: {:b 6}

8:28 tcrayford: haha, welp

8:30 borkdude: lol

8:31 That is what you get when you don't program Clojure for 3 months... #crying

8:32 tcrayford: I've been nearly full time in clojure since uh, before leingingen existed, and I forgot it :/

8:32 am currently all up in the guts of lein uberjar spitting out corrupt jars during downtime though, so not toooo surprised

8:34 ddima: borkdude: personally I always have a laminated version of the clojure cheat-sheet on my table ;)

9:22 qerub: Is there any way to disable Leiningen's standard JVM switch `-XX:TieredStopAtLevel=1` when using `lein try`?

9:23 Ah, unsetting LEIN_JVM_OPTS might work… D'oh.

9:23 tcrayford: you can also use ^:replace

9:24 qerub: Ah, yes. Thank you qerub. :p

9:24 tcrawley: I have no project.clj when using `lein try`.

9:24 tcrayford: oh, haha

9:24 true

9:25 tcrawley: tcrayford: again? one of us has to go.

9:25 tcrayford: haha

9:26 qerub: tcrayford, tcrawley: Oh, sorry about that. But yes, one of you has to go. ;)

9:26 tcrawley: qerub: heh, no worries

9:28 hyPiRion: qerub: yeah, the trick is to do `export LEIN_JVM_OPTS=''`

9:30 clgv: qerub: why is that jvm option important if you are only trying something?

9:31 qerub: clgv: I like to use `lein try criterium some-library-a some-library-b` for one-off benchmarking.

9:33 Like here: https://gist.github.com/qerub/8031665 (Anybody else find that result surprising BTW?)

9:34 hyPiRion: clgv: it's because Clojure programs are very slow to startup, so Leiningen uses some specific options to speed up startup at the sacrifice of advanced optimisations. Some JVMs don't have those options available, and sometimes you want those advanced optimisations

9:35 clgv: qerub: just add criterium to ~/.lein/profiles.clj

9:35 hyPiRion: I know. I was just curious about his motivation.

9:36 hyPiRion: ah

9:36 qerub: [cont.] I'd expected commons.lang3.StringUtils.split(Char) to beat Pattern.split(String)…

9:36 clgv: Yeah, I could do that. Thanks.

9:37 Oh, damn, I should avoid reflective calls.

9:38 clgv: definitely

9:39 qerub: I'd incorrectly assumed that Clojure would infer all the needed types.

9:39 *rebenchmarking*

9:39 clgv: not in interop when there are overloaded methods

9:40 with same arity

9:40 hyPiRion: yay lein check

9:41 qerub: I had (def test-input "a string") and (org.apache.commons.lang3.StringUtils/split test-input \.) and had assumed test-input would be annotated as ^String automatically.

9:42 clgv: hyPiRion: yeah I had an alias for the same task until a few weeks ago when I noticed there has been added a lein task to do that

9:46 AeroNotix: grrr emacs is segfaulting

9:46 I have some plugin which makes it segfault

9:46 not sure which one

9:46 clgv: lol I first thought the purpose of the plugin is to segfault it :P

9:47 AeroNotix: yeah that'd be pretty useful

9:47 M-x segv

10:23 daGrevis: i'm trying to re-implement if as a macro just for fun

10:23 this is what I have so far http://vpaste.net/eTtpA

10:23 why isn't get call returning correct quoted-expr?

10:26 jcromartie: you need to quote the return value of your macro

10:29 daGrevis: jcromartie, something like this? http://vpaste.net/RplCu

10:32 shafire: hi

10:33 do you have noticed differences running clojure on openjdk7 or oracle jvm7?

10:33 coventry: daGrevis: That evaluates both branches.

10:34 daGrevis: coventry, nop, no branch is evaluated

10:37 coventry: You're right, neither branch appears in the macro output, which is also a problem. :-)

10:39 daGrevis: coventry, http://vpaste.net/b5scV i get correct cond returned. don't know how can I say to eval it instead of returning it thought :(

10:39 clojurebot: Excuse me?

10:40 cark: doing a map lookup for an if expression is kind of heavyweight =)

10:42 daGrevis: cark, that's not the point here. :P just wanna see if I can really implement if. that would be so awesome! :)

10:42 cark: =)

10:44 daGrevis: lol any help

10:46 tutysara: sritchie: hi, I was able to run the examples from friend-oauth2, we were missing the credential function and after correcting that, things were fine

10:46 sritchie: nice

10:47 make sure it works with a failed auth too

10:47 maruks: why is fn a macro ? (macroexpand '(fn [x] x)) => (fn* ([x] x))

10:47 tutysara: sritchie: i haven't tried a failed login, thanks for bringing that up, let me try that. any luck on the blog post

10:47 maruks: (macroexpand '(fn [x] x))

10:48 jonasen: maruks: fn has built in destructuring. fn* does not

10:48 maruks: OMG fn turns into fn*

10:48 ok, I see

10:48 sritchie: tutysara: polishing this AM :) so easy to procrastinate on writing. thanks for the push, let me get to it

10:49 jonasen: ,(macroexpand '(fn [[x y]] x))

10:49 clojurebot: (fn* ([p__27] (clojure.core/let [[x y] p__27] x)))

10:49 maruks: awesome

10:49 tutysara: sritchie: I am also looking to implement a workflow that support authentication using either Facebook/Google/Github where the user selects one of the providers to authenticate, did you tried something like this?

10:49 sritchie: yeah, but not for login

10:49 * otfrom gently nudges sritchie and hopes for a blog post soon :-D

10:52 tutysara: most websites usually give some combination of them for oath, and I wanted to give these options to the user :)

10:53 `cbp:

10:53 tutysara: sritchie: I saw from the comments to one of the issues in friend-oauth2 that you had implemented a workflow on your own, does it support multiple providers?

10:53 :)

10:54 sritchie: yeah, I can gist it

10:54 clojurebot: Huh?

10:55 sritchie: it does the token negotiation and callback, etc for a bunch of providers

10:55 BUT, I haven't written anything for storing the tokens, etc

10:55 tutysara: sritchie: wow fantastic, yes please if you have some time

10:55 sritchie: yeah, one sec

11:03 coventry: daGrevis: You likely can't write if without using primitives which use if in their own definitions. It's a special form. "http://clojure.org/special_forms#Special Forms--(if test then else?)"

11:04 daGrevis: You could write a version like yours which evaluated both branches and only returned the results from one branch, but that has different semantics, which are important if one of the branches has side effects.

11:04 cark: coventry: he's not in chan anymore

11:04 coventry: Thanks. Oh, well.

11:05 sritchie: tutysara: https://gist.github.com/sritchie/9a7d9b1b22339a6e2dff

11:07 tutysara: so the way this works is that you navigate to yoursite/oauth/facebook, or /oauth/strava -

11:07 and if that particular provider is in the config map,

11:07 boom, it negotiates

11:07 using that schema that I laid out

11:08 I haven't tried that standalone, just migrated it out of hte project,

11:08 tutysara: sritchie: cool, let me try with a couple of providers and see how it all goes

11:09 sritchie: nice

11:09 you'll need liberator and compojure for this...

11:09 that's about all

11:09 oh, cheshire, clj-http

11:09 [crypto-random "1.1.0"]

11:17 matt444: Is there a function that calculates where a number falls between a min and max number?

11:17 Or should I write my own?

11:18 for example (fake function name): (between 0 10 15) ;; returns 10

11:18 (between 0 10 4) ;; returns 4

11:18 mdrogalis: ,(contains? (into #{} (range 10) -1))

11:18 clojurebot: #<ArityException clojure.lang.ArityException: Wrong number of args (3) passed to: core/into>

11:18 mdrogalis: ,(contains? (into #{} (range 10)) -1)

11:18 clojurebot: false

11:19 matt444: mdrogalis: I thought about range but those are ints

11:19 I need to support arbitrary floats

11:19 mdrogalis: matt444: Ah, yeah you're on your own. :)

11:19 matt444: mdrogalis: thanks, thought i'd ask first

11:20 bbloom: matt444: i believe the function is generally called "clamp"

11:20 mdrogalis: Sure :)

11:20 coventry: ,(#(max %1 (min %2 %3)) 0 10 4)

11:20 clojurebot: 4

11:21 matt444: bbloom: not in clojuredocs, you're saying i can find one though?

11:21 kzar: matt444: something like this? (defn between [& args] (second (sort args)))

11:21 matt444: coventry: will try this real quick

11:21 dnolen: ,(let [x 2] (< 1 x 3))

11:21 clojurebot: true

11:21 dnolen: matt444: ^

11:21 bbloom: matt444: it's not in clojure, that's just the common name for a function that takes three numbers and min/max-es it in to range

11:22 matt444: wow, lots of good answers, thanks everyone

11:22 mdrogalis: bbloom: TIL. Nice

11:25 TimMc: kzar: Oh, that's cute!

11:25 kzar: ?

11:25 Oh sorry I forgot I had posted some code there

11:26 TimMc: kzar: second sort

11:26 sritchie: tutysara: lmk how it goes

11:26 I can package this up into a lib if it's useful

11:28 tutysara: sritchie: looks neat and pleasent with records and all keys in inputs listed

11:28 :)

11:28 sritchie: yeah, the schema stuff is good

11:29 jcromartie: so Enlive doesn't like headers inside anchors

11:29 although that's valid HTML5, so I'm told?

11:30 tutysara: sritchie: would be great if it could be made into a general purpose lib

11:30 sritchie: try it out and let me know if you run into any issues with your other providers;

11:30 if you need extra params, etc

11:30 then let's do it

11:30 I'll make a project

11:35 zerokarmaleft: sritchie: can you explain what you're doing with (= :dev mode) in the facebook config?

11:35 sritchie: yeah, I'm using the test oauth tokens, instead of the live ones

11:35 in development mode

11:36 you can set up test and prod API keys when creating a facebook app

11:36 ddellacosta: sritchie: that code looks familiar ;-)

11:36 sritchie: :)

11:36 ddellacosta: yeah man, let me add a credit to the gist -

11:36 tutysara: sritchie: yes have noticed it

11:36 ddellacosta: sritchie: thanks. :-)

11:36 sritchie: ddellacosta: also, if you can figure out how to merge this into your stuff, let's do it

11:36 ddellacosta: sritchie: yeah, dunno. There's a bigger conversation to be had re: future of Friend

11:37 tutysara: (s/optional-key :auth-query) {s/Keyword s/String}}) - can this be replaced with something else

11:37 zerokarmaleft: ddellacosta: that sounds ominous

11:37 sritchie: added: https://gist.github.com/sritchie/9a7d9b1b22339a6e2dff

11:38 ddellacosta: cemerick, gotta get some love from you on friend!

11:38 ddellacosta: I'd be happy to help with Friend stuff

11:38 ddellacosta: we just need to get some types in play, and think a bit more about the API

11:38 it confounds routing with workflows

11:38 ddellacosta: zerokarmaleft, sritchie: yeah, I mean, I think it's telling that sritchie had to role his own to get it to work smoothly for him. I'm pondering the right way to do this.

11:39 sritchie: well, this was because I;'m not logging in with oauth2

11:39 I wanted to negotiate for the tokens to associate with a user acct

11:39 but yeah, clearly it's similar

11:41 ddellacosta: sritchie: yeah. Probably shouldn't start this conversation late on my Friday night after I've had a few beers...haha. But seriously, I think there are some things to think about here. I think the Clojure web stack needs an easier authn/authz lib, which was Friend's original motivation, but it's not quite there.

11:41 zerokarmaleft: sritchie: ok, so you're just redacting boths sets of keys

11:41 sritchie: yes

11:41 yeah

11:42 zerokarmaleft: sritchie: also, why aren't you using schema with the facebook config? I'm not familiar with its usage

11:42 sritchie: and leaving the original function structure that I'm using

11:42 gtrak: ibdknox: would light table have anything to say about nrepl middlewares? I'm working on an auto-complete implementation that'll work with piggieback.

11:42 sritchie: zerokarmaleft: oh, whoops

11:42 just forgot to

11:42 zerokarmaleft: sritchie: ok :)

11:43 sritchie: fixed

11:43 tutysara: sritchie: ohh nice, let me refer to the latest gist

11:44 sritchie: :require [schema.core :as s - this code is from which lib?

11:45 sritchie: from prismatic's schema

11:45 I added the required deps at the bottom

11:45 jcromartie: I'd like enlive to work with HTML5… seems like a sensible thing, no?

11:45 lvh: Hi!

11:46 jcromartie: https://github.com/cgrand/enlive/issues/90

11:47 cemerick: sritchie, ddellacosta: just replied briefly to the friend-oauth2 issue that's been threading the past couple of days. I'm not really clear on what the problem(s) or suggestion(s) are.

11:48 sritchie: cemerick: link?

11:48 cemerick: https://github.com/ddellacosta/friend-oauth2/issues/13#issuecomment-32574048

11:48 lvh: So, I'm a clojure newbie; I'm trying to wite some code that will do hotel room allocations. I have a bunch of users; users consist of names, genders, start dates and end dates

11:48 sritchie: the fact that two of the three return values from a workflow are just maps is confusing, I think

11:48 lvh: What would be the appropriate data structure to use? A list of whats?

11:48 sritchie: and the use of structural typing to distinguish a friend auth map;

11:49 cemerick: in a sort of undocumented way was really confusing

11:49 lvh: Maps would work, but seem a bit silly for something with such a fixed record like structure.

11:49 also, are genders something I should break out symbol for, or not?

11:49 cemerick: sritchie: you mean, credential map vs. ring response map?

11:49 sritchie: yes

11:49 cemerick: I think wrapping records, like (defrecord Authentication […..]) and (defrecord RingResponse [m]), or even just the first,

11:49 and assume that any other response is ring,

11:49 would be helpful

11:50 cemerick: or even a workflow protocol -

11:50 with "accept?", "handle", where "handle" returns either an Auth map or a failure

11:50 cemerick: the other issue, I think, is that routing is handled inside the workflows -

11:51 "accept?" is sort of tied up with routing

11:51 cemerick: sritchie: isn't that just replacing one predicate for another?

11:51 sritchie: you mean replacing the internal wrapping (when pred … ) that all the workflows use?

11:52 justin_smith: lvh: a map of maps, don't use a list when you want to be able to look things up

11:52 if you hit a performance bottleneck, change the map of maps to a map of records

11:52 cemerick: sritchie: I'm talking about s/metadata on a map/record type

11:53 justin_smith: lvh: the reason to wait is that for interactive development changing the record on the fly leads to annoyance and fumbling, and the syntax for working with maps vs. records, once they are created, is identical

11:53 sritchie: cemerick: I guess it'd be good for me to write up what I find confusing

11:53 lvh: justin_smith: Okay, fair enough :)

11:53 justin_smith: I don't really want to look things up though. I'm trying to pair people.

11:54 justin_smith: lvh: pairing based on what?

11:54 lvh: justin_smith: Matching start, end dates + matching genders.

11:54 justin_smith: I assume once you have a pair you need to look up the people paired for example

11:54 cemerick: sritchie: Please. In any case, the current approach is pretty clearly documented in the README. Flowchart diagram and everything! :-P

11:54 sritchie: there's for sure WAY more documentation than teh typical lib

11:55 major props for that

11:55 lvh: justin_smith: I'd expect the pairing function to return a list of pairs of people; what lookup am I issing?

11:55 missing*

11:55 cemerick: sritchie: now what's this about routing?

11:55 sritchie: but even with all that, it's telling that both ddellacosta and I, after many hours of working with the lib and implementing workflows, both find it quite confusing

11:55 cemerick: well, many workflows only apply on certain routes

11:55 the interactive-form takes a path, for example, and returns nil for requests that aren't hitting "login"

11:56 cemerick: life became really hairy when I wanted to write a json login that applied to some path, but had to give different responses for different accepted content types

11:56 so I was having to use compojure's internal route matching code in my workflow

11:57 cemerick: since I wanted to log a user in at "/oauth/:provider", for example

11:57 justin_smith: lvh: but, if you consider the flow of actions, I assume you have a list, you extract two matches, and return what remains - it may be simple to assoc by a unique identifier, and update to mark as matched with some id, and then search the list for unmatched on the next go

11:57 cemerick: sritchie: why internal? A workflow is just a function, so can be the top-level of a (logically-speaking) whole other ring app, if desired.

11:58 jcromartie: any reason why someone *wouldn't* want to use Jsoup for enlive? seems like it should be the default

11:58 it is much more up to date than tagsoup

11:58 justin_smith: lvh: though of course implementation is up to you, you could just have a list, and return a list with the matches removed - but then your code spends a lot of time list-walking...

11:58 sritchie: cemerick: what if I want to wrap that in two workflows?

11:58 cemerick: if I wrap an inner ring app,

11:58 and I want to auth on /oauth/:token,

11:59 how am I supposed to have my workflow catch taht response and do auth?

12:00 cemerick: sritchie: Now I'm confused. Workflows aren't middleware, they can't catch responses...

12:00 Are you wanting to redirect to a login upon an unauthorized req?

12:00 sritchie: cemerick: so what's happening here

12:00 https://github.com/cemerick/friend/blob/master/src/cemerick/friend/workflows.clj#L75

12:00 when login uri, and a post request...

12:01 lvh: justin_smith: Suppose I write a function that does the eager-match part (so finds one pair of exactly matching (gender, start-date, end-date)); how would I keep calling it until it doesn't work anymore (ie there are no exact match pairs left; either no-one left, one person left, or only inexact pairs left)?

12:02 sritchie: cemerick: that workflow is absolutely intercepting that response

12:02 cemerick: sritchie: there's no ring response anywhere there

12:03 justin_smith: lvh: you could iterate or loop and take results until no new matches are found, then return matches + unmatched

12:03 cemerick: sritchie: `request` is a ring request; the fn returned by `interactive-form` validates the credentials it provides, or passes the request on to the login failure handler

12:03 sritchie: cemerick: that line I pointed to us confounding routing for sure

12:04 like, say I wanted to build this, but log in a user to a custom account

12:04 sdegutis: So, it turns out Swing is kind of hard to "theme". Making it look like Windows 8 seems pretty intimidating.

12:04 sritchie: "/accounts/:custom-account-id/login"

12:04 cemerick: how would you deal with that?

12:04 broquaint: sdegutis: Not even when using (native!)?

12:04 (From seesaw)

12:04 jcromartie: sdegutis: make your app "authentically Java" :)

12:04 cemerick: sritchie: by not using the stock interactive-form workflow, which presume a single fixed login URI :-)

12:05 tutysara: sritchie: [paddleguru.util.liberator :as l -> can you change this in gist when you find time

12:05 jcromartie: or "unapologetically 90s"

12:05 sritchie: cemerick: so, most of the guts would be the same

12:05 but they're trapping inside that (when <route-matches> … ) predicate

12:05 justin_smith: lvh: something like this, I wrote it but haven't ran it :) (loop [matches [] unmatched input] (if (empty? unmatched) [matches nil] (let [match (find-match unmatched)] (if match (recur (conj matches match) (remove-matches match input)) [matches unmatched]))))

12:06 sritchie: cemerick: I'm not trying to bust on your library, I'm using it and like it

12:06 cemerick: sritchie: There's no reason why a better interactive-form workflow couldn't just return a ring handler that uses all the usual userland compojure bits to do whatever routing it wants prior to or as part of authentication

12:06 justin_smith: maybe find-match could return the match + the things not matched and remove the remove-matches step

12:06 sdegutis: broquaint: I'm not on Windows 8 so no :)

12:06 sritchie: I'm just giving feedback that it's extremely confusing, and I think I have a tremendous tolerance for confusing code, after my monad trips

12:06 sdegutis: jcromartie: you mean just use the Metal look-and-feel?

12:06 cemerick: sritchie: no worries; I just think you're expecting the default workflows to do more than they do :-)

12:07 sritchie: I can gist the code that I had to write to handle content type negotiation in these workflows

12:07 cemerick: sritchie: the line you pointed out is there in the form it is because I didn't want friend to require compojure

12:08 sritchie: if you did it without writing a new workflow, then I suspect it's pretty gnarly

12:08 sritchie: no, I wrote new workflows

12:08 cemerick: oh; well, then I'd expect it to be pretty sane ;-P

12:10 coventry: sdegutis: How did you get stuck with the job of making a windows-8-themed app out of swing?

12:10 sdegutis: coventry: That's a different way of looking at it.

12:11 coventry: I just want to make something like LightTable (i.e. a flat theme) but in Clojure.

12:12 broquaint: sdegutis: Aha :)

12:12 coventry: Oh, sounds like a fun project.

12:12 sdegutis: I thought it was going to be fun. But then I got stuck early on trying to make it look pretty.

12:12 And it looked really intimidating to do in Swing.

12:13 Call me shallow, but I don't want to use an app that isn't pretty, and I won't write an app that I won't use. So I put the project on hold.

12:14 lvh: justin_smith: I'm having trouble parses that (if (empty? unmatched) [matches nil] (let ... ;; isn't an if supposed to have two exprs in it?

12:14 justin_smith: [matches nil] is one expression

12:15 and it should have three - the condition, the true case, and the false case

12:15 lvh: justin_smith: yes, I just realized how to parse that; sorry, brainfart :)

12:15 justin_smith: np

12:16 I so often use the "small literal vector to return multiple values" idiom that I forget it can be non-obvious

12:16 lvh: justin_smith: So, (if match (recur ...)) means (if (nil? match) (recur ...)); right? Is truthiness-to-check-for-nil idiomatic?

12:17 justin_smith: yeah, very much so - and it is (if (not (nil? match)) ...

12:17 lvh: justin_smith: Awesome, thanks. Dinnertime for me, but thank you for the help so far!

12:18 justin_smith: np, glad it was helpful

12:21 sdegutis: And man, LightTable is so nice looking these days. I can't wait until someone completes the paredit plugin, then I can use it full time.

12:22 locks: sdegutis: that person could be you ;)

12:22 sdegutis: locks: I am not talented enough to do that.

12:23 Plus I imagine AST mutation is probably not pleasant or easy in Clojure.

12:23 jcromartie: sdegutis: how do you mean?

12:24 justin_smith: sdegutis: clojure excells at it, it's just a dissoc followed by an assoc and then replace the state

12:24 it's like maybe one of the things clojure is most bestest at

12:24 sdegutis: justin_smith: even when the dissoc and assoc are deep within a nested structure?

12:24 (and in different places)

12:24 justin_smith: update-in

12:25 lvh: justin_smith: I'm surprised remove-matches is a function; I'd expect there to be a dissoc or unconj or something

12:25 justin_smith: althoguh perhaps you wrote that with different implementations in mind

12:25 justin_smith: lvh: it's pseudo-code :)

12:25 sdegutis: I figured you couldn't use update-in because it'd be hard to build the traversal param at runtime.

12:26 justin_smith: sdegutis: well, you could use a zipper instead, but in my experience a known path to the thing you are grabbing / spot to insert suffices

12:27 sdegutis: Hmm maybe I just need to redesign my AST then.

12:27 mikerod: clojure.walk :)

12:27 sdegutis: Oh wait, I don't have an AST, I gave up on it because I couldn't make the app look pretty in Swing.

12:28 * sdegutis is going in circles

12:29 gtrak: why does piggieback get an atom in the message's :session key, but my middleware gets a uuid-str?

12:29 nrepl middlewares

12:29 sdegutis: It's kind of strange that HTML+CSS is the easiest way to customize how a cross-platform app looks. Surely we'd have done better by now.

12:29 justin_smith: gtrak: because of the order of the middlewares I assume?

12:30 gtrak: justin_smith: would you know which one's responsible?

12:30 justin_smith: no, not at all, sorry

12:30 gtrak: that's my guess, too.

12:30 justin_smith: I usually do a binary search repositioning the middleware that isn't seeing the data transformation it needs :)

12:31 eventually you find the magic spot

12:31 gtrak: I usually do a brute-force search..

12:32 justin_smith: well, since order is significant, binary search is faster - anything after the magic one gets the data it needs, anything before does not

12:32 though of course before and after can be tricky concepts with some middleware :)

12:33 gtrak: ah yea.

12:39 yea, ok, it's the session middleware.

12:41 lvh: justin_smith: During dinner, a background thread joined, and suddenly your map comment made total sense.

12:41 justin_smith: heh, do tell

12:42 lvh: justin_smith: If I turn everthing into a {[gender start-date end-date] [people...]} map, suddenly it's way easier to generate the pairs.

12:43 justin_smith: and you can generate that with a group-by

12:44 (group-by (juxt :gender :start-date :end-date) people)

12:44 (inc juxt)

12:47 jocrau: I am experimenting with om (https://github.com/swannodette/om). How can I deref the current application state (from root) in an event handler? (to sync the client app state with the server app state)

12:48 tried (om/read state #(put! endpoint/outgoing-changes (om/join % [])))

12:50 lvh: justin_smith: why would I increment juxt?

12:50 justin_smith: I was trying to

12:50 it is an informal channelism to show appreciation

12:50 $karma juxt

12:50 there was no result shown since I have already incremented it in the past

12:51 lvh: justin_smith: Ahhh; okay, that makes sense :)

12:51 justin_smith: ahh, lazybot is not online it seems

12:51 lvh: Somehow in #python we end up doing x++ even though it's not even valid syntax

12:51 justin_smith: right

12:51 same deal

12:52 lvh: keywords being functions is still kinda crazy to me but I guess I'll get used to it :)

12:52 matt444: How can a function (not a defn) refer to itself?

12:52 bbloom: lvh: keywords being functions is the single best idea in clojure

12:52 justin_smith: matt444: letfn

12:52 matt444: or named fn

12:53 matt444: justin_smith looks let letfn is what i need, thanks

12:53 justin_smith: ,((fn example [x] (if (< x 5) x (example (- x 10)))) 33)

12:53 clojurebot: 3

12:53 matt444: oh

12:53 justin_smith: see above if you just want an fn that refers to itself

12:53 matt444: didn't know you can do that

12:54 justin_smith: also the (fn some-name []...) thing makes stack traces much more readable

12:54 lvh: So, I'm using a fairly standard lein new whatever ;; project with emacs. I figured out how to do cider-jack-in; is there an easy way to run the tests, or do I just use lein in a term

12:54 bbloom: matt444: it's also useful as "documentation", like if you have (f #(whatever) #(other-thing)) and can't remember the order of arguments, you can use (fn some-name ...) to clarify

12:54 justin_smith: lvh: I like to require clojure.test in the repl and (test/run-tests)

12:55 bbloom: yeah, good point - naming helps clarify intent

12:56 coventry: jocrau: It's a bit messy, but try (.-value %) instead of om/join.

12:57 lvh: justin_smith: (require "clojure.test") doesn't seem to be it. How do I spell that?

12:57 (Also paredit-mode appears to be off in my REPL window by default; will things go horribly wrong if I enable it? That seems like an obvious win to me)

12:57 justin_smith: (require '[clojure.test :as test])

12:57 lvh: justin_smith: Thanks! Why is that vector quoted?

12:58 I feel bad asking soo many silly questions :)

12:58 olliefr: is there a way to EASILY plot stuff in Clojure, ideally from the console. i am exploring simple dynamical systems (discrete iterative functions) and they work well in Clojure because of lazy sequences, but i would like to be able to plot the orbits as well - a quality xy scatterplot would suffice

12:58 justin_smith: because clojure.test is a symbol in that expression, as is test

12:58 lvh: sometimes output from the repl confuses paredit, such that I need to C-u M-x paredit-mode in order to force it to turn on even though things are not balanced

12:58 lvh: Yay! that worked. Thanks :) also has the benefit that it doesn't take six hours to run the tests :)

12:59 justin_smith: lvh: otherwise it seems to work

12:59 lvh: just remember to reload any definitions / reload any changed test namespaces before running the tests again, of course

13:01 lvh: I'm assuming that using java.util.Date is okay? IIRC it's immutable, so that's nice.

13:02 technomancy: a reasonable-looking assumption, unfortunately one that is not correct

13:02 java.util.Date is the opposite of okay

13:03 bbloom: lvh: it's MUTABLE

13:03 lvh: in jvm land, the correct answer is: "use joda time"

13:03 lvh: that is unfortunate

13:04 bbloom: there are several clojure wrappers for joda time, but i don't know if any are good

13:04 technomancy: quite =(

13:04 bbloom: shouldn't be too problematic to use joda time directly

13:04 lvh: hm

13:04 bbloom: also, time is hard.

13:05 even more unfortunate is js/Date

13:05 justin_smith: ,(class #inst "2014-01-17T18:02:19.115-00:00")

13:05 clojurebot: #<SecurityException java.lang.SecurityException: denied>

13:05 technomancy: how can it be worse?

13:05 bbloom: which copies java.util.Date and all of its flaws, then manages to add some new ones too

13:05 justin_smith: ,(type #inst "2014-01-17T18:02:19.115-00:00")

13:05 clojurebot: #<SecurityException java.lang.SecurityException: denied>

13:05 justin_smith: blergh

13:05 bbloom: technomancy: oh, it can be worse

13:05 lvh: clj-time looks nice

13:06 technomancy: copying the zero-indexed months struck me as pretty hilarious

13:07 jocrau: coventry: That was the right direction, thanks. Wrapped it in om/allow-reads and deref on -state.

13:09 coventry: There's got to be a cleaner way to do this sort of thing.

13:10 jocrau: Agreed. It's pre-alpha though and already a lot of fun stuff in there.

13:11 coventry: Oh, yeah, it's great, I'm just hoping someone will come along and recommend such a more skillful approach.

13:13 lvh: calendaring is always pretty hard

13:13 coventry: s/such a/a/

13:13 lvh: I mean come on leap days inserted in the 24th, except recently, when its the 29th, unless you're in hungary

13:14 bbloom: meanwhile, even UTC is fucking broken. damn leap seconds

13:16 justin_smith: hell, leap seconds even break the unix epoch counter

13:17 technomancy: one good way to detect an advanced civilization is to find a planet whose year is an even multiple of its day

13:17 because it's easier to shift the orbit of your planet than to deal with leap years, leap seconds, etc

13:17 jjl`_: that was my next question

13:17 koalalla1a: yup. throw up some sails and slow down the planet

13:17 justin_smith: (inc technomancy)

13:18 jjl`_: koalalla1a: er no, it's slowing down, not speeding up

13:18 koalalla1a: jjl`_: i imagine some planets have the opposite problem too though

13:19 rplaca: it's funny how some of the easiest seeming problems in CS (like time and date management and text formatting) actually turn out to be some of the hardest

13:19 bbloom: technomancy: lol awesome

13:19 koalalla1a: not funny at all. it's very disturbingly sad and frustrating

13:19 bbloom: technomancy: one day we are all startled awake

13:19 ... by the acceleration of the planet

13:19 rplaca: koalalla1a: I meant funny strange, not funny ha-ha

13:19 bbloom: some guy working on calendaring software HAS HAD ENOUGH

13:20 technomancy: rplaca: it's really all very simple until you have to start accounting for humans

13:20 koalalla1a: rplaca: i know, just being a pain ;)

13:20 rplaca: koalalla1a: :)

13:20 jcromartie: "funny uh-oh"

13:20 kzar: I've spent the last 2 or 3 months adding timezone support into a legacy application written in Javascript and Python

13:20 rplaca: technomancy: eventually the system will eliminate that problem

13:20 lvh: (inc technomancy)

13:20 koalalla1a: that kind of funny makes me want to throw my hands up and become a dog walker

13:20 lvh: is it promising if I think that is gross because it is side-effectful

13:21 justin_smith: yes

13:21 lvh: I mean I just created a new technomancy with more karma!

13:21 kzar: if you can avoid doing calendars / dates/ times / timezones please do

13:22 lvh: it makes perfect sense for your timezone to be 1hr and 40s before GMT

13:22 (I'm looking at you, Sweden)

13:22 bitemyapp: kzar: bet you'd kill for a non-terrible type system right about :)

13:22 rplaca: the only thing I've found that even comes close for dealing with time is Joda time

13:22 kzar: I found a bug in chrome and a bug in moment-js so far along the way

13:23 rplaca: it's far from perfect, but way ahead of the other systems (esp. what's avaialble in languages like python and JS)

13:23 *available

13:24 kzar: I recommend this video http://www.youtube.com/watch?v=GBKqRhn0ekM

13:24 although nothing will really prepare you for the crazy

13:24 jjl`_: for most purposes, it's not too painful. i'm glad i won't be programming when we start adding multiple leap seconds a day though

13:27 kzar: I really want to get a job doing clojure so I can spend my time learning clojure instead. It's hard to learn much in evenings when you've been coding all day

13:28 jcromartie: kzar: I'd recommend finding a local Clojure meetup

13:28 kzar: I'm not sure there are any in Bristol

13:29 shep-werk: kzar: not yet :-)

13:31 lvh: How do I drag in deps in my project.clj? I'm in emacs but my file won't compile: FileNotFoundException Could not locate clj_time/core__init.class or clj_time/core.clj on classpath: clojure.lang.RT.load (RT.java:443)

13:32 technomancy: lvh: typically you restart your repl when you ad deps, but there is athing called alembic that lets you avoid restarts

13:33 lvh: technomancy: so cider-restart?

13:33 technomancy: Cool, thanks :)

13:33 olliefr: kzar yo bristol functional is a good start

13:33 kzar nokia here in bristol develops in clojure and they host bristol functional

13:33 kzar: oh sweet

13:33 jcromartie: big ups to the bristol functional mandem

13:34 kzar: haha

13:34 olliefr: sound I'll go to the next one

13:34 olliefr: kzar http://brisfunctional.github.io

13:35 kzar there's a google group; all the announcements are there

13:35 bitemyapp: lvh: (require '[alembic.still :as alembic]) (alembic/load-project)

13:35 nDuff: Heh.

13:35 TimMc: technomancy: Tidal resonance could also account for that.

13:36 technomancy: TimMc: could it fix things on earth, because that would be awesome; let's get some more tides going.

13:37 TimMc: I dunno. I think the Moon's influence probably complicates any Earth/Sun resonance.

13:38 lvh: Where can I find the differences between use/load/require/import etc?

13:38 They are completely opaque to me

13:40 justin_smith: lvh: load is for ugly ass hacks

13:40 lvh: use is for the repl

13:40 `cbp: import for java classes, require for clojure vars, load to run clojuree code in a file, use to never be used

13:40 justin_smith: require is for actual code you ship

13:40 import is for java classes, and is orthogonal to the others

13:40 `cbp: use is nice in the repl sometimes!

13:41 bitemyapp: justin_smith: write an Emacs macro ya bum.

13:41 justin_smith: don't use use :(

13:41 justin_smith: heh

13:41 * `cbp has an emacs macro

13:41 * bitemyapp has many emacs macros

13:42 justin_smith: I only use emacs functions, because the macros are in terms of keybindings which is much more opaque than the functions the keybindings refer to

13:42 *than what the

13:42 `cbp: you can always yasnippet

13:42 justin_smith: unless you really mean macros not keyboard-macros, and I never need those because I am not an elisp hacker

13:42 lvh: Okay; so [clj-time.core :refer '(local-time)] looks like a sane thing inside :require?

13:43 justin_smith: no need for the '

13:43 but yeah, looks fine

13:43 lvh: justin_smith: why won't it try to eval that?

13:43 oh, wait, it's a macro

13:44 technomancy: clojurebot: ns macro?

13:44 clojurebot: Titim gan éirí ort.

13:44 technomancy: come on clojurebot

13:45 bitemyapp: technomancy: bot ain't playin' ball today

13:45 technomancy: clojurebot: the ns macro is more complicated than it needs to be, but this might help http://blog.8thlight.com/colin-jones/2010/12/05/clojure-libs-and-namespaces-require-use-import-and-ns.html

13:45 clojurebot: You don't have to tell me twice.

13:45 technomancy: clojurebot: if only that were true

13:45 clojurebot: excusez-moi

13:46 hiredman: ~ns

13:46 technomancy: lvh: ^

13:46 clojurebot: ns is unfortunately more complicated than it needs to be, but http://blog.8thlight.com/articles/2010/12/6/clojure-libs-and-namespaces-require-use-import-and-ns may be helpful.

13:46 hiredman: if only you asked for what you put in

13:47 technomancy: shouldn't it be doing fuzzy matches or something?

13:47 labour-saving devices and what have you

13:48 hiredman: it tries its best

13:49 lvh: the-kenny: Thank you :)

13:50 sorry, I meant technomancy

13:50 cark: hum divide is a thing in refer-clojure ?

13:50 lvh: I'm getting this error: IllegalStateException second already refers to: #'clj-time.core/second in namespace: pairing.core-test clojure.lang.Namespace.warnOrFailOnReplace (Namespace.java:88)

13:50 I thought that meant "you are using :all too much"

13:50 bitemyapp: ah yes, the joys of clj-time nomenclature.

13:50 My old nemesis, we meet again.

13:50 lvh: what version of clj-time are you using?

13:51 lvh: 0.6.0 I think

13:51 * bitemyapp rubs chin

13:51 lvh: bitemyapp: So, I'm a total newbie, but I thought that [clj-time.core :refer (local-time)]

13:51 would just get me local-time, and nothing else.

13:51 actually that should be local-date. Oops.

13:51 cark: when i try to define divide, i have to (:refer-clojure :exclude [divide]). but i can't find the definition of this divide in clojurescript

13:51 hiredman: not if you use :use

13:52 cark: hiredman: if you're answering me, can you be more specific ? i don't get what you mean

13:52 lvh: hiredman: I'm not using use; test file: https://gist.github.com/lvh/df36d7b13b9277934c6c

13:52 cark: ah =P

13:53 bitemyapp: cark: http://dev.clojure.org/jira/browse/CLJS-594 https://github.com/clojure/clojurescript/blob/master/src/cljs/cljs/core.cljs#L1469

13:54 hiredman: lvh: then some other namespace is

13:54 cark: ahh got it ... i guess i shouldn't try to search from github =/

13:57 bitemyapp: cark: I don't actually answer questions

13:57 cark: I take the nouns and verbs from peoples' queries in here, add some choice quotes around specific words sometimes, then Google.

13:57 cark: then I cherry-pick one or two relevant URLs and paste them back.

13:58 technomancy: bitemyapp: you really need a bot for that

13:58 cark: well thanks anyways

13:58 lvh: I'm also getting that exception in the second file in https://gist.github.com/lvh/df36d7b13b9277934c6c

13:58 technomancy: labour-saving devices and what have you

13:58 lvh: which I totally don't get

13:58 bitemyapp: technomancy: I kno rite.

13:58 technomancy: for the record, this tactic doesn't work nearly as well in #haskell

13:58 technomancy: the questions there are actually hard.

13:58 cark: it's completely crazy that github will not find me that though

13:59 bitemyapp: "what's a bifunctor of this typeclass?" "ahh hum. uhm...."

13:59 cark: things at Github only get worked on to the degree that they interest somebody.

13:59 cark: perhaps they should hire a search engine nut?

13:59 cark: yes =)

14:01 zerowidth: if you have systems experience with large elasticsearch clusters, by all means apply

14:02 bitemyapp: zerowidth: you're a GH employee?

14:03 zerowidth: aye

14:05 kzar: To be fair the search works a lot better in GH than it does in Bitbucket, I have to use it for work now and I miss being able to find things easily without checking it out and greping myself

14:06 octagon: an interface to `git grep` would definitely be nice to have on github.com

14:06 zerowidth: individual-repo search? yeah

14:06 bitemyapp: kzar: that applies for a lot of verbs/nouns in that category.

14:07 kzar: my company uses bitbucket and mercurial and I'm practically crawling out of my own skin on a regular basis.

14:07 kzar: lol

14:08 to be fair it's a damn lot cheaper

14:09 bitemyapp: kzar: penny-wise.

14:09 kzar: Well actually if your company has a lot of repos paying per repo instead of per employee is more than pennies

14:09 lvh: is there an emacs thing for extract-sexp-to-function

14:09 bitemyapp: kzar: we have around 40.

14:10 lvh: Right now I'm munging it with manual editing + ESC C-f

14:10 justin_smith: lvh: not off the top of my head, but paredit makes deleting a sexp starting at point easy

14:10 hiredman: hosted codeq

14:11 technomancy: lvh: you'd need the analyzer to see which identifiers are locals vs vars

14:11 justin_smith: lvh: which brings down the cost of "manual editing" quite a bit

14:11 hiredman: technomancy: hosted codeq!

14:11 technomancy: though I guess you could just prompt for locals

14:11 hiredman: no

14:12 lvh: justin_smith: Oh, right, I forgot that C-k at start is even easier than C-SPC forward-sexp

14:12 so, clj has absolutely no haskelly desire to make functions pointfree, right?

14:12 justin_smith: lvh: c-m-k in case there are multiple sexp on one line

14:13 lvh: you can do it, I find it often obfuscates

14:13 technomancy: you could try the slamhound approach too (attempt to compile and read compiler errors), but that would lead to some false positives when you shadow things

14:13 lvh: a few simple comp/partials here and there are nice

14:13 justin_smith: there are things like comp and partial and juxt which are kinda-points-free-ish but no true points free I don't think

14:13 technomancy: it's easy to go overboard though

14:13 lvh: So something like def instead of defn?

14:14 technomancy: except with juxt; it is impossible to use too much juxt

14:14 justin_smith: yeah, (def nothing (constantly nil)) is a function definition I will sometimes use

14:14 lvh: basically I just think that (juxt :gender :start-date :end-date) is too much typing

14:14 technomancy: lvh: def instead of defn is not so good because your stack traces will get even worse

14:14 lvh: I want that to be called "prefs"

14:14 technomancy: though if you're just applying keywords that's not an issue

14:15 justin_smith: hmm is there a usage of metadata that would make (def get-key (juxt ...)) look better in stack traces?

14:16 jjl`_: technomancy: i hear you on that one. my style is adapting to move a lot of defs with function factories into defns

14:17 lvh: so basically the one thing that really ruffles my jimmies is that the index of a thing inside braces mod two determines if it is a key or a value

14:17 maybe that will go away once I learn how to indent things

14:18 technomancy: http://thereisnoneed.com/

14:18 joegallo: Jimmies status [ ] unruffled [x] ruffled

14:18 jjl`_: er, you see this as a problem?

14:18 justin_smith: ,(into {} [[:a 0] [:b 1]]) ; lvh

14:18 clojurebot: {:a 0, :b 1}

14:18 justin_smith: it's an option at least, if you hate the lack of grouping that much

14:18 jjl`_: also you can use the comma

14:18 Wild_Cat: oh, hi lvh!

14:19 jjl`_: but is it really any different from let forms?

14:20 technomancy: let usually has newlines

14:20 joegallo: in theory, it's a problem. in practice, literal maps are usually broken over multiple lines, or :a "foo" (keys are keywords and values aren't), or you use commmas in them to make it obvious

14:20 Wild_Cat: lvh: the good news is that at the very least, you get an error when you have an off number of things in your map literal.

14:20 odd*

14:20 jjl`_: my map definitions usually have newlines

14:20 lvh: Wild_Cat: hello

14:21 Okay, I didn't realize you could add commas. Would that make my clj code unidiomatic, or is it just taste?

14:21 justin_smith: commas are whitespace, and idiomatic in maps and let statements

14:21 Wild_Cat: commas are fine for one-line map definitions.

14:21 jjl`_: i expect align-cljlet for emacs deals with maps as well

14:21 Wild_Cat: when your map has one entry per line, the newline is enough of a separator.

14:21 justin_smith: ,(+ 1, 1, 2) ; is not idiomatic

14:21 clojurebot: 4

14:21 technomancy: justin_smith: I don't know about idiomatic in maps

14:22 when I see commas in maps I think "new to clojure"

14:22 which is fine FWIW

14:22 justin_smith: {:a 0, :b 1} for a one liner?

14:22 if my keys and vals are textually short I totally do that

14:22 Wild_Cat: {:foo 1, :bar 2} is nicer than {:foo 1 :bar 2} IMO

14:22 justin_smith: exactly

14:22 lvh: is there a way to get better erro r messages out of clojure.test/is assertion failures

14:22 Wild_Cat: however, {:foo 1,\n :bar 2} is redundant.

14:22 * jjl`_ mostly uses keywords for maps and aligns things in columns where necessary. my synhi makes it look sufficiently different anyway

14:22 lvh: like pretty printed data structures maybe

14:23 or even better, highlight differences!

14:23 joegallo: technomancy: yeah, commas are "i'm new here"

14:23 technomancy: lvh: check out difftest

14:23 justin_smith: lvh: (is false "I wanted this test to fail.")

14:23 test/is of course

14:23 technomancy: Wild_Cat: but deleting trailing whitespace will fix it =)

14:23 lvh: technomancy: oh man that is super great

14:24 technomancy: the implementation is janky, but the end result is nice

14:24 Wild_Cat: oh yeah, difftest looks awesome!

14:24 totally stealing that.

14:25 jjl`_: i expect difftest and midje are incompatible :(

14:25 justin_smith: lvh: I find liberal use of the third arg to is, and wrapping groups of is calls in (test/testing "general category of things I am testing" ...) clarify things a lot

14:25 the message from testing also gets printed with failures

14:26 lvh: justin_smith: I only have one is per test; https://gist.github.com/lvh/2d762fd80e499ed50266

14:26 justin_smith: I know *which* test fails, but I can't tell what's going on, because both the expected and the actual are basically just a giant wall of text

14:27 technomancy: I added {:user {:plugins [[lein-difftest "2.0.0"]]}} to ~/.lein/profiles.clj; (use 'difftest.core) can't find difftest

14:27 jjl`_: lvh: lein deps

14:27 technomancy: lvh: the plugin is just for CLI use

14:27 lvh: jjl`_: Inside the project?

14:27 technomancy: for repl use you need a :dependencies entry

14:28 lvh: technomancy: Oh. I was trying to use the REPL instructins

14:28 Oh, okay.

14:29 (activate) looks like an incredibly scary thing.

14:29 technomancy: yeah... it's pretty nuts

14:29 justin_smith: (do (use 'autobots.core) (transform) (roll-out))

14:31 KeithPM: Good day. Can anyone decipher this tutorial example for me please? I am particularly curious about the (conj ret (fn [] i)) form as well as the (map #(%) fns) form. The full example is here https://gist.github.com/kpmaynard/8479693

14:32 Wild_Cat: lvh: speaking of useful plugins, you'll probably want to take a look at lein-environ

14:32 joegallo: KeithPM: it's returning a list of thunks (that is, no-arg functions)

14:32 justin_smith: ,(map #(%) [(constantly 1) (constantly 2) (fn [] 3)])

14:32 clojurebot: (1 2 3)

14:33 joegallo: then it's mapping "invoke thyself, function!" across them all.

14:33 justin_smith: (fn [] i) is just a weird way of saying (constantly i)

14:33 KeithPM: Wow… I'm amazed :)

14:33 lvh: technomancy: Which dependencies entry? It's not difftest or lein-difftest, apparently; when I use lein-difftest, (use 'difftest.core) still fails FileNotFoundException Could not locate difftest/core__init.class or difftest/core.clj on classpath: clojure.lang.RT.load (RT.java:443)

14:34 sritchie: okay, here's my post on Liberator and Friend: http://sritchie.github.io/2014/01/17/api-authentication-with-liberator-and-friend/

14:34 technomancy: lvh: difftest alone should do it in :dependencies

14:34 joegallo: KeithPM: does that make more sense now, or are you still not really gettin' it?

14:34 technomancy: that's what the plugin is doing behind the scenes

14:36 lvh: technomancy: My bad; screwed up the version.

14:36 KeithPM: joegallo: I 'get it' on a surface level, I am now trying to come to terms with the purpose …

14:36 sritchie: cemerick: would love if you'd take a look to see if I'm correct on my description of how friend does its thing

14:36 lvh: technomancy: is there a :latest keyword or something? I realize that would probably be an incredibly bad idea.

14:36 joegallo: i seriously wouldn't stress it -- it's not meant to be like "good" code or anything

14:36 justin_smith: there is lein-ancient to check if you are up to date

14:36 joegallo: it's just pointing out this difference between what would happen in javascript versus what happens here -- it's not really meant to useful

14:37 besides just "oh, hey, you know that thing you hate about js!? yeah, we don't have that here!!!!"

14:37 KeithPM: justin_smith: Thanks Justin, I had never seen 'constantly', will look it up

14:37 technomancy: lvh: you can use "RELEASE" for things like dev tools if you are OK with some breakage, but using it for anything required for the project itself is definitely a bad idea

14:37 KeithPM: joegallo: Thanks joe, you know I was beginning to stress it :)

14:38 justin_smith: KeithPM: if you know what (fn [& ignored] x) would do, that is constantly is, pretty much

14:38 lvh: YESSSSSSS

14:39 technomancy: I just got a sane response from my REPL; thanks :)

14:39 technomancy: no problem

14:39 sounds like the readme could use some work

14:39 Wild_Cat: lvh: how do you deal with reloading all the things before running your tests?

14:39 (reload, the bane of any programming language with a REPL :p )

14:39 KeithPM: justin_smith: Oh yes… I'm familiar with the constant function in lambda…

14:41 Wild_Cat: ...related: is there at all a function you can call from the REPL that reloads every NS?

14:41 lvh: Wild_Cat: Have only two modules

14:41 Wild_Cat: lvh: and do they have dependencies?

14:42 KeithPM: What would you call the #(%) function in the map expression? It looks like 'apply' (???)

14:42 joegallo: (apply f []) is what it is, basically

14:43 lvh: Wild_Cat: oh, yeah; cider-restart

14:43 gtrak: cemerick: I can't seem to catch piggieback in a state where (get @session #'*cljs-repl-env) works, is that the right approach?

14:43 KeithPM: joegallo: OK thanks.. Imagine running in to that example in an intro tutorial to clojurescript :)

14:43 joegallo: yikes

14:44 KeithPM: :)

14:44 It was a little disconcerting to say the least :)

14:44 gtrak: cemerick: the keys are in there, but they're nil.

14:44 joegallo: definitely i would say "this is not on the quiz"

14:44 KeithPM: :)

14:45 gtrak: cemerick: and I've added the wrap-cljs-repl (using resolve to avoid a compile-time dep) to the :requires

14:45 which I thought would work

14:45 cemerick: gtrak: it's only going to be non-nil if the current session is a CLJS REPL

14:45 s/is/has

14:45 gtrak: well, it is.

14:46 I've got austin in there and I ran (cemerick.piggieback/cljs-repl)

14:47 i can push it if you want to take a look.

14:47 cemerick: gtrak: but the code you are using to touch piggieback is Clojure, which is in a different session

14:48 sritchie: that looks about right after a skim (though it should be :cemerick.friend/foo; the double-colons are only used to expand either *ns* or an :as-required alias)

14:48 gtrak: cemerick: not sure I understand what you mean there, the sequence is: I open up a repl in a terminal, I connect to it via emacs, autocomplete works there, I start the cljs repl in emacs and try autocomplete again, which switches on truthiness of those session keys, and I've got debug printlns on my terminal.

14:49 cemerick: oh, ok, I thought you were REPL-ing to check the status of the session map

14:50 gtrak: how is this autocomplete being triggered? It has to use the same session as the CLJS REPL in order to access its CLJS env

14:50 gtrak: cemerick: I can check, hold on one sec.

14:51 cemerick: sritchie: it sounds like liberator's assumption that a request can be statically evaluated as authorized or not is the biggest point of friction?

14:51 gtrak: cemerick: as far as I can tell, there's only one repl session, if I print id's I can verify that.

14:58 cemerick: gtrak: but you can evaluate CLJS expressions?

14:58 gtrak: yes

14:59 cemerick: gtrak: If the CLJS env weren't in the session, that wouldn't work

14:59 gtrak: cemerick: if I debug print it from where piggieback captures it, it's definitely in there.

15:00 I haven't verified that autocomplete is using the same session, but I don't see any reason to doubt it.

15:00 cemerick: this is cider?

15:00 gtrak: yes

15:00 cemerick: I'm 99% sure that it uses a different session for tooling-related stuff

15:00 gtrak: aww, godammit. :-)

15:00 cemerick: Otherwise, evaluating clojure-complete expressions would contaminate *1, etc

15:01 This is a wrinkle in the "just use the piggieback CLJS env" strategy :-)

15:01 gtrak: so, now what :-). This whole exercise relied on the fact that I could grab the value of the env from the session.

15:01 if I can pass along the real session id in the tooling session, I can do it that way.

15:02 cemerick: don't do that, you don't want tooling to hose the interactive session

15:02 Just get at it a bit off to the side. https://github.com/clojure/tools.nrepl/blob/master/src/main/clojure/clojure/tools/nrepl/middleware/session.clj#L15

15:02 gtrak: why would it hose it?

15:03 yea, that's what I'm thinking

15:03 in a separate key.

15:03 not masquerading as the first session, which is what I think you mean.

15:03 cemerick: right

15:03 Hrm, right, you're not eval-ing anything, so the risk of blocking a session is ~nil.

15:04 coventry: I've got an om/cljs codebase where changing (select-keys [:mykey] cursor) to {:mykey (:mykey cursor)} seems to speed the app's responsiveness by an order of magnitude. Is this a known issue?

15:04 cemerick: gtrak: Anyway, as long as you can get at the tooling session ID in cider somehow, you should be able to get at things without a problem.

15:05 gtrak: target-session or something, that's complicated, but oh well.

15:05 would it make sense to restrict things to one session?

15:05 or to generally have ops be able to work with other sessions?

15:06 cemerick: gtrak: it hasn't come up yet, honestly

15:06 bitemyapp: "Don't be too proud of this technological terror you've constructed. The ability to write servers in JavaScript is not an advantage."

15:06 gtrak: pfft, well, I'll do what I imagine has been done elsewhere, just get it working and talk about it later :-).

15:07 cemerick: gtrak: The "use a different session" advice became the overriding message when everyone decided they'd just ship expressions to be eval'd, and I didn't have enough gas in the tank to evangelize the op-based approach to tooling.

15:08 gtrak: if I can get cider to use the same session, that would definitely be cleaner.

15:09 cemerick: not sure if you saw my last message, I'll try to get it working in cider in the same session first.

15:09 cemerick: gtrak: yeah, that may be best if you can manage it

15:09 gtrak: that seems like a more coherent thing in the long run.

15:10 tpope: ^

15:10 coventry: Don't try to frighten us with your sorcerer's ways, Lord bitemyapp.

15:11 lvh: I have a lot of defns with like three words in it. Does that mean I'm doing it right, or wrong?

15:11 arrdem: bitemyapp + Cthulu for channel dictators, why vote for the lesser evils?

15:11 cemerick: gtrak: ok, yeah, verified there's no way for an op to hose a session if it misbehaves. That's only relevant for eval, since only one eval can occur at a time per session.

15:12 I should have called the eval op "this-is-for-the-user-dammit"

15:12 gtrak: hopefully that means the extra decoupling is always superfluous for not-eval.

15:12 cemerick: should be, yeah

15:12 bitemyapp: arrdem: that gem belongs to pelotom, but I liked it :)

15:18 gtrak: yak-shaving, I was trying really hard to avoid elisp up till now

15:18 bitemyapp: gtrak: drink deep

15:18 gtrak: I did last night and this morning.

15:19 arrdem: gtrak: lifting & running usually go well with the above..

15:20 bitemyapp: arrdem: HHH

15:21 magnars: Using Enlive, it ruins my HTML markup - this is valid HTML5 <a><div></div></a>, but Enlive (or Tagsoup, or what that is using), insists on moving the <div> out of the <a>, since <a> was an inline-only element in some old HTML-spec. ... Any ideas other than "don't use Enlive"?

15:21 arrdem: bitemyapp: ???

15:22 bitemyapp: arrdem: hash house harriers :)

15:22 hiredman: what do you mean insists?

15:22 bitemyapp: magnars: I don't like Enlive, but it *is* bad HTML.

15:24 lvh: if I want my function to return a seq-of-seqs and another seq, the right thing to do is to return a 2-vector, right?

15:24 gtrak: cemerick: the op thing isn't so much about the ops, but the decoupling it provides, it would be nice if we could standardize on ops along the way, since that means we don't have to reinvent it M-IDEs x N-clojure-impls x O-ops times.

15:25 magnars: bitemyapp: No, sorry, that's pretty outdated thinking. http://html5doctor.com/block-level-links-in-html-5/ Also, clicking entire block elements to navigate is a good thing.

15:25 arrdem: lvh: in general yes.

15:25 kzar: magnars: I guess raise an issue if you think it's wrong

15:25 bitemyapp: magnars: the former example is a bit of a strawman, but as thou wilt.

15:25 kzar: / pull request

15:26 gtrak: I'm hoping we can just bundle a bunch of middlewares at some point.

15:26 magnars: kzar: sure, it's open source, I am aware of how that works - I was just wondering if there was already some way around it before going down that path.

15:26 hiredman: I still want to know what he means by insists, does he mean enlive moves it, or he has to move it to make enlive happy

15:27 magnars: hiredman: It moves it out for me.

15:27 hiredman: huh

15:27 magnars: hiredman: pretty much like a browser would do when encountering a <p> nested inside <p>. Closing it early, if you will.

15:29 stuartsierra: magnars: You can override the parser that Enlive uses.

15:29 dnolen: magnars: I'm pretty sure that's tagsoup doing that

15:29 magnars: Thanks, I'll look into switching out the parser.

15:32 paulswilliamsesq: Hi all, hopefully a simple question - trying to connect Lighttable 0.6.0 on Mavericks to a new Leiningen (2.3.3) project. No errors, but don't receive the connecting prompt and no evaluation occurs. Any pointers?

15:38 jcromartie: paulswilliamsesq: open a file in your project and press Command+Enter

15:39 I don't know why it doesn't do anything when you connect but it threw me off

15:39 lvh: hm

15:39 is nil also the empty list in clojure?

15:39 I'm trying to figure out why (nil? (vals {}) )

15:40 stuartsierra: lvh: No.

15:40 teslanick: .(vals {})

15:40 lvh: I was expecting [].

15:40 stuartsierra: (= () nil)

15:40 lvh: (or ())

15:40 stuartsierra: ,(= () nil)

15:40 clojurebot: false

15:40 lvh: ,(vals {})

15:40 clojurebot: nil

15:40 Wild_Cat: lvh: only false and nil are falsy, btw.

15:40 AimHere: ,(empty? nil)

15:40 clojurebot: true

15:41 stuartsierra: lvh: `vals` returns a sequence. An empty sequence can be nil.

15:41 ,(seq [])

15:41 clojurebot: nil

15:41 Wild_Cat: stuartsierra: wait, you mean nil implements the seq interface?

15:41 stuartsierra: Wild_Cat: No, nil is just null.

15:41 but `seq` on any empty thing is defined to return nil.

15:42 Wild_Cat: stuartsierra: then I don't understand why nil can be considered an empty sequence.

15:42 lvh: so, vals returns a sequence, or maybe nil

15:42 Wild_Cat: I'd expect (vals {}) to return [] or (), not nil.

15:42 stuartsierra: Any function which returns a sequence can legitimately return nil.

15:43 Wild_Cat: yeah, but doesn't nil mean "special case, something went wrong" in that case?

15:43 stuartsierra: Wild_Cat: Not necessarily. `nil` in those cases just means "nothing"

15:43 hiredman: no

15:43 lvh: stuartsierra: okay, accruing fact

15:43 Wild_Cat: whereas "empty sequence" is not a special case. It's just something that, when iterated upon, returns no values.

15:43 lvh: I still don't get why it doesn't do [] instead

15:44 hiredman: there used to not be an empty seq

15:44 so you really either had nil, or a seq with stuff in it

15:44 Wild_Cat: well, if anything nil can be iterated upon, it seems.

15:44 ,(map inc nil)

15:44 clojurebot: ()

15:44 paulswilliamsesq: jcromartie: cheers - that worked. Yeah, not intuitive. Normally and vim-fireplace guy, but thought I'd give this lighttable a crack. After learning, it looks great.

15:44 Wild_Cat: so there's that.

15:45 lvh: Wild_Cat: maybe that just specialcases nil

15:45 angusiguess: ,(cons 1 nil)

15:45 clojurebot: (1)

15:45 `cbp: ,(iterate inc nil)

15:45 clojurebot: #<NullPointerException java.lang.NullPointerException>

15:45 michaniskin: ,[(first nil) (rest nil) (seq nil)]

15:45 clojurebot: [nil () nil]

15:45 Wild_Cat: lvh: figures. So that means nil can be used as a list/vector/map -- it's considered an empty one.

15:46 michaniskin: ,(conj nil 1)

15:46 clojurebot: (1)

15:46 riley526: ,(next nil)

15:46 clojurebot: nil

15:46 Wild_Cat: it's bizarre, but okay,

15:47 stuartsierra: It's not that `nil` can be used as a collection. Most of the sequence-oriented functions call `seq` on their argument. `seq` on nil or an empty collection returns nil.

15:47 `rest` is a rare exception.

15:47 Wild_Cat: ,(empty? nil)

15:47 clojurebot: true

15:47 stuartsierra: `(empty? x)` is just `(not (seq x))`

15:48 riley526: hm

15:48 Wild_Cat: stuartsierra: which actually means seq *has* to return nil on an empty container.

15:48 stuartsierra: yes

15:48 Wild_Cat: ,(not [])

15:48 clojurebot: false

15:48 Wild_Cat: I'm not sure how I feel about that but okay, I guess I'll just have to accept it and remember it :p

15:48 stuartsierra: [] is an Object, which is truthy.

15:48 (seq []) => nil which is falsey.

15:49 Wild_Cat: yeah.

15:52 lvh: in a loop/recur situation, where the body of the loop is an if determining the terminating condition; is there a preference for putting the terminal case first vs second?

15:53 Sorry for my nomenclature. I'm new.

15:53 gfredericks: lvh: I don't think there's a preference

15:54 cark: i prefer my tests to be positive like (if (seq instead of (if-not (seq .... so that's what decides of the order in my loops

15:54 gfredericks: there _is_ a tendency for new people to overuse loop/recur though :)

15:54 bmath: lvh: I'm not sure there's a clear winner all the time. with recursion you sometimes see the base case first for tail-recursive optimizations… but I think that's an artefact of recursion and detecting tail-recursion may be starer than that by now

15:55 stuartsierra: lvh: The docstring for `empty?` says `seq` should be preferred over `(not (empty? …)` but not everyone agrees.

15:56 deadghost: anyone happen to have compojure/enlive project code I can see?

15:56 lvh: stuartsierra: is that "seq?"? I don't understand how seq can replace empty?

15:56 cark: ,(seq [])

15:56 clojurebot: nil

15:56 stuartsierra: lvh: Remember `(seq [])` => nil which is logical false.

15:57 lvh: stuartsierra: ohhh

15:57 stuartsierra: but why would I want to do that when I can do seq? instead?

15:57 stuartsierra: `seq?` is different

15:58 `seq?` just tests if something is of a type implementing the ISeq interface.

15:58 lvh: (if (seq a-thing) ...) seems wasteful; I'm not using the seq, I just want to know if it's empty or not

15:58 oh

15:58 bbloom: lvh: but what is "emptiness" anyway?

15:58 gtrak: I prefer terminating case first.

15:58 stuartsierra: And since lots of built-in functions call `seq` automatically, this can lead to more concise code.

15:59 gtrak: I think because it makes it easier to ignore visually.

15:59 lvh: bbloom: there are no more things in this list

15:59 bbloom: gtrak: yeah, that annoys me a bit too. i tend to do (if (seq ...) TODO then start typing

16:00 gtrak: bbloom: I've wanted an if-not-let :-)

16:00 bbloom: lvh: but what if you don't know the list yet? if you have a lazy sequence, determining if it's empty means you need to realize/force it

16:00 stuartsierra: There is an if-not

16:00 bbloom: lvh: in that case, it's not wasteful to call seq, it's inherit

16:00 also:

16:00 edbond: just saw this in enliven #_#_#=(eval org.w3c.css.sac.Condition/SAC_PSEUDO_CLASS_CONDITION) what is this?

16:00 bbloom: (source empty?)

16:01 edbond: https://github.com/cgrand/enliven/blob/master/src/enliven/html.clj#L113

16:01 gtrak: stuartsierra: sure.. I mean I could build one if I really wanted, but I figured it was more unclear than useful.

16:01 cark: bbloom: so what the binding would work in the "else" part ?

16:01 edbond: sorry, it's commented out. I thought this some cool optimization macro :)

16:02 lvh: bbloom: oh, okay :)

16:02 gtrak: (if-not-let [[s & more] (seq my-seq)]] ... shudders.

16:02 cark: i mean gtrak

16:02 lvh: What's conj, except add-all-of-these-things-in-this-seq-separately, not add-this-entire-seq

16:02 gtrak: cark: the second.

16:02 is the truthy branch

16:03 cark: gtrak: man that sound horrible =)

16:03 lvh: I want (add [[]] [[] [] []]) --> [[] [] [] []]

16:03 (if anyone speaks python: I want list.extend, not list.append)

16:03 gtrak: cark: especially when you consider how easy it is to forget that what needs to be truthy is the seq, not the bindings.

16:03 gfredericks: ,(into [[]] [[] [] []])

16:03 clojurebot: [[] [] [] []]

16:04 mikerod: ,(concat [[]] [[] [] []])

16:04 clojurebot: ([] [] [] [])

16:04 mikerod: lazy variety

16:04 dee5: hello, would anyone familiar with midje know how to stub a function for an arbitrary number of arguments?

16:05 I'm currently using (provided (f anything anything anything) => irrelevant :times 0

16:05 lvh: (inc gfredericks)

16:05 (inc mikerod)

16:05 bbloom: lvh: use into

16:05 matt444: is there an easy way to combine leiningen tasks together?

16:06 technomancy: matt444: there are lots of higher-order lein tasks, yeah

16:07 lvh: last claims to do linear time; I presume that for vecs its faster

16:07 how do I spell everything-besides-last? I have something that came out of partition-all; the last odd element out has to be treated specially

16:08 technomancy: butlast?

16:08 lvh: Yay

16:08 matt444: technomancy: For example in Grunt (node) you can say registerTask('test' ['frontend', 'backend']) which combines the two separate tasks into one. Is there something like that for leiningen? Or is this what :hooks is about?

16:09 technomancy: when you see a weird name like that, there's a good chance it came from CL

16:09 matt444: so... depends on how you want to combine them. if it's just "run this, then that" you use the `do` task

16:09 there are other valid combinators though

16:10 :aliases {"stuff" ["do" "test," "deploy"]} or something

16:10 matt444: awesome, i'll research from here, thanks

16:10 technomancy: https://github.com/technomancy/lein-thrush

16:10 lvh: ugh; apparently I am calling a vector somewhere actual: java.lang.IllegalArgumentException: Key must be integer

16:10 but I can't see where :/

16:12 It's complaining about this line, but I can't see what's wrong with it: (let [these-pairs (pairs (first subgroups))]

16:12 (pairs is just (parition-all 2 %))

16:14 gfredericks: lvh: is there some way pairs is accidentaly a vector?

16:14 lvh: oh.

16:14 gfredericks: nasty habit I picked up from CL, sorry

16:16 AeroNotix: what's the idiomatic why to check the types of stuff?

16:16 lvh: so, is "pairs" a bad function name, or is "pairs" a bad variable name, or both/neither?

16:17 technomancy: nothing wrong with that name

16:18 gfredericks: pears is a tastier name

16:18 lvh: rightn ow I fixed it by putting the- in front of the variables (also what should I call it? it's not a variable; it's a thing in a let clause)

16:19 arrdem: (inc gfredericks)

16:19 gfredericks: lvh: a local

16:19 arrdem: lazybot where art thou

16:19 gfredericks: as in "the locals get really annoyed with the tourists swarming about during the festival"

16:20 s/tourists/vars/

16:20 sritchie: cemerick: the friction is more about who's handling the response

16:20 cemerick: liberator's handler, or some friend workflow's handler

16:20 (the unauthorized response, that is)

16:22 lvh: so, my code, as expected, doesn't work :-p

16:22 gfredericks: add moar parens

16:23 lvh: hey, that worked

16:24 https://gist.github.com/lvh/8481597

16:24 gfredericks: parens are like pomegranates for compilers

16:25 lvh: oh, actually, I think I might want conj

16:25 nope, I don't

16:26 gtrak: gfredericks: gimme a fractal IDE anytime.

16:26 ivan: https://ludios.org/tmp/cljsbuild-smb.png I'm seeing this dialog in IDEA quite frequently; this file is being read by another host via a SMB share, and IDEA can't save it

16:26 starting IDEA with -Didea.no.safe.write=true didn't help

16:26 lvh: ivan: it's funny how I go to different channels and see all the same people

16:26 ivan: I wonder if there is some way to get lein-cljsbuild to not hold onto handles or something

16:27 or some secret SMB flags or some way to hack IDEA into behaving

16:28 technomancy: IDEA is enterprise software. you can't use it at a small-to-medium business.

16:28 * gfredericks gives gtrak a fractal IDE anytime

16:29 technomancy: sorry

16:29 TEttinger: technomancy was that a pun on SMB?

16:29 technomancy: attempted pun

16:30 lvh: oh, wait, I found the bug

16:30 so, I want last and butlast, except when there's one element, then I want last to mean that element, and butlast to mean nothing.

16:31 gfredericks: normalize data as early as possible

16:32 lvh: gfredericks: maybe partition-all is not what I want :)

16:32 LBRapid: Real beginner question: To get the metadata of an object, why do I need to run (meta #'+) versus just (meta +)?

16:32 function, not object

16:32 technomancy: LBRapid: it's just a historical quirk

16:33 it used to be that functions could not have metadata attached to them

16:33 these days you can attach metadata, but it doesn't happen by default for some reason

16:33 memory usage, I guess

16:33 LBRapid: technomancy: Thanks for the explanation

16:33 hcumberdale: Hi :)

16:34 Is marmalade-repo offline?

16:34 technomancy: hcumberdale: yes =(

16:35 lvh: okay, so how can I get [(partition 2 it) (the-rest-that-didnt-make-it-in-the-first-term it)]

16:35 hcumberdale: what happened technomancy?

16:35 had a lot of problems. Already tought about mirroring it 4 free

16:35 technomancy: hcumberdale: node.js is screwing everything up

16:36 there's an experimental port at http://marmalade-repo.ferrier.me.uk/ that seems to be working ok; could try falling back to that for now

16:36 arrdem: lvh: (rest)?

16:36 hcumberdale: arggggg this fancy new technology

16:36 arrdem: ,(rest [1, 2, 3])

16:36 clojurebot: (2 3)

16:36 technomancy: hcumberdale: moving off node is the top priority, but it's all volunteer run

16:36 mikerod: bbloom: are you suggesting that concat is bad?

16:37 gfredericks: concat is triksy if you don't have any use for laziness

16:37 mikerod: gfredericks: yes, I've been tricked by it with StackOverflow before indeed

16:37 lvh: arrdem: sorry, my description was bad

16:37 mikerod: what about when you want to concat several seqs together though

16:38 ,(concat ['a] ['b] ['c])

16:38 clojurebot: (a b c)

16:38 lvh: arrdem: (kinda-partition 2 [1 2 3 4 5]) -> [[[1 2] [3 4]], [5]]

16:38 gfredericks: I think it's fine; but I think people initially expect that it's a great solution for appending to the end of anything

16:38 lvh: (partition 2 [1 2 3 4 5]) gets me the first part; partition all gets me those two concatenated

16:39 mikerod: lazyness scares me at times. mostly when dealing with macros that perform lazy operations.

16:39 hcumberdale: technomancy: thx

16:39 mikerod: since the env can be different by the time the lazy things are evaluated

16:39 arrdem: mikerod: as long as you write pure code it doesn't matter!

16:39 mikerod: what is a good pattern for non-lazy concatenation of an unknown # of coll's?

16:40 arrdem: in theory...

16:40 arrdem: (doall (reduce concat seqs))

16:40 egghead: mapcat identity :)

16:40 mikerod: I'm seeing lazy answers

16:40 well, not the doall

16:40 egghead: mikerod: reduce isn't lazy

16:40 hiredman: mikerod: reduce into

16:41 mikerod: arrdem: yeah, why doall outside of a reduce

16:41 ztellman: mikerod: apply concat

16:41 arrdem: mikerod: I thought that reduce was lazy. apparently I'm wrong.

16:41 bitemyapp: mapcat concat if you're a true believer.

16:41 mikerod: hiredman: reduce into - sounds reasonable

16:41 egghead: lol

16:41 hiredman: mikerod: if you are running into those issues in a macro that is a terrible macro

16:41 mikerod: hiredman: DSL drama

16:42 jcromartie: any Enlive wizards want to tell me if there's a better way to do this: https://gist.github.com/jcromartie/4deb16fd17c673cb50a3

16:42 hiredman: that is a terrible dsl

16:42 mikerod: :)

16:42 hiredman: don't use it

16:42 jcromartie: i.e. I have a <li> with an <a> in it, and I want to clone the li but alter the a

16:42 clojurebot: Cool story bro.

16:42 bitemyapp: mikerod: laziness isn't scary

16:42 egghead: bitemyapp: lol mapcat concat

16:43 i like it

16:43 arrdem: bitemyapp: given a compiler capble of reasoning about it, yes.

16:43 * arrdem missed an a

16:43 jcromartie: derp

16:43 clone-for has an implicit at?

16:44 yay

16:44 mikerod: bitemyapp: well, stack overflow from a nested concat can be scary; I'm just finding that lazy things tend to sneak up on me later; I'm just too much of a n00b most likely

16:45 hiredman: don't use libraries/macros/functions/etc by people who don't know what they are doing and are clearly just blasting out whatever while intoxicated on the heady rush of using the jvm without java

16:45 bitemyapp: egghead: the choice of programmers of distinction and honor.

16:46 jcromartie: hiredman: while that's good advice, it's also a bit elitist no? they need feedback

16:47 mikerod: haha

16:50 benkay: hey all - I'm running a ring server from my repl in emacs, but haven't figured out how to capture stdout and also run the ring server with :join :false - suggestions?

16:51 mikerod: hiredman: I actually retract my thoughts on lazy things happening in macros causing issues. I can't think of an example of that. I guess the only thing that has really caused me problems before was unknown nesting depths with concat.

16:52 gfredericks: I've had issues with surprising head-holding due to closures

16:52 mikerod: but yes, I have experienced macro abuse

16:52 I've had trouble with macros returning anonymous fn's with closures

16:52 since that doesn't really work

16:52 but there are a few posts out there about that

16:53 maravillas: benkay: have you looked in your *nrepl-server ...* buffer for output?

16:53 Profpatsch: Is it normal that with (defmacro foo [x y & args]) args is passed as a LIST? Like in (foo :x :y :z :baz) args is (:z :baz).

16:53 benkay: thanks maravillas!

16:53 maravillas: yw!

16:54 Profpatsch: Which screws stuff up when used in a macro.

16:54 amalloy: Profpatsch: that's really like...exactly what & does

16:54 arrdem: Profpatsch: when used how?

16:54 amalloy: what else would it do?

16:55 TEttinger: Profpatsch, & is a seq yeah

16:56 Profpatsch: So, I’ve got (defmacro baz [& args] args) and (baz :z {:z 42}) returns 42.

16:56 mikerod: haha

16:56 macroexpand-1 that

16:57 (macroexpand-1 '(baz :z {:z 42}))

16:57 Profpatsch: But I want to return (:z {:z 42}). The best I’ve come up with so far is (defmacro baz [& args] `~'args).

16:57 Which is kind of creepy.

16:58 mikerod: (defmacro baz [& args] `'~args) you mean?

16:58 Profpatsch: Yeah.

16:58 mikerod: seems legit

16:58 jcromartie: why do you want a macro that returns its args?

16:59 stuartsierra: Maybe something like (defmacro baz [& args] `[~@args]) is what you want.

16:59 Profpatsch: I thought &args would return somethign sensible, like, a list.

16:59 mikerod: it does

16:59 jcromartie: Profpatsch: it is *calling* that list

16:59 mikerod: then it is evaluated

16:59 amalloy: stuartsierra: that's just (def baz vector)

16:59 jcromartie: evaluating

16:59 stuartsierra: amalloy: I know

16:59 jcromartie: which is (:z {:z 42})

16:59 Profpatsch: Nah, you know, whatever [] is called. ;)

16:59 So it isn’t evaled by default in macros.

17:00 mikerod: hmmm

17:00 Profpatsch: Right, vector.

17:00 mikerod: I guess that is an interesting thought

17:00 jcromartie: Profpatsch: what is the purpose of this macro?

17:00 edbond: cljs/async/alts! doesn't consume channels - https://www.refheap.com/24570 Am I miss something there?

17:00 jcromartie: seems kind of like do?

17:00 or not?

17:00 mikerod: Why was the variadic args, via & a seq instead of a vector

17:00 jcromartie: not at all actually… hm sorry

17:01 amalloy: mikerod: (apply (fn [& args] (take 3 args)) (range))

17:01 Profpatsch: mikerod: Making it a vector would probably destroy things no one except Hickey thought about. ;)

17:01 stuartsierra: It's a sequence because it can be lazy.

17:01 jcromartie: I don't think it's possible to make a form that expands into more than one form

17:01 that's the fundamental issue

17:02 stuartsierra: ,(apply take 3 (range))

17:02 clojurebot: #<OutOfMemoryError java.lang.OutOfMemoryError: Java heap space>

17:02 jcromartie: macros are 1 form in 1 form out

17:02 Profpatsch: jcromartie: I actually want to do something more sensible, but I tried the basic things first so I don’t have to spend hours searching for a mistake.

17:02 jcromartie: i.e. the macro form is replaced

17:02 `cbp: that didnt seem to work

17:02 jcromartie: Profpatsch: well maybe there's a better solution than whatever this is :)

17:03 mikerod: stuartsierra: that makes sense, supporting laziness

17:03 stuartsierra: Arg. That's not what I meant.

17:03 tim_: ,(apply + (range 44))

17:03 clojurebot: 946

17:03 mikerod: well, amalloy answered as well :)

17:03 tim_: something like that?

17:03 stuartsierra: ,(apply (fn [x & args] x) (range))

17:03 clojurebot: 0

17:03 jcromartie: Profpatsch: and a macro like "(foo :x :y)" that evaluates to ":x :y" is equivalent to ":x :y" in the first place so I don't see the need

17:03 it's algebra

17:04 it's simply unnecessary

17:04 tbaldridge: stuartsierra: there we go. tjat

17:04 benkay: maravillas: is it not idiomatic to want to see that kind of messaging in the repl buffer?

17:04 tbaldridge: stuartsierra: that's a good example, I'll have to remember that one.

17:04 hlship: I'm starting to look at Om right now

17:04 and this (week) is my first use of ClojureScript

17:04 stuartsierra: tbaldridge: I remember trying to implement `apply` in ClojureScript way back when and getting stuck on that very case.

17:04 Profpatsch: jcromartie: That’s what I meant. I want to do something more complicated but I first had to experiment around with the basic cases.

17:04 maravillas: iirc, there's some technical challenge that's keeping it separate at the moment. i'm not clear on the details

17:05 jcromartie: Profpatsch: I don't think you can do it.

17:05 hlship: In the ToDo example, there's a #js reader macro

17:05 jcromartie: Profpatsch: you need to redefine your problem :)

17:05 maravillas: cemerick briefly mentioned it somewhat recently

17:05 hlship: Can't find documentation for it, looks like it might do the same thing as clj->js

17:05 bbloom: hlship: it is different than clj->js

17:05 stuartsierra: hlship: #js is a recent addition that creates literal JavaScript arrays & objects.

17:05 bbloom: hlship: it is shallow

17:06 hlship: cool

17:06 Profpatsch: jcromartie: Wat. My problem is a different one. I’m just trying to grok macros. ;)

17:06 hlship: very hard to search the web for "#js"

17:06 jcromartie: OK

17:07 Profpatsch: so the lesson is that a macro form is always expanded to a single form :)

17:07 Profpatsch: hlship: http://symbolhound.com

17:07 jcromartie: Actually, my lesson kind of was that &args is a seq, which is called when used in a macro. :)

17:08 lvh: How do I remove one layer of parens in '((5))?

17:09 OscarZ: i have a lazy seq x and when i use (println x) on it, it prints out nicely.. how can i get the same output as a string? I tried (str x) but it doesnt quite do the trick :)

17:09 lvh: I guess I want itertools.chain.from_iterable in python

17:09 amalloy: ,(apply concat '((5)))

17:09 clojurebot: (5)

17:09 lvh: oh, right, apply is how you do that.

17:09 stuartsierra: or `first`

17:09 hlship: #js

17:09 lvh: stuartsierra: well, for now that'll work, because it can only ever be one element

17:09 hlship: (still waiting for a system that tracks focus based on what window I'm looking at)

17:10 (I type into the wrong window ALL the fucking time)

17:10 ivan: do you look at your keyboard while you type?

17:10 arrdem: hlship: xmonad, Awesome and a host of tiling window managers to that with the mouse...

17:11 hlship: I want to build eye tracking for mouse control sometime to get exactly what you just described.

17:11 bitemyapp: hlship: use XMonad! It's wonderful. You can set GTK/Gnome to focus-follows-mouse too!

17:12 hlship: Not ready to give up the Mac

17:12 technomancy: focus follows head

17:12 need a kind of digital compass thing

17:12 arrdem: yeah I'm concerned that any static gaze tracker will break down on 2+ screens...

17:13 hlship: part of it is retraining me to use a trackpad after decades with a mouse

17:13 technomancy: I actually do want to build that into xmonad fwiw

17:13 arrdem: I find myself turning to glance at my 2nd and 3rd all the time.

17:13 hlship: You could imagine a invisible-to-the-eye flicker in every window that would identify, to a head mounted sensor, exactly which window was being looked at

17:13 technomancy: arrdem: seems like the main problem would be glancing without turning your head

17:13 hlship: kind of like the way the old nintendo light gun worked

17:14 ivan: I frequently type into something while looking at something else

17:15 arrdem: technomancy: computer vision isn't my specialty. I played with detecting which screen I was facing for a while, but never got anywhere with it.

17:15 technomancy: arrdem: I was thinking of something you'd wear on your head

17:15 because I work out of a shed in my back yard where no one can actually see me

17:15 so looking ridiculous is not off the table

17:15 angusiguess: I wonder how feasible tracking pupils would be.

17:15 arrdem: haha.

17:16 * arrdem digs for an old MIT Technology Review issue

17:17 stuartsierra: There are IR head-trackers that use a reflector on a hat.

17:17 Flight Sims can use them.

17:17 arrdem: stuartsierra: that's what I'm digging for atm...

17:18 Profpatsch: So now my real macro problem: https://bigmac.caelum.uberspace.de/paste/macro.html

17:18 stuartsierra: I recall some mention of pupil-tracking using nothing but a laptop's built-in camera.

17:18 arrdem: http://www.naturalpoint.com/trackir/

17:18 lvh: Is it polite to ask for code review? I'm new and want to cleanse my clj from dumb things.

17:18 (If so, https://gist.github.com/8482701 ; please and thank you :))

17:18 arrdem: lvh: totally.

17:18 Profpatsch: What to do about props being a list now?

17:19 lvh: I guess group-by-prefs is a really stupid function

17:19 but when I first wrote it, prefs wasn't a thing.

17:19 Profpatsch: I have no idea how to quote/splice/unqote/stuff props no.

17:19 arrdem: throw the Vim Clutch peddal in with this and we could have a full developer rig! :P

17:21 technomancy: https://www.linux.com/learn/tutorials/550880-weekend-project-take-a-tour-of-open-source-eye-tracking-software

17:21 technomancy: looks like webcam only is viable...

17:21 I may have to play with this at some point...

17:21 Profpatsch: jcromartie: What would you do about prefs here: https://bigmac.caelum.uberspace.de/paste/macro.html

17:22 technomancy: probably hard to do if the lighting changes dramatically though

17:22 arrdem: lvh: not that it matters, but lists (parens not braces) are used in the ns form...

17:22 `cbp: lvh: this seems redundant (split-with #(= (count %) 2) (partition-all 2 subgroup))

17:22 angusiguess: Guess that means I can't work in da club anymore :(

17:23 arrdem: lvh: prefs could just be a def not a defn... def can have a docstring.

17:24 `cbp: oh i guess not nevermind me

17:24 the -all part didnt click heh

17:24 arrdem: lvh: pair-with-matching-perfs could probably be (reduce) rather than (loop) because there is no case in which you are really backing up...

17:24 lvh: but nothing I find personally offensive in there...

17:27 lvh: `cbp: why is that redundant?

17:27 `cbp: I want the "tail" separately.

17:27 `cbp: lvh: i was mistaken

17:28 lvh: `cbp: oh, okay, no problem; that is definitely the one that makes me go "uhh wa"

17:29 arrdem: so (def prefs

17:29 arrdem: remove the [x], remove the call, remove outer braces?

17:29 arrdem: lvh: yeah but that's totally a style thing.

17:29 lvh: the problem with using a repl is that I'm always afraid I'm using old code

17:29 so I don't know anything about reduce, I will google that

17:29 arrdem: thanks for the review

17:31 arrdem: I don't understand. Which one is the binary callable?

17:32 arrdem: lvh: so (juxt) returns a function. If you write (defn foo [x] ((juxt a b c) x)), this is really (def foo (juxt a b c))

17:32 lvh: not sure what you mean by binary callable

17:32 justin_smith: arrdem: the difference is the defn shows prettier in stack traces

17:33 arrdem: justin_smith: ah yes. this is true.

17:33 lvh: arrdem: no, I got that

17:33 arrdem: justin_smith: also you do get the single arity in gen'd documents.

17:33 lvh: arrdem: I meant the reduce comment

17:34 arrdem: lvh: so essentially what you are doing here is building a pair of sequences [all-pairs, all-leftovers]

17:34 lvh: this is defined by joining the previous pair [pairs, leftovers] to a new call to (pairs-and-leftovers).

17:35 lvh: arrdem: yep. That's, to my mind, what the loop/recur spells

17:36 arrdem: lvh: you could also write this as (reduce (fn [[pairs, leftovers] subg] (let [[np nl] (pairs-and-leftovers subg)] [(into pairs np) (into leftovers nl)])) [[][]] subgroups)

17:36 ,(doc reduce)

17:36 clojurebot: "([f coll] [f val coll]); f should be a function of 2 arguments. If val is not supplied, returns the result of applying f to the first 2 items in coll, then applying f to that result and the 3rd item, etc. If coll contains no items, f must accept no arguments as well, and reduce returns the result of calling f with no arguments. If coll has only 1 item, it is returned and f is not called. If val i...

17:37 justin_smith: arrdem: lvh ahh yeah, I was the one who initially sketched it out as a loop/recur but it is better as a reduce (taking each item in turn, and attempting to match it with leftovers, putting it in pairs if so, leftovers if not

17:37 )

17:37 arrdem: justin_smith: the reason I say it's a reduce is that there is no such conditional... the only condition is the termination case which you get for free with reduce.

17:39 justin_smith: when I initially suggested the loop, it was a flat list

17:39 so it was a partitioning, in a way, with the potential of taking something out of leftovers and into pairs at each step

17:46 lvh: arrdem: is subg just a different way of spelling subgroups or is it actually a differnt variable? I can't tell where it's defined

17:47 arrdem: lvh: it's just a different spelling of subgroups since I'm live coding in channel :P

17:48 well. no it isn't.

17:48 so... did you understand what (reduce) does with its fn argument?

17:48 subg as I use it above is singular. it is _the_ subgroup which is being operated on in the current reduce iteration.

17:49 so what reduce will do, is it will take the pair [[], []] and bind it to [pairs, leftovers].

17:50 I then compute the new pairs-and-leftovers of the current subgroup, just as you do with (first subgroups) except that here I don't need the first because reduce has pulled off the head of the sequence for me.

17:50 then the into is just your same update, in that I build a new [pairs, leftovers] vector to feed into the next iteration or return.

17:50 lvh: arrdem: it calls it on val, and the next thing in seq, right

17:51 I didn't get that it binds anything. I thought it was a function

17:51 arrdem: lvh: <cptnjacksparrow> savvy? </cptnjacksparrow>

17:51 lvh: correct. I'm making a leap here to what the fn will do when invoked by reduce.

17:51 lvh: oh. okay.

17:52 arrdem: *inductive leap

17:53 lvh: arrdem: okay, I get why I didn't grok it

17:53 arrdem: I was parsing the [[a b] c] as destructuring let

17:54 it's a destructuring function arg spec :)

17:54 arrdem: lvh: in the function arguments?

17:54 lvh: it worked a lot better when I wrote it down :)

17:54 arrdem: lvh: bingo! argument destructuring is so great :D

17:55 also note, if you want to horrify yourself with what you could do, that destructuring is supported to arbitrary depth. So nested map destructurings are totally legit 0.o

17:56 lvh: this channel is great; I keep seeing all the same people

17:56 (hi Luyt )

18:06 bitemyapp: arrdem: general pattern matching that takes it a step further is even better :)

18:14 shafire: wow

18:14 how many people are here?

18:14 arrdem: about 850

18:15 shafire: :O

18:22 amalloy: in this irc channel? 733

18:23 which, i mean, i guess is about 850

18:24 hey yogthos, i was curious why you posted http://www.reddit.com/r/Clojure/comments/1vc0at/clojurescript_gc_and_memory_leaks/ - that's not your blog, right?

18:24 akurilin: Quick question: if I want to serialize operations on a separate thread, is an agent the right construct to use? In my case, I don't have a chunk of state I want to maintain, just want to serialize a side-effecting operation.

18:27 amalloy: agents are fine. really a java.util.concurrent.Executor is "right", but nothing terrible will happen if you use an agent, and they're easier

18:28 akurilin: amalloy: not a big Java person myself, do you mind just giving me the gist of why the former is right?

18:29 amalloy: because agents are just a wrapper around some j.u.c stuff with a chunk of state added. if you don't want the state, they don't bring anything to the table

18:31 bbloom: i find that having the state there is useful sooner rather than later for stats or debugging or something

18:31 i'm guilty of using an agent w/o state out of laziness, but quickly find a need to keep a count or the most recent whatever

18:31 akurilin: amalloy: I see, good point.

19:02 bitemyapp: amalloy: he posts all kinds of things on the subreddit.

19:02 akurilin: So everybody on this side of the country is going to clojurewest I imagine?

19:02 Trying to figure out if I should get the tix.

19:03 bitemyapp: akurilin: I'm iffy on it.

19:03 * arrdem checks that doing a C/W travel estimate is on his deadlines list

19:03 akurilin: I just never really met in person a lot of the fine gents on this channel who have been gracious with me for the past year :)

19:04 Bronsa: wtf. so (.get ^:foo [0] 0) reports a reflection warning while (.get [0] 0) no

19:05 akurilin: bitemyapp: can you have your gig comp it?

19:05 bitemyapp: akurilin: def could.

19:05 akurilin: it's all about time, not money.

19:05 mikeyg6754: Hello everyone, I've been looking at options for production clojure web app deployment. I will be running on Amazon AWS. Any suggestions? Jetty? Apache? Nginx?

19:05 `cbp: http-kit

19:06 technomancy: mikeyg6754: jetty is the simplest way to go

19:06 bitemyapp: mikeyg6754: http-kit is simple and you should use it.

19:06 mikeyg6754: [org.httpkit.server :refer [run-server]] -- (run-server handler {:port 3000})

19:06 mikeyg6754: bada bing, bada boom.

19:07 mikeyg6754: hold onto the function it returns if you want to be able to kill the server instance off.

19:07 cark: bitemyapp: you need a reverse proxy for http-kit don't you ?

19:08 bitemyapp: to do SSL i mean

19:08 bitemyapp: cark: a reverse proxy is a good idea regardless of whether you're using http-kit or jetty.

19:08 mikeyg6754: bitemyapp: http-kit looks pretty interesting

19:08 bitemyapp: cark: you should let things like nginx handle SSL, yes.

19:08 cark: bitemyapp: i'm not doing thousands of connections a second, jetty is good enough for me =)

19:09 mikeyg6754: my company likes Apache, I'd prefer Nginx, but both have "Reverse Proxy" functionality

19:09 bitemyapp: mikeyg6754: whatevs.

19:09 justin_smith: mikeyg6754: putting nginx in front of apache is perfectly cromulent

19:09 technomancy: justin_smith: really?

19:09 `cbp: wat

19:10 bitemyapp: I've done it before.

19:10 I don't remember why, but I've done it before.

19:10 justin_smith: I've seen it done many times

19:11 technomancy: for a single server that has to be responsible for apps written in mod_php alongside something reasonable?

19:11 bitemyapp: cark: part of the reason I use http-kit is because it's small enough to be understood.

19:11 technomancy: I think it was something like that where apache was handling a proglang runtime and I didn't really trust it to "front" the server and handle static assets, so I handed that off to nginx.

19:11 haproxy on the outer layer.

19:11 mikeyg6754: Thanks for your input everyone, http-kit looks like it would be worth using

19:11 bitemyapp: (inc http-kit)

19:11 ...

19:12 justin_smith: bitemyapp: I think lazybot is on vacation

19:12 `cbp: hes dead gim

19:12 jim

19:12 justin_smith: and yes, http-kit is awesome

19:12 `cbp: maybe lazybot is being really lazy about logging in

19:13 `cbp: need TimMc's mystical powers to summon it

19:13 back from the dead

19:14 bitemyapp: Tim the Necromancer

19:22 yogthos: amalloy: no it's not mine, figured somebody would know what was going on :)

19:22 amalloy: I didn't look too hard myself, but good catch with the laziness

19:23 hlship: I wish http-kit supported https, in which case I would be using it.

19:25 gtrak: cljs autocomplete: http://i.imgur.com/GmBJ6Fj.png :-)

19:25 * bitemyapp scowls from his perch above the chat room at hlship and begins sharpening knives absentmindedly

19:26 gtrak: dnolen: ^ release within a couple days.

19:27 using piggieback

19:28 hlship: bitemyapp: What's that about?

19:28 bitemyapp: hlship: it's friday, friday, friday

19:29 hlship: bitemyapp: well, then, I'm sorry I exist in the same time stream as you

19:30 bitemyapp: hlship: oh pah. I was teasing over the SSL thing. I don't think application runtimes should concern themselves with things like SSL.

19:31 hlship: that sort of thing should get implemented once in something like nginx with a reverse proxy to your app.

19:31 chare: who here likes pizza

19:34 bitemyapp: chare: most constructive thing you've ever said in this channel.

19:36 chare: bitemyapp you gonna buy pizza?

19:37 bitemyapp: chare: I don't eat pizza.

19:37 hlship: bitemyapp: Yes, not my call. And writing a banking application (credit card switch) means you have to jump through some silly hoops with regards to security (real or imagined)

19:38 justin_smith: http-kit supports client side ssl

19:38 which is in some situations better than server-side

19:39 tpope: gtrak: hooray!

19:39 gtrak: :-D

19:40 * arrdem observes the knife fingering and searches for beer and popcorn

19:40 tpope: literally just got piggieback working in vim

19:40 so I'm close to being able to try it

19:40 gtrak: excellent

19:40 I just used austin in the project.clj

19:40 justin_smith: it's so pretty watching all the CPUs peg in htop when I am running a criterium benchmark

19:40 gtrak: not sure how to write tests for these things.

19:40 gotta run though!

19:41 arrdem: justin_smith: gotta love all dem worker threads :D

19:42 justin_smith: for shure

19:42 bitemyapp: justin_smith: just wish it generated the nice reports criterion dumps.

19:42 chare: justin_smith you need to change your name, I always think of justin bieber when I see your name

19:42 justin_smith: that's your problem

19:43 bitemyapp: chare: all white people names look the same?

19:43 SparkySparkyBoom: does anyone know of something like the following, but for lein 2?

19:43 https://github.com/paraseba/lein-reload

19:43 bitemyapp: SparkySparkyBoom: (require '[clojure.tools.namespace.repl :refer [refresh]]) (refresh) (require '[clojure.pprint :refer [pprint]]) (require '[clojure.data :refer [diff]]) (require '[clojure.repl :refer :all])

19:43 SparkySparkyBoom: lein repl is pretty slow to load

19:44 arrdem: technomancy: so if I were to put together a proposal for a channel history based votekick bot along with proof of resistance to various invasion attacks, where could I direct it? clj-dev?

19:44 bitemyapp: arrdem: what constitutes quorum?

19:45 arrdem: bitemyapp: that is open to debate, I just have a member evaluation algorithm in mind that's pretty sturdy.

19:45 bitemyapp: I'm actually gonna go prototype it now I think...

19:45 s/member/voter/g

19:46 bitemyapp: arrdem: too complicated.

19:46 arrdem: you should simplify the model.

19:46 gregorstocks: oh boy, only an hour and 15 minutes until I can ask about haskell

19:46 arrdem: gregorstocks: 20. don't get ahead of yourself.

19:46 SparkySparkyBoom: huh

19:46 that just gave me a bunch of exceptions

19:46 bitemyapp: gregorstocks: sorry about that.

19:47 gregorstocks: arrdem: well I type very slowly

19:47 bitemyapp: SparkySparkyBoom: look the namespaces.

19:47 SparkySparkyBoom: make certain the appropriate libraries are loaded via profiles.clj

19:47 SparkySparkyBoom: don't just blindly copy-pasta.

19:47 SparkySparkyBoom: gah

19:47 screw it

19:48 arrdem: bitemyapp: not really... basically I'm resurrecting the work gdev and I did for cloutjure to have some concept of an individual's clout which is really really hard to game. Then the votekick is just can you get enough clout together to kick someone.

19:48 SparkySparkyBoom: ctrl-d, lein repl, ctrl-d isnt that inconvenient

19:48 chare: so why isn't clojure beating python

19:48 arrdem: bitemyapp: kick threshold is probably the clout of the victim more some constant roughly equivalent to technomancy.

19:49 bitemyapp: the idea being that a significant voting fraction of active users is required to achieve quorum.

19:51 bitemyapp: arrdem: so what would keep a single individual with established clout from booting a new user?

19:52 arrdem: bitemyapp: in the model which I'm considering, an old user with exceedingly high karma would effectively have ops. While you are correct that this would allow for an effectively rogue "ancient" I claim that such an occurance is exceedingly unlikely given the character of this channel. The attack set which I'm designing against are new troll users and new troll floods.

19:54 bitemyapp: $karma bitemyapp

19:54 arrdem: lazybot is MIA

19:54 bitemyapp: ...right. bot. vacation. right.

19:54 yes yes

19:54 justin_smith: lazybot is pining for the fjords

19:54 * bitemyapp curses under breath

19:55 arrdem: don't worry, it isn't directly karma based although karma will, I suspect, correlate strongly with the ranking I have in mind.

19:55 justin_smith: arrdem: port page-rank over to nick-rank

19:55 so inc from someone with a high inc-count has a heigher weight

19:55 SparkySparkyBoom: i didnt even know #clojure had trolls

19:55 arrdem: justin_smith: conceptually page-rank is pretty close to what I had in mind

19:56 bitemyapp: I wouldn't say that I'm worried, just that I know where I stand karma-wise relative to the dnolen/bloom oligarchy.

19:56 arrdem: SparkySparkyBoom: we haven't until chord/chare shoed up.

19:56 *showed

19:56 and we had one last night which was especially foul mouthed..

19:56 SparkySparkyBoom: oh

19:56 bitemyapp: arrdem: oh, who's the other bad egg?

19:57 arrdem: bitemyapp: lemme see if that crud is still in my or rayne's logs...

19:57 SparkySparkyBoom: it's weird how much clojure has grown on me

19:58 arrdem: bitemyapp: http://clojure-log.n01se.net/date/2014-01-16.html#09:54d

19:58 bitemyapp: wasn't all it said, but that's the line I remember it for.

20:02 technomancy: aw crap not again

20:03 arrdem: I think it's up to Rich; I didn't get ops till he had OK'd it

20:03 had to have chouser bug him about it

20:03 arrdem: technomancy: okay. that's the answer I was expecting. I didn't know that chouser would be the PoC.

20:05 bitemyapp: yogthos: I love you.

20:05 technomancy: we should have some ops in europe and asia though

20:05 yogthos: I try :P

20:05 technomancy: maybe eastern US too

20:07 hlship: Here's an Om idea; I kind of which that there was a remove! function that accepted a cursor and did the work to remove that cursor from its immediate container (dissoc the key, or remove the element from a vector, etc.)

20:08 Not quite seeing how to do that cleanly yet, without introducing a bunch of infrastructure (that will be useful, but getting ahead of myself).

20:09 arrdem: gah I forgot what a mess the entire cloutjure project is...

20:11 Bronsa: gah. reflection warning for (.get {} 0) and (fn [x] (.get {0 x} 0) but not for (.get {0 1} 0)

20:12 noto2: (class {})

20:12 TEttinger: I think maybe {} has Object keys

20:13 Bronsa: TEttingerno, it's a compiler bug

20:14 TEttinger: ah, that explains the .get rather than get

20:14 Bronsa: yeah. so for EmptyExpr and MapExpr getJavaClass returns the interface, for ConstantExpr it returns the class.

20:17 tpope: gtrak: I can't get anything out of it but special forms. anything obvious I might be doing wrong?

20:50 quizdr: is there anyway to quickly and easily comment-out several lines of code in clojure? I find myself wanting to do this all the time, but putting semicolons in front of each line is a bit tedious

20:50 danneu: quizdr: #_(form)

20:51 #_ reader ignores following form

20:51 amalloy: quizdr: M-;

20:51 is another option

20:52 danneu: Given the code (eval user-input), is there anything you can do to ensure that user-input is always treated as a literal string?

20:52 quizdr: typing an M followed by a dash, is that right? amalloy or is that an emacs Meta keystroke

20:53 danneu: Meta dash

20:53 er

20:53 meta semicolon

20:53 amalloy: danneu: always treated as a literal string? i don't understand the question at all

20:54 quizdr: wow that's pretty nify, much better than adding semicolons by hand! thanks!!

20:54 kzar: danneu: Something like (eval (str (quote user-input))) ?

20:54 danneu: amalloy: i don't really know my own question either. this error popped up in my site's error log "java.lang.ClassFormatError: Unknown constant tag 40 in class file clojure/core$eval675575" and it traces back to an eval i stupidly have.

20:55 I'm not sure what that error actually means

20:57 hiredman: ,#40

20:57 clojurebot: #<RuntimeException java.lang.RuntimeException: Reader tag must be a symbol>

20:57 hiredman: classformat error anyway

20:59 danneu: i had no luck reproducing it in the textbox

20:59 at least it's clojure

21:00 a real monkeywrench in the life of the user-input exploiter

21:00 hey probably don't even use emacs

21:07 muhoo: wow, i just got an email TODAY about early registration for cljwest, and went to the link, and it's sold out already

21:08 that's pretty quick

21:10 are there any promotional codes floating around anywhere? a couple years back there was a friend-referral discount or some such thing.

21:10 arubin: The entire conference or just the early bird tickets?

21:11 muhoo: the early bird tickets

21:11 usually there's a deadline of a week or at least a few days to get the early discount. in this case it looks like it was less than a few hours.

21:11 arubin: Well, registration is starting pretty late.

21:12 There are also a large number of tech people in SF who will not have to travel.

21:12 muhoo: indeed, i am one

21:23 andrew_fm: y

21:31 locks: destructuring still confuses me a bit

21:31 what’s a good resource to help me out with that?

21:34 andrew_fm: braveclojure.com has some good tutorials, including basic destructuring

21:36 locks: I was doing the koans, but I ended but just wanting to go through it, instead of actually understanding what I was doing

21:36 thanks

21:38 andrew_fm: there is also 4clojure.com i'm sure you'e heard about. i like that one a lot, lets you see how other users solved the same problems. very educational

21:46 danneu: locks: http://blog.jayfields.com/2010/07/clojure-destructuring.html

22:14 andrew_fm: If I get this back from a function, what am I looking at? (p2__2002# p2__2002#)

22:14 what do those symbols represent?

22:16 amalloy: andrew_fm: those are gensyms of the sort used by #(foo %)

22:16 ,'#(% %), for example

22:16 clojurebot: (fn* [p1__100#] (p1__100# p1__100#))

22:17 andrew_fm: why would a function return the gensym directly if the % is used in a reduce function operating on a sequence?

22:18 amalloy: you probably have something quoted where it shouldn't be

22:18 Bronsa: andrew_fm: there might be some good use case for that but I don't see one. It is more probable that there's a '% somewhere that should be %

22:19 andrew_fm: ah, i have a '(%2), that would probably do it, I guess right? I was trying to return a list with the %2 value inside it

22:19 Bronsa: ,'(%2)

22:19 clojurebot: (%2)

22:19 Bronsa: ,#(do '(%2))

22:19 clojurebot: #<sandbox$eval151$fn__152 sandbox$eval151$fn__152@6cf8ff>

22:20 Bronsa: ,(#(do '(%2)))

22:20 clojurebot: #<ArityException clojure.lang.ArityException: Wrong number of args (0) passed to: sandbox/eval179/fn--180>

22:20 Bronsa: ,(#(do '(%2)) 1 1)

22:20 clojurebot: (p2__205#)

22:20 Bronsa: andrew_fm: you can't have symbols starting with % inside a #() without having them gensym'd

22:21 amalloy: Bronsa: he meant (list %2)

22:21 avoiding gensyms was not the goal

22:21 Bronsa: oh, my bad

22:22 andrew_fm: ok

22:25 domino14: i want to iterate through a map with doseq and generate an array that contains some numbers that might pass a truth test

22:25 andrew_fm: I'm trying to use concat which requires two collections, so I want to turn one a %2 in a function into a collection, hence why I tried '(%2)

22:25 domino14: i can't figure out how to do it with doseq since doseq returns nil always

22:26 amalloy: ,(doc filter) ;; domino14

22:26 clojurebot: "([pred coll]); Returns a lazy sequence of the items in coll for which (pred item) returns true. pred must be free of side-effects."

22:26 andrew_fm: in other words, i have the numeral 2 for example, and i want to join it to the end of a list, therefore cannot use conj or cons

22:28 ,(concat [1 2 3] '(4))

22:28 clojurebot: (1 2 3 4)

22:28 domino14: i have no idea what that bot just said

22:28 andrew_fm: ,(concat '(1 2 3) '(4))

22:28 clojurebot: (1 2 3 4)

22:28 andrew_fm: suppose 4 was a %2?

22:29 Bronsa: andrew_fm: as amalloy told you, you want to use (list %2) instead of '(%2)

22:29 andrew_fm: oh, i misunderstood that exchange

22:29 my bad, thanks

22:29 amalloy: but, also, it's unlikely that you want to concat onto the end of a list as your reduce function - generating a lazy seq is generally easier and better

22:29 domino14: oh

22:29 filter

22:30 andrew_fm: amalloy i'm solving one of the 4clojure problems so it worked, now I can see how others did likely better!

22:30 sztamas: Hi, I have a multimethod question. Is it common that the dispatch function uses other arguments then the methods? Probably easier if you see the code https://github.com/sztamas/yabi-copy/blob/master/src/yabi_copy/core.clj

22:31 the usage of & _ in the methods is it alright?

22:32 andrew_fm: amalloy ah the reason i used concat is because I was solving #30 and was thining it would be nice if it worked on a list input, but none of those require list functionality, just vectors and strings, so the solutions are mostly using conj or cons

22:32 domino14: how do i use filter with do_seq

22:33 Bronsa: ,(filter even? (range 10))

22:33 clojurebot: (0 2 4 6 8)

22:34 domino14: my thing is a map, does it work the same way?

22:34 Bronsa: domino14: if you want to use a doseq look-alike approach, you can use for with :when ##(for [x (range 10) :when (even? x)] x)

22:34 domino14: ,(filter even? {2 3 4 5})

22:34 clojurebot: #<IllegalArgumentException java.lang.IllegalArgumentException: Argument must be an integer: [2 3]>

22:34 Bronsa: ,(for [x (range 10) :when (even? x)] x)

22:34 clojurebot: (0 2 4 6 8)

22:35 arrdem: domino14: {} is a map literal. Not what you wanted there.

22:35 Bronsa: ,(seq {2 3 4 5})

22:35 clojurebot: ([2 3] [4 5])

22:35 domino14: i am parsing through the keys and values of a map

22:35 Bronsa: domino14: [2 3] and [4 5] will be the args of the function given to filter in that case

22:36 domino14: ok

22:36 dyreshark: ,(for [x {2 12 3 13 4 14} :when (even? (first x))] (second x))

22:36 clojurebot: (12 14)

22:37 dyreshark: can also destructure x for more clarity

22:44 also, has anyone here tried LightTable? if so, how did you like it/what are your thoughts [primarily for clj/cljs dev]?

22:45 dnolen: dyreshark: work in progress but promising for clj/cljs dev

22:46 dsrx: I know this has probably been bandied around a lot over the past ~40 years, but it feels like it could be a real successor to emacs

22:47 kristof: dsrx: What, Lighttable?

22:47 dsrx: yes

22:47 kristof: Is it as programmable as Emacs?

22:47 dsrx: yep

22:47 kristof: Well, there you go

22:47 Good replacement

22:48 arrdem: eh... don't be so hastey. the plugin community needs time to grow and kick the tires before I'm willing to hand out the "next emacs" tag.

22:49 also: irc client :P

22:49 kristof: People actually use Emacs as an IRC client? I thought that was a hearty joke by some humorous fellow.

22:49 arrdem: kristof: ... I'm using it to talk to you now.

22:50 kristof: totally part of my normal dev workflow at this point...

22:50 kristof: arrdem: you don't just alt-tab to a term? :P

22:51 arrdem: kristof: no I don't. the setup is rather complicated and the short version is that I've done a lot of mucking about with tiling window managers and the minimum of keystrokes and convenience was to use ERC rather than tmuxing into a remote irssi or something.

22:52 kristof: I have an irssi instance running ssl'd connections to the the servers and providing a secured proxy, and then I connect from ERC (my desktop or laptop) to the proxy. works a treat.,

22:52 kristof: Well, alright. It sounds like you know what works for you :)

22:52 bitemyapp: arrdem: chare thinks it was me that got him muted.

22:52 lol.

22:52 kristof: Oh, remote session, that's why

22:53 bitemyapp: It must have been, there's no way he could have been muted for being a combative troll on his own...

22:53 arrdem: bitemyapp: haha. yep. he's bugging me about it. or trying to. god bless the fools list.

22:53 bitemyapp: kristof: <3

22:53 xuser: is there something like curses for clojure?

22:53 bitemyapp: 03:50 <chare> I KNOW IT WAS YOU

22:53 03:50 <chare> DON'T LIE

22:53 xuser: :)

22:53 bitemyapp: too great.

22:53 arrdem: kristof: one so young and yet so wise... he will do well here.

22:53 bitemyapp: I didn't know I was going to get dinner and a show tonight.

22:53 * arrdem snickers unkindly


22:54 arrdem: bitemyapp: hang on I need another beer before you post more of this gold.

22:54 bitemyapp: apparently he doesn't know how to read IRC logs, because it's pretty clear it's not me :)

22:55 arrdem: well it clearly isn't a bot... at least most of the time it isn't.

22:55 bitemyapp: arrdem: it's not a bot, just somebody with absurd amounts of free time.

22:55 arrdem: the one who was spamming curses could be a bot.

22:56 bitemyapp: 03:53 <chare> who muted me

22:56 kristof: xuser: Why don't you look for java bindings to curses?

22:56 clojurebot: Gabh mo leithscéal?

22:57 bitemyapp: xuser: 03:53 <chare> who muted me

22:57 sigh.

22:57 arrdem: xuser: yeah I'm sure that there's a jcurses kicking around somewhere.

22:57 bitemyapp: not what I wanted copy-pasta.

22:57 technomancy: bitemyapp: http://p.hagelb.org/mystery.gif

22:57 bitemyapp: xuser: hold on, I have a library for you.

22:57 domino14: i need to pass three arguments to my filter function

22:57 bitemyapp: xuser: https://github.com/sjl/clojure-lanterna

22:57 domino14: (filter my_fn map) would call my_fn with [key val] -- i need to call my_fn with [map key val]

22:58 bitemyapp: 03:54 <chare> LINK TO IRC LOG

22:58 arrdem: domino14: use (filter (partial my_fn map) map)

22:58 bitemyapp: 03:54? how long has he been bugging you, or are you set to some strange timezone...

22:59 bitemyapp: arrdem: it's UTC you freakin' pagan.

22:59 he's PRIVMSG'ing me right now.

22:59 Cr8: better you than me

23:00 arrdem: bitemyapp: ... the only timezone deltas I have memorized are US/EAST US/WEST and US/CENTRAL. (+1, -2, 0).

23:00 Cr8: I only remember the difference between central and pacific

23:02 arrdem: okay.. time to ddos log4noise again

23:02 oh pfffft.

23:02 <chare> unmute me or I use proxy

23:02 chare: just crawl off to whatever hellhole spawned you and die

23:03 * arrdem composes himself and goes back to devising a votekick bot

23:03 bitemyapp: arrdem: http://www.timeanddate.com/library/abbreviations/timezones/na/pdt.html http://www.timeanddate.com/library/abbreviations/timezones/na/pst.html

23:03 eagleflo: What happened to #clojure?

23:03 bitemyapp: eagleflo: muggles took notice

23:03 arrdem: ^ this

23:04 goddamn visigoths sacking our capital...

23:04 eagleflo: Well, trolls happen, what's this vitriolic reaction to them? Why paste their attention-seeking to the channel?

23:04 kristof: eagleflo: Humor.

23:05 arrdem: bitemyapp: well today's adventure is gonna be rethinkdb...

23:05 bitemyapp: eagleflo: chare is a veteran #clojure troll and he was amusing me.

23:05 arrdem: bitemyapp: we'll see how well this ends.

23:05 bitemyapp: arrdem: in Clojure?

23:05 domino14: ok, i'm almost there. i have this: (filter (partial amicables? num_map) num_map) -- my function is receiving a vector that looks like [key value], i need it to receive key, value as separate args

23:05 zerokarmaleft: if only trolling #clojure ended as well as https://gist.github.com/quchen/5280339

23:05 arrdem: bitemyapp: I wouldn't write a Haskell bot to lurk here...

23:05 bitemyapp: arrdem: complain to me and `cbp about Revise :)

23:06 kristof: 20:03 <chare> did you mute me?

23:06 20:04 <kristof> It was I, the holy op of #clojure

23:06 arrdem: bitemyapp: I was gonna bitch at you whether you wrote the library or not

23:06 (inc kristof)

23:06 kristof: lol

23:07 domino14: is there a way to make filter call the function with the parameters split up as separate args?

23:07 arrdem: kristof: sadly lazybot is skiving off today, so no karma for you :/

23:07 domino14: i know i can change the function, but i don't want to

23:07 technomancy: zerokarmaleft: that's pretty amazing

23:07 kristof: arrdem: sounds pretty... lazy! *nudge nudge*

23:07 arrdem: (dec kristof)

23:08 (reset! zerokarmaleft 0)

23:08 bitemyapp: zerokarmaleft: very proud of them :)

23:09 kristof: domino14: You mean filtering a list with a multi-arg'd function instead of a single arg'd one?

23:10 domino14: And so multiple elements of the list would serve as the arguments for the predicate

23:10 domino14: Maybe what you should look for is a mix of filtering over an a-list and using "apply"

23:11 domino14: kristof: yes

23:11 what is an a-list

23:11 arrdem: bitemyapp: rethinkdb up and running... that didn't hurt too much...

23:12 kristof: domino14: ((association value) (other-association value) (etc. etc.) . . . )

23:12 bitemyapp: arrdem: it's a pretty low-pain database.

23:12 kristof: domino14: A list consisting of lists which all contain two elements.

23:12 Someone correct me if I am wrong

23:12 arrdem: bitemyapp: this instance just named itself omniknight. I win.

23:12 kristof: and then your "predicate function" in filter would simply have apply in it

23:13 bitemyapp: arrdem: that's actually pretty funny

23:13 arrdem: bitemyapp: I'm gonna see if I can fix that to Warlock...

23:13 kristof: domino14: I apologize, you don't want an association list. You just want a list with lists in it, each containing however many elements you need. ((arg1 arg2 arg3) (arg1 arg2 arg3) . . .)

23:13 bitemyapp: arrdem: your rethinkdb'ing has inspired me to reboot and start hacking the old H.

23:14 arrdem: bitemyapp: okay. mongodb can go suck eggs. rethinkdb wins already.

23:14 bitemyapp: if you're in windows fuck that I'm comming over to play dotaz

23:14 bitemyapp: arrdem: wait really?

23:15 arrdem: bitemyapp: dude. friday night. I'm ahead on homework. totally.

23:15 bitemyapp: arrdem: also, I tell people to use RethinkDB > MongoDB all the time. there is literally not a single reason in the universe to use MongoDB.

23:15 kristof: domino14: I suppose a problem with that would be that your resulting list would still contain lists of args, but then again that's probably what you want? plz rspnd

23:15 arrdem: hang on... lemme see if I can automagically cluster my gaming box and my main server with Rethink...

23:16 kristof: Do you two know each other?

23:16 bitemyapp: arrdem: if they can ping via IP, you should be able to join them against each other.

23:16 kristof: In person.

23:16 bitemyapp: kristof: never met in person.

23:16 arrdem: kristof: not yet

23:16 bitemyapp: kristof: probably will when I visit Austin this late winter/spring

23:17 kristof: Ah. A happy couple, I see :')

23:17 domino14: kristof: i have a map im pasing to the function looks like {num num}, {num num}, etc

23:17 so then the filter function makes it take in [num num] instead num num

23:17 arrdem: kristof: http://i.imgur.com/r4aVfMr.gif

23:18 kristof: arrdem: Ugh, am I the only one who despised that movie?

23:18 domino14: kritofs pls

23:18 arrdem: kristof: I actually haven't seen it yet... the gif just sprang to mind.

23:19 kristof: domino14: methinks a map doth not consist of {num num}

23:20 domino14: my map is a bunch of num num pairs

23:21 bitemyapp: kristof: an optimized intmap implementation like Haskell's in Clojure would be kinda nice.

23:22 arrdem: bitemyapp: holy shit. that "just worked".

23:23 bitemyapp: this is glorious. I literally spent three days trying to figure out Mongo sharding prior to clojurecup.

23:23 kristof: bitemyapp: ...mapping integers to items is, uh, just a vector, isn't it?

23:23 bitemyapp: arrdem: the clustering in RethinkDB is similar to ElasticSearch. If you leave multicast on, ES will let you even skip the manual "join" part.

23:23 arrdem: bitemyapp: rm -rfing mongo then rebooting.

23:24 bitemyapp: kristof: sparse, no append.

23:24 kristof: "Big Endian Patricia Trees". Sounds like a cranky aunt from Louisiana.

23:25 domino14: lol

23:25 arrdem: bitemyapp: you saw that we now have a core.red-black-tree, right?

23:25 oh. no. it's data.avl.

23:26 https://github.com/clojure/data.avl/

23:26 in case you really don't trust a standard map...

23:26 kristof: bitemyapp: Neat stuff. I'm sure someone could write this for Clojure.

23:26 * arrdem reboots

23:27 bitemyapp: 04:21 <chare> see you assholes are not helpful but kristof is

23:27 04:21 <chare> he told me about "do"

23:28 kristof: Caught red-handed

23:29 bitemyapp: Is this a homogeneous data structure? Or can the pairs be anything?

23:29 Well, these are tuples...

23:29 bitemyapp: kristof: http://hackage.haskell.org/package/containers-

23:29 kristof: bitemyapp: I'm reading it

23:29 Oh, they have to support fold

23:30 I guess that implies homogeneous

23:30 bitemyapp: kristof: you'd be surprised how little homogeneity matters in a type system that isn't terrible.

23:32 kristof: bitemyapp: I thought it was Haskell's type system which prevented many cases of heterogeneous, arbitrary length data types? :)

23:32 you can pry named/keyword arguments from my cold, dead hands!

23:32 bitemyapp: kristof: no?

23:32 kristof: not at all.

23:33 kristof: bitemyapp: Haskell '98 did, according to someone in #haskell

23:33 * bitemyapp tilts head

23:33 bitemyapp: oh that doesn't matter anyway, but it's still not strictly true.

23:33 nobody actually uses Haskell '98

23:33 it's a baseline for experimentation with compilers.

23:33 for one thing, the current standard is Haskell 2010, and even *that* doesn't matter, only GHC does.

23:33 kristof: defacto standard I see

23:34 bitemyapp: yeah but there's still a sensible spec to work with.

23:34 kristof: bitemyapp: I don't know if you're familiar with it, but I was reading about Haxl and that stuff is very cool.

23:34 bitemyapp: and standardized tooling for parsing and all that.

23:34 kristof: one of the first things you learn is that you don't need what you think you need.

23:34 kristof: Haxl is interesting to me, partly because I like Erlang-esque code-reloading and the like.

23:35 we'll see how far they take it.

23:35 kristof: Yes, hotloading is cool!

23:35 bitemyapp: I know they use Haskell a fair bit.

23:35 type-checked hotloading sounds kewl :)

23:35 zerokarmaleft: bitemyapp: oh man, more clojure db client libraries need to be like revise

23:35 kristof: There's a fundamental trade-off though between code-efficiency and hotloaded code :(

23:35 bitemyapp: zerokarmaleft: async pipelined connection management is me, query DSL is cbp.

23:35 kristof: yeah well, that's why Haskell defaults to AOT and all that.

23:36 kristof: bitemyapp: On this note, I've been thinking lately and aside from the context of macro-writing, I can't see much use for variadic functions.

23:36 bitemyapp: zerokarmaleft: 80% of the work was cbp.

23:36 kristof: yeah you don't need them and they're unprincipled anyway.

23:37 kristof: that you can't accomplish with, say, fold, passing an actual list, or simply restructuring what you wanted to write

23:37 bitemyapp: kristof: right.

23:37 kristof: apply/reduce

23:38 kristof: there's no reason the "carry" of the fold can't be a tuple or record.

23:38 having two different ways to do the same thing isn't valuable in this case.

23:38 kristof: bitemyapp: for a second, I thought you meant that there was an apply in Haskell :P

23:38 bitemyapp: I don't like kwargs either.

23:38 kristof: no, I was speaking to their relative equivalence.

23:38 kristof: right, right

23:39 bitemyapp: kwargs are a fucking terror in python for large codebases.

23:39 kristof: kwargs?

23:39 bitemyapp: kristof: there is no reduce in Haskell, you get your pick of various fold functions.

23:39 kristof: keyword args.

23:39 I hate kwargs in Clojure too.

23:39 kristof: ah, I see

23:39 domino14: ok so how do i make filter call its args separately

23:39 bitemyapp: kwargs are part of what ruined Elastisch for us.

23:39 kristof: Clojure does not have keyword arguments.

23:39 bitemyapp: kristof: some people fake them with destructuring pairs.

23:39 kristof: Gross.

23:39 bitemyapp: kristof: right? see?

23:40 kristof: people learn the pattern from Ruby or Python and then bring it over and it makes me fucking gag.

23:40 kristof: bitemyapp: I meant gross when you compare to keyword arguments in DARPA ^H^H^H^H^H Common Lisp

23:40 xuser: bitemyapp: thanks for the link

23:40 bitemyapp: xuser: np

23:41 xuser: bitemyapp: ruby has keywords args since 2.0

23:41 not to long ago ;)

23:42 bbloom: xuser: they already had defacto keyword args, they added explicit keyword args, complicating their already complex calling conventions

23:42 bitemyapp: xuser: they'd fake it with HashMaps

23:42 kristof: I used to use CL.

23:42 kristof: bitemyapp: I still use it.

23:43 It is a complicated relationship.

23:43 bitemyapp: You rekindled my interest in Haskell, though, so thank you.

23:43 bitemyapp: kristof: <3

23:43 kristof: I still cannot abide "do" syntax

23:43 bitemyapp: kristof: I didn't really like static type systems in practice until Haskell.

23:44 kristof: even OCaml was bleghkh

23:44 partly because of typeclasses. Sexy, sexy typeclasses.

23:44 john2x: is it possible to list all aliases defined in the current repl session?

23:45 bitemyapp: kristof: I liked *type theory*, I just didn't like how people were putting it into practice which is why I stayed in CL/Python/Clojure

23:46 xuser: bitemyapp: no javascript?

23:47 kristof: ha

23:47 javascript

23:48 bitemyapp: I didn't appreciate types until I learned to appreciate polymorphism.

23:48 bbloom: john2x: use (find-doc "ns-")

23:48 xuser: kristof: polymorphism like overriding methods Java?

23:49 +in

23:50 kristof: xuser: :) cheeky. I just mean the (only good) idea from OO that "there are different kinds of thingy-things in this world, and when I want to do different actions depending on that thingy-thing."

23:50 *sometimes I want to

23:54 bitemyapp: xuser: by necessity, not because I liked it.

23:54 ddellacosta: kristof: I would argue that that is not OO's redeeming good quality...in fact I would say that is one thing that OO does rather poorly, at least in most implementations in common use (C++, Java, etc.)

23:54 bitemyapp: xuser: I write mostly Fay lately when I need JS

23:55 kristof: ddellacosta: Really?

23:56 xuser: bitemyapp: nice, is the integration with 3rd party libs better thatn cljs?

23:56 bbloom: kristof: really

23:56 kristof: Well I can't think of anything else that could be offered by single-dispatch kingdom-of-nouns yada yada . . .

23:56 bbloom: kristof: IMO, the gift OOP/SmallTalk gave to the world was noun.verb syntax

23:57 hurray -> syntax :-)

23:57 kristof: bbloom: Boo! Someone switched the order of verb arg syntax, that's all that is.

23:57 bbloom: Smalltalk did not start with noun.verb syntax anyway

23:57 ddellacosta: I struggle to understand what OO is good for, honestly. I find that, the more I spend time with languages like Clojure and Haskell the less I can find anything redeeming in OO, as it is practiced.

23:57 bbloom: kristof: well then whoever deserves the credit :-P

23:57 xuser: is better to invest in learning the closure library for cljs than jquery?

23:58 kristof: I think those two things are not related.

23:59 ddellacosta: xuser: if you haven't read my article on the CLJS libs I suggest taking a look, it could help you answer that question: http://davedellacosta.com/cljs-dom-survey

Logging service provided by n01se.net