#clojure log - Jan 22 2014

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

0:00 sdegutis: !!

0:00 Which one TEttinger?

0:01 TEttinger: 2d game

0:01 sdegutis: Sweet :)

0:01 TEttinger: in clojure actually

0:02 i'm constantly tempted to refactor so I can use stuff like Play-CLJ :|

0:02 alew: hiredman: so protocls are kind of like what you get with duck typing?

0:04 hiredman: alew: no, you can ask if a type satifies some protocol

0:04 alew: hiredman: right, it's more explicit, but the end result is the same?

0:08 hiredman: alew: protocol functions are normal protocol functions, so they get all the benfits of being properly namespaced, etc, whereas, for example, in ruby, the language typically being considered when discussing duck typing, an object cannot have two foo methods that do different things

0:09 sdegutis: TEttinger: that'll kill your project if you ain't careful!

0:11 TEttinger: sdegutis, it actually would just be a change to "using a java library with no wrapper" to "using the same library with a clojure REPL-friendly wrapper"

0:13 sdegutis: Anyone wanna fork https://github.com/sdegutis/clojuretip before I delete it?

0:16 quizdr: sdegutis if you think it's worthy of a fork, a Readme would be useful to describe what it actually is

0:16 sdegutis: quizdr: it's just http://clojuretip.herokuapp.com/

0:18 arrdem: Bronsa: okay well Compiler.java held exactly zero surprises...

0:18 dsrx: I'm working on a patch for the clojurescript project (in browser.repl), is the right way to approach this to create a lein cljs project that has a checkout for my local clojurescript repo and hack on them in parallel?

0:23 alew: hiredman: that makes sense, thanks

0:25 sdegutis: last chance to fork github.com/sdegutis/clojuretip before its deleted

0:26 marcopolo`: sdegutis: just the tip

0:29 sdegutis: deleted.

0:31 Does anyone here use https://github.com/sdegutis/clojuredocs/wiki ?

0:31 I made it because I got pretty tired of waiting for clojuredocs.org to eventually support Clojure 1.5 and up.

0:32 seancorfield: I pretty much only use clojure-doc.org and clojureatlas.com

0:32 I do wish chas would update the latter tho' :)

0:35 although now i'm using lighttable full time i'm use doc and source a lot more than i used to which means even less reliance on external sites

0:35 zerowidth: ooh. clojure-doc.org, didn't know about that

0:36 sdegutis: seancorfield: hmm interesting idea, I might give LightTable a more serious try

0:36 I love the way it looks now (version 0.6.0), but the plugin system has some apparent bugs that are making it hard to install mandatory stuff

0:37 akurilin: Random question: are there specific use cases where I benefic of using deftype and defrecord? I've been able to get away with it for a very long time so far.

0:37 Or to phrase it another way, how do I know it's time to use them?

0:38 seancorfield: sdegutis: on what basis are you making that claim about plugins? i'm finding the plugin system works pretty darn well...

0:38 sdegutis: akurilin: for what it's worth, I think I have not touched them at all at work

0:38 and at work I wrote cleancoders.com in Clojure with Datomic

0:40 akurilin: sdegutis: ok, appreciate the datapoint. I simply don't know enough myself to be able to fully discredit them.

0:40 sdegutis: seancorfield: when I try to install a plugin, sometimes the spinner-puzzle keeps spinning until I restart. Sometimes it says "installed" but I don't see it in the "installed" list until I restart. Sometimes clicking "install" doesn't install it the first time. Things like that.

0:42 TEttinger: sdegutis, don't delete that please?

0:42 seancorfield: What platform are you on sdegutis ?

0:42 sdegutis: TEttinger: don't delete which?

0:42 seancorfield: mac

0:42 Mac OS X 10.9.1

0:42 TEttinger: err I forked the clojuredocs thing

0:42 sdegutis: TEttinger: ah, you use it?

0:43 seancorfield: akurilin: I've used deftype to provide hooks for adding Trace metadata to enable New Relic tracing on a set of function calls

0:43 TEttinger: no, but I didn't know it existed, i will now

0:43 seancorfield: sdegutis: I wonder if your problems are Mavericks-specific? I've had no problems at all on 10.8...

0:43 sdegutis: TEttinger: Okay. You don't have to fork it, I wasn't planning on deleting it. However, if you want to take it over, you're welcome to, and I'll post a link to your fork from mine.

0:44 seancorfield: I wouldn't doubt if it was just my computer being haunted, sometimes it does that.

0:44 c.f. http://xkcd.com/1316/

0:44 akurilin: seancorfield: got it. So no general rule of thumb for when to use them?

0:45 seancorfield: chas emerick did a great decision tree about it ... let's see if i can find that

0:46 http://cemerick.com/2011/07/05/flowchart-for-choosing-the-right-clojure-type-definition-form/

0:46 sdegutis: TEttinger: it's a pretty low-maintenance repo, since nobody knows about it, so all you'd have to do is let it sit in your github account

0:46 akurilin: seancorfield: awesome, thank you, looks like what I was looking for!

0:47 sdegutis: TEttinger: (or you could post about it on the mailing list and win some friends/enemies)

0:51 TEttinger: ...yeah it's kinda ridiculous that I'm using clojure but can't repl-debug my running app. I'll see what I can do in a day to refactor my code to use play-clj.

1:00 dsrx: ugh.... ughhhh

1:01 pro-tip everyone: the cljs browser repl http server will treat http://localhost:9000/repl_foo.js the same as a request for http://localhost:9000/repl

1:01 i've wasted like 30 minutes of my life :(

1:12 akurilin: Sanity check: I have two validation routines: required and nonempty. Does it make sense for me to let nonempty pass on nil so that I can still use it without required? As in, I don't need that parameter to exist, but when it does, I want it to be nonempty.

1:13 Technically nil is empty, but then I'd have to implement custom logic based on whether required is set or not.

1:32 alew: seancorfield: did you evaluate any other monitor services before going with new relic?

1:38 experio: anyone have experience using Mongor (mongodb driver) ? Seemingly simple: Just want to query a collection and sort... ref here: http://clojuremongodb.info/articles/querying.html

1:39 (with-collection ...) ?

1:39 can't find any docs on that.

1:42 sdegutis: Sounds like Haskell may be my next language.

1:42 Raynes: May your path take you far and wide, lad! Far and wide!

1:43 * Raynes gallops off

1:49 sdegutis: Raynes: is that a fat joke? are you calling me fat?

1:50 seancorfield: also it's a bit weird that Ctrl-P and Ctrl-N don't move me up and down in the command list

1:52 akurilin: Am I correctly understanding that in clj it's more idiomatic to return nil on failed operations rather than to throw an exception?

1:52 e.g. clj-time will return nil or failure to parse a date

1:53 sdegutis: akurilin: generally yeah

1:53 akurilin: Makes a more predictable flow, right?

1:53 more monadic and what not

1:54 sdegutis: dunno what monadic means, but yeah it's easier to handle nils, as long as they're unambiguous as a return result and don't throw away important context as to why it failed

1:56 akurilin: Fair enough

1:56 To me just the fact that you have to use a separate flow control system for functions that throw exceptions is a bit a hassle

1:56 unless you really want an exception thrown

1:57 Kind of the get vs nth scenario.

1:57 alew: clj-time returns nil? I remember it returning a parse exception

1:58 fairly certain it still does

1:58 akurilin: :let [d (try (parse f s) (catch Exception _ nil))]

1:59 alew: Ah, if you don't provide a formatter

1:59 if you do provide a formatter, it returns an error

2:00 exception*

2:02 akurilin: Fair enough, not sure what the design decision process there was.

2:05 Are macros a good fit for replacing the same boilerplate with a single form?

2:05 Right now I have a sequence of validation steps on all of my handlers that's virtually identical for all of them and it makes little sense to repeat it over and over again.

2:05 On the other hand debugging errors within large macros is a pita.

2:06 alew: Small macro, large supportin function

2:06 just use the macro for the syntatic transformation and the function for all the validation parts

2:06 akurilin: Ah interesting. Do you know of good examples of that being done that I could look at?

2:08 alew: not off the top of my head, sorry

2:08 akurilin: No worries.

2:09 I have a solid list of great libraries out there that I'll mine for examples: http://www.kurilin.net/post/66730524627/list-of-great-clojure-libraries-for-reference

2:09 alew: Ah, cool

2:20 koreth_: What are some good Clojure open-source projects that have open tasks a relative newcomer could take on?

2:22 Maybe that list of libraries is a good starting point!

2:22 akurilin: Yeah those are pretty good if you just need solid clojure style reference.

2:23 They tend to be pretty idiomatic and do functional properly

2:24 Also just really nice apis. Anything dakrone touches seems to come out pretty well.

2:25 koreth_: Thanks; I'll try my hand at a task or two from their open issues and see if I can do a good enough job to be worthy of a pull request!

2:26 akurilin: Sounds like a plan. Don't know how easy it will be given how instrumental a lot of these libraries are (as in, if you break something, a lot of people will be sad), but that shouldnt' stop you

2:27 koreth_: If nothing else, hopefully I'll learn something in the attempt. And of course I won't bug the maintainers until I have something that won't be a total waste of their time.

2:29 akurilin: Either way they're all really nice folks, they'll consider what you propose one way or another.

2:29 I remember harassing weavejester within a few weeks of starting clj and he'd put up with me :P

2:30 koreth_: The Clojure community seems pretty welcoming in general. Hopefully that won't go away as the language gets more popular.

2:31 ddellacosta: dammit, what's with all the newbies! Cast them out! </joke>

2:31 egghead: ya ddellacosta seriously :)

2:31 akurilin: Yeah we're all working, some more than others, on preserving a pleasant environment.

2:31 ddellacosta: seriously though, koreth_ agreed wholeheartedly

2:31 egghead: ddellacosta: how have you been, doing mush cljs lately?

2:31 s/mush/much

2:31 quizdr: the community is arguably one major differentiating factor between Clojure and its uncle, Common Lisp

2:31 ddellacosta: egghead: howdy! fine, yourself? yep, lately lots of CLJS

2:32 egghead: doing well, also lots of cljs :) fun stuff

2:32 ddellacosta: egghead: in fact, I should probably be writing some CLJS right now, but procrastinating a bit...haha

2:32 egghead: lol

2:32 ddellacosta: egghead: nice. :-)

2:33 * clgv sometimes has the feeling to be the only one using Clojure since the rest only seems to be using CLJS ;)

2:33 akurilin: clgv: I hear ya.

2:33 ddellacosta: actually I still feel like a newbie although I've been writing Clojure professionally for about a year, and using Clojure for longer. There is just always so much to learn and so many smart folks in this community.

2:33 * quizdr is dancing out on the balcony, yelling down to passers-by on the street, "yo, what's up, you write Clojure? No? Why you looking at me like that?"

2:33 ddellacosta: clgv: naw, I'm using both every day.

2:33 heh

2:34 egghead: lol clgv cljs apps almost always have a clj backend too :)

2:34 ddellacosta: yeah, I think some folks are using a CLJS front-end with some other backend...maybe seangrove is doing that?

2:35 akurilin: he's not on clj backend? interesting!

2:35 clgv: the only web thingy I built is a minimal UI with progress report for running experiments. no CLJS there - plain old web 1.0 ;)

2:36 ddellacosta: akurilin: don't quite me on that, but I seem to recall that at some point that was true...may have changed though.

2:36 *quote

2:36 web 1.0, those were the days

2:36 alew: ddellacosta: where do you work?

2:36 ddellacosta: alew: I work remotely for a small Canadian startup.

2:37 alew: these guys: http://diligenceengine.com

2:37 alew: ddellacosta: ah ok. remote work seems to be the story of many clojure programmers

2:37 akurilin: Seems like outside of the climate corporation, if you want to use clj in production then you want to start your own gig.

2:37 ddellacosta: alew: yah. I wouldn't object to working actually at a company, but this was just the best way for me to get a clojure gig at the time, which I was interested in.

2:37 akurilin: Or some have coworkers that don't freak out if slowly introduced to the ecosystem.

2:38 ddellacosta: akurilin: yeah, definitely seen the same trends

2:38 egghead: i use clj at work but we have little services

2:38 ddellacosta: I remember talking to my previous company's co-workers about how I would be writing clojure, and one of them just snorted

2:38 egghead: so long as I can offer up an api no one really cares what the service is written in

2:38 alew: There's prismatic, staples labs

2:38 akurilin: Our websites / api are all clojure because I have no common sense and also get to decide that :P

2:38 egghead: so long as there are those willing to maintain it :3

2:38 ddellacosta: "what is that bullshit" kind of response. It's really weird compared to my current work environment, where folks are knee-deep in it every day.

2:38 akurilin: alew: oh yeah, Runa are hardcore.

2:39 quizdr: Haskell guys I've met, in particulary ,don't seem to take Clojure seriously

2:39 ddellacosta: runa = staples labs, right?

2:39 akurilin: they were using cljs before it was cool

2:39 alew: ddellacosta: yeah

2:39 ddellacosta: quizdr: I think Haskell folks not taking Clojure seriously is very different from...most other developers not taking Clojure seriously. At least the Haskell folks have a perspective that is other than "that's so weird"

2:39 (which is mostly what I run into)

2:40 quizdr: perhaps

2:40 Cr8: oh you're one of those *lisp* people

2:40 akurilin: ddellacosta: To outsiders, both clj and haskell look like completely alien-speak gibberish

2:40 ddellacosta: akurilin: yeah, it's disappointing. :-(

2:40 quizdr: ha ha Cr8 they did in fact single me out at the first FP meeting I went to in my town

2:40 "he's a lisper...."

2:40 akurilin: I actually thought the same of Haskell before starting to learn it. I had no idea what I was looking at whenever I'd run into some of their syntax.

2:40 alew: the lisp thing is part of it, but I think the real issue people have is that it's not ruby, python, java, scala

2:41 akurilin: so different from your typical C-family language

2:41 ddellacosta: yeah, sadly, I think that's definitely part of it. It's just not familiar, and not algol-like

2:41 akurilin: ALGOLoids

2:41 quizdr: Haskell looks to me like a good contender, had it been invented 45 years earlier, as a method for Nazis to encrypt their messages.

2:42 ddellacosta: I like Haskell, I want to get better at it.

2:42 would like to learn erlang too

2:42 Cr8: i've gotten capable at reading it and writing simple programs

2:42 quizdr: i am jealous of anyone who knows Haskell. ddellacosta i am jealous of YOU

2:42 alew: quizdr: malbolge would be a better start :P

2:42 ddellacosta: quizdr: dude, I *don't* know Haskell past baby-steps

2:42 quizdr: ...well right now all my work is in Assembly so i'm busy with that

2:42 (grin)

2:43 ddellacosta: quizdr: unless you mean you're jealous I get to write clojure daily. In which case, carry on. :-)

2:43 Cr8: I still pull out clojure most of the time I run into a situation where I have a problem that can be solved by writing code and there's no reason for it to be in anything in particular

2:43 ddellacosta: holy crap, malbolge, forgot about that

2:43 Cr8: because I get from zero to basically working thingy pretty quickly and can then get on with whatever I was doing

2:43 fredyr: ouch malbolge

2:44 fitting name though

2:44 ddellacosta: it really does look like line noise, doesn't it!

2:44 awesome

2:44 quizdr: i heard a rumor there are more clojure job openings in the world than there are capable clojure devs. i wonder if that's true. there is a new Clojure startup here in Singapore but it's out of my league at this point

2:44 akurilin: I'd do a lot of things just to avoid JVM startup time :P

2:44 alew: I think it took like... 20 years for the first hello world program to be written in it

2:44 akurilin: such a pita.

2:44 ddellacosta: quizdr: huh, really? Interesting. Many of them seem to be data-focused positions...gotta learn me some more machine learning.

2:45 quizdr: i think it was announcedon the clojure mailing list

2:45 Cr8: akurilin: my macbook is doing a thing lately where occasionally it'll get stuck in a state such that any JVM I launch hangs for a couple minutes and throws an out of heap error (now matter how much heap I give it)

2:45 only fix is to reboot

2:45 alew: there is no way there are more clojure job openings than clojure programmers

2:45 akurilin: Cr8: :(

2:46 quizdr: the "significantly shorter version" on this page really made me laugh out loud: http://en.wikipedia.org/wiki/Malbolge

2:46 akurilin: Cr8: for me the annoyance is that I have this really beastly machine and it still takes seconds for the simplest test to run. I really need to rewire our ring app to be resettable a la Stuart Sierra's flow

2:46 ddellacosta: alew: I suspect there are definitely more Clojure job openings than there are developers who are qualified for those positions though--not enough NLP or data science PhDs in the world

2:46 koreth_: A non-technical friend of mine is doing a startup and I have seriously considered telling him to get his prototype done in Clojure for the sole purpose of attracting a higher class of developers to his company once he goes to hire people full-time to productize it.

2:47 ddellacosta: alew: just based on what I see out there

2:47 xsyn: well you if you don't know how to read I guess Dr. Suess is the same as T.S. Eliot

2:47 quizdr: koreth_ that would be wise advice i think

2:47 ddellacosta: xsyn: ...?

2:47 akurilin: bbl

2:48 alew: ddellacosta: I could believe that

2:48 xsyn: ddellacosta: a non-technical person running a clojure prototype for his startup

2:48 quizdr: ddellacosta, alew yes the keyword is "capable" after all there are 25,000 clojure programmers with memberships to 4clojure

2:48 ddellacosta: xsyn: ah. Yeah, I mean, that sort of person really needs a qualified tech partner

2:48 quizdr: yep.

2:49 alew: I actually convinced my cofounders why we should use clojure on the backend for the startup I'm currently working on

2:49 quizdr: koreth_ your non-technical friend needs to partner up with you, my man! :)

2:49 * quizdr pops the champagne and congratulates koretch_

2:50 koreth_: quizdr: He lives in China, not quite ready to make that leap yet! My Chinese is way too rusty to have technical discussions with his local staff...

2:50 alew: And I think one of the best arguments is exactly what koreth_ said: tons of really high quality programmers in the clojure community

2:50 ddellacosta: alew: what was your argument, if you can sum up?

2:50 ah, maybe that was it

2:51 alew: Also, I compared clojure to what ruby/python were several years ago

2:52 ddellacosta: yes, I suspect clojure is positioned similarly, although I think the landscape is a lot different.

2:52 alew: and the pains being felt by many companies when they can't scale well with rails applications because of the lack of concurrency

2:52 ddellacosta: I don't think we'll see any monolithic web framework coming out of the clojure community to storm the gates

2:52 quizdr: lets keep in mind that Twitter went whole-hog with Scala infrastructure after that language had been out for only 5 years or so, so Clojure is similarly aged for today's businesses.

2:54 ddellacosta what about pedestal? seems geared to enterprise development, front and back end consistency, etc

2:57 ddellacosta: quizdr: I mean, we'll see, but I feel like it's still too challenging to wrap your head around #1, and #2 I don't see any major uses yet (but I may just be ignorant of them).

2:58 alew: pedestal is super early in development

2:58 I'm hoping the abstractions will get cleaner and simpler

2:58 quizdr: what do you mean by #1 and #2

2:59 ddellacosta: quizdr: personally, I feel like one of Clojure's strong points is having a bunch of smaller, composable libraries and pedestal feels very un-clojure-like in that way. I think it would be better to have a stack of stuff like ring + core.async + Om to build a modular sort of thing to do what Pedestal does (glossing over a lot of course)

2:59 alew: yeah, I don't want to judge it prematurely--in fact I looked into it in some detail for using with our own system a few months back, and was definitely very impressed. But it just feels like this platonic ideal to me right now, not quite viable in the real world. I hope that changes, sincerely.

3:00 alew: It seems like the ideal a lot of people here strive for: an frp approach to web apps

3:00 ddellacosta: quizdr: as far as #1, it's just not a simple web app framework is all I mean--it's never going to compete with something like Rails or Django in terms of fitting into a mold that web developers coming from other backgrounds can grok right away (see Caribou for a contrasting approach). But that's not a bad thing, in my opinion Pedestal is a superior architecture.

3:01 It's just hard to get right away--it asks developers to actually think about the architecture differently. Again, not a bad thing, just unfamiliar and challenging.

3:02 alew: for most people unfamiliar is bad, see: lisp :P

3:02 ddellacosta: alew: yeah, there's that too, which is unfortunate. :-(

3:03 I don't really understand it, as far as the "lisp = eewwwww" thing

3:03 dsrx: writing lisp is a nightmare w/o something like paredit

3:05 bja: dsrx, I hear that a lot but I don't know that I agree with it. Writing lisp without paredit still leaves you writing a highly regular syntax. Compare that to writing perl

3:05 You would write lisp the same way you write perl, except vim supports navigating sexps out of the box and perl isn't normal enough to navigate without random plugins

3:06 (not arguing that you shouldn't use something like paredit, just saying that without it, you're no worse off than writing in some arbitrary non-lisp language)

3:07 koreth_: Comparing Lisp to Perl isn't great, though. I think most people who have the "eww" reaction to Lisp have the same reaction to Perl.

3:07 bja: compare it to python then

3:07 same problem

3:08 python's syntax isn't easy to navigate or manipute in a random text editor without special plugins

3:08 dsrx: it isn't just navigating sexps, it's editing them, manipulating them, ensuring all the parens/brackets/braces are balanced (while doing those previous things), etc

3:08 bja: dsrx, you still have to do those things in python

3:09 dsrx: uh, to a much lesser extreme

3:09 bja: dsrx, disagree strongly

3:09 you still have lists, dicts, sets, and a lot of random functions

3:09 dsrx: keeping a single group of parens balanced isn't hard

3:09 algernon: and significant whitespace. arranging your blocks, moving them around...

3:09 dsrx: keeping two balanced isn't hard

3:09 bja: dsrx, two? I take it you don't use twisted

3:10 or genexps

3:10 algernon: moving one block to another place, with possibly different indentation - good luck doing tha without plugins.

3:10 dsrx: algernon: good luck doing that with sexps too

3:10 bja: dsrx, that's my point.

3:10 dsrx: unless you have something that, i dunno, kills a sexp

3:10 bja: dsrx, paredit for lisp is no different than needing python-mode for python to do editing of code without manually counting parens, brackets, curly braces, and whitespace

3:11 algernon: dsrx: yes. you need proper support for *both*, not just for sexps. neither is any harder or easier than the other without plugins.

3:11 and with plugins, both are fairly straightforward to work with.

3:13 bja: this reminded me to enable paredit mode for Hy

3:14 algernon: (though, for me, sexps are easier, because paredit can kill my sexps, out of the box, but python-mode can't do the same for python code - or at least not with the same keybinding)

3:14 bja: algernon, are we talking python-mode for vim or emacs?

3:14 algernon: emacs

3:15 bja: (because vim's just makes python syntax constructs into text objects, and as such, lets you delete them however you wish)

3:16 dsrx: my personal experience is that editing lisps with paredit is (far) easier and more natural than editing other languages (even with specialized modes), but that without any specialized modes lisps are harder to edit than algol-esque languages

3:17 dropping from a weekend of writing clojure into ruby/js again was disappointing

3:17 and i don't mean just because of the languages ;)

3:19 ddellacosta: dsrx: sincerely curious, what do you notice going back to Ruby/JS? In particular, with Ruby, I found after writing Clojure for a while I was doing much more messing about with enumerable stuff

3:20 bja: trying to convince a project I'm working with to adopt mori for some of our JS

3:21 ddellacosta: mori is sweet, I want to use it next time I touch JS

3:21 bja: so I can have my seq functions back

3:22 quizdr: with deftype, you are essentially creating a type in the Java sense, right?

3:23 if you have a protocol that lists a function, and you implement this function in a deftype, those functions will be prepended with dots like (.bar ...) because the type is a Java type?

3:24 fredyr: a java class even

3:24 so yes

3:25 quizdr: ok, so if you are trying to strictly keep things in the Clojure domain, using deftype would not be a likely tool in your bucket

3:25 as opposed to defrecord, which is more entirely clojurish, right?

3:26 fredyr: yeah id say so, but obviously it depends -- sometimes it might make sense to use deftype anyways

3:26 ddellacosta: quizdr: I don't know if either one is not clojurish--they both reflect opinions of how clojure works--this is worth a read if you haven't read it yet: http://clojure.org/datatypes

3:27 quizdr: thanks i'll read that

3:27 ddellacosta: or rather, they reflect opinions with regard to how certain things work, like derivation, programming to interfaces, immutability, etc.

3:27 dsrx: ddellacosta: ruby's syntax makes me miserable, the pervasive "bad" metaprogramming + monkey patching in 3rd party libs make code harder to understand, very much miss having cheap + performant immutable data structures

3:28 ddellacosta: dsrx: gotcha. It's been a while since I've programmed Ruby on a large scale so I'm not sure how'd I do if I had to go back to it now.

3:28 dsrx: but the things you list are things I would likely miss too.

3:28 or be frustrated with

3:29 dsrx: JS has all the little warts and gotchas, writing async code stinks even with 'good' abstractions like promises, no core.async etc

3:30 ddellacosta: dsrx: I've heard about generators, that you could supposedly do things similar to core.async with them, have you investigated that? I have no idea how well supported that is in browsers, though...

3:30 fredyr: quizdr: deftype is one way to implement a protocol, so if your building library stuff you might be using it

3:30 dsrx: ddellacosta: i haven't looked at generators too closely, because they're not implemented outside of gecko afaik

3:30 quizdr: it is ironic that my entire discovery of the lisp world was thanks to javascript when one day I accidentally saw a guy on stackoverflow show some code for a function that returned a function and my thought was, "wow these guys needs a comp sci 101 course" ha the joke was on me.

3:30 ddellacosta: dsrx: ah, yeah, I was afraid that something like that may be the case

3:31 quizdr: heh...I know what you mean, I've had similar moments of stupidity/revelation

3:31 quizdr: fredyr the only other way being defrecord, yeah?

3:31 dsrx: ddellacosta: i know someone who writes es6 for a living, and let's just say he's not terribly happy even with the new things in es6 :)

3:31 fredyr: quizdr: reify also

3:31 quizdr: oh yes

3:31 dsrx: for what that's worth

3:31 ddellacosta: dsrx: ah, interesting.

3:31 dsrx: I suppose it's still javascript. ;-)

3:31 dsrx: ayuppp

3:32 ddellacosta: quizdr: no, you can flat out create a protocol with defprotocol (if I understand what you're asking...?)

3:32 quizdr: i generally think of "type" as something that "stores data," like a "string type" stores characters and an "integer type" stores only integers. so when I see deftype that only mentioned functions, it seems strange to me.

3:33 ddellacosta know i meant how the protocol is ipmlemented. defprotocol just defines it yeah?

3:33 fredyr: ddellacosta: i think we were talking about implementing protocols

3:33 ddellacosta: quizdr, fredyr: ah, sorry to interrupt...

3:33 fredyr: no worries

3:35 actually, i don't recall seeing defrecord being used alot

3:36 ddellacosta: I've had trouble finding cases where a map wouldn't suffice, personally

3:36 quizdr: i think i'd be more inclined to just use multimethods with built-in types like maps rather than deal with records or deftypes or protocols

3:36 fredyr: yes

3:36 ddellacosta: yeah

3:36 dsrx: hmmm... must find reason to write 'defleppard' macro

3:36 fredyr: hah

3:37 quizdr: According to Halloways book even multimethods are exceedingly rare, like only about 0.1% of all Clojure code uses them.

3:37 ddellacosta: dsrx: :-)

3:37 quizdr: I find multimethods to be just the right thing in a few very specialized cases

3:38 quizdr: whenever I've written parsing code they seem to come in handy

3:38 llasram: quizdr: It depends on what you're doing with them... And re: your original question, when you create a new JVM type (via reify, deftype, or defrecord) which implements a protocol, as an implementation details that JVM type implements a JVM interface to hold the backing protocol implementation.

3:38 Those interface methods may be directly accessed via the .method JVM iterop, but you normally don't --

3:38 normally you just call the protocol functions

3:39 quizdr: llasram i thought defrecord was not technically creating a new type, that all records are a particular type that is part of the clojure system

3:39 hence their difference from deftype and their automatic use of map interfaces

3:41 llasram: The type you create with defrecord is still a new full type (class) at the JVM level. It just automatically implements a few interfaces

3:42 quizdr: ok

3:42 i assume defstruct is pretty much obsolete in the face of records and types?

3:43 llasram: 100%

3:43 If you see code using defstruct, you know that code is ancient and has received no recent love :-)

3:44 Glenjawork: Hi guys, a quick core.async question: it is more "idiomatic" for a message to be a command to perform an action, or a notification that an action has happened?

3:45 ddellacosta: Glenjawork: the latter--pass data around. core.async definitely doesn't follow an RPC model.

3:46 Glenjawork: so, taking the cljs dom event model, it'd be (>!! ch :button-clicked) over (>!! ch :save-document)

3:47 koreth_: Does a type hint on a defmulti automatically apply to the member functions? (Return value type hint in this case, though I guess the question is valid for parameters as well.)

3:47 Glenjawork: and if that's the case, can you do fanout?

3:48 ddellacosta: Glenjawork: I would say so--then anything that receives button-clicked can decide what it means to them. In some cases it may mean save the document, in some cases it may mean show the user a dialogue. Especially with cljs and events + core.async, it's about inverting the relationship, so you avoid doing stuff like callbacks.

3:48 Glenjawork: ie. multiple actions triggered from a single message on a single channel?

3:48 ddellacosta: Glenjawork: check out stuff like tap http://clojure.github.io/core.async/#clojure.core.async/mult

3:48 llasram: koreth_: On a multimethod return value, or... the dispatch function argument types?

3:49 ddellacosta: Glenjawork: and also pub/sub http://clojure.github.io/core.async/#clojure.core.async/pub

3:49 koreth_: llasram: Multimethod return value.

3:49 ddellacosta: Glenjawork: one pattern I use a lot is to set up different tap channels with predicate filters, where I can decide if I want a specific instance of an event based on some other criteria--especially useful with key events

3:49 Glenjawork: ddellacosta: aha, i hadn't seen those in example yet - that fits my mental queues model much better

3:50 llasram: koreth_: Ok. I don't believe that multimethods may return primitive types, so that just leaves reference types. For reference types,

3:50 Glenjawork: "Each item is distributed to all subs in parallel and synchronously" seems surprising to me though

3:50 ddellacosta: Glenjawork: why?

3:50 llasram: koreth_: the hint is only used by the compiler, via looking at the :tag metadata on a function-vars. The multimethod definition var will get that metadata, so the implementation functions need nothing

3:50 Glenjawork: because you now have to have subscribers yeild to avoid blocking others

3:51 or be fast

3:51 koreth_: llasram: Excellent, just what I hoped would be the case. Thanks.

3:51 llasram: np

3:53 koreth_: One thing to be careful of during development is that if you redefine a multimethod (recompile a file with `defmulti` in it) then you lose the metadata for that var >_<

3:53 ddellacosta: Glenjawork: hmm, I'm not sure what you mean by "yield to avoid blocking others." I've never had to do that in practice.

3:54 llasram: koreth_: The workaround I stole from technomancy is to have (def foo) right above every (defmulti foo ...)

3:54 Glenjawork: well, if one of your subscribers ties up the thread, the others won't receive the message

3:54 ddellacosta: Glenjawork: but maybe I'm not understanding your point

3:54 Glenjawork: it may not be a problem in practice, it just seems surprising to me

3:55 oh

3:55 koreth_: llasram: If the type hint is in the defmulti, won't it just get re-added? E.g., (defmulti ^java.util.Date my-func [x] ...)?

3:55 Glenjawork: i just read that again

3:55 it only blocks if you don't read the channel

3:56 llasram: koreth_: Actually, yes... Re-checking, the issue is that any metadata in the separate `attr-map` argument to `defmulti` won't

3:56 koreth_: Which is how I typically do return value metadata: {:tag `Date}

3:57 koreth_: llasram: Gotcha. I will be careful about that.

3:57 (Also, I will put my type hints before the argument vector where they belong.)

4:04 quizdr: I was just looking at a macro that generated a defn and the author put the defn inside the whole backquoted return expression as (symbol defn) why would that be necessary?

4:05 sorry, not the defn but rather than name of the function, so defn (symbol name)

4:05 or rather defn ~(symbol name)

4:05 wouldn't ~name work just as well?

4:07 Glenjawork: i think ~name would eval

4:07 but ~(symbol name) is a symbol

4:07 llasram: quizdr: If `name` were always a symbol, then those are identical

4:07 Glenjawork: maybe, macro's aren;t my strong point

4:07 quizdr: llasram that's what I thought. they would be a symbol since it is a function name, after all

4:08 seems unnecessary and i hadn't seen anyone take that precaution before in a macro

4:08 llasram: (defthingie "being-different" ...)

4:08 Probably just inexperience / refactoring cruft

4:08 quizdr: well it's a well-know clojure author in web development in his new book so I figured i was missing something

4:09 llasram: We all make mistakes. They may have intended it to strip metadata from the symbol. It doesn't work that way, but that's the only intent-derived reason I can think of off the top of my head

4:09 quizdr: just wanted to make sure it isn't "required" to do that

4:10 llasram: Gotcha

4:59 katox: ping dakrone

5:00 dakrone: I found this https://groups.google.com/forum/#!topic/clojuredocsorg/_rQIa2JQ9yc

5:00 dakrone: the project seems to be stalled, something's changed or blocking the progress?

5:39 jonathanj: i've worked through "Clojure for the Brave and True", are there any other good free online resources for Clojure anyone could suggest?

5:41 andrevdm: jonathanj: http://www.4clojure.com/ & http://clojurekoans.com/ are very popular

5:42 jonathanj: andrevdm: thanks, i'll check those out. what about resources that are more prose heavy?

5:43 (also: howzit ;))

5:43 andrevdm: :), checking bookmarks

5:44 jonathanj: i guess browsing through the clojure reddit might come up with some interesting stuff too

5:44 mkuitune: jonathanj: I'm starting to read Sotnikov's "Web development with Clojure" and liking it so far http://pragprog.com/book/dswdcloj/web-development-with-clojure

5:44 it's not free though

5:45 andrevdm: Rich Hickey's talks: http://thechangelog.com/rich-hickeys-greatest-hits/

5:45 mkuitune: but very beginner friendly, which I like

5:46 andrevdm: if you like vids, the check vids from the conj etc on youtube (ClojureTV)

5:46 jonathanj: i'm really not a fan of videos, but they do often seem to have good content

5:47 i watched Hickey's talk on core.async recently

5:47 andrevdm: http://fasttrackclojure.blogspot.com/2010/09/lesson-1-hello-clojure.html

5:47 http://adambard.com/blog/clojure-in-15-minutes/

5:48 the clojure vids have very high signal/noise. Well worth it, I never really liked vids before waching them either

5:49 jonathanj: great, thanks; i'm sure that'll keep me busy for today ;)

5:49 andrevdm: Also IMO "The Joy of Clojure" makes an exceptional 2nd clojure book. Its a bit faced paced if you are just starting out. Once you have a little experience it is truly brilliant though

5:50 s/faced/fast

5:50 jonathanj: have fun :)

5:51 Ember-: Joy of Clojure 2nd ed is just about to come out

5:51 just fyi

5:51 andrevdm: Ember: Yip, get it on MEAP if you want to get it now

5:51 Ember-: if you preorder it you'll get the 1st ed for free as ebook

5:51 andrevdm: I have it

5:51 :)

5:52 and I also have the unfinished beta book, preordered it the instant it came available

5:52 jonathanj: so should i wait for the release of the second edition then?

5:53 andrevdm: Ember: same. Its worth mentioning that the beta book is very polished already.

5:53 Ember-: yeah

5:53 it's just the finishing touches left

5:53 andrevdm: jonathanj: IMO get the MEAP now

5:53 jonathanj: MEAP?

5:53 Ember-: I think pretty much all of the relevant chapters are finished

5:53 andrevdm: http://www.manning.com/fogus2/

5:54 MEAP = manning early access program i.e. you get the book before it is done

5:58 jonathanj: okay then, twist my rubber arm

6:00 andrevdm: again, I'll say its good as a 2nd book :), in my opinion of course.

6:00 ddellacosta: jonathanj: definitely want to recommend Rich Hickey's talks--they are important for understanding the higher-level concepts encoded in Clojure--they help you understand how to use the structures provided in the language idiomatically. Otherwise, I definitely suggest reading through the resources on clojure.org itself--they are really great for summaries of major language features: http://clojure.org/documentation (and ditto

6:00 everything everyone else has said)

6:00 Ember-: agree, good as the second book

6:00 too much too quickly as the first book

6:01 ddellacosta: that's the general consensus and I would tend to agree...it is dense. I do keep coming back to it though for really understanding things I missed before.

6:02 andrevdm: +1 ddellacosta re vids. Also be sure to watch Tim Ewald's "Programming with Hand Tools" - http://www.youtube.com/watch?v=ShEez0JkOFw

6:02 ddellacosta: yeah, I think someone else mentioned the videos above but just wanted to drive home the point

6:03 oh, I guess that was you andrevdm ;-)

6:03 andrevdm: its a point worth reiterating :)

6:11 dsrx: hickey's talks are all great

6:13 rurumate: I'm trying to connect to elasticsearch 1.0.0-RC1 using elastisch 1.5.0-beta1, but all I get is a java.lang.NoClassDefFoundError: org/elasticsearch/repositories/RepositoriesModule

6:13 and that's making me nervous

6:15 clgv: I'd like to see a change log for the JoC2 book^^

6:16 an update price for owners of JoC1 would be great too ;)

6:17 rurumate: is the client lib correctly listed in your dependencies so that it is on the classpath of your current repl?

6:18 rurumate: clgv: yes, are you affiliated with the elastisch project?

6:19 by any chance, that is

6:19 clgv: rurumate: no. I just tried to eliminate a common pitfall ;)

6:19 rurumate: I've overriden the elasticsearch dependency, downgrading to 1.0.0-RC1 which is the exact version the server is using

6:20 now getting a different error

6:20 clgv: rurumate: the classdef error sonds more like a classpath issue then a protocoll incompatibility

6:20 rurumate: yes, it's a strange one

6:20 I'll post a full stacktrace hang on

6:20 clgv: "lein clean" and try again?

6:21 rurumate: I'm doing lein do clean, deps, ring server-headless 3000

6:23 now this is with the elasticsearch version inherited from beta-1 again: https://www.refheap.com/26484

6:24 there seems to be no reference to RepositoriesService in PluginsService.java

6:25 clgv: rurumate: RepositoriesModule you mean?

6:25 rurumate: that elasticsearch project seems overly complex java code

6:25 uhm yes

6:28 same problem with elastisch-1.4.0 dependency

6:29 and also with 1.3.0

6:30 hmm it used to work with 1.3.0 and 0.90.5 on the server side

6:30 so maybe it's a server side problem?

6:30 this is very inconvenient

6:30 not very elastic

6:31 clgv: rurumate: does the exception happen on server or client side?

6:32 rurumate: client

6:32 let me check the server logs

6:33 alew: rurumate: I know the native client is very finicky about which versions of the client and server you are using

6:33 rurumate: there's nothing in the server logs

6:33 clgv: you could check the classpath within the running repl

6:33 rurumate: alew: yes that seems to be the problem

6:34 alew: maybe it would work if I was using the exact server version (1.0.0-RC1) but then I get compile (load) errors inside elastisch code

6:35 alew, I'll post that stacktrace too, hang on

6:35 alew: rurumate: https://github.com/clojurewerkz/elastisch/commit/c1971c850aba33241d5f00ce3aa2d60cd51d3c3a

6:36 Are you sure 1.5.0-beta1 supports 1.0.0-RC1?

6:36 rurumate: here https://www.refheap.com/26486

6:37 alew: actually I'm pretty sure it doesn't, but I could not find the info which version IS supported

6:37 alew: I just linked it

6:37 rurumate: ph

6:37 *oh

6:38 alew: much thanks

6:38 darn I was about to use 0.90.10 but then decided to go with 1.0.0.RC1 since it's a few days younger

6:39 now to set up these indexes again.. *sigh*

6:41 clgv: a problem with mismatched versions in server and client is unlikely manifesting as classnotfoundexception though

6:41 rurumate: hmm

6:42 but it used to work with 1.3 and now even that fails with the same error

6:42 clgv: that would only happen if some remote classloading is going on

6:42 rurumate: I'll try 1.3 with an 0.90.5 server again, hang on

6:43 clgv: either the jar is not on the classpath (or maybe two different versions of it are) or the release is inconsistently missing the class

6:43 rurumate: clgv: I suppose remote classloading is a possibility, considering the twistedness of the elasticsearch code

6:45 clgv: rurumate: well, that would be documented I guess

6:45 alew: I think the issue is that you are including the elasticsearch 1.0.0-RC1 client when the elastisch client depends on 9.10

6:45 thus it prefers the version you declared, which likely has some breaking changes as it is a 1.0.0

6:46 so when elastisch goes to find the classes it depends on, they aren't there

6:46 rurumate: hmmm

6:46 clgv: alew: ah he overrides a transitive dependency in the project.clj?

6:47 alew: https://www.refheap.com/26486

6:47 the comment at the top

6:47 rurumate: I'll try dependency:tree to find out what version beta1 really depends on

6:47 deps :tree

6:47 clgv: https://clojars.org/clojurewerkz/elastisch

6:48 rurumate: yup it's 0.90.10

6:49 but I'm also using the cloud-aws-plugin and that declares a dependency on 1.0.0.RC1

6:49 clgv: welcome to dependency hell

6:49 alew: welcome to the worst part about clojure (and java?)

6:50 clgv: alew: nope dependency systems in general

6:50 alew: I have this hope deep inside that some language out there has solved it

6:50 kzar: to be fair clojure does it pretty well with lein if you contrast to python and ruby tools

6:50 rurumate: I hope that cloud-aws-plugin 1.16.0 works with 0.90.10, can't understand the dependency table on github page

6:51 clgv: alew: sometime ago there was an irc discussion about it. seems as if this is an unsolvable problem even in theory.

6:51 rurumate: it's not solvable I'm pretty sure

6:51 clgv: i.e. no optimal solution, but solutions with different tradeoffs

6:52 rurumate: maybe with static typing everywhere but even then you only shift the problem to compile time

6:53 clgv: rurumate: no not even there. since a version of a library does not contain a description of the public interface

6:53 rurumate: yes, the packaging system would need to learn that

6:53 clgv: rurumate: I guess elastisch maintainers will wait until 1.0.0 is released before introducing its breaking changes into their lib

6:54 alew: The Clojure community's propensity toward orthogonal and focused libraries somewhat alleviates the problem

6:54 rurumate: how about introducing header files to clojure, while we're at it?

6:54 clgv: rurumate: but how do you then describe what you need? ;)

6:54 rurumate: please don't

6:55 rurumate: I wasn't serious

6:56 clgv: but I was :P

7:03 xificurC: ,(re-matches #"a" "sdfa")

7:03 clojurebot: nil

7:04 xificurC: why is this nil? I'd expect "sdfa" as e.g. grep would return

7:04 rurumate: ,(re-find #"a" "sdfa")

7:04 clojurebot: "a"

7:05 rurumate: ,(re-matches #"a" "a")

7:05 clojurebot: "a"

7:05 xificurC: thanks

7:06 rurumate: ,(vec (re-seq #"a" "sdfa"))

7:06 clojurebot: ["a"]

7:09 rurumate: For the record, I'm now using elastisch 1.5.0-beta1 and elasticsearch-cloud-aws 1.16.0 to connect to a 0.90.10 server, it seems to work

7:09 thanks everyone

7:10 alew: Sometimes I think my clojure code is starting to look really weird

7:10 but then I just look at the doseq source

7:14 quizdr: lol alew some things cannot be unseen! i just looked up the source for doseq

7:17 alew: It's pretty spectacular. I'm sure you could spend just as long analyzing that one macro as you would some moderatly sized libraries

7:17 quizdr: no doubt

7:24 AeroNotix: where is compojure.http.* ?

7:25 alew: macros are like that, look up SBCL's `loop' macro

7:25 shouldhavesentapoet.png

7:26 alew: They don't HAVE to be like that though. You can always break something up to be more manageable

7:28 Wow, SBCL's `loop` is incredible

7:28 AeroNotix: isn't it

7:29 alew: that's the nonstandard looking loop macro right?

7:29 the one that looks pretty imperative?

7:29 AeroNotix: alew: yeah

7:30 I don't particularly like using it, but it provides some excellent features.

7:30 clgv: alew: an eager `for` constructing a vector would be awesome ;)

7:30 AeroNotix: http://en.wikibooks.org/wiki/Compojure/Core_Libraries this suggests a compojure.http.* exists

7:31 basically I'm looking for this: http://briancarper.net/clojure/compojure-doc.html#compojure.http.request

7:31 cookie handling in compojure

7:31 xificurC: cl's loop macro is too amazing not to like it

7:32 AeroNotix: xificurC: but it sticks out like a sore thumb, it's the only thing of its kind in CL

7:32 (a very specific DSL for something)

7:33 xificurC: AeroNotix: if it gets the job done I dont really care

7:33 AeroNotix: xificurC: then use php

7:33 xificurC: you can use iterate if you want more lispiness

7:34 AeroNotix: things "working" does not a good argument make

7:34 xificurC: well things not looking "pretty" isnt a much better one tbh

7:34 just because its unusual doesnt mean its bad

7:35 AeroNotix: xificurC: it's not about that, it's about being able to compose various portions of the constructs where you can use them singlely and not have to understand a construct which does not come from the regular structuring of the language

7:35 there are no places in CL besides Loop where the api is just symbols one after the other to represent your intention (imperitive)

7:36 xificurC: AeroNotix: well thats true I guess

7:37 still, everybody is using it right now

7:37 AeroNotix: xificurC: like we said though-- it has too many useful features not to use it

7:38 there are plenty features from CL I want in Clojure

7:38 xificurC: AeroNotix: yeah, you can write the same stuff with e.g. do but its longer and less readable

7:38 AeroNotix: xificurC: depends

7:39 quizdr: for what it's worth, my switch to clojure from CL was particularly refreshing because of losing all that extra weight of things like loop. it can be intimidating to have to learn a new separate language just to use one function. format is another one.

7:39 or macro, rather, not function...

7:39 AeroNotix: quizdr: indeed

7:40 alew: I really prefer the naming conventions in clojure

7:40 AeroNotix: the API for CL is clunky and doesn't really make sense. Setf and friends are just a horrible API to use

7:40 datastructure literals, awesome. Who *doesn't* like that?

7:40 quizdr: what in clojure do you miss from CL AeroNotix? besides mutability and dynamic vars for default, etc

7:40 (kidding about those, obviously)

7:40 AeroNotix: quizdr: good keyword arguments

7:41 quizdr: as in, how they are named?

7:41 AeroNotix: I wouldn't mind *trying* to see how the condition system would fit into Clojure

7:41 quizdr: the whole thing, Clojure's just seems like a hack

7:41 xificurC: I never learned format well enough to use it extensively

7:41 its present in clojure/pprint isnt it

7:41 alew: What does the keyword arguments situation in CL look like?

7:42 AeroNotix: alew: (defun foo (&key ((:apple a)) ((:box b) 0) ((:charlie c) 0 c-supplied-p))

7:43 so, you can have defaults, renames and check if they are supplied

7:43 quizdr: oh for supplying defaults you mean? thinks like &rest &key and their siblings?

7:43 AeroNotix: quizdr:

7:43 quizdr: the idiom for that in clojure seems pretty simple, to set a default map of values, take rest parameters, etc.

7:43 the ordering is different in the destructuring, but I don't see the major difference

7:43 AeroNotix: compared to clojure: (defn foo [{:keys [apple box charlie] :or {box 0 charlie 0}}])

7:44 but yo ucan't even check if they were *actually* supplied

7:44 It's not a big thing for me though, just would like it to be at least similar.

7:45 quizdr: hm.

7:45 AeroNotix: alew: read Practical Common Lisp, great book on CL.

7:45 quizdr: i'm not sure i follow you when you say "know if they were supplied". the :or in clojure would be in effect if they weren't supplied, right? you mean, the caller didn't include them as arguments?

7:45 alew: That's not how you do keyword args in clojure

7:46 xificurC: I'd say it's more readable to have the argument and its default value coupled together than having them separate

7:46 alew: (defn foo [& {:keys [apple box charlie]}])

7:46 AeroNotix: xificurC: exactly

7:46 alew: how do you supply defaults for them, then?

7:46 you need to use :or to supply defaults

7:46 alew: you can still do the or

7:47 But leaving out the & changes it significantly

7:47 AeroNotix: not really

7:47 xificurC: but if you'll put say :or {apple 2 charlie 3}

7:47 it doesnt seem that obvious who has default values and who doesnt

7:48 I mean you look at the :keys vector

7:48 and you cannot tell who has and who doesnt have default values

7:48 AeroNotix: exactly

7:48 and you end up repeating the names twice

7:48 so it's a lot longer

7:49 quizdr: i find this syntactical distinction a tad trivial, to be honest. it's true you repeat keywords twice, that's a bit inelegant, but i can't say it's a showstopper

7:49 xificurC: so you check the :keys vector and the :or map and compare them in your head to get the result

7:49 AeroNotix: quizdr: never said it was, just said I miss it :)

7:49 xificurC: how do you make an optional argument in clojure?

7:50 quizdr: i guess its just a matter of taste and readability

7:50 alew: Personally, I think the choice of unifying the destructuring of maps with keyword args was a great choice

7:50 AeroNotix: multiple arity or & rest with destruscturing

7:50 quizdr: i think the way parenthesis are used in clojure makes things easier to read in general, so there are tradeoffs. for example in the CL version you posted, there are a lot more nested parenthesis while the clojure version you see the list of arguments quickly and cleanly in one sequence

7:50 xificurC: aye, multiple arity, I always forget :)

7:51 AeroNotix: quizdr: for sure, different parenthesis is probably in my top 5 feartures

7:51 quizdr: xificurC but the & rest is quite useful, over multiple arity a lot of the time i'd say

7:51 alew: AeroNotix: I started reading PCL a bit, but then found Clojure. I enjoy seibels writing so I'll probably get around to it someday

7:52 xificurC: quizdr: when I check the clojure sources I see more multiple arities than &rests, why is that?

7:52 and why are so many built-in functions written out so tediously?

7:52 like one for [a], [a b] [a b c] [a b c d] [a b c d & more]

7:52 alew: For efficiency reasons

7:53 oskarkv: xificurC for performance and/or because the more convenient functions has not yet been defined at that point

7:53 quizdr: check this: http://stackoverflow.com/questions/3208347

7:53 AeroNotix: alew: I enjoyed it

7:53 quizdr: that shows 3 different approaches to defaults and optional parameters

7:54 alew: Keyword arguments don't seem to be very prevalent in clojure code anyways

7:54 xificurC: quizdr: thanks

7:54 alew: AeroNotix: Need to read the new Joy of Clojure first

7:55 xificurC: but back to my last question, if you check the source of apply or map

7:55 AeroNotix: alew: Same :)

7:55 xificurC: why is the function written out for the first 2-4 cases?

7:56 AeroNotix: xificurC: efficiency

7:56 xificurC: AeroNotix: is the performance that different?

7:56 quizdr: it would be worth timing alternatives for fun

7:56 oskarkv: i tried the keyword argument thing a long time ago, there was something weird about it, but i don't remember what it was. anyway, one can just pass a map as well

7:57 AeroNotix: xificurC: there's no reason to not choose the faster one in the cases of standard library code.

7:57 oskarkv: cargo cult programming

7:57 oskarkv: learn instead of making up stuff

7:57 xificurC: AeroNotix: but its ugly :(

7:57 AeroNotix: xificurC: indeed, but that's the price you pay

7:58 oskarkv: AeroNotix bad memory leads to cargo cult programming?

7:58 or, implies it rather

7:58 quizdr: bad memory leads to waking up and writing ansi c code

7:59 AeroNotix: oskarkv: You said you tried it long ago, then stopped because there was something weird about it. You imply that you don't use it currently, you also imply that the reasoning is because you found it weird.

8:00 oskarkv: I never used it. I just played around with it, and there was something i didn't like about it. But I have since forgotten what it was.

8:01 alew: I really despise working with timezones

8:01 oskarkv: But, I have never felt the need for it since, but if i did i would try it again

8:01 quizdr: hm, the "keyword argument thing" is a fundamental part of the entire clojure way. i'm not sure how it can be easily ignored?

8:02 oskarkv: just use maps :p

8:02 AeroNotix: alew: unix on the backend, let the front-end dudes sort out display :)

8:04 Profpatsch: I’ve got a coll of maps, all with a key :foo. Now I want to get the map where :foo is max of all maps. How to do that?

8:04 oskarkv: To be clear I'm talking about the implementation, the [s & {:keys [base] :or {base 10}}] stuff, not keyword arguments in general

8:05 quizdr: without destructing you must be avoiding various caller flexibility, like defaults, optional parameters, etc

8:06 Profpatsch you could reduce your coll of maps with a function that only looks at :foo in each map item in the seq

8:06 oskarkv: quizdr I don't really follow

8:06 Profpatsch: quizdr: Ooooh, right, thanks.

8:06 quizdr: Profpatsch no prob

8:07 clgv: Profpatsch: (apply max-key :foo coll)

8:07 quizdr: ,(doc max-key)

8:08 clojurebot: "([k x] [k x y] [k x y & more]); Returns the x for which (k x), a number, is greatest."

8:08 quizdr: clgv i think he wants the entire map the key came from

8:08 Profpatsch: clgv: I knew there was a convenience function for that. I bet it uses a reduce internally.

8:08 clgv: quizdr: yes and he gets it

8:09 quizdr: clgv well i'll be a jolly darn sweet pie-eating squirrel of a rabbit hunter, then!

8:09 AeroNotix: How crazy is it to assoc fields into the request value in Compojure middleware?

8:09 In other frameworks this is considered normal, in others BAT SHIT INSANE

8:09 so.. lemme know the ballpark idiocy here

8:09 Profpatsch: clgv: Yep, it does.

8:10 clgv: With a little recursion.

8:10 clgv: Profpatsch: standard building block when you do lots of data analysis ;)

8:10 Profpatsch: you could also use (reduce (partial max-key :foo) coll)

8:10 Profpatsch: clgv: It seemed like such a basic operation on maps, there just had to be a function for it. I just didn’t know where to look.

8:11 clgv: Profpatsch: max-key is awesome because `key` can be any function not neccesarily a keyword

8:11 alew: AeroNotix: That works, until you have a text reminders system

8:12 Profpatsch: clgv: Neat

8:13 AeroNotix: alew: ?

8:13 alew: AeroNotix: Need the backend to send reminders at specific times

8:14 AeroNotix: but I don't want to send a reminder at 5 am when people are sleeping :P

8:14 AeroNotix: alew: I'm associng in parsed cookies

8:15 alew: so I'll add :parsed-cookies (parsecookies rawcookies) or w/e

8:15 alew: AeroNotix: I was talking about your Unix comment

8:15 AeroNotix: as for associng in values, that's pretty standard

8:16 AeroNotix: ohhhh ! ok

8:16 alew: AeroNotix: https://github.com/ring-clojure/ring-json/blob/master/src/ring/middleware/json.clj

8:16 AeroNotix: alew: usually you have a user profile, if you store the user's preferred TZ, then it's coo'

8:17 alew: sweet, assocs away

8:17 alew: AeroNotix: preferred TZ's are so old fashion

8:17 AeroNotix: then what?

8:17 alew: AeroNotix: you can probably use the fb api or google api to find their information and hometown and figure it out for them!

8:18 AeroNotix: lol

8:37 ambrosebs: anyone following the definline conversation on the ML?

8:38 llasram: Seems pretty gross to me

8:38 ambrosebs: at a glance it seems ridiculous not to accept a patch.

8:39 mdrogalis: Relevant: https://twitter.com/MichaelDrogalis/status/425354886897618944

8:40 llasram: Could use a bit more B in the BFDL. Or maybe more D too. It's kind of hard to tell from the available signal

8:40 s,BFDL,BDFL,

8:41 ambrosebs: I personally would like to see definline die a quick death. But I'm more worried that apparently the clojure.core array cast functions cannot be used higher order safely.

8:41 mdrogalis: I'd opt for more D, but need to hear more out of Rich on some of these tickets in that case

8:42 ambrosebs: I also don't see the point of definline if it can't be used higher-order.

8:42 llasram: ambrosebs: Is it `definline` itself you dislike, or compiler support for inlining via explicit :inline functions in metadata?

8:43 ambrosebs: llasram: I don't really have an opinion on definline, I'm just saying resolve the issue so we can fix the array casts.

8:43 llasram: Gotcha

8:44 ambrosebs: llasram: It seems like Rich is saying he's not touching any definlines until it dies.

8:44 so kill it ..

8:44 I could be misinterpreting though, Rich hasn't actually said anything explicitly.

8:45 mdrogalis: 1.2 -> 1.3 broke backwards a great deal, I don't see why removing definline in 1.6 is such a big thing.

8:45 ambrosebs: mdrogalis: I would think the proximity to 1.6 release is a factor

8:45 llasram: mdrogalis: I think 1.2 -> 1.3 broke more than intended, and has created a bit of a "never again" attitude

8:46 Or at least "not until 2.0"

8:46 ambrosebs: llasram: yea

8:46 soo, anyone listening please stop using definline in your code :)

8:47 llasram: Fiiiiine. Explicit :inline metadata it is

8:47 mdrogalis: 2.0 better be patch now or forever hold your peace lol

8:47 tbaldridge: definline was just the mark of a crappy compiler, imo

8:48 no language should require the user to manually mark code for inlining

8:48 mdrogalis: tbaldridge: Yeah, I suppose that's an argument.

8:48 tbaldridge: Even C++ ignores the inline keyword these days

8:49 llasram: tbaldridge: I use the explicit inlining occasionally to allow a user-specified class to be used as a type-hint when the function is called in-line

8:49 stuartsierra: Even more than that, I think `definline` was a hack to work around the failure of the JVM to fully inline some hot code paths.

8:49 tbaldridge: stuartsierra: ... and the fact that the compiler can't figure that out on its own.

8:50 mdrogalis: Honestly though, either patch it or excise it. Don't leave it an open wound. :/

8:55 ambrosebs: just so I'm understanding, is there a difference between the normal (defn ^{:inline ..}) and (definline), aside from reducing duplication?

8:56 Profpatsch: Is it just me or is using loop a code smell? Pointing at a too iterative style?

8:56 ambrosebs: Profpatsch: depends what you're doing

8:59 Profpatsch: ambrosebs: You mean high speed vs high level?

9:00 ambrosebs: Profpatsch: well you might be porting iterative code ;)

9:00 Profpatsch: but seriously, I've ported a lot of Racket which sometimes has local mutation. loop has been useful for that.

9:01 stuartsierra: Some operations can only be written with loop/recur. Usually map/filter/reduce suffice.

9:01 Profpatsch: ambrosebs: Yeah, I’m implementing an algorithm that is described in an iterative way.

9:02 ambrosebs: Profpatsch: :D

9:02 Profpatsch: Temporal Difference Lerning with Sarsa: http://i.imgur.com/19EGHxH.jpg

9:05 ambrosebs: Profpatsch: looks like you want local mutation and c.c/while ?

9:08 Profpatsch: ambrosebs: Nah, I’m going to check the high-level perf first.

9:09 alandipert: new day, new hoplon demo. please enjoy! http://alandipert.github.io/hoplon-demos/tictactoe/

9:22 zerokarmaleft: alandipert: heh, rand-nth for AI :D

9:23 alandipert: zerokarmaleft: minimax is... an exercise for the reader :-)

9:28 redinger: alandipert: It's quite an effort to get this AI to win a game. :)

9:28 alandipert: redinger: simple ain't easy!

9:33 redinger: i'm putting together a multiplayer minesweeper we can hack on for an upcoming triclojure

9:35 zerokarmaleft: MMO minesweeper, with auto-generation when players approach a boundary...for ultimate madness and loafing

9:36 alandipert: zerokarmaleft: basically, yup!

9:37 clgv: ambrosebs: I only found a thread with 3 posts on definline - did you mean that one

9:38 ambrosebs: clgv: yes with Tassilo

9:38 clgv: pk

9:38 ok

9:40 redinger: alandipert: Sounds fun!

9:49 katox: oh, I just found out that projectil work fine unlike (probably deprecated) C-c C-t in emacs with cljx

9:49 another tooling hurdle gone

9:53 gozala: anyone knows what’s idiomatic way to report errors in core.async ?

9:54 tbaldridge: gozala: the idiomatic way is to do what works best for your project :-)

9:55 So use dedicated error channels, or return them from gos, whatever works best. Core.async is very agnostic in this area

9:55 gozala: tbaldridge: I mean am I supposed to just put errors on channel

9:55 or have an error channel

9:56 tbaldridge: I have being returning records of input and error channels in most of my APIs now

9:57 but feel like there should be a better way

9:57 way in which high order functions provided by core.async would propagate errors

10:00 mmitchell: technomancy: I'm attempting to set a command-line option with "lein" but I'm doing something wrong. How can I do something like: "lein ring server -Dsome.prop=x"?

10:01 augustl: mmitchell: tried JAVA_OPTS?

10:01 edbond: mmitchell, ENV=production lein ring server

10:02 mmitchell: augustl: Oh yep, that did it!

10:02 clgv: mmitchell: maybe you need "--" to separate plugin task and commandline parameters for the program

10:02 mmitchell: clgv: I'll try that too

10:02 edbond: thanks, ENV settings looking ok

10:03 clgv: mmitchell: e.g. when using lein run: lein run -m my.main -- arg1 arg2

10:03 edbond: ,(System/getenv "LEIN_JVM_OPTS")

10:03 clojurebot: #<AccessControlException java.security.AccessControlException: access denied (java.lang.RuntimePermission getenv.LEIN_JVM_OPTS)>

10:03 edbond: &(System/getenv "LEIN_JVM_OPTS")

10:03 lazybot: java.security.AccessControlException: access denied (java.lang.RuntimePermission getenv.LEIN_JVM_OPTS)

10:03 edbond: ah, so much security

10:04 ddellacosta: wow

10:04 so security

10:04 mdrogalis: ambrosebs: Taking the temperature of the water on the ML? :P

10:04 clgv: at least, clojurebot lets you def things now ;)

10:04 mmitchell: Yeah, looks like JAVA_OPTS works with -Dprop=xyz

10:04 clgv: btw: when did clojurebot improve upon lazybot?

10:05 ambrosebs: mdrogalis: :)

10:05 ddellacosta: mmitchell: dunno your needs, but may also want to take a look at environ if you haven't: https://github.com/weavejester/environ

10:05 gfredericks: ambrosebs: yes there's a difference between the two as I understand it

10:06 My understanding of ^:inline is it lets you define a hybrid function/macro; it's a macro in the call position and a function otherwise

10:06 mmitchell: ddellacosta: ahh nice, yeah that's basically what I want

10:07 ddellacosta: cool.

10:08 ambrosebs: gfredericks: yes that's my understanding.

10:08 gfredericks: ambrosebs: I expected once that definline was just sugar for ^:inline but hiredman convinced me that didn't make any sense

10:09 something about hygiene I think?

10:09 i.e. such a thing could be written but would require some code walking for reasons I can't recall without thinking

10:09 ambrosebs: gfredericks: I'm obviously missing something.

10:10 gfredericks: okay fine I'll try thinking

10:11 I think what I wanted was something that was syntactically function-like, but could still be inlined

10:11 and was surprised that definline was required to return code in the manner of defmacro

10:12 ambrosebs: gfredericks: I guess I see what you mean, but I'm wondering if there's a difference in compiler interpretation of a normal :inline vs a definline

10:13 does it give more efficient code? From my reading, definline can always be converted to an :inline with no runtime penalty.

10:13 gfredericks: I'm looking at the source of definline now and it's weird; would not have expected a call to eval

10:14 ambrosebs: gfredericks: that's just to get the body of the defn, as I read it

10:14 gfredericks: presumably the body of the defn there is exactly the code that would never get run under alex's interpretation

10:14 i.e., if you never use it outside the call position, why is there anything there at all?

10:15 ambrosebs: yep.

10:15 gfredericks: it's compiling the function AND calling it at macroexpansion time?? I can't figure out what that accomplishes

10:16 ambrosebs: No-one has clarified that.

10:16 I'm just ignoring that issue for now, the real problem in my eyes is that clojure.core uses definline.

10:16 llasram: I always thought the intent was pretty clear, but at odds with Alex's explanation

10:17 gfredericks: ,(definline snort [a] `(+ 1 ~a))

10:17 clojurebot: #'sandbox/snort

10:17 llasram: It creates a thing which expands like a macro in call position, but get's called as a function elsewhere

10:17 gfredericks: ,(snort 5)

10:17 clojurebot: 6

10:17 gfredericks: ,(map snort [1 2 3])

10:17 clojurebot: (2 3 4)

10:17 gfredericks: oh I guess the eval is for evaluating the syntax quote

10:17 llasram: So if it doesn't do the latter, it isn't any different from a macro

10:18 gfredericks: okay so I think the defn part makes sense to me now; haven't figured out where the bug comes from

10:18 haven't read the ticket in depth either

10:19 ambrosebs: gfredericks: if it's AOT related, I'm not sure more than a handful of people understand it ;)

10:20 gfredericks: oh the patch says that it has to do with expanding to (do (defn ...) (alter-meta! ...) ...)

10:20 and if you put the metadata on directly then it works fine

10:20 ambrosebs: gfredericks: oh right. I didn't read it either :)

10:21 gfredericks: so presumably it has to do with AOT and alter-meta!?

10:21 ambrosebs: gfredericks: AOT and meta never work properly.

10:21 gfredericks: slight overstatement

10:21 gfredericks: AOT and meta never work properly together

10:22 gfredericks: are there any downsides to the patch? just the cost of changes?

10:23 AeroNotix: ,(doc snort)

10:23 clojurebot: "([a]); "

10:23 AeroNotix: wat

10:23 ambrosebs: gfredericks: it contradicts the intention of definline

10:24 gfredericks: I guess Rich wrote it (?), so you can't argue with the man.

10:24 AeroNotix: Why can't you argue with Rich?

10:25 gfredericks: ambrosebs: assuming the intention is to only use in the call position? is there any theory for why the defn body exists then?

10:25 ambrosebs: gfredericks: well any theory has been debunked now if Alex is to be believed :)

10:28 AeroNotix: Rich wrote the documentation. It's vague. He has clarified. We move on.

10:32 eraserhd: Rough implementation of a splay rope for clojure. Clojure style review greatly appreciated: https://gist.github.com/eraserhd/8560700

10:33 silasdavis: I'm using carica config and between two development and production I've relied on a config.clj in resources/ and an overriding config in dev-resources/ to separate config values

10:35 now I have multiple environments and I'm using an uberjar for deployment

10:35 Wild_Cat: eraserhd: why (defn ^:private) and not simply (defn-) ?

10:35 silasdavis: how should I manage my configuration

10:35 gfredericks: Wild_Cat: ^:private is more general/portable

10:35 llasram: (inc gfredericks)

10:35 lazybot: ⇒ 36

10:36 Wild_Cat: how so?

10:36 ambrosebs: Wild_Cat: careful with that word simply..

10:36 :)

10:36 katox: silasdavis: environ?

10:36 llasram: Wild_Cat: Well you don't need `defmacro-`, `def-`, `defrecord-` `defmulti-` and so on

10:36 gfredericks: Wild_Cat: also applies to def and other def-based macros

10:36 llasram: Wild_Cat: One way of making a var private

10:37 gfredericks: does defrecord- make any sense? records aren't vars amirite?

10:37 silasdavis: katox, carica provides similar functionality

10:37 llasram: gfredericks: I was thinking the ->Record functions

10:37 Wild_Cat: yeah, sure, but in the case of a function, defn- exists.

10:37 unless you mean to tell me there are Clojure implementations that don't have it?

10:37 llasram: Wild_Cat: And is generally regarded as a mistake :-)

10:37 pbostrom: silasdavis: wouldn't you specify your prod profile when you build the uberjar?

10:37 silasdavis: my problem is not combining multiple sources, it's about the best way to use environment specific configs, I suppose I could switch on an environment variable

10:37 gfredericks: Wild_Cat: no, just that most people prefer having just one way of doing something than two

10:38 eraserhd: Wild_Cat: I'm following what I see, really. Someone explained to me that ^:private allows access if you know the symbol name, while defn- doesn't.

10:38 silasdavis: pbostrom, that sounds like what I should be doing

10:38 resource-paths

10:38 ah

10:38 eraserhd: But... I'm not sure that's actually right.

10:38 Wild_Cat: llasram: OK, I'm a massive Clojure noob, but this is the first time I've heard this, so [citation needed]?

10:39 gfredericks: eraserhd: ^:private and defn- should be equivalent

10:39 llasram: eraserhd: That person lied to you :-). `defn-` is identical in effect to `defn ^:private`

10:39 gfredericks: jinx!

10:39 * gfredericks explodes

10:39 eraserhd: Ah

10:39 mmitchell: Yesterday I was wondering why Clojure doesn't have a "def-" ?

10:40 sdegutis: mmitchell: ditto

10:40 katox: silasdavis: yeah, env variable seems to solve it. Any reason why to avoid that solution?

10:40 llasram: Wild_Cat: Citation -- consensus of long-time Clojure users in this channel :-)

10:40 There's been some clojure-users mailing list discussion, but not recently enough that I could find it easily

10:40 You can dig it up if you're curious

10:40 Wild_Cat: ...although I do see that there can be confusion between (defn- foo) and (defn -foo), which do not do the same thing at all.

10:40 tbaldridge: Wild_Cat: almost every time I've used defn- I've later gone and gotten a large boot and kicked myself with it.

10:40 Wild_Cat: (and *that* sucks :p )

10:41 mdrogalis: Pretty sure this is a good time for @FakeRichHickey to pipe up.

10:41 gfredericks: that doesn't stop 'foo and foo' from being completely different :)

10:41 eraserhd: Well, I guess I'd prefer defn- then, it seems easier to read. Even if its not consistent with def ^:private and stuff.

10:41 oskarkv: tbaldridge elaborate please. About the reason, not the kicking.

10:41 silasdavis: katox, I'd rather ship as much configuration with the uberjar rather than rely on the instance

10:41 looking at lein profiles

10:41 i can specify my resource path

10:41 `cbp: i'd prefer not to make anything private :D

10:42 silasdavis: which is how carica is designed so I think that will do what i want

10:42 llasram: eraserhd: To each their own. I do warn you, then when I read code using `defn-` I immediately think "this is Clojure 1.2 era code, or written by a newbie"

10:42 sdegutis: tbaldridge: Really? I've had the opposite experience.

10:42 katox: silasdavis: ok, I thought that you needed different runtime behaviour for the same uberjar

10:42 eraserhd: llasram: Interesting.

10:42 sdegutis: tbaldridge: Every time I don't use it, I almost forget that the function is not part of the public API.

10:42 katox: silasdavis: lein profiles should work but mind that they are merged by default (user and dev, I think)

10:43 tbaldridge: oskarkv: 1) it makes the code harder to test. 2) it limits the ability of users to extend your code

10:43 llasram: OTOH, rhickey still uses `defn-` so *shrug*

10:44 oskarkv: tbaldridge i see. thanks! I'm unsure about using it myself

10:44 eraserhd: tbaldridge: That conflicts with llasram said. Is defn- equivalent to defn ^:private or not?

10:44 RickInAtlanta: dnolen: I saw you merged my pull request on lt-cljs-tutorial. thx. This was my first time doing a pull request, just wanted to make sure there weren't any conventions/procedures that I failed to observe.

10:45 dnolen: RickInAtlanta: nah, looked good

10:45 stuartsierra: eraserhd: yes, defn- and defn ^:private are the same

10:46 RickInAtlanta: thx. I also wanted to ask: in the section on keywords, it says that namespaced keywords are essential to light table's modularity. Wasn't sure if that should have read "clojurescript's modularity"

10:46 arcatan: hmm. what happens if you deref an atom while doing swap! to it? i.e. (swap! a-atom foo @a-atom)

10:47 gfredericks: arcatan: that's not while, that's before

10:47 arcatan: but why would you need to?

10:47 stuartsierra: The values won't necessarily agree.

10:47 dnolen: RickInAtlanta: well the tutorial is for LT users primarily

10:47 RickInAtlanta: but yes falls out CLJS

10:47 out of

10:47 arcatan: gfredericks: i don't need it, but i encountered some code that does it and i'm wondering whether it works

10:48 RickInAtlanta: I thought it made good sense either way.

10:48 stuartsierra: arcatan: It's not necessary, since swap! always passes the current value of the Atom to the function you pass it.

10:49 arcatan: stuartsierra: i know - my question is an exercise in intellectual curiosity

10:49 stuartsierra: And since the deref happens before swap! is called, it could return a *different* value from the one that your swapping function sees.

10:49 arcatan: yeah, makes sense

10:50 silasdavis: katox, ah no, I think you're right in that case, environment variables or command line system properties, of which i think I prefer the latter because you can see the configuration options via ps

10:50 nDuff: silasdavis: you can also see environment variables through ps

10:50 silasdavis: look at ps -E

10:50 eraserhd: ,(macroexpand '(defn- f [] nil))

10:50 clojurebot: (def f (clojure.core/fn ([] nil)))

10:51 nDuff: ...ehh, just e on GNU systems.

10:51 gfredericks: eraserhd: the metadata is there it just doesn't print

10:51 ,(binding [*print-meta* true] (prn (macroexpand '(defn- f [] nil))))

10:51 clojurebot: (def ^{:arglists (quote ([])), :private true} f (clojure.core/fn ([] nil)))\n

10:52 silasdavis: nDuff, didn't know that, thanks

10:52 gfredericks: does anybody use robert.hooke for testing? I feel like it could use a with-redefs style macro

10:52 katox: silasdavis: right, with ps it's usually easier to debug

10:52 silasdavis: nDuff, actually can't find -E option..

10:53 nDuff: silasdavis: I corrected myself, it's just e

10:53 S11001001: or just "env"

10:53 nDuff: S11001001: does that show you for other processes?

10:53 S11001001: nDuff: ah, I see, no

10:56 AeroNotix: my compojure middleware looks like it's being applied in a different order than what I said, huh?

10:57 gfredericks: AeroNotix: is it exactly backwards from your expectations?

10:57 AeroNotix: gfredericks: no, the first one is run, then the third, then the second ><

10:58 let me just triple check that, I've had very little sleep.

10:59 gfredericks: compojure middleware can be a bit subtle at first making it not surprising when people have backwards expectations

10:59 AeroNotix: huh, ok

11:00 gfredericks: if you really are seeing a [1 3 2] ordering then something much weirder is happening

11:00 AeroNotix: gfredericks: no it's 321, nevermind

11:01 Need sleep

11:01 mdrogalis: ambrosebs: Temperature received. lol

11:02 ambrosebs: mdrogalis: unsuprising, since I was essentially proposing an enhancement.

11:02 mdrogalis: Sometimes it feels like I'm speaking to an older coworker on a legacy system and the motto is "DONT TOUCH ANYTHING"

11:05 silasdavis: do resources specified via -classpath take precedence over resources in a jar when running

11:05 java -classpath <resource-dir> -jar uberjar.jar?

11:07 katox: silasdavis: no, they are ignored

11:09 silasdavis: you can combine it with cp alone though

11:09 silasdavis: st like this (first googled workaround) http://www.tiwoc.de/blog/2008/10/java-jar-ignores-classpath-workaround/

11:20 noprompt`: tbaldridge: tim, does relevance have any shared settings or techniques for remote pairing?

11:21 tbaldridge: noprompt`: to be honest, I don't know. stuartsierra may know

11:22 stuartsierra: noprompt`: old but still somewhat relevant http://thinkrelevance.com/blog/2010/09/02/remote-pairing

11:22 Also https://github.com/relevance/etc

11:23 redinger: noprompt`: Also https://github.com/karnowski/pairhost

11:49 mdrogalis: ambrosebs: IMO the worst thing that Alex could do right now is stop responding. :/

11:49 ambrosebs: mdrogalis: I disagree, at this point he has better things to do.

11:49 mdrogalis: :/ such a waste of time

11:49 mdrogalis: I'm sure he does, but it just looks bad.

11:50 katox: A datomic question: with compount natural key, is it reasonable to use an artificial key (for instance UUID) for new entities? Having to support compound keys everywhere seems uncomfortable. Just using datomic generated entity ID seems to introduce possible problems with refs during imports and exports. Thoughts?

11:51 mdrogalis: katox: Second to last sentence is accurate. That seems fine.

11:52 ambrosebs: mdrogalis: it's just another under-documented corner of clojure that we have to live with for awhile. Surely we're all used to that.

11:52 mdrogalis: ambrosebs: Yeah, I suppose so.

11:52 ambrosebs: I've wasted my evening getting to that conclusion unfortunately.

11:53 mdrogalis: Evening.. Still haven't had lunch yet here.

11:53 gfredericks: ambrosebs: mdrogalis: a docstring change at least is acceptable

11:53 katox: mdrogalis: so what about the uuid part? The first sentence ;)

11:54 gfredericks: I'm curious what the docstring will end up saying that won't make it obvious that definline is just defmacro

11:54 mdrogalis: katox: Go with a SQUUID so its indexable.

11:54 But yeah, that's what I'd do.

11:55 ambrosebs: gfredericks: mdrogalis: I was going to comment further but I have better things to work on ;)

11:55 gfredericks: I get sucked into drama a little bit

11:56 katox: mdrogalis: I see, squuid(), thanks. Makes sense I was about to look for something built-in ;).

11:56 ambrosebs: I'll get back to ... writing a parser for TypeScript. Hmm I see how I got sidetracked now.

11:56 mdrogalis: katox: Have at it.

11:58 S11001001: ambrosebs: what's it for?

11:58 ambrosebs: S11001001: harvesting annotations

11:58 for core.typed cljs

11:59 katox: mdrogalis: the name is hilarious ;)

11:59 S11001001: ambrosebs: Hmm. Probably a big leap forward, though I have concerns about their quality given how little the typescript people care about soundness.

12:01 mdrogalis: katox: I'm fond of it, too.

12:01 ambrosebs: S11001001: I share your concerns.

12:02 S11001001: ambrosebs: probably save a lot of work anyhow, even if the results have to be improved.

12:03 ambrosebs: S11001001: seems like a good place to start.

12:17 Mandar: hi

12:17 i'm trying to understand into

12:17 ambrosebs: Mandar: Hi

12:17 Mandar: let's say i want to get the results of this: (partition 2 [:a 1 :b 2 :c 3 :d 4 :e 5]) into a map

12:17 jcromartie: Mandar: it's basically just reduce with conj

12:17 Mandar: i wrote this: (into {} (map (partial into []) (partition 2 [:a 1 :b 2 :c 3 :d 4 :e 5])))

12:17 but it's not pretty at all...

12:18 technomancy: Mandar: you don't need the second into iirc

12:18 Mandar: ,(map (partial into []) (partition 2 [:a 1 :b 2 :c 3 :d 4 :e 5]))

12:18 clojurebot: ([:a 1] [:b 2] [:c 3] [:d 4] [:e 5])

12:18 `cbp: ,(into {} (partition 2 [:a 1 :b 2 :c 3]))

12:18 clojurebot: #<ClassCastException java.lang.ClassCastException: clojure.lang.Keyword cannot be cast to java.util.Map$Entry>

12:18 technomancy: Mandar: what you probably want is apply hash-map

12:19 jcromartie: if you *do* have a sequence of key-value pairs as vectors, you can use into

12:19 ,(into {} (map vec (partition 2 [:x 1 :y 2])))

12:19 clojurebot: {:x 1, :y 2}

12:19 Mandar: jcromartie, awesome!

12:19 jcromartie: but technomancy has the better answer

12:19 ,(apply hash-map [:x 1 :y 2])

12:19 clojurebot: {:y 2, :x 1}

12:20 technomancy: huh; didn't realize it was picky about vec vs seq

12:20 `cbp: i thought that would work :P

12:20 Mandar: thanks guys!

12:21 ambrosebs: technomancy: either a vector, nil, IMapEntry, or an IPersistentMap can be conjed onto a map

12:21 technomancy: I wish I didn't know that :)

12:21 technomancy: ambrosebs: haha; hard-won knowledge

12:22 gfredericks: ,(conj {} nil)

12:22 clojurebot: {}

12:22 gfredericks: ,(conj [] nil)

12:22 clojurebot: [nil]

12:22 technomancy: whoever was asking about why nil doesn't work with clojure.string yesterday; I think I have a better explanation

12:22 gfredericks: ,(conj () nil)

12:22 clojurebot: (nil)

12:22 gfredericks: ,(conj #{} nil)

12:22 clojurebot: #{nil}

12:22 ambrosebs: technomancy: actually not an IPersistentMap, a (Seqable (MapEntry Any Any))

12:22 ;)

12:23 rasmusto: ,(conj {} '())

12:23 clojurebot: {}

12:23 technomancy: it's because clojure has its own collection types that go out of their way to be nil-safe, but we can't have our own string type for two reasons 0) String is final, and 1) String is pretty close to already doing the right thing out of the box

12:23 the two exceptions to 1) being nil safety and not accepting metadata

12:24 though I guess with interned strings the metadata question is less clear-cut

12:27 gfredericks: it surprises me how many people's first reaction to metadata is "why on earth is THAT a good idea?"

12:27 gtrak: it is a bit weird.

12:28 hiredman: I thought most people's first reaction was to use it for *everything*

12:28 rasmusto: I refactored my code to use nothing but vectors of nil and metadata

12:29 gtrak: I used it once to debug and trace things, generally I avoid it.

12:29 seems like if the info needs to actually be there, it should be part of a data structure like everything else.

12:29 gfredericks: I have a hard time giving a succinct defense

12:30 it seems to be used for various rather different categories of things

12:30 technomancy: the canonical application is for source code forms' :file/:line

12:30 dnolen: gfredericks: it's pretty nice in compilers of all kinds

12:30 gfredericks: core.match and ClojureScript use and it rocks

12:30 gfredericks: dnolen: yeah compiler stuff seems to be the primary use case

12:30 gtrak: what is it about compiler stuff, adding an extra :meta key to every node gets tedious?

12:31 technomancy: gtrak: it's not all maps

12:31 dnolen: gtrak: this is pre-AST

12:31 gtrak: you need to put information symbols for later phases

12:31 information on

12:31 gtrak: ah, you don't want to have to wrap and unwrap everything.

12:32 or you want a universal interface for different types of data.

12:33 gfredericks: there are other uses on vars too e.g. robert.hooke

12:33 gtrak: I think it's at some level a back-door for lack of pointers, an alternative might be a map of object-keys to metadata, but that relies on equality, not identity.

12:34 gfredericks: oh yeah there was a lisp guy here who was quite surprised that two equal symbols could have different metadata

12:34 but no way would the compiler work the other way

12:36 ambrosebs: dnolen: any idea why this is here? https://github.com/LightTable/LightTable/blob/master/src/lt/util/cljs.cljs#L10

12:38 technomancy: gfredericks: IIRC you can do the same thing with symbol property lists in CL

12:43 gfredericks: technomancy: not knowing anything about what those are, that makes no sense to me

12:43 technomancy: I feel that way about a lot of CL even after knowing what things are.

12:43 gfredericks: technomancy: speaking of robert.hooke how would you like a with-redefs style macro called with-hooks or something?

12:44 I wanted this for monkey patching stuff in clojure.test fixtures

12:45 technomancy: gfredericks: with-scope+add-hook won't do the same thing?

12:45 gfredericks: technomancy: it would, but in two steps :P

12:45 technomancy: I guess with-hooks would be more declarative

12:45 gfredericks: that would be how I would implement it

12:45 technomancy: sure

12:45 a simple composition of those two existing forms sounds good

12:45 gfredericks: k cool; I will get to that if it's worth it to me

12:46 hiredman: gfredericks: well, cl symbols are in some respects similary to clojure keywords(interning) and keywords don't have metadata

12:48 technomancy: I guess the difference is you can go out of your way to create a CL symbol that's eq to another, but the symbols the reader returns are singletons like keywords

12:48 err... maybe not eq

12:50 hiredman: I imagine clojure is a bewildering place for someone steeped in the hyperspec

12:51 dnolen: ambrosebs: probably just need a patch to CLJS

12:53 katox: dnolen: unless compiler stuff gets into your program https://github.com/LightTable/LightTable/issues/919

12:55 dnolen: katox: I'm not even sure that issue is about

12:55 katox: but yes *tradeoffs*

12:55 zerokarmaleft: gfredericks: what's the advantage of using hooks over with-redefs?

12:55 katox: dnolen: it's just that in light table if you create an empty vector, the ide attaches its own metadata to it

12:56 dnolen: and if you replace those with your own, weird things happen

12:56 dnolen: katox: vary-meta is your friend :)

12:56 and namespaced keywords

12:57 katox: that issue isn't about LT anyway, :line and :column is from the reader

12:57 katox: dnolen: yes, I noticed

12:58 dnolen: katox: granted LT needs that information

12:58 katox: dnolen: yeah, you are right, if you take special care about the metadata it can work

13:01 dnolen: still, it is a bit wierd to have the ide changing the code path your program takes without a warning

13:01 dnolen: I guess there is no easy way out for top level forms

13:02 dnolen: other than not using metadata on such things foolishly (as you were the only master)

13:02 dnolen: katox: :line meta has been in Clojure forever, this isn't not something I've widely heard as pain point

13:02 ambrosebs: dnolen: FYI doc typo: diffenent https://github.com/clojure/clojurescript/blob/master/src/cljs/cljs/core.cljs#L21

13:03 katox: dnolen: nope, it's a minor thing

13:04 dnolen: ambrosebs: thx fixed

13:04 ambrosebs: dnolen: np

13:05 gtrak: tpope: yt? curious if you've got a middleware for var-info or whatever yet. I'll try to finish up my stuff tonight.

13:06 katox: dnolen: btw. I've seen your core.async talk, some very good points there

13:06 dnolen: katox: thx

13:07 katox: dnolen: is there something more about channel error handling? (besides <? gist macro)?

13:07 dnolen: katox: not really different application need different approaches to error handling, and core.async is flexible.

13:08 katox: dnolen: yeah, it seems that the price for a general re-throw is too high.

13:34 OscarZ: I'm trying to experiment with protocols.. I've created protocol DAO and a type AtomDAO "implementing" that protocol.. im getting "Unable to resolve classname AtomDAO" on my type.. Im calling it like (p/get-entry (p/AtomDAO. "foo")) I have :required the namespace :as p

13:35 egghead: hmm, my cljs app doesn't work with advanced mode :(

13:35 OscarZ: any ideas?

13:36 stuartsierra: OscarZ: deftype creates classes, not Vars. Use the fully-qualified class name or :import it

13:37 ivan: egghead: if you're using non-GClosure libraries, did you add the externs you need?

13:38 OscarZ: thanks stuartsierra.. I think I need to read up on those namespaces again

13:38 koreth_: Does (slurp) ever return anything but java.lang.String? I am surprised that I'm getting a reflection warning when I call a String method on slurp's return value.

13:39 egghead: yup ivan, I'm going to try fiddling with these optimization modes until I get a build that works... :|

13:39 ivan: egghead: are you using react?

13:39 mdrogalis: Has anyone here used Simulant before? I have a technique question.

13:39 egghead: ivan: yes

13:39 I bet that stuartsierra has used simulant before

13:39 :)

13:39 ivan: egghead: you need :externs ["react/externs/react.js"] as seen in https://github.com/swannodette/om

13:40 egghead: ivan: ya, i'm probably experiencing a cljs bug

13:40 `cbp: koreth_: the point is the compiler doesn't know the type of slurp

13:42 technomancy: koreth_: the inference you get is pretty limited

13:42 mdrogalis: I'll just ask it :P Has anyone used Simulant in the scenario where the agents are reactive at runtime to the system under test? e.g. subsequent actions in the action stream depend on previous actions.

13:43 koreth_: That being the case, I wonder if it makes sense to explicitly type-hint it in core.clj -- looking at the implementation, it seems like it can't ever return a non-String value. Or would that not help?

13:44 technomancy: ~tias

13:44 clojurebot: tias is try it and see

13:44 sdegutis: ~tiafo

13:44 clojurebot: Titim gan éirí ort.

13:45 egghead: it looks like cljs advanced is behaving differently on different build environments

13:48 md5sum of the generated js file changes

13:48 rurumate1: I have a question about reflection warnings in general; I've never seen any, is there some flag to turn them on, or am I just lucky not to produce any?

13:49 egghead: rurumate1: ya you need a flag to turn them on

13:49 rurumate1: I see

13:49 egghead: for anyone interested: my cljs issue *looks* like it was caused by files left around in the target dir colliding ... somehow...

13:49 rurumate1: is there a lein option to turn them on or something?

13:49 egghead: http://clojuredocs.org/clojure_core/clojure.core/*warn-on-reflection*

13:50 hyPiRion: rurumate1: `lein check` ?

13:50 rurumate1: oh thanks

13:50 egghead: or you can do it in your project.clj rurumate1

13:50 `cbp: :global-vars

13:50 egghead: https://github.com/technomancy/leiningen/blob/master/sample.project.clj#L219

13:51 rurumate1: nice, I guess I should go to some clojure user group or something. Oh wait, I'm in one

13:51 gfredericks: zerokarmaleft: hooks make it more straightforward to call the original

13:51 pretty similar advantage over with-context+add-hook -- just eliminating a bit of boilerplate

13:58 rurumate1: what's the reference page on type hints and performance tuning?

13:59 it's because I have some clojure-defending work to do at my day job

13:59 the first attack was, it doesn't perform because reflection

14:00 is there a standard reply?

14:00 `cbp: rurumate1: type hints are easy, just turn on *warn-on-reflection* and typehint till it stops complaining

14:00 egghead: `cbp: :p

14:01 tbaldridge: rurumate1: if it is, it's wrong. most well-written clojure code has no reflection.

14:01 jcromartie: rurumate1: is your code slow?

14:01 rurumate1: jcromartie: usually not

14:01 jcromartie: rurumate1: or are people just saying "Clojure is slow"

14:01 rurumate1: ithe the lattwer

14:01 it's the latter

14:01 duh

14:02 jcromartie: I've rewritten Java services in Clojure to be 100X faster and 10% smaller. But that's not because Clojure is fast (or slow).

14:02 I mean 10% the size.

14:02 technomancy: clojure code that performs reflection *is* slow. it's just not remotely difficult to avoid.

14:04 rurumate1: thanks, that was a good briefing

14:05 I feel confident now

14:06 sdegutis: I wonder if we could speed up our Datomic-based statistics generating code by eliminating a little reflection. We should profile that one day.

14:07 gtrak: it's easy to reason about why it's slow, if it is slow.

14:07 rurumate1: I've been using clojure for a year, and my output got dramatically better. Unfortunately there was no official decision to use the language, and now the project lead is changing and clojure will probably be banned in favor of pure java

14:07 gtrak: which makes it easier to make it fast

14:07 rurumate1: they are taking away my repls

14:07 tbaldridge: rurumate1: when my company got that sort of attitude, I left the company

14:07 sdegutis: rurumate1: The good thing about Clojure is that you can sneak it into a Java project without much visible ceremony. ;)

14:08 gtrak: sdegutis: forgiveness over permission usually works for me :-)..

14:08 * sdegutis just realized the Quake2 engine is open source and can be compiled locally and modified

14:08 gtrak: people are less likely to throw stuff out than they are to say no when you ask them if you can do something.

14:08 * sdegutis is about to lose an hour or so

14:08 rurumate1: tbaldridge: your company happens to be looking for new staff?

14:09 it seems clojure is not very common where I live

14:09 bbloom: gfredericks: shameless self promotion.... i quoted you in my talk: http://www.hakkalabs.co/articles/clojure-software-dendrology :-)

14:09 tbaldridge: rurumate1: I was just saying, I used to work for a place that was only interested in "industry standard" tech. When that was made clear, I left the company. I want to work with people who aren't afraid to try powerful new tech.

14:09 * gfredericks omg omg omg

14:10 gfredericks: bbloom: is this where I called you a dendrologist?

14:10 ~bbloom

14:10 clojurebot: bbloom is a dendrologist

14:10 bbloom: gfredericks: haha indeed

14:10 gfredericks: <3

14:10 ~botsnack

14:10 clojurebot: thanks; that was delicious. (nom nom nom)

14:10 gfredericks: I spout so much nonsense in #clojure I'm surprised I was able to recall that at all

14:11 bbloom: gfredericks: well i certainly remembered it. and now it's immortal in video form on the interwebs. so thank you :-)

14:11 gfredericks: rurumate1: specifically a single instance of reflection is on the order of a microsecond I think; so this is only slow when it's part of a task that's supposed to be a lot faster than that

14:11 a lot of clojure code leaves reflection in places that can easily tolerate it

14:12 bbloom: anytime :) I'm not interested in watching this

14:12 jcromartie: hmm, doall makes for shorter stack traces…

14:12 bbloom: gfredericks: aw, okay :-(

14:13 gfredericks: bbloom: oh whoops

14:13 lol

14:13 llasram: heh

14:13 gfredericks: s/not/now

14:13 bbloom: gfredericks: yay :-) haha

14:13 gfredericks: sorry for those 30 seconds of rejection

14:13 llasram: Is that really any better? I mean, you weren't interested until you knew that you'd get a narcissistic thrill out of it?

14:13 bbloom: gfredericks: haha it's ok, i can handle it

14:13 gfredericks: I mix up not<->now all the time I think it has something to do with dvorak

14:14 llasram: oh definitely the narcissistic thrill -- but I think the fact that I don't *mind* watching it is better than not wanting to watch it despite the narcissism

14:14 llasram: gfredericks: You can always tell fellow Dvorak-typists by their hypos

14:15 gfredericks: some things are not worth enduring for the sake of seeing yourself mentioned on the internet and my guess is that bbloom's talk is nowhere near that category

14:15 bbloom: gfredericks: if it does approach that category, please let me know so that i can make future talks suck less

14:15 gfredericks: bbloom: absolutely

14:16 Kant's ex is king

14:19 jcromartie: whoever wrote hiccup.form obviously never used it in an app


14:19 technomancy: llasram: hehe

14:20 gfredericks: bbloom: oh this means I inspired the title as well!

14:20 bbloom: gfredericks: and lots of tree-related puns

14:27 TimMc: ~gfredericks

14:27 clojurebot: gfredericks is polluting your memory and must be destroyed

14:27 TimMc: hah

14:28 gfredericks: I guess that didn't catch on

14:32 llasram: ~llasram

14:32 clojurebot: It's greek to me.

14:32 llasram: Awww

14:32 clojurebot, I thought we were friends!

14:32 clojurebot: No entiendo

14:40 jcromartie: ah, I was wrong… hiccup's handling of nil attributes works, but Enlive's is not

14:40 I mean Enlive's is not compatible with hiccup's

14:44 gfredericks: &(let [ow #(assert false)] (->> (repeatedly 1000 #(let [^Throwable t (try (ow) (catch Throwable t t))] (-> t (.getStackTrace) (alength)))) (frequencies)))

14:44 lazybot: java.lang.SecurityException: You tripped the alarm! catch is bad!

14:45 gfredericks: ,(let [ow #(assert false)] (->> (repeatedly 1000 #(let [^Throwable t (try (ow) (catch Throwable t t))] (-> t (.getStackTrace) (alength)))) (frequencies)))

14:45 clojurebot: gfredericks: No entiendo

14:45 gfredericks: huh?

14:45 Raynes: gfredericks: That'd be robots telling you to <expletive> yourself, sir.

14:50 gfredericks: ,(let [ow #(assert false)] (->> (repeatedly 1000 #(let [^Throwable t (try (ow) (catch Throwable t t))] (-> t (.getStackTrace) (alength)))) (frequencies)))

14:50 clojurebot: gfredericks: excusez-moi

14:51 gfredericks: ,(let [what "is going on"] what)

14:51 clojurebot: "is going on"

14:51 gfredericks: ,(try 42 (catch Exception e e))

14:51 clojurebot: gfredericks: No entiendo

14:51 gfredericks: ,(try 42)

14:51 clojurebot: 42

14:51 gfredericks: ,(catch 42)

14:51 clojurebot: gfredericks: Titim gan éirí ort.

14:51 gfredericks: ,catch

14:51 clojurebot: gfredericks: Excuse me?

14:52 gfredericks: haha

14:57 djcoin: I'm relatively new to clojure but is there some way to intercept mutation to a datastructure (any kind) to be able to replicate those change later (rather than saving each time the new structure, I want to know the diff to apply it client side and to serialize it). Is there a lib somewhere which already does that ? I guess it may not be so hard to implement maybe cumbersome. Also if it worked with

14:57 clojurescript, it would be great :)=

14:57 jocrau: add-watch to an atom

14:58 (add-watch

14:58 state ::state-change

14:58 (fn [key reference old-state new-state]

14:58 (put! outgoing-changes new-state)))

14:59 djcoin: it won't work as I will be loosing the kind of change that happended between the two states I guess. Or I need to make a diff

14:59 jocrau: no ?

14:59 teslanick: You can use clojure.zip to walk through the object and find changes.

14:59 jocrau: You are right. It only gives you the state before and after the change.

15:00 djcoin: Or I could just use a fn wrapper and call each time: (applyAndSave conj mydatastructure "a")

15:00 But in this case the caller need to know

15:00 justin_smith: djcoin: you could make a wrapper over swap! that saves the function applied for later

15:01 arohner: djcoin: that doesn't sound very clojure-y

15:01 nDuff: ...well, a wrapper over swap seems ugly

15:01 arohner: the whole goal seems non-idiomatic

15:01 justin_smith: djcoin: or make a data based swapping function, (on top of swap!) that is guaranteed to be self-describing and serializable

15:01 nDuff: but you could certainly implement your own Atom

15:01 justin_smith: since arbitrary functions are not

15:01 djcoin: arohner: tracking change to an immutable datastructure transparently is non-idiomatic ?

15:01 nDuff: ...oooh. point.

15:02 teslanick: Capturing diffs eagerly is non-idiomatic to clojure.

15:02 nDuff: (re: serializability of functions).

15:02 `cbp: you can save every version of your data structure in a vector or something and it will be memory efficient

15:02 teslanick: It raises the question of why you want diffs and not whole objects.

15:02 djcoin: `cbp: yeah I know but thise is not my goal there

15:02 jcromartie: once you introduce an outside client, you have to throw consistency of Clojure's reference types out the window

15:03 you can't hold on to those guarantees anymore

15:03 djcoin: justin_smith: I will need to understand what you said :) I don't know serializability of functions but will check out

15:03 jcromartie: djcoin: are you talking about like AJAX on a web page?

15:04 justin_smith: djcoin: by serializable I mean expressable as vanilla edn data

15:04 djcoin: jcromartie: kind of, that would be used to push diff from one client to anoter

15:04 justin_smith: so that one app could send it to another (or save to disk and load later)

15:04 djcoin: *another

15:04 jcromartie: djcoin: either way, you're now in distributed computing territory: good luck!

15:04 :P

15:06 jocrau: djcoin: hmm, could you send the changing function and apply it on server side

15:06 sturner: Hi all -- is anyone aware of anything like MeteorJS DDP (https://www.meteor.com/blog/2012/03/21/introducing-ddp) in the clojure community or java I suppose. Basically providing subscription of a 'collection' with push updates as the client persists?

15:06 teslanick: That sounds like "here be dragons" territory. Unless your really bandwidth constrained, it's conceptually way simpler to send the whole object

15:06 justin_smith: teslanick: what comes up is the need to synchronize data where each end can change

15:07 so you have different effective ordering on each side, but want all changes to be present

15:07 think git

15:07 teslanick: Git sends whole files, so there! ;)

15:07 justin_smith: telex: it sends deltas that are used to construct files

15:08 djcoin: teslanick: yeah but copy the whole structure seems non idiomatic to me, we have the chance to have persistent datastructure, I would have prefered to use it byu just replicating the change

15:08 justin_smith: and checkouts recreate based on different deltas / orderings

15:08 err s/telex/teslmanick above

15:10 teslanick: Well, git stores the entirety of changed files as refs. To that end, it has some smallest level of what can be diffed that's pretty chunky.

15:11 To make the comparison, you'd need to describe the kind of data you're diffing more completely, and you have to figure out what the system does when reconciliation isn't possible.

15:11 Hence, "here be dragons" territory.

15:12 xavriley: I'm trying to develop a leiningen plugin locally and I'm not sure what the best setup is - can anyone help me with leiningen setup?

15:12 djcoin: However, I think it would be fairly easy to just implements all collections interface and trap the call

15:14 llasram: xavriley: https://github.com/technomancy/leiningen/blob/master/doc/PLUGINS.md#writing-a-plugin

15:15 xavriley: That said, note that you verily likely just need an alias, not a plugin

15:16 jocrau: djcoin: here is an example project using #om: https://bitbucket.org/infinitecloud/omg/src. By now, I send the whole data structure.

15:16 InSighter: <<<< www.TheShowBay.tv - Watch all shows for free! >>>>

15:17 djcoin: jocrau: thanks!

15:26 xavriley: llasram: thanks I'm back on track now. It was eval-in-leiningen that fixed it

15:26 llasram: xavriley: OOC, what's your plugin for?

15:27 xavriley: It's adding full-text lucene type search to static doc sites using http://reyesr.github.io/fullproof/ :)

15:28 llasram: Interesting. Well, probably can't do that in an alias :-) Not exactly sure I understand why it goes in leiningen though?

15:31 xavriley: llasram: codox is a static docs generator that runs as a leiningen plugin - I'm still learning my way around what all the options in project.clj do but it's working better now anyway

15:32 llasram: Oh, I see -- specifically project documentation static sites. That makes sense.

15:42 mmitchell: technomancy: Is it possible to :exclude a user profile plugin in a project.clj file?

15:42 For example, I have lein-ring in my user profile, but would like to add it to my project. pedantic shows that I have conflicting dependencies, but they're actually the same version.

15:43 hyPiRion: mmitchell: that's going to be fixed for 2.4.0

15:43 mmitchell: hyPiRion: interesting, good to know!

15:44 hyPiRion: Well, it is fixed, but the fix introduced a bug we have to fix before release

15:47 danneu: How do yall generally cache your webapp? In a controller I set 'latest-posts' from the db. In the view, I render a column of those latest posts. It seems to make more sense to just move the db-call into the view and cache the whole html tree.

15:52 Oh yeah, in Rails I remember caching the view with the same key I'd cache the controller response with so the invalidation would trickle down.

16:00 technomancy: xavriley: IMO codox should not be a lein plugin

16:02 unless it needs to read the project map, I guess that could makes ense to get :description and :license, etc

16:08 xavriley: technomancy: it's interesting you should say that. I've been thinking about other approaches but having some of the project.clj details seems necessary for signposting versions etc. Would you have any other suggestions?

16:11 technomancy: xavriley: yeah, I guess I'm not that familiar with what it does

16:11 but most people writing lein plugins these days are doing things that shouldn't be plugins

16:13 bbloom: technomancy: there's something weird about THE TOOL

16:13 technomancy: by that i mean whatever it is, lein, bundle/gem/rake, make, grunt, whatever

16:13 people want everything to work via THE TOOL

16:13 meanwhile, ./script/whatever gets the fucking job done quicker and easier 9 out of 10 times

16:15 technomancy: bbloom: but you don't even need a plugin for `lein foo`

16:15 just an alias

16:16 ro_st: quicker and easier, until you have 20 of the damned things with duplicated code across half of them and across projects

16:16 bbloom: technomancy: solution: rename "alias" to "alias extension" and rename plugin to "plugin extension" then make a docs section called "extensions" and add an introductory paragraph about how to choose the correct type

16:16 technomancy: i am 100% serious

16:16 technomancy: ro_st: except you can write an alias against a namespace in :dependencies

16:17 bbloom: technomancy: you have in the docs "Writing Plugins". Replace that with "Writing Extensions" and link to the plugin section

16:17 technomancy: that sort of stuff influences behavior big time. you need to create a pit of success :-)

16:19 technomancy: bbloom: or just delete the plugin docs. we have enough plugins; all these plugins are confusing everyone.

16:19 </ryan-dahl>

16:20 bbloom: technomancy: lol, won't be as helpful as putting a giant warning on top of the plugin docs page that says "You usually don't need to write a plugin! See how to create other types of _extensions_" with a link there

16:20 technomancy: http://shitryandahlsays.tumblr.com/ is missing a lot of great lulz

16:23 bbloom: but yeah, I should add a warning

16:26 xavriley: technomancy: OOC what would you say is the best usecase for writing a plugin?

16:28 technomancy: xavriley: it's when you either need info in the project map or access to functions that are part of Leiningen's own API

16:29 lots of people write plugins so they can do `lein my-thingy x y z` instead of `lein run -m my.thingy x y z`

16:30 noonian: my plugins just wrap other plugins or tools so i don't have to start up 2-5 tabs just to watch files or w/e

16:31 xavriley: technomancy: thanks for the clarification - I'll give it some thought in terms of what I'm working on.

16:31 technomancy: noonian: what that tells me is that the other plugins you're using aren't flexible enough

16:31 you should be able to express things as higher-order task invocations

16:32 noonian: yeah, they aren't all plugins is part of the problem

16:32 technomancy: I think possibly "profiles you can load out of plugins" might be a missing piece of the puzzle

16:32 noonian: things like compiling sass, or building projects that used cmd line tools to build when assets change

16:58 mookerji: hi, I have a question about instrumentation libraries. does anyone have any experience with using lamina+narrator (vs say, interval-metrics) for client-side metrics aggregation and event generation? (question repeated from #riemann)

17:02 ztellman: mookerji: some

17:03 mookerji: ztellman: interval-metrics and narrator+lamina seem have some overlap. is there any reason i'd want to use one over the other?

17:04 overlap in terms of metrics aggregation, specifically.

17:04 ztellman: mookerji: interval-metrics requires an external driver for the aggregating and emitting

17:05 unless kyle's changed it a lot since I last looked at it

17:05 mookerji: sure. do you have a sense of how they differ performance-wise?

17:06 at least, interval-metrics README has some numbers on the update bandwidth for rate/latency, etc.

17:07 ztellman: the narrator performance should be more or less identical

17:07 it's just a slightly different implementation of the same thing

17:07 mookerji: ah, ok. that makes sense.

17:07 ztellman: but since there's more machinery to drive the aggregation, it might be slightly slower if you compare narrator's query-seq versus the bare interval-metrics aggregators

17:08 mookerji: i was hoping to confirm that before attempting to run my own test.

17:08 by machinery, you're talking about interval-metrics being slightly slower

17:10 in either case, I'm using a batch riemann async client to emit events.

17:10 ztellman: sorry, on a call, I'll be able to answer in a bit

17:11 mookerji: no problem. you've definitely answered the original question. thanks!

17:36 ztellman: mookerji: to clarify, what I meant was that narrator is wrapped around something like interval-metrics, but because there's a framework between you and the raw counting, narrator is likely to have lower throughput than a "comparable" test with interval-metrics

17:36 I'm not sure by how much, though

17:36 probably not a lot

17:36 mookerji: ah, ok.

17:37 the framework being async channels and instrumentation?

17:39 alew: are clojure expressions guaranteed to be evaluated left to right?

17:40 `cbp: alew: functions? sure. Special forms/macros not so much

17:40 alew: yeah I meant functions

17:40 noonian: yep

17:41 rasmusto: functions + do are, and macros vary

17:41 alew: Great, thanks

17:46 technomancy: pretty sure technically that is an implementation detail

17:47 unlikely to change, granted, but not guaranteed afaik

17:47 rasmusto: technomancy: re: left-to-right expressions?

17:48 technomancy: rasmusto: for arguments of a single function

17:49 rasmusto: oh, ok. Is left-to-right in the body something that's safer?

17:49 (guaranteed I mean)

17:49 technomancy: (vector (prn :hi) (/ 8 0)) ; <- whether this prints or not is technically undefined

17:49 justin_smith: yeah, counting on order of evaluation in args to a function is just bad style anyway

17:49 I mean people will try to read your code...

17:49 ztellman: use a let binding, if you want guaranteed ordering

17:49 technomancy: rasmusto: arguments to the do macro are definitely guaranteed

17:50 rasmusto: (fn [a b] (do (prn a) (prn b)))

17:50 justin_smith: as are let bindings (this is exploited extensively, probably even in clojure.core)

17:50 technomancy: rasmusto: fn has an implicit do

17:50 rasmusto: but then (thatfn a b), a doesn't necessarily get eval'd before b, yea?

17:51 technomancy: right

17:51 alandipert: the l-r arg eval is specified somewhere, i checked once

17:51 rasmusto: technomancy: ok, understood

17:51 technomancy: alandipert: oh, in the docs?

17:51 alandipert: technomancy: http://clojure.org/evaluation

17:52 technomancy: well look at that; quite right

17:52 justin_smith: oh, so you can even count on the thing in call position being evaluated before the args are

17:52 ((do (println :OK) identity) (/ 1 0)) would print

17:53 rasmusto: , ((do (println :OK) identity) (/ 1 0))

17:53 clojurebot: :OK\n#<ArithmeticException java.lang.ArithmeticException: Divide by zero>

17:54 alandipert: the only lisp i know of that evals op first is newLisp, because reasons

17:54 justin_smith: and clojure - or is clojure not a lisp?

17:55 technomancy: it's a zombie-animated corpse of a dream, obvs =)

17:56 TimMc: There's at least one Scheme that evaluates every other argument left-to-right and then the other ones right-to-left, just to keep people from relying on arg eval order.

17:56 justin_smith: that's nice

18:02 TimMc: There's also the question of whether the *first* term is evaluated before the args.

18:02 You can do some really obscure stuff that way.

18:02 that way = if it is evaluated afterwards

18:02 bbloom: alandipert: isn't it b/c newlisp has fexprs?

18:03 alandipert: bbloom: oh right

18:03 bbloom: alandipert: with macros, you only need to check if the op is a literal symbol before deciding on an evaluation strategy

18:03 alandipert: with fexprs, you need a value

18:04 rovar: does anyone use Lighttable with the Ring nrepl? I'm trying to figure out how to load the appropriate middleware

18:05 alandipert: bbloom: but... lisp 1.5 had fexpr and args eval'd left to right, i don't understand why it matters

18:05 if it's a symbol with 'macro on the plist it's a macro, if it's a fexpr it's a fexpr, no?

18:06 bbloom: alandipert: fexprs get to decide whether or not to evaluate their arguments

18:06 alandipert: but fexprs are first class, so you can ((f x) y z) where f is a function call that looks up and returns an fexpr object

18:06 alandipert: bbloom: oh right, tracking

18:06 tomjack`: fexpr?

18:07 oh, I can google

18:07 rasmusto: tomjack`: http://en.wikipedia.org/wiki/Fexpr

18:07 save you a few keystrokes

18:07 alandipert: also https://twitter.com/fexpr

18:07 bbloom: tomjack`: John Shutt's dissertation is the best thing worth reading in the department of fexprs and first class environments

18:07 rasmusto: alandipert: haha what

18:07 tomjack`: fexprs are a good substrate for expansion-passing style macros?

18:08 TimMc: justin_smith: Actually, it might be a special build of Larceny used for stress-testing, not the default mode. Ah well.

18:08 Bronsa: alandipert: lol'd

18:08 TimMc: I can't find any good references online.

18:08 alew: My use case for having l-r arg eval was using juxt for side effects

18:08 alandipert: TimMc: i made https://github.com/alandipert/fclojure awhile ago but it's broken and pretty dumb, has some references on the README tho

18:09 rasmusto: ,((juxt prn println pr print) "foo")

18:09 clojurebot: "foo"\nfoo\n"foo"foo[nil nil nil nil]

18:12 bbloom: alandipert: heh, i made one too that i never published, but mine also had algebraic effect handlers

18:13 alandipert: was hilariously bugged to the point that when i went back to tinker with it again a few months later it was too far gone to be saved

18:25 tpope: gtrak: I have not, and probably won't get around to it this week

18:41 bbloom: i'm writing some C right now (don't ask why) and surely not 5 minutes in to working, i accidentally write an infinite loop

18:41 haven't accidentally written an infinite loop in like 2 entire years of clojure

18:42 RickInAtlanta: what's a loop?

18:42 rasmusto: not even a c-c c-b?

18:42 `cbp: i haven't had off by 1 errors in 2 entire years of clojure either!

18:42 rasmusto: i haven't had off by 2 errors in 1 entire years of clojure either! :D

18:46 aperiodic: has anyone run into a class cast exception between SimpleVCell and PSimpleCell while using prismatic.schema? googling yields exactly zero results (I counted twice)

18:48 it's weird because the deftype for SimpleVCell implements the PSimpleCell interface, so I don't understand why that cast can't happen

18:48 gfredericks: "don't try to use it for anything boring" is the most interesting disclaimer I've ever seen on a README

18:48 (inc alandipert)

18:48 lazybot: ⇒ 2

18:49 alandipert: what does the inc thing mean?

18:49 AeroNotix: (dec alandipert )

18:49 lazybot: ⇒ -1

18:49 AeroNotix: sorry

18:49 locks: LOL

18:49 alandipert: ahaha

18:50 locks: first rule: you don’t talk about inc

18:50 alandipert: as long as my score isn't on my permanent record

18:50 AeroNotix: It is

18:50 bbloom: $karma alandipert

18:50 lazybot: alandipert has karma 2.

18:50 bbloom: $karma alandipert

18:50 lazybot: alandipert has karma 2.

18:50 bbloom: $karma "alandipert "

18:50 locks: $karma lazybot

18:50 lazybot: "alandipert has karma 0.

18:50 lazybot has karma 20.

18:50 AeroNotix: (dec lazybot )

18:50 lazybot: You want me to leave karma the same? Fine, I will.

18:50 bbloom: that space is bugged, i think

18:50 AeroNotix: (dec lazybot)

18:50 lazybot: ⇒ 19

18:50 bbloom: (inc alandipert)

18:50 lazybot: ⇒ 3

18:50 locks: $karma lazybot

18:50 lazybot: lazybot has karma 19.

18:50 bbloom: (inc alandipert )

18:50 lazybot: ⇒ 0

18:50 AeroNotix: OH GOD

18:50 locks: (inc lazybot )

18:50 lazybot: ⇒ 2

18:50 bbloom: weeeee regex parsing

18:50 Anderkent: AeroNotix: with technomancy's help I figured out where the parse-opts thing was coming from. Fix incoming!

18:51 AeroNotix: Anderkent: wicked! Looking forward to it :)

18:51 zaiste: how can i force `lein ring` to automatically reload files from resources/ e.g. htmls ?

18:52 AeroNotix: Anderkent: I'm looking to integrate cloverage with cobertura/jenkins, any ideas?

18:52 alandipert: gfredericks: btw the best part of fclojure is actually https://github.com/alandipert/fclojure/blob/master/src/fclojure/color.clj#L31

18:53 bbloom: (inc alandipert )

18:53 lazybot: ⇒ 1

18:53 `cbp: f clojure!

18:53 AeroNotix: (inc a landipert )

18:53 lazybot: ⇒ 1

18:53 AeroNotix: (inc a landipert)

18:53 lazybot: ⇒ 1

18:53 AeroNotix: (inc alandipert)

18:53 lazybot: ⇒ 4

18:53 AeroNotix: wat

18:54 bbloom: (inc this shit is busted)

18:54 lazybot: ⇒ 1

18:54 Anderkent: AeroNotix: Alas, I haven't tried that. The EMMA output was made by someone else for that purpose, but I'm not sure how they wired it together

18:54 locks: stahp AeroNotix

18:54 AeroNotix: locks: stahping

18:54 Anderkent: fingers crossed for the emma version then :)

18:54 sdegutis: (inc hyPiRion)

18:54 lazybot: ⇒ 30

18:55 technomancy: hyPiRion: so what are you writing in ocaml for school?

18:55 Anderkent: AeroNotix: you should be able to try it out now by checking out the aot-fix branch from my repo and running the same steps (lein install etc.). That won't have the 'hangs if you leave threads' fix yet though

18:55 AeroNotix: Anderkent: cool, looking

18:55 hyPiRion: sdegutis: Did I do anything? :p

18:55 sdegutis: probably

18:56 hyPiRion: technomancy: nothing for school actually, "just" a genetic algorithm

18:56 technomancy: oh gotcha, cool

18:57 hyPiRion: The goal is just to get better at it, so that I can use it professionally

18:57 And then I end up using it at work, and since noone apart from me knows OCaml, I can work in peace.

18:57 That's the idea, at least.

18:58 technomancy: best of luck!

18:58 Anderkent: goddamnit clojars username is case sensitive, I always get caught at that -.-

18:58 hyPiRion: thanks, I would probably need it :p

18:58 AeroNotix: hyPiRion: we have a dude who writes all languages as if they were OCaml our team

18:58 Anderkent: same!

18:58 hyPiRion: his Erlang looks ridiculous

18:58 hyPiRion: very annoying

18:59 brehaut: AeroNotix: could be worse. most teams have someone who writes every language as if its the worse of enterprise java

18:59 Anderkent: TBH all erlang looks ridiculous to me. ;_;

18:59 hyPiRion: AeroNotix: oh, you would love to see mine :p

18:59 AeroNotix: Anderkent: lol

18:59 Anderkent: I had to debug RabbitMQ internals once...

18:59 AeroNotix: the horrors...

18:59 Yeah generally older Erlang codebases are terrible

18:59 even the OTP source is a rat's nest

19:05 sdegutis: Hey guys.

19:05 I came up with a riddle the other day that I told my wife and kids.

19:05 It's totally off topic. Want to hear it?

19:08 Anderkent: I'm not hearing a no.

19:09 locks: I do

19:09 sdegutis: What did the alphabet say to the insect?

19:09 O, I C.. U R A B!

19:10 * `cbp dies

19:10 Anderkent: ...

19:10 mischov: :D

19:10 rasmusto: what did the alphabet say to the computer programmer? "hello world"

19:11 locks: sdegutis: that’s a very poor riddle, sorry to say

19:11 AeroNotix: sdegutis: oh I see you're a bug

19:11 locks: a bee AeroNotix

19:12 AeroNotix: makes sense :)

19:12 insamniac: It's a complex joke.

19:12 mischov: Well I liked it.. :D

19:12 sdegutis: locks: I may disagree with what you say but I'll defend to the death your right to say it good sir.

19:12 locks: sdegutis: :)

19:19 RickInAtlanta: llasram: you around?

19:29 quizdr: I don't see women as objects. I consider each to be in a class of her own.

19:33 akurilin: Hey guys. Does anybody know if it's possible to unroll a vec of maps into a where's "or" in Korma? As in: turn [{:foo 1} {:baz 2}] into (where (or {:foo 1} {:baz 2})) ?

19:33 I can't apply the or, of course, and as far as I can tell that or is part of the DSL anyway

19:34 so I almost need to splice the vec up one level to make this work

19:37 ztellman: finally, google acknowledges that my ads are high-quality enough to be shown: https://twitter.com/danielwithmusic/status/426133408498995201

19:37 technomancy: <3

19:37 brehaut: haha

19:38 alandipert: ztellman: i fell off my chair

19:38 sdegutis: ztellman: ha!

19:38 Anderkent: Love it :)

19:38 ztellman: it took a few weeks of google telling me they were too low-quality before they started showing up

19:39 not sure why, the people deserve to know

19:39 brehaut: ztellman: great readme image

19:40 rasmusto: haha

19:41 ztellman: brehaut: thanks, I remember being especially proud of that when I published the library

19:41 RickInAtlanta: :)

19:42 ztellman: it remains the funniest joke in code form I've ever written

19:42 which subsequently was referenced in a book about "high performance clojure"

19:42 brehaut: how much did the ads cost for the joke?

19:42 akurilin: Quick question: how do I execute a form after I've quoted it? e.g. how do I run `(println ~@stuff) ?

19:43 ztellman: I dunno, I can spend at most $3/day, and I've never hit the limit

19:43 Anderkent: akurilin: eval

19:43 brehaut: hah great

19:43 ztellman: for just a cup of coffee a day, I can bring joy to the clojure community

19:43 brehaut: worth it

19:43 technomancy: ztellman: google kept sending me free $100 adword vouchers for like three consecutive months a few years ago

19:43 ztellman: haha

19:43 publicity blitz

19:43 brehaut: time for multiple yaers worth of jokes

19:43 Anderkent: the first one is always free

19:43 technomancy: I think I split them between lein ads and ones for the Clojure PeepCode =)

19:44 akurilin: Anderkent: perfect, thank you. I'm assuming it's ok to use eval as long as you know what you're passing into the thing, right? As in, not a bunch of code you just got from outside the system?

19:45 ztellman: akurilin: if you do it repeatedly, you can get a slow memory leak

19:45 but otherwise, it's fine

19:45 there are classes of problems that can't be solved any other way

19:45 Anderkent: but they're not that comomn, so I'd still stop and think for a bit before using eval

19:47 noonian: usually, you would just write a macro and then call it normally so you don't have to use eval

19:47 alew: ztellman: what causes the memory leak?

19:47 ztellman: alew: if you eval a function definition, or something else which generates a class, it takes up space in the JVM PermGen

19:47 Anderkent: multimethods and protocols leak permgen afaik

19:47 ztellman: which without special arguments to the JVM, are never collected

19:48 Anderkent: http://dev.clojure.org/jira/browse/CLJ-1152

19:48 clojurebot: It's greek to me.

19:48 Anderkent: java8 gets rid of permgen, right? Does that help?

19:49 akurilin: So it looks like doing that splice + eval inside of another macro might nto be trivial.

19:49 As in, the order in which multiple macros are dealt with it pretty important there.

19:49 alew: ztellman: ah, so you eval a function and then lose the reference to it and it's stuck in PermGen

19:50 Anderkent: is there an article about that? Would love to read up

19:50 Anderkent: alew: http://openjdk.java.net/jeps/122

19:53 alew: Anderkent: looks like a great change

19:54 akurilin: Hey folks, could I get some feedback on this splice + eval quirk I'm seeing? Trying to understand what I'm getting wrong here: https://www.refheap.com/26621

19:55 Anderkent: wow, does refheap take forever to load or is it me

19:55 quizdr: if I can run lein repl from a project directory fine, but trying to jack in with cider from emacs for the same project results in compiler error (unresolved symbol) why would this be? all files are saved so i'd expect both repl activations to be a similar process

19:55 ztellman: akurilin: are you trying to unroll the vector of arguments?

19:55 if so, you need a ~@ around the vector

19:56 akurilin: Anderkent: oops, sorry, let me actually add the stupid ~@ in there

19:57 Anderkent: Is (where) a macro or a function?

19:57 akurilin: Anderkent, ztellman : updated

19:57 turbofail: it's got to be a macro

19:57 if it were a function it would've only seen {:foo 1}

19:57 noonian: akurilin: i think you can solve this using (apply or [{:foo 1} ...]) i know it's weird since or is a macro in clojure, but in the where dsl it works iirc

19:58 ztellman: akurilin, I'm guessing 'or' has a special meaning inside select*

19:58 (apply or ...) isn't valid, or is a macro

19:58 akurilin: ztellman: yeah I think Korma does that

19:58 noonian: it isn't valid clojure, but it is valid korma where clause dsl

19:58 ztellman: akurilin, you need to quote and eval the entire form, not just that clause

19:58 right now it's just evaluating (or x y) and return x

19:59 returning*

19:59 noonian: no, it isn't

19:59 Anderkent: it's just passing th eliteral (eval ')... to where

19:59 akurilin: noonian: oh shoot I didn't expect that to work. Some serious magic in there :|

19:59 noonian: it's turning the or into: ((answers.foo = 1) OR (answers.foo = 2))

19:59 ztellman: noonian: oh, you're right

19:59 nm

19:59 akurilin: noonian: how would I reproduce this without korma's apply or, if I wanted to?

19:59 turbofail: well the original eval version wouldn't have done that

20:00 noonian: akurilin: i'd write a macro that does the unquote splicing you were trying to do inside an eval

20:01 (defmacro or* [coll] `(or ~@coll))

20:01 turbofail: does korma not have some sort of data-structure representation for queries?

20:01 Anderkent: it does, the macros just modify it

20:01 turbofail: ah. if it were me i would modify that.

20:02 akurilin: noonian: that macro still results in just the first item in the vec

20:02 Anderkent: Well, I'm very confused about the purpose of this evaling in query building, so I can't suggest anything :P

20:02 akurilin: noonian: I'm probably doing something wrong here

20:02 Anderkent: akurilin: what you you want to produce?

20:03 akurilin: (or {:foo 1} {:foo 2})

20:03 noonian: ah

20:03 because syntax quote will use clojures or, you want something that expands that would work in korma?

20:03 turbofail: that said i suspect korma can probably generate a "foo in (a, b, c)" clause if you just put in a sequence of values

20:03 which would be a better way to do this particular thing

20:04 noonian: ,`(~'or foo bar)

20:04 clojurebot: (or sandbox/foo sandbox/bar)

20:04 noonian: yeah, i have no idea what the most proper way to do this is lol

20:05 akurilin: I'm just trying this to understand the process a bit better

20:05 I already got what I was looking for from apply or

20:05 just trying to grok how these transformations are happening for my own sanity

20:06 noonian: with a macro the key is you want korma to see the symbol 'or, not a namespace qualified symbol like 'clojure.core/or

20:06 akurilin: I'm basically writing a vector of ids route like /users/1;2;3;4 and I want to pass those ids as a where in korma.

20:06 Anderkent: riight, the transformations are being done by korma, so you'll have to look at what it does

20:06 noonian: so (defmacro or* [coll] `(~'or ~@coll)) might work

20:07 Anderkent: korma gets whatever you type, unmodified, so it has to eval it itself, and whether that happens before or after it looks for the 'or' does matter

20:08 akurilin: Anderkent: yes, the order there seems pretty critical

20:10 noonian: akurilin: try (macroexpand '(where (select* answers) (or {:foo1} {:foo 2})))

20:10 not sure if it'll work, i don't have a repl up with korma

20:13 Anderkent: noonian: lein try!

20:13 akurilin: noonian: want me to paste that?

20:13 Anderkent: https://github.com/rkneufeld/lein-try

20:13 lein try korma -> repl with korma. You just need to know the group/artifact name :p

20:14 I use it *all the time*

20:17 noonian: here it is compared to with apply: https://www.refheap.com/26625

20:17 so its calling clojure's apply with korma.sql.fns/pred-or (which must be a fn since it works)

20:25 Anderkent: Pff, who said you can't apply clojure.core/or?

20:26 ,(eval (apply #'or [nil nil 1 2 3]))

20:26 clojurebot: 1

20:26 turbofail: huh.

20:26 noonian: thats sweet

20:27 i never thought of using var literals for using macros in higher order functions

20:27 turbofail: the semantics of that are a little weird

20:27 jcromartie: I didn't know you could do that

20:27 Anderkent: turbofail: so they are. It's one of those 'cool, but if you actually use it, then WAT' things

20:28 noonian: how are the semantics different from using or normally?

20:28 turbofail: well for one thing it won't be short-circuited

20:28 noonian: ah

20:28 turbofail: unless it's a lazy seq

20:28 jcromartie: well it doesn't prevent evaluating the arguments, for one

20:28 JINX!!!!!!!!!LOLOLOL

20:30 Anderkent: turbofail: just quote all the args! :P

20:30 turbofail: ,(eval (apply #'or [1 nil 1 2 3]))

20:30 clojurebot: 1

20:30 Anderkent: ,(eval (apply #'or [nil nil '(println 2) 1 2 3 '(println 3)]))

20:30 clojurebot: 2\n1

20:30 Anderkent: the first two args are actually not passed to or

20:31 they're the &form and &env

20:31 :P

20:31 ,(eval (apply #'or [1 nil :tricky 2 3]))

20:31 clojurebot: :tricky

20:31 turbofail: ,(eval (#'or 1 nil nil 2))

20:31 clojurebot: 2

20:31 turbofail: huh, that's giving me different results in my local REPL

20:32 Bronsa: unlikely

20:32 turbofail: oh wait i shouldn't be using eval

20:33 quizdr: why would :tricky be return rather than 1? what?

20:33 turbofail: or should. one or the other

20:33 Anderkent: quizdr: macros take two more args than they seem to take (which is a cause of a fun bug when you don't give enough args for a nested macro)

20:33 Bronsa: quizdr: there are two implicit args that get passed to macros by the compiler

20:34 akurilin: I have no clue what half of what you guys wrote up there would evaluate to :) Gotta delve more into that whole area at some point.

20:34 Bronsa: Anderkent: not only for a nested macro, simply when an exception happend in the body of the macro

20:34 Anderkent: right, yes.

20:34 or rather the exception, not an exception

20:35 ArityException, that is

20:35 Bronsa: right

20:37 turbofail: hm. so this whole thing depends on passing it to eval afterwards, which is still not quite what i would call "applying a macro"

20:37 Bronsa: thr

20:37 j

20:37 so much fail.

20:37 quizdr: o i see which is probably why it is not wise to pass macros as functions to things like apply?

20:37 Bronsa: turbofail: macros aren't high order, that's just how it is.

20:37 noonian: well, your program is being eval'ed so you wouldn't have to eval it yourself

20:38 quizdr: it's an error if you actually try to pass a macro as a value

20:38 ,(apply or [nil 1 3])

20:38 clojurebot: #<CompilerException java.lang.RuntimeException: Can't take value of a macro: #'clojure.core/or, compiling:(NO_SOURCE_PATH:0:0)>

20:38 turbofail: Bronsa: yeah but for a brief moment it looked slightly like they had found some weird loophole around it

20:41 noonian: it's still useful if your expressions don't have side effects and you just want the semantics of or for either the truthyness result or setting a default

20:41 rasmusto: can't you just make an eager "or" function if you want its behavior?

20:42 Bronsa: rasmusto: that's (partial some identity)

20:42 (some identity [nil nil false 1 2])

20:42 ,(some identity [nil nil false 1 2])

20:42 clojurebot: 1

20:43 noonian: yeah, but then you aren't being as lazy or clever as using #'or :P it would probably make me feel better about the code though

20:43 turbofail: you can't really use the #'or trick without using eval

20:44 noonian: ,(apply #'or [nil nil :true])

20:44 clojurebot: :true

20:44 noonian: why not?

20:44 turbofail: ,(apply #'or [nil nil nil :true])

20:44 clojurebot: (clojure.core/let [or__3947__auto__ nil] (if or__3947__auto__ or__3947__auto__ (clojure.core/or :true)))

20:44 turbofail: that's why

20:44 noonian: hmm, why do we see different behavior from clojurebot?

20:45 turbofail: it's not different behavior, before we were calling it with an (eval ...)

20:45 noonian: i just called it without eval 2 lines above your call

20:45 Bronsa: noonian: yours is (or :true), turbofail's is (or :nil :true)

20:45 noonian: and it worked

20:45 Bronsa: s/:nil/nil

20:45 noonian: or is defined as identity for 1-arity

20:46 rasmusto: ,(true? :nil)

20:46 clojurebot: false

20:46 rasmusto: that's one to show newbies

20:46 noonian: ,(apply #'or [nil nil nil :true])

20:46 clojurebot: (clojure.core/let [or__3947__auto__ nil] (if or__3947__auto__ or__3947__auto__ (clojure.core/or :true)))

20:46 t3soro: ,(true? :x)

20:46 clojurebot: false

20:46 noonian: ,(apply #'or [nil nil :true])

20:46 clojurebot: :true

20:47 t3soro: (false? nil)

20:47 ,(false? nil)

20:47 clojurebot: false

20:47 turbofail: ,(macroexpand '(or foo))

20:47 clojurebot: foo

20:47 rasmusto: t3soro: sorry to confuse. :nil is "truthy" (because it's a keyword), but not true?, because its not = true

20:47 noonian: Bronsa: i'm sorry, i don't understand your explanation

20:47 turbofail: ,(macroexpand '(or nil))

20:47 clojurebot: nil

20:47 t3soro: ,(false? false)

20:47 clojurebot: true

20:47 rasmusto: t3soro: nil is falsey, but not false? since it isn't = false

20:47 Bronsa: noonian: read the source of or

20:47 t3soro: right rasmusto I get it

20:47 Bronsa: $source or

20:47 lazybot: or is http://is.gd/V4ulVq

20:47 turbofail: noonian: the or macro, when called with a single arg, expands to that arg

20:48 rasmusto: t3soro: kk, just didn't want my clojure joke to get out of hand, haha

20:48 Bronsa: (defmacro or .. ([x] x) ..)

20:48 rhg135: cant wait to see #'or all over gh

20:48 noonian: but how does that apply to the 2 minimally different examples?

20:48 Bronsa: ,(macroexpand-1 '(or 1))

20:48 clojurebot: 1

20:48 Bronsa: ,(macroexpand-1 '(or 1 2))

20:48 clojurebot: (clojure.core/let [or__3947__auto__ 1] (if or__3947__auto__ or__3947__auto__ (clojure.core/or 2)))

20:48 noonian: yeah, i get that

20:48 Bronsa: that's what you're doing

20:49 that's how or is defined

20:49 it's nil when called with no arg

20:49 it's the arg when called with 1 arg

20:49 turbofail: noonian: because your call was effectively the same as calling `or' with a single arg, once you take the first two implicit arguments away

20:49 Bronsa: it's that recursive expression when called with two or more args

20:49 noonian: ,(apply #'or [nil nil nil])

20:49 clojurebot: nil

20:49 noonian: ,(apply #'or [nil nil nil nil])

20:49 clojurebot: (clojure.core/let [or__3947__auto__ nil] (if or__3947__auto__ or__3947__auto__ (clojure.core/or nil)))

20:50 noonian: ,(macroexpand '(or 1 2 3 4))

20:50 clojurebot: (let* [or__3947__auto__ 1] (if or__3947__auto__ or__3947__auto__ (clojure.core/or 2 3 4)))

20:50 noonian: ,(macroexpand '(or 1 2 3 ))

20:50 clojurebot: (let* [or__3947__auto__ 1] (if or__3947__auto__ or__3947__auto__ (clojure.core/or 2 3)))

20:50 noonian: oh i get it

20:50 rasmusto: (inc #'or)

20:50 lazybot: ⇒ 1

20:50 noonian: because the recusive definition of or returns code not values

20:51 Anderkent: or always returns code not values, it's just taht you're passing it values here (as code)

20:51 ,(macroexpand '(or (+ 1 2)))

20:51 clojurebot: (+ 1 2)

20:51 rhg135: code==values, just it's valid

20:52 hence why we need to eval it

20:52 noonian: right, its not wrapping it in unevaluated code which makes it work in the first case but not the second because its not being called at macro expansion time

20:52 rhg135: exactly

20:53 noonian: code == values but not always the values you wanted :P

20:53 rhg135: that too

20:54 think thats why debuggers exist

20:54 fix bad values

20:54 noonian: thanks guys, that was fun

20:55 gotta run now though

20:56 rhg135: applying a macro, so simple but wow

21:03 sdegutis: locks: also, your response reminded me of: http://buttersafe.com/2007/06/28/the-cat-drawing/

21:04 locks: hahaha

21:04 sdegutis: Yup, one of my favorites.

21:04 locks: poor kitten :C

21:04 sdegutis: Do any of you wonderful nerds hide your development stuff behind virtualization?

21:06 rhg135: maybe, why, who told you?

21:06 sdegutis: I'm considering being a crazy person and installing linux inside virtualbox.

21:07 (I'm using a MBP with OS X.)

21:07 rhg135: ah

21:07 thats what i did

21:07 sdegutis: And OS X just isn't compatible with half the world. It's really frustrating.

21:07 technomancy: I would do that if I had a macbook

21:07 rhg135: then i said f*** it

21:08 sdegutis: I kind of want to dual-boot linux and OS X, but I doubt linux support for rMBP has gotten any better in the past 2 years.

21:08 rhg135: bought a new laptop :D

21:08 or...

21:08 sdegutis: I honestly want to just buy a $500 laptop and use linux on that half the time. Just wish I had the money. Might sell this rMBP to do it.

21:08 rhg135: build a server and ssh

21:08 sdegutis: Seems legit.

21:09 rhg135: i dev on mine

21:09 technomancy: it's pretty easy to try out vbox though

21:09 clojurebot: excusez-moi

21:09 rhg135: dev.rhg135.com but shhh

21:09 locks: sdegutis: $500 for your rMBP you said?

21:09 sdegutis: Ha.

21:10 technomancy: I just feel like vbox is a little heavy-weight, even when I'm sshing into it running headless.

21:10 rhg135: server

21:10 technomancy: sdegutis: I don't know about heavy-weight, but it does introduce overhead for disk I/O

21:10 rhg135: dual hexacores ftw!

21:10 quizdr: my experience with vbox on MBP suggests that it doesn't integrate well with the mac trackpad, it's a bit unsmoothlike. when I switched to vmware that changed considerably, much more native feel

21:10 sdegutis: rhg135: yeah that's why I'm liking that route, especially since then I can work from any machine and my data persists without needing to use dropbox to sync it. But hardware costs.

21:10 rhg135: i laugh at jvm startup :D

21:11 technomancy: oh, you would have to deal with meta not being next to the space bar though

21:11 yay RSI

21:11 sdegutis: quizdr: oh yeah I wouldn't use virtualbox seriously for anything with a GUI, only headless to ssh into it

21:11 quizdr: sdegutis oh, word

21:11 i feel you

21:11 alew: clj-time has no way to set one of the time fields on a date-time object? by set I mean generate a new value with the modified field. Seems like there is only plus or minus

21:11 rhg135: and my desktop is only a fx8320

21:12 if i had a dual i7 box...

21:13 sdegutis: And I thought I was over my linux phase :(

21:14 rhg135: no

21:14 linux isnt a phase

21:14 sdegutis: Honestly I'm not a huge fan of linux. I'm just getting really tired of Apple.

21:16 rhg135: at least it has a cli o a lot

21:16 i ran a bsd vm

21:16 but since i started with android i moved to linux

21:37 quizdr: yeah

21:51 rovar: Clojure: Monotonically increasing versions since 1.5

22:18 rhg135: rovar, wut

22:19 rovar: rhg135: Currently at 1.5.1; top analysts expect this to be followed by newer versions with still higher numbers:

22:19 rhg135: hmm

22:20 i don't think we'll see any major fixes

22:20 cuz there's nothing major to fix in clojure lol

22:23 quizdr: overtone freakin' rocks my fellas! my ninjas of the trade of the code! it's the super cool kind, the type that has with it the really awesome kind!

22:49 noprompt: dnolen: when you say it's an anti-pattern to wrap reify with let for stateful enties, you don't mean it's anti-pattern to wrap reify w/ let for non-statefule entities.

22:51 dnolen: ie. wrapping reify in let with helper fn's.

22:51 dnolen: because we do that until we're able to extract a component and it's subcomponents in to an ns.

22:51 dnolen: then we typically pull all of those helpers out.

22:51 clojurebot: It's greek to me.

22:52 quizdr: clojurebot hang in there you will get it eventually

22:56 ddellacosta: clojurebot: rtfm dude

22:59 technomancy: there's a manual for greek?

23:00 kanja: Is there a version of django-registration that's maintained?

23:01 shoot, wrong channel :(

23:03 noprompt: dnolen: patched some grammar/spelling on the wiki ;)

23:03 technomancy: man greek?

23:08 ambrosebs: hmm why is clojurescript so hard to search for on github https://github.com/search?q=clojurescript&type=Repositories&ref=searchresults

23:11 bbloom: ambrosebs: seems like their search engine prefers descriptions over repo names & weights stars highly

23:12 ambrosebs: sheesh, that's bad. you should file a bug or tweet at github or something

23:12 ambrosebs: bbloom: I can't find the official repo no matter what I search

23:12 bbloom: usually have to go to my fork and trace back to the origin

23:13 noprompt: ambrosebs: or if you have it stared you can just check there.

23:13 bbloom: ambrosebs: here's my guess: they are incorrectly limiting the number of results in subqueries during the ranking/merging algorithm

23:14 ivan: it's because https://github.com/clojure/clojurescript was forked

23:14 bbloom: ambrosebs: and "title" results are, by chance, being chopped off :-P

23:14 ivan: oooh that could be it

23:14 ivan: github doesn't index code in forked repos either

23:14 bbloom: one of our friendly cognitect folks should ask github to fix that

23:15 ambrosebs: ivan: nice catch

23:15 bbloom: i have had them fix the "forked from" pointer for me once or twice in the past

23:15 tbaldridge: since you're the first cognitectian who showed up in my irc autocomplete, i'm nominating you to take care of it :-)

23:16 tbaldridge: ?

23:17 bbloom: tbaldridge: are you or do you know an owner of the clojure github org?

23:17 tbaldridge: alex miller handles all that stuff these days

23:18 bbloom: tbaldridge: ah, ok. ambrosebs: you should tweet at him :-)

23:18 * bbloom is delegating

23:18 ambrosebs: bbloom: yessir

23:22 logic_prog: how do the dynamics of growth stage and seed stage investing differ?

23:27 ambrosebs: tpope: thanks a million for fireplace CLJS support.

23:27 also cemerick if he shows up :)

23:29 sm0ke: whoa fireplace supports cljs too now

23:29 ambrosebs: sm0ke: yes!

23:29 sm0ke: tpope is hero for vimmers!

23:30 ambrosebs: AFAICT, thanks to cemerick this was all that was needed https://github.com/tpope/vim-fireplace/commit/0095241a6fb3aa9aa59a60003903d28b41176ac7

23:30 either way, major props to all

23:31 sm0ke: honestly, i never had a dev environement better than clojure and fireplace together

23:31 noprompt: sm0ke: emacs + evil-mode is pretty nice ;)

23:32 logic_prog: what hapens when an exception is thrown inside a swap! ?

23:33 sm0ke: logic_prog: derefing the atom shows error i guess

23:34 ,(def a (atom "a"))

23:34 clojurebot: #'sandbox/a

23:34 sm0ke: ,(swap! a inc)

23:34 clojurebot: #<ClassCastException java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Number>

23:34 sm0ke: ,@a

23:34 clojurebot: "a"

23:34 sm0ke: hmm oh

23:36 ambrosebs: logic_prog: the atom isn't updated and you get an exception

23:39 akurilin: Quick question: is there some kind of macro that lets me loop through a list of functions and apply them all one at a time to a certain datastructure?

23:39 So essentially a threading macro, but that takes a list of fns

23:40 sm0ke: akurilin: ##(map #(% 0) [inc dec])

23:40 lazybot: ⇒ (1 -1)

23:41 akurilin: sure, this returns a list though

23:41 sm0ke: akurilin: ##(reduce #(% 0) [inc dec])

23:41 lazybot: clojure.lang.ArityException: Wrong number of args (2) passed to: sandbox5671$eval11728$fn

23:41 akurilin: I can probably do this with a reduce

23:41 sm0ke: heh

23:42 akurilin: even though it's somewhat ugly

23:42 or maybe not.

23:42 ambrosebs: akurilin: do you want a reverse comp?

23:43 technomancy: (map (rpartial funcall) my-fns) or something

23:43 akurilin: I'm essentially trying to turn the last function here into taking a list of those function: https://www.refheap.com/26666

23:43 sm0ke: ,((apply comp [inc dec]) 0)

23:43 clojurebot: 0

23:43 sm0ke: ,((apply comp [inc inc dec str]) 0)

23:43 clojurebot: #<ClassCastException java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Number>

23:43 technomancy: (rpartial funcall x) rather

23:44 ambrosebs: sm0ke: backwards :)

23:44 sm0ke: heh yea

23:44 ,(doc rpartial)

23:44 clojurebot: Pardon?

23:46 akurilin: Actually that err->> macro might take a vecf

23:46 *vec

23:48 technomancy: oh, rpartial and funcall don't actually exist in clojure

23:48 I wish rpartial did though

23:48 funcall, not so much

23:49 sm0ke: ->> would take apply i guess

23:50 ,(apply ->> 0 [inc dec])

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

23:50 sm0ke: wouldnt*

23:54 tutysara: ddellacosta: GA

23:54 ddellacosta: tutysara: sorry, what does GA mean?

23:54 tutysara: ddellacosta: good afternoon

23:55 ddellacosta: tutysara: ah, good afternoon! I'm terrible with acronyms. :-o

23:55 technomancy: what does funcall do, basically what it says on the tin?

23:56 tutysara: ddellacosta: ha ha, people in my workplace use TLAs wherever possible ;)

23:56 ddellacosta: I got the multiple provider working

23:57 ddellacosta: tutysara: oh, nice--using sritchie's thing, or using friend?

23:57 tutysara: sorry, been so busy I haven't been able to dig into all the friend/oauth2 stuff that's been flying by in the past week. :-(

23:57 tutysara: ddellacosta: using friend

23:57 ddellacosta: tutysara: nice

23:58 tutysara: any interested in writing up an example and adding it to friend-oauth2-examples (assuming that's what you're using)?

23:59 tutysara: ddellacosta: thx, have some questions, we are associating the state with anti forgery key, when I use multiple providers I see many anti forgery tokens in session

23:59 ddellacosta: yes sure I am interested in putting together an example

Logging service provided by n01se.net