2014-01-22
| 00:00 | sdegutis | !! |
| 00:00 | sdegutis | Which one TEttinger? |
| 00:01 | TEttinger | 2d game |
| 00:01 | sdegutis | Sweet :) |
| 00:01 | TEttinger | in clojure actually |
| 00:02 | TEttinger | i'm constantly tempted to refactor so I can use stuff like Play-CLJ :| |
| 00:02 | alew | hiredman: so protocls are kind of like what you get with duck typing? |
| 00:04 | hiredman | alew: no, you can ask if a type satifies some protocol |
| 00:04 | alew | hiredman: right, it's more explicit, but the end result is the same? |
| 00: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 |
| 00:09 | sdegutis | TEttinger: that'll kill your project if you ain't careful! |
| 00: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" |
| 00:13 | sdegutis | Anyone wanna fork https://github.com/sdegutis/clojuretip before I delete it? |
| 00:16 | quizdr | sdegutis if you think it's worthy of a fork, a Readme would be useful to describe what it actually is |
| 00:16 | sdegutis | quizdr: it's just http://clojuretip.herokuapp.com/ |
| 00:18 | arrdem | Bronsa: okay well Compiler.java held exactly zero surprises... |
| 00: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? |
| 00:23 | alew | hiredman: that makes sense, thanks |
| 00:25 | sdegutis | last chance to fork github.com/sdegutis/clojuretip before its deleted |
| 00:26 | marcopolo` | sdegutis: just the tip |
| 00:29 | sdegutis | deleted. |
| 00:31 | sdegutis | Does anyone here use https://github.com/sdegutis/clojuredocs/wiki ? |
| 00:31 | sdegutis | I made it because I got pretty tired of waiting for clojuredocs.org to eventually support Clojure 1.5 and up. |
| 00:32 | seancorfield | I pretty much only use clojure-doc.org and clojureatlas.com |
| 00:32 | seancorfield | I do wish chas would update the latter tho' :) |
| 00:35 | seancorfield | 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 |
| 00:35 | zerowidth | ooh. clojure-doc.org, didn't know about that |
| 00:36 | sdegutis | seancorfield: hmm interesting idea, I might give LightTable a more serious try |
| 00:36 | sdegutis | 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 |
| 00: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. |
| 00:37 | akurilin | Or to phrase it another way, how do I know it's time to use them? |
| 00:38 | seancorfield | sdegutis: on what basis are you making that claim about plugins? i'm finding the plugin system works pretty darn well... |
| 00:38 | sdegutis | akurilin: for what it's worth, I think I have not touched them at all at work |
| 00:38 | sdegutis | and at work I wrote cleancoders.com in Clojure with Datomic |
| 00:40 | akurilin | sdegutis: ok, appreciate the datapoint. I simply don't know enough myself to be able to fully discredit them. |
| 00: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. |
| 00:42 | TEttinger | sdegutis, don't delete that please? |
| 00:42 | seancorfield | What platform are you on sdegutis ? |
| 00:42 | sdegutis | TEttinger: don't delete which? |
| 00:42 | sdegutis | seancorfield: mac |
| 00:42 | sdegutis | Mac OS X 10.9.1 |
| 00:42 | TEttinger | err I forked the clojuredocs thing |
| 00:42 | sdegutis | TEttinger: ah, you use it? |
| 00: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 |
| 00:43 | TEttinger | no, but I didn't know it existed, i will now |
| 00:43 | seancorfield | sdegutis: I wonder if your problems are Mavericks-specific? I've had no problems at all on 10.8... |
| 00: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. |
| 00:44 | sdegutis | seancorfield: I wouldn't doubt if it was just my computer being haunted, sometimes it does that. |
| 00:44 | sdegutis | c.f. http://xkcd.com/1316/ |
| 00:44 | akurilin | seancorfield: got it. So no general rule of thumb for when to use them? |
| 00:45 | seancorfield | chas emerick did a great decision tree about it ... let's see if i can find that |
| 00:46 | seancorfield | http://cemerick.com/2011/07/05/flowchart-for-choosing-the-right-clojure-type-definition-form/ |
| 00: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 |
| 00:46 | akurilin | seancorfield: awesome, thank you, looks like what I was looking for! |
| 00:47 | sdegutis | TEttinger: (or you could post about it on the mailing list and win some friends/enemies) |
| 00: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. |
| 01:00 | dsrx | ugh.... ughhhh |
| 01:01 | dsrx | 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 |
| 01:01 | dsrx | i've wasted like 30 minutes of my life :( |
| 01: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. |
| 01:13 | akurilin | Technically nil is empty, but then I'd have to implement custom logic based on whether required is set or not. |
| 01:32 | alew | seancorfield: did you evaluate any other monitor services before going with new relic? |
| 01: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 |
| 01:39 | experio | (with-collection ...) ? |
| 01:39 | experio | can't find any docs on that. |
| 01:42 | sdegutis | Sounds like Haskell may be my next language. |
| 01:42 | Raynes | May your path take you far and wide, lad! Far and wide! |
| 01:49 | sdegutis | Raynes: is that a fat joke? are you calling me fat? |
| 01:50 | sdegutis | seancorfield: also it's a bit weird that Ctrl-P and Ctrl-N don't move me up and down in the command list |
| 01: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? |
| 01:52 | akurilin | e.g. clj-time will return nil or failure to parse a date |
| 01:53 | sdegutis | akurilin: generally yeah |
| 01:53 | akurilin | Makes a more predictable flow, right? |
| 01:53 | akurilin | more monadic and what not |
| 01: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 |
| 01:56 | akurilin | Fair enough |
| 01:56 | akurilin | 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 |
| 01:56 | akurilin | unless you really want an exception thrown |
| 01:57 | akurilin | Kind of the get vs nth scenario. |
| 01:57 | alew | clj-time returns nil? I remember it returning a parse exception |
| 01:58 | alew | fairly certain it still does |
| 01:58 | akurilin | :let [d (try (parse f s) (catch Exception _ nil))] |
| 01:59 | alew | Ah, if you don't provide a formatter |
| 01:59 | alew | if you do provide a formatter, it returns an error |
| 02:00 | alew | exception* |
| 02:02 | akurilin | Fair enough, not sure what the design decision process there was. |
| 02:05 | akurilin | Are macros a good fit for replacing the same boilerplate with a single form? |
| 02:05 | akurilin | 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. |
| 02:05 | akurilin | On the other hand debugging errors within large macros is a pita. |
| 02:06 | alew | Small macro, large supportin function |
| 02:06 | alew | just use the macro for the syntatic transformation and the function for all the validation parts |
| 02:06 | akurilin | Ah interesting. Do you know of good examples of that being done that I could look at? |
| 02:08 | alew | not off the top of my head, sorry |
| 02:08 | akurilin | No worries. |
| 02:09 | akurilin | 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 |
| 02:09 | alew | Ah, cool |
| 02:20 | koreth_ | What are some good Clojure open-source projects that have open tasks a relative newcomer could take on? |
| 02:22 | koreth_ | Maybe that list of libraries is a good starting point! |
| 02:22 | akurilin | Yeah those are pretty good if you just need solid clojure style reference. |
| 02:23 | akurilin | They tend to be pretty idiomatic and do functional properly |
| 02:24 | akurilin | Also just really nice apis. Anything dakrone touches seems to come out pretty well. |
| 02: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! |
| 02: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 |
| 02: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. |
| 02:29 | akurilin | Either way they're all really nice folks, they'll consider what you propose one way or another. |
| 02:29 | akurilin | I remember harassing weavejester within a few weeks of starting clj and he'd put up with me :P |
| 02:30 | koreth_ | The Clojure community seems pretty welcoming in general. Hopefully that won't go away as the language gets more popular. |
| 02:31 | ddellacosta | dammit, what's with all the newbies! Cast them out! </joke> |
| 02:31 | egghead | ya ddellacosta seriously :) |
| 02:31 | akurilin | Yeah we're all working, some more than others, on preserving a pleasant environment. |
| 02:31 | ddellacosta | seriously though, koreth_ agreed wholeheartedly |
| 02:31 | egghead | ddellacosta: how have you been, doing mush cljs lately? |
| 02:31 | egghead | s/mush/much |
| 02:31 | quizdr | the community is arguably one major differentiating factor between Clojure and its uncle, Common Lisp |
| 02:31 | ddellacosta | egghead: howdy! fine, yourself? yep, lately lots of CLJS |
| 02:32 | egghead | doing well, also lots of cljs :) fun stuff |
| 02:32 | ddellacosta | egghead: in fact, I should probably be writing some CLJS right now, but procrastinating a bit...haha |
| 02:32 | egghead | lol |
| 02:32 | ddellacosta | egghead: nice. :-) |
| 02:33 | akurilin | clgv: I hear ya. |
| 02: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. |
| 02:33 | ddellacosta | clgv: naw, I'm using both every day. |
| 02:33 | ddellacosta | heh |
| 02:34 | egghead | lol clgv cljs apps almost always have a clj backend too :) |
| 02:34 | ddellacosta | yeah, I think some folks are using a CLJS front-end with some other backend...maybe seangrove is doing that? |
| 02:35 | akurilin | he's not on clj backend? interesting! |
| 02: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 ;) |
| 02: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. |
| 02:36 | ddellacosta | *quote |
| 02:36 | ddellacosta | web 1.0, those were the days |
| 02:36 | alew | ddellacosta: where do you work? |
| 02:36 | ddellacosta | alew: I work remotely for a small Canadian startup. |
| 02:37 | ddellacosta | alew: these guys: http://diligenceengine.com |
| 02:37 | alew | ddellacosta: ah ok. remote work seems to be the story of many clojure programmers |
| 02: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. |
| 02: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. |
| 02:37 | akurilin | Or some have coworkers that don't freak out if slowly introduced to the ecosystem. |
| 02:38 | ddellacosta | akurilin: yeah, definitely seen the same trends |
| 02:38 | egghead | i use clj at work but we have little services |
| 02: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 |
| 02:38 | egghead | so long as I can offer up an api no one really cares what the service is written in |
| 02:38 | alew | There's prismatic, staples labs |
| 02:38 | akurilin | Our websites / api are all clojure because I have no common sense and also get to decide that :P |
| 02:38 | egghead | so long as there are those willing to maintain it :3 |
| 02: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. |
| 02:38 | akurilin | alew: oh yeah, Runa are hardcore. |
| 02:39 | quizdr | Haskell guys I've met, in particulary ,don't seem to take Clojure seriously |
| 02:39 | ddellacosta | runa = staples labs, right? |
| 02:39 | akurilin | they were using cljs before it was cool |
| 02:39 | alew | ddellacosta: yeah |
| 02: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" |
| 02:39 | ddellacosta | (which is mostly what I run into) |
| 02:40 | quizdr | perhaps |
| 02:40 | Cr8 | oh you're one of those *lisp* people |
| 02:40 | akurilin | ddellacosta: To outsiders, both clj and haskell look like completely alien-speak gibberish |
| 02:40 | ddellacosta | akurilin: yeah, it's disappointing. :-( |
| 02:40 | quizdr | ha ha Cr8 they did in fact single me out at the first FP meeting I went to in my town |
| 02:40 | quizdr | "he's a lisper...." |
| 02: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. |
| 02: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 |
| 02:41 | akurilin | so different from your typical C-family language |
| 02:41 | ddellacosta | yeah, sadly, I think that's definitely part of it. It's just not familiar, and not algol-like |
| 02:41 | akurilin | ALGOLoids |
| 02: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. |
| 02:42 | ddellacosta | I like Haskell, I want to get better at it. |
| 02:42 | ddellacosta | would like to learn erlang too |
| 02:42 | Cr8 | i've gotten capable at reading it and writing simple programs |
| 02:42 | quizdr | i am jealous of anyone who knows Haskell. ddellacosta i am jealous of YOU |
| 02:42 | alew | quizdr: malbolge would be a better start :P |
| 02:42 | ddellacosta | quizdr: dude, I *don't* know Haskell past baby-steps |
| 02:42 | quizdr | ...well right now all my work is in Assembly so i'm busy with that |
| 02:42 | quizdr | (grin) |
| 02:43 | ddellacosta | quizdr: unless you mean you're jealous I get to write clojure daily. In which case, carry on. :-) |
| 02: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 |
| 02:43 | ddellacosta | holy crap, malbolge, forgot about that |
| 02:43 | Cr8 | because I get from zero to basically working thingy pretty quickly and can then get on with whatever I was doing |
| 02:43 | fredyr | ouch malbolge |
| 02:44 | fredyr | fitting name though |
| 02:44 | ddellacosta | it really does look like line noise, doesn't it! |
| 02:44 | ddellacosta | awesome |
| 02: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 |
| 02:44 | akurilin | I'd do a lot of things just to avoid JVM startup time :P |
| 02:44 | alew | I think it took like... 20 years for the first hello world program to be written in it |
| 02:44 | akurilin | such a pita. |
| 02:44 | ddellacosta | quizdr: huh, really? Interesting. Many of them seem to be data-focused positions...gotta learn me some more machine learning. |
| 02:45 | quizdr | i think it was announcedon the clojure mailing list |
| 02: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) |
| 02:45 | Cr8 | only fix is to reboot |
| 02:45 | alew | there is no way there are more clojure job openings than clojure programmers |
| 02:45 | akurilin | Cr8: :( |
| 02:46 | quizdr | the "significantly shorter version" on this page really made me laugh out loud: http://en.wikipedia.org/wiki/Malbolge |
| 02: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 |
| 02: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 |
| 02: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. |
| 02:47 | ddellacosta | alew: just based on what I see out there |
| 02:47 | xsyn | well you if you don't know how to read I guess Dr. Suess is the same as T.S. Eliot |
| 02:47 | quizdr | koreth_ that would be wise advice i think |
| 02:47 | ddellacosta | xsyn: ...? |
| 02:47 | akurilin | bbl |
| 02:48 | alew | ddellacosta: I could believe that |
| 02:48 | xsyn | ddellacosta: a non-technical person running a clojure prototype for his startup |
| 02:48 | quizdr | ddellacosta, alew yes the keyword is "capable" after all there are 25,000 clojure programmers with memberships to 4clojure |
| 02:48 | ddellacosta | xsyn: ah. Yeah, I mean, that sort of person really needs a qualified tech partner |
| 02:48 | ddellacosta | quizdr: yep. |
| 02:49 | alew | I actually convinced my cofounders why we should use clojure on the backend for the startup I'm currently working on |
| 02:49 | quizdr | koreth_ your non-technical friend needs to partner up with you, my man! :) |
| 02: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... |
| 02: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 |
| 02:50 | ddellacosta | alew: what was your argument, if you can sum up? |
| 02:50 | ddellacosta | ah, maybe that was it |
| 02:51 | alew | Also, I compared clojure to what ruby/python were several years ago |
| 02:52 | ddellacosta | yes, I suspect clojure is positioned similarly, although I think the landscape is a lot different. |
| 02: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 |
| 02:52 | ddellacosta | I don't think we'll see any monolithic web framework coming out of the clojure community to storm the gates |
| 02: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. |
| 02:54 | quizdr | ddellacosta what about pedestal? seems geared to enterprise development, front and back end consistency, etc |
| 02: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). |
| 02:58 | alew | pedestal is super early in development |
| 02:58 | alew | I'm hoping the abstractions will get cleaner and simpler |
| 02:58 | quizdr | what do you mean by #1 and #2 |
| 02: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) |
| 02:59 | ddellacosta | 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. |
| 03:00 | alew | It seems like the ideal a lot of people here strive for: an frp approach to web apps |
| 03: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. |
| 03:01 | ddellacosta | 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. |
| 03:02 | alew | for most people unfamiliar is bad, see: lisp :P |
| 03:02 | ddellacosta | alew: yeah, there's that too, which is unfortunate. :-( |
| 03:03 | ddellacosta | I don't really understand it, as far as the "lisp = eewwwww" thing |
| 03:03 | dsrx | writing lisp is a nightmare w/o something like paredit |
| 03: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 |
| 03:05 | bja | 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 |
| 03:06 | bja | (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) |
| 03: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. |
| 03:07 | bja | compare it to python then |
| 03:07 | bja | same problem |
| 03:08 | bja | python's syntax isn't easy to navigate or manipute in a random text editor without special plugins |
| 03: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 |
| 03:08 | bja | dsrx, you still have to do those things in python |
| 03:09 | dsrx | uh, to a much lesser extreme |
| 03:09 | bja | dsrx, disagree strongly |
| 03:09 | bja | you still have lists, dicts, sets, and a lot of random functions |
| 03:09 | dsrx | keeping a single group of parens balanced isn't hard |
| 03:09 | algernon | and significant whitespace. arranging your blocks, moving them around... |
| 03:09 | dsrx | keeping two balanced isn't hard |
| 03:09 | bja | dsrx, two? I take it you don't use twisted |
| 03:10 | bja | or genexps |
| 03:10 | algernon | moving one block to another place, with possibly different indentation - good luck doing tha without plugins. |
| 03:10 | dsrx | algernon: good luck doing that with sexps too |
| 03:10 | bja | dsrx, that's my point. |
| 03:10 | dsrx | unless you have something that, i dunno, kills a sexp |
| 03: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 |
| 03: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. |
| 03:11 | algernon | and with plugins, both are fairly straightforward to work with. |
| 03:13 | bja | this reminded me to enable paredit mode for Hy |
| 03: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) |
| 03:14 | bja | algernon, are we talking python-mode for vim or emacs? |
| 03:14 | algernon | emacs |
| 03:15 | bja | (because vim's just makes python syntax constructs into text objects, and as such, lets you delete them however you wish) |
| 03: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 |
| 03:17 | dsrx | dropping from a weekend of writing clojure into ruby/js again was disappointing |
| 03:17 | dsrx | and i don't mean just because of the languages ;) |
| 03: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 |
| 03:20 | bja | trying to convince a project I'm working with to adopt mori for some of our JS |
| 03:21 | ddellacosta | mori is sweet, I want to use it next time I touch JS |
| 03:21 | bja | so I can have my seq functions back |
| 03:22 | quizdr | with deftype, you are essentially creating a type in the Java sense, right? |
| 03:23 | quizdr | 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? |
| 03:24 | fredyr | a java class even |
| 03:24 | fredyr | so yes |
| 03: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 |
| 03:25 | quizdr | as opposed to defrecord, which is more entirely clojurish, right? |
| 03:26 | fredyr | yeah id say so, but obviously it depends -- sometimes it might make sense to use deftype anyways |
| 03: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 |
| 03:27 | quizdr | thanks i'll read that |
| 03:27 | ddellacosta | or rather, they reflect opinions with regard to how certain things work, like derivation, programming to interfaces, immutability, etc. |
| 03: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 |
| 03: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. |
| 03:28 | ddellacosta | dsrx: but the things you list are things I would likely miss too. |
| 03:28 | ddellacosta | or be frustrated with |
| 03:29 | dsrx | JS has all the little warts and gotchas, writing async code stinks even with 'good' abstractions like promises, no core.async etc |
| 03: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... |
| 03:30 | fredyr | quizdr: deftype is one way to implement a protocol, so if your building library stuff you might be using it |
| 03:30 | dsrx | ddellacosta: i haven't looked at generators too closely, because they're not implemented outside of gecko afaik |
| 03: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. |
| 03:30 | ddellacosta | dsrx: ah, yeah, I was afraid that something like that may be the case |
| 03:31 | ddellacosta | quizdr: heh...I know what you mean, I've had similar moments of stupidity/revelation |
| 03:31 | quizdr | fredyr the only other way being defrecord, yeah? |
| 03: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 :) |
| 03:31 | fredyr | quizdr: reify also |
| 03:31 | quizdr | oh yes |
| 03:31 | dsrx | for what that's worth |
| 03:31 | ddellacosta | dsrx: ah, interesting. |
| 03:31 | ddellacosta | dsrx: I suppose it's still javascript. ;-) |
| 03:31 | dsrx | ayuppp |
| 03:32 | ddellacosta | quizdr: no, you can flat out create a protocol with defprotocol (if I understand what you're asking...?) |
| 03: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. |
| 03:33 | quizdr | ddellacosta know i meant how the protocol is ipmlemented. defprotocol just defines it yeah? |
| 03:33 | fredyr | ddellacosta: i think we were talking about implementing protocols |
| 03:33 | ddellacosta | quizdr, fredyr: ah, sorry to interrupt... |
| 03:33 | fredyr | no worries |
| 03:35 | fredyr | actually, i don't recall seeing defrecord being used alot |
| 03:36 | ddellacosta | I've had trouble finding cases where a map wouldn't suffice, personally |
| 03: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 |
| 03:36 | fredyr | yes |
| 03:36 | ddellacosta | yeah |
| 03:36 | dsrx | hmmm... must find reason to write 'defleppard' macro |
| 03:36 | fredyr | hah |
| 03:37 | quizdr | According to Halloways book even multimethods are exceedingly rare, like only about 0.1% of all Clojure code uses them. |
| 03:37 | ddellacosta | dsrx: :-) |
| 03:37 | ddellacosta | quizdr: I find multimethods to be just the right thing in a few very specialized cases |
| 03:38 | ddellacosta | quizdr: whenever I've written parsing code they seem to come in handy |
| 03: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. |
| 03:38 | llasram | Those interface methods may be directly accessed via the .method JVM iterop, but you normally don't -- |
| 03:38 | llasram | normally you just call the protocol functions |
| 03: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 |
| 03:39 | quizdr | hence their difference from deftype and their automatic use of map interfaces |
| 03: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 |
| 03:42 | quizdr | ok |
| 03:42 | quizdr | i assume defstruct is pretty much obsolete in the face of records and types? |
| 03:43 | llasram | 100% |
| 03:43 | llasram | If you see code using defstruct, you know that code is ancient and has received no recent love :-) |
| 03: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? |
| 03:45 | ddellacosta | Glenjawork: the latter--pass data around. core.async definitely doesn't follow an RPC model. |
| 03:46 | Glenjawork | so, taking the cljs dom event model, it'd be (>!! ch :button-clicked) over (>!! ch :save-document) |
| 03: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.) |
| 03:47 | Glenjawork | and if that's the case, can you do fanout? |
| 03: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. |
| 03:48 | Glenjawork | ie. multiple actions triggered from a single message on a single channel? |
| 03:48 | ddellacosta | Glenjawork: check out stuff like tap http://clojure.github.io/core.async/#clojure.core.async/mult |
| 03:48 | llasram | koreth_: On a multimethod return value, or... the dispatch function argument types? |
| 03:49 | ddellacosta | Glenjawork: and also pub/sub http://clojure.github.io/core.async/#clojure.core.async/pub |
| 03:49 | koreth_ | llasram: Multimethod return value. |
| 03: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 |
| 03:49 | Glenjawork | ddellacosta: aha, i hadn't seen those in example yet - that fits my mental queues model much better |
| 03:50 | llasram | koreth_: Ok. I don't believe that multimethods may return primitive types, so that just leaves reference types. For reference types, |
| 03:50 | Glenjawork | "Each item is distributed to all subs in parallel and synchronously" seems surprising to me though |
| 03:50 | ddellacosta | Glenjawork: why? |
| 03: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 |
| 03:50 | Glenjawork | because you now have to have subscribers yeild to avoid blocking others |
| 03:51 | Glenjawork | or be fast |
| 03:51 | koreth_ | llasram: Excellent, just what I hoped would be the case. Thanks. |
| 03:51 | llasram | np |
| 03:53 | llasram | 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 >_< |
| 03: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. |
| 03:54 | llasram | koreth_: The workaround I stole from technomancy is to have (def foo) right above every (defmulti foo ...) |
| 03:54 | Glenjawork | well, if one of your subscribers ties up the thread, the others won't receive the message |
| 03:54 | ddellacosta | Glenjawork: but maybe I'm not understanding your point |
| 03:54 | Glenjawork | it may not be a problem in practice, it just seems surprising to me |
| 03:55 | Glenjawork | oh |
| 03: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] ...)? |
| 03:55 | Glenjawork | i just read that again |
| 03:55 | Glenjawork | it only blocks if you don't read the channel |
| 03:56 | llasram | koreth_: Actually, yes... Re-checking, the issue is that any metadata in the separate `attr-map` argument to `defmulti` won't |
| 03:56 | llasram | koreth_: Which is how I typically do return value metadata: {:tag `Date} |
| 03:57 | koreth_ | llasram: Gotcha. I will be careful about that. |
| 03:57 | koreth_ | (Also, I will put my type hints before the argument vector where they belong.) |
| 04: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? |
| 04:05 | quizdr | sorry, not the defn but rather than name of the function, so defn (symbol name) |
| 04:05 | quizdr | or rather defn ~(symbol name) |
| 04:05 | quizdr | wouldn't ~name work just as well? |
| 04:07 | Glenjawork | i think ~name would eval |
| 04:07 | Glenjawork | but ~(symbol name) is a symbol |
| 04:07 | llasram | quizdr: If `name` were always a symbol, then those are identical |
| 04:07 | Glenjawork | maybe, macro's aren;t my strong point |
| 04:07 | quizdr | llasram that's what I thought. they would be a symbol since it is a function name, after all |
| 04:08 | quizdr | seems unnecessary and i hadn't seen anyone take that precaution before in a macro |
| 04:08 | llasram | (defthingie "being-different" ...) |
| 04:08 | llasram | Probably just inexperience / refactoring cruft |
| 04:08 | quizdr | well it's a well-know clojure author in web development in his new book so I figured i was missing something |
| 04: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 |
| 04:09 | quizdr | just wanted to make sure it isn't "required" to do that |
| 04:10 | llasram | Gotcha |
| 04:59 | katox | ping dakrone |
| 05:00 | katox | dakrone: I found this https://groups.google.com/forum/#!topic/clojuredocsorg/_rQIa2JQ9yc |
| 05:00 | katox | dakrone: the project seems to be stalled, something's changed or blocking the progress? |
| 05: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? |
| 05:41 | andrevdm | jonathanj: http://www.4clojure.com/ & http://clojurekoans.com/ are very popular |
| 05:42 | jonathanj | andrevdm: thanks, i'll check those out. what about resources that are more prose heavy? |
| 05:43 | jonathanj | (also: howzit ;)) |
| 05:43 | andrevdm | :), checking bookmarks |
| 05:44 | jonathanj | i guess browsing through the clojure reddit might come up with some interesting stuff too |
| 05: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 |
| 05:44 | mkuitune | it's not free though |
| 05:45 | andrevdm | Rich Hickey's talks: http://thechangelog.com/rich-hickeys-greatest-hits/ |
| 05:45 | mkuitune | but very beginner friendly, which I like |
| 05:46 | andrevdm | if you like vids, the check vids from the conj etc on youtube (ClojureTV) |
| 05:46 | jonathanj | i'm really not a fan of videos, but they do often seem to have good content |
| 05:47 | jonathanj | i watched Hickey's talk on core.async recently |
| 05:47 | andrevdm | http://fasttrackclojure.blogspot.com/2010/09/lesson-1-hello-clojure.html |
| 05:47 | andrevdm | http://adambard.com/blog/clojure-in-15-minutes/ |
| 05:48 | andrevdm | the clojure vids have very high signal/noise. Well worth it, I never really liked vids before waching them either |
| 05:49 | jonathanj | great, thanks; i'm sure that'll keep me busy for today ;) |
| 05: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 |
| 05:50 | andrevdm | s/faced/fast |
| 05:50 | andrevdm | jonathanj: have fun :) |
| 05:51 | Ember- | Joy of Clojure 2nd ed is just about to come out |
| 05:51 | Ember- | just fyi |
| 05:51 | andrevdm | Ember: Yip, get it on MEAP if you want to get it now |
| 05:51 | Ember- | if you preorder it you'll get the 1st ed for free as ebook |
| 05:51 | Ember- | andrevdm: I have it |
| 05:51 | Ember- | :) |
| 05:52 | Ember- | and I also have the unfinished beta book, preordered it the instant it came available |
| 05:52 | jonathanj | so should i wait for the release of the second edition then? |
| 05:53 | andrevdm | Ember: same. Its worth mentioning that the beta book is very polished already. |
| 05:53 | Ember- | yeah |
| 05:53 | Ember- | it's just the finishing touches left |
| 05:53 | andrevdm | jonathanj: IMO get the MEAP now |
| 05:53 | jonathanj | MEAP? |
| 05:53 | Ember- | I think pretty much all of the relevant chapters are finished |
| 05:53 | andrevdm | http://www.manning.com/fogus2/ |
| 05:54 | andrevdm | MEAP = manning early access program i.e. you get the book before it is done |
| 05:58 | jonathanj | okay then, twist my rubber arm |
| 06:00 | andrevdm | again, I'll say its good as a 2nd book :), in my opinion of course. |
| 06: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 |
| 06:00 | ddellacosta | everything everyone else has said) |
| 06:00 | Ember- | agree, good as the second book |
| 06:00 | Ember- | too much too quickly as the first book |
| 06: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. |
| 06: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 |
| 06:02 | ddellacosta | yeah, I think someone else mentioned the videos above but just wanted to drive home the point |
| 06:03 | ddellacosta | oh, I guess that was you andrevdm ;-) |
| 06:03 | andrevdm | its a point worth reiterating :) |
| 06:11 | dsrx | hickey's talks are all great |
| 06: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 |
| 06:13 | rurumate | and that's making me nervous |
| 06:15 | clgv | I'd like to see a change log for the JoC2 book^^ |
| 06:16 | clgv | an update price for owners of JoC1 would be great too ;) |
| 06:17 | clgv | rurumate: is the client lib correctly listed in your dependencies so that it is on the classpath of your current repl? |
| 06:18 | rurumate | clgv: yes, are you affiliated with the elastisch project? |
| 06:19 | rurumate | by any chance, that is |
| 06:19 | clgv | rurumate: no. I just tried to eliminate a common pitfall ;) |
| 06:19 | rurumate | I've overriden the elasticsearch dependency, downgrading to 1.0.0-RC1 which is the exact version the server is using |
| 06:20 | rurumate | now getting a different error |
| 06:20 | clgv | rurumate: the classdef error sonds more like a classpath issue then a protocoll incompatibility |
| 06:20 | rurumate | yes, it's a strange one |
| 06:20 | rurumate | I'll post a full stacktrace hang on |
| 06:20 | clgv | "lein clean" and try again? |
| 06:21 | rurumate | I'm doing lein do clean, deps, ring server-headless 3000 |
| 06:23 | rurumate | now this is with the elasticsearch version inherited from beta-1 again: https://www.refheap.com/26484 |
| 06:24 | rurumate | there seems to be no reference to RepositoriesService in PluginsService.java |
| 06:25 | clgv | rurumate: RepositoriesModule you mean? |
| 06:25 | rurumate | that elasticsearch project seems overly complex java code |
| 06:25 | rurumate | uhm yes |
| 06:28 | rurumate | same problem with elastisch-1.4.0 dependency |
| 06:29 | rurumate | and also with 1.3.0 |
| 06:30 | rurumate | hmm it used to work with 1.3.0 and 0.90.5 on the server side |
| 06:30 | rurumate | so maybe it's a server side problem? |
| 06:30 | rurumate | this is very inconvenient |
| 06:30 | rurumate | not very elastic |
| 06:31 | clgv | rurumate: does the exception happen on server or client side? |
| 06:32 | rurumate | client |
| 06:32 | rurumate | let me check the server logs |
| 06:33 | alew | rurumate: I know the native client is very finicky about which versions of the client and server you are using |
| 06:33 | rurumate | there's nothing in the server logs |
| 06:33 | clgv | you could check the classpath within the running repl |
| 06:33 | rurumate | alew: yes that seems to be the problem |
| 06:34 | rurumate | 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 |
| 06:35 | rurumate | alew, I'll post that stacktrace too, hang on |
| 06:35 | alew | rurumate: https://github.com/clojurewerkz/elastisch/commit/c1971c850aba33241d5f00ce3aa2d60cd51d3c3a |
| 06:36 | alew | Are you sure 1.5.0-beta1 supports 1.0.0-RC1? |
| 06:36 | rurumate | here https://www.refheap.com/26486 |
| 06:37 | rurumate | alew: actually I'm pretty sure it doesn't, but I could not find the info which version IS supported |
| 06:37 | alew | I just linked it |
| 06:37 | rurumate | ph |
| 06:37 | rurumate | *oh |
| 06:38 | rurumate | alew: much thanks |
| 06:38 | rurumate | 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 |
| 06:39 | rurumate | now to set up these indexes again.. *sigh* |
| 06:41 | clgv | a problem with mismatched versions in server and client is unlikely manifesting as classnotfoundexception though |
| 06:41 | rurumate | hmm |
| 06:42 | rurumate | but it used to work with 1.3 and now even that fails with the same error |
| 06:42 | clgv | that would only happen if some remote classloading is going on |
| 06:42 | rurumate | I'll try 1.3 with an 0.90.5 server again, hang on |
| 06: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 |
| 06:43 | rurumate | clgv: I suppose remote classloading is a possibility, considering the twistedness of the elasticsearch code |
| 06:45 | clgv | rurumate: well, that would be documented I guess |
| 06: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 |
| 06:45 | alew | thus it prefers the version you declared, which likely has some breaking changes as it is a 1.0.0 |
| 06:46 | alew | so when elastisch goes to find the classes it depends on, they aren't there |
| 06:46 | rurumate | hmmm |
| 06:46 | clgv | alew: ah he overrides a transitive dependency in the project.clj? |
| 06:47 | alew | https://www.refheap.com/26486 |
| 06:47 | alew | the comment at the top |
| 06:47 | rurumate | I'll try dependency:tree to find out what version beta1 really depends on |
| 06:47 | rurumate | deps :tree |
| 06:47 | clgv | https://clojars.org/clojurewerkz/elastisch |
| 06:48 | rurumate | yup it's 0.90.10 |
| 06:49 | rurumate | but I'm also using the cloud-aws-plugin and that declares a dependency on 1.0.0.RC1 |
| 06:49 | clgv | welcome to dependency hell |
| 06:49 | alew | welcome to the worst part about clojure (and java?) |
| 06:50 | clgv | alew: nope dependency systems in general |
| 06:50 | alew | I have this hope deep inside that some language out there has solved it |
| 06:50 | kzar | to be fair clojure does it pretty well with lein if you contrast to python and ruby tools |
| 06: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 |
| 06:51 | clgv | alew: sometime ago there was an irc discussion about it. seems as if this is an unsolvable problem even in theory. |
| 06:51 | rurumate | it's not solvable I'm pretty sure |
| 06:51 | clgv | i.e. no optimal solution, but solutions with different tradeoffs |
| 06:52 | rurumate | maybe with static typing everywhere but even then you only shift the problem to compile time |
| 06:53 | clgv | rurumate: no not even there. since a version of a library does not contain a description of the public interface |
| 06:53 | rurumate | yes, the packaging system would need to learn that |
| 06:53 | clgv | rurumate: I guess elastisch maintainers will wait until 1.0.0 is released before introducing its breaking changes into their lib |
| 06:54 | alew | The Clojure community's propensity toward orthogonal and focused libraries somewhat alleviates the problem |
| 06:54 | rurumate | how about introducing header files to clojure, while we're at it? |
| 06:54 | clgv | rurumate: but how do you then describe what you need? ;) |
| 06:54 | clgv | rurumate: please don't |
| 06:55 | rurumate | I wasn't serious |
| 06:56 | clgv | but I was :P |
| 07:03 | xificurC | ,(re-matches #"a" "sdfa") |
| 07:03 | clojurebot | nil |
| 07:04 | xificurC | why is this nil? I'd expect "sdfa" as e.g. grep would return |
| 07:04 | rurumate | ,(re-find #"a" "sdfa") |
| 07:04 | clojurebot | "a" |
| 07:05 | rurumate | ,(re-matches #"a" "a") |
| 07:05 | clojurebot | "a" |
| 07:05 | xificurC | thanks |
| 07:06 | rurumate | ,(vec (re-seq #"a" "sdfa")) |
| 07:06 | clojurebot | ["a"] |
| 07: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 |
| 07:09 | rurumate | thanks everyone |
| 07:10 | alew | Sometimes I think my clojure code is starting to look really weird |
| 07:10 | alew | but then I just look at the doseq source |
| 07:14 | quizdr | lol alew some things cannot be unseen! i just looked up the source for doseq |
| 07: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 |
| 07:17 | quizdr | no doubt |
| 07:24 | AeroNotix | where is compojure.http.* ? |
| 07:25 | AeroNotix | alew: macros are like that, look up SBCL's `loop' macro |
| 07:25 | AeroNotix | shouldhavesentapoet.png |
| 07:26 | alew | They don't HAVE to be like that though. You can always break something up to be more manageable |
| 07:28 | alew | Wow, SBCL's `loop` is incredible |
| 07:28 | AeroNotix | isn't it |
| 07:29 | alew | that's the nonstandard looking loop macro right? |
| 07:29 | alew | the one that looks pretty imperative? |
| 07:29 | AeroNotix | alew: yeah |
| 07:30 | AeroNotix | I don't particularly like using it, but it provides some excellent features. |
| 07:30 | clgv | alew: an eager `for` constructing a vector would be awesome ;) |
| 07:30 | AeroNotix | http://en.wikibooks.org/wiki/Compojure/Core_Libraries this suggests a compojure.http.* exists |
| 07:31 | AeroNotix | basically I'm looking for this: http://briancarper.net/clojure/compojure-doc.html#compojure.http.request |
| 07:31 | AeroNotix | cookie handling in compojure |
| 07:31 | xificurC | cl's loop macro is too amazing not to like it |
| 07:32 | AeroNotix | xificurC: but it sticks out like a sore thumb, it's the only thing of its kind in CL |
| 07:32 | AeroNotix | (a very specific DSL for something) |
| 07:33 | xificurC | AeroNotix: if it gets the job done I dont really care |
| 07:33 | AeroNotix | xificurC: then use php |
| 07:33 | xificurC | you can use iterate if you want more lispiness |
| 07:34 | AeroNotix | things "working" does not a good argument make |
| 07:34 | xificurC | well things not looking "pretty" isnt a much better one tbh |
| 07:34 | xificurC | just because its unusual doesnt mean its bad |
| 07: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 |
| 07:35 | AeroNotix | there are no places in CL besides Loop where the api is just symbols one after the other to represent your intention (imperitive) |
| 07:36 | xificurC | AeroNotix: well thats true I guess |
| 07:37 | xificurC | still, everybody is using it right now |
| 07:37 | AeroNotix | xificurC: like we said though-- it has too many useful features not to use it |
| 07:38 | AeroNotix | there are plenty features from CL I want in Clojure |
| 07:38 | xificurC | AeroNotix: yeah, you can write the same stuff with e.g. do but its longer and less readable |
| 07:38 | AeroNotix | xificurC: depends |
| 07: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. |
| 07:39 | quizdr | or macro, rather, not function... |
| 07:39 | AeroNotix | quizdr: indeed |
| 07:40 | alew | I really prefer the naming conventions in clojure |
| 07:40 | AeroNotix | the API for CL is clunky and doesn't really make sense. Setf and friends are just a horrible API to use |
| 07:40 | AeroNotix | datastructure literals, awesome. Who *doesn't* like that? |
| 07:40 | quizdr | what in clojure do you miss from CL AeroNotix? besides mutability and dynamic vars for default, etc |
| 07:40 | quizdr | (kidding about those, obviously) |
| 07:40 | AeroNotix | quizdr: good keyword arguments |
| 07:41 | quizdr | as in, how they are named? |
| 07:41 | AeroNotix | I wouldn't mind *trying* to see how the condition system would fit into Clojure |
| 07:41 | AeroNotix | quizdr: the whole thing, Clojure's just seems like a hack |
| 07:41 | xificurC | I never learned format well enough to use it extensively |
| 07:41 | xificurC | its present in clojure/pprint isnt it |
| 07:41 | alew | What does the keyword arguments situation in CL look like? |
| 07:42 | AeroNotix | alew: (defun foo (&key ((:apple a)) ((:box b) 0) ((:charlie c) 0 c-supplied-p)) |
| 07:43 | AeroNotix | so, you can have defaults, renames and check if they are supplied |
| 07:43 | quizdr | oh for supplying defaults you mean? thinks like &rest &key and their siblings? |
| 07:43 | AeroNotix | quizdr: |
| 07:43 | quizdr | the idiom for that in clojure seems pretty simple, to set a default map of values, take rest parameters, etc. |
| 07:43 | quizdr | the ordering is different in the destructuring, but I don't see the major difference |
| 07:43 | AeroNotix | compared to clojure: (defn foo [{:keys [apple box charlie] :or {box 0 charlie 0}}]) |
| 07:44 | AeroNotix | but yo ucan't even check if they were *actually* supplied |
| 07:44 | AeroNotix | It's not a big thing for me though, just would like it to be at least similar. |
| 07:45 | quizdr | hm. |
| 07:45 | AeroNotix | alew: read Practical Common Lisp, great book on CL. |
| 07: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? |
| 07:45 | alew | That's not how you do keyword args in clojure |
| 07:46 | xificurC | I'd say it's more readable to have the argument and its default value coupled together than having them separate |
| 07:46 | alew | (defn foo [& {:keys [apple box charlie]}]) |
| 07:46 | AeroNotix | xificurC: exactly |
| 07:46 | AeroNotix | alew: how do you supply defaults for them, then? |
| 07:46 | AeroNotix | you need to use :or to supply defaults |
| 07:46 | alew | you can still do the or |
| 07:47 | alew | But leaving out the & changes it significantly |
| 07:47 | AeroNotix | not really |
| 07:47 | xificurC | but if you'll put say :or {apple 2 charlie 3} |
| 07:47 | xificurC | it doesnt seem that obvious who has default values and who doesnt |
| 07:48 | xificurC | I mean you look at the :keys vector |
| 07:48 | xificurC | and you cannot tell who has and who doesnt have default values |
| 07:48 | AeroNotix | exactly |
| 07:48 | AeroNotix | and you end up repeating the names twice |
| 07:48 | AeroNotix | so it's a lot longer |
| 07: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 |
| 07:49 | xificurC | so you check the :keys vector and the :or map and compare them in your head to get the result |
| 07:49 | AeroNotix | quizdr: never said it was, just said I miss it :) |
| 07:49 | xificurC | how do you make an optional argument in clojure? |
| 07:50 | xificurC | quizdr: i guess its just a matter of taste and readability |
| 07:50 | alew | Personally, I think the choice of unifying the destructuring of maps with keyword args was a great choice |
| 07:50 | AeroNotix | multiple arity or & rest with destruscturing |
| 07: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 |
| 07:50 | xificurC | aye, multiple arity, I always forget :) |
| 07:51 | AeroNotix | quizdr: for sure, different parenthesis is probably in my top 5 feartures |
| 07:51 | quizdr | xificurC but the & rest is quite useful, over multiple arity a lot of the time i'd say |
| 07: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 |
| 07:52 | xificurC | quizdr: when I check the clojure sources I see more multiple arities than &rests, why is that? |
| 07:52 | xificurC | and why are so many built-in functions written out so tediously? |
| 07:52 | xificurC | like one for [a], [a b] [a b c] [a b c d] [a b c d & more] |
| 07:52 | alew | For efficiency reasons |
| 07:53 | oskarkv | xificurC for performance and/or because the more convenient functions has not yet been defined at that point |
| 07:53 | quizdr | check this: http://stackoverflow.com/questions/3208347 |
| 07:53 | AeroNotix | alew: I enjoyed it |
| 07:53 | quizdr | that shows 3 different approaches to defaults and optional parameters |
| 07:54 | alew | Keyword arguments don't seem to be very prevalent in clojure code anyways |
| 07:54 | xificurC | quizdr: thanks |
| 07:54 | alew | AeroNotix: Need to read the new Joy of Clojure first |
| 07:55 | xificurC | but back to my last question, if you check the source of apply or map |
| 07:55 | AeroNotix | alew: Same :) |
| 07:55 | xificurC | why is the function written out for the first 2-4 cases? |
| 07:56 | AeroNotix | xificurC: efficiency |
| 07:56 | xificurC | AeroNotix: is the performance that different? |
| 07:56 | quizdr | it would be worth timing alternatives for fun |
| 07: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 |
| 07:57 | AeroNotix | xificurC: there's no reason to not choose the faster one in the cases of standard library code. |
| 07:57 | AeroNotix | oskarkv: cargo cult programming |
| 07:57 | AeroNotix | oskarkv: learn instead of making up stuff |
| 07:57 | xificurC | AeroNotix: but its ugly :( |
| 07:57 | AeroNotix | xificurC: indeed, but that's the price you pay |
| 07:58 | oskarkv | AeroNotix bad memory leads to cargo cult programming? |
| 07:58 | oskarkv | or, implies it rather |
| 07:58 | quizdr | bad memory leads to waking up and writing ansi c code |
| 07: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. |
| 08: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. |
| 08:01 | alew | I really despise working with timezones |
| 08:01 | oskarkv | But, I have never felt the need for it since, but if i did i would try it again |
| 08: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? |
| 08:02 | oskarkv | just use maps :p |
| 08:02 | AeroNotix | alew: unix on the backend, let the front-end dudes sort out display :) |
| 08: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? |
| 08:04 | oskarkv | To be clear I'm talking about the implementation, the [s & {:keys [base] :or {base 10}}] stuff, not keyword arguments in general |
| 08:05 | quizdr | without destructing you must be avoiding various caller flexibility, like defaults, optional parameters, etc |
| 08:06 | quizdr | Profpatsch you could reduce your coll of maps with a function that only looks at :foo in each map item in the seq |
| 08:06 | oskarkv | quizdr I don't really follow |
| 08:06 | Profpatsch | quizdr: Ooooh, right, thanks. |
| 08:06 | quizdr | Profpatsch no prob |
| 08:07 | clgv | Profpatsch: (apply max-key :foo coll) |
| 08:07 | quizdr | ,(doc max-key) |
| 08:08 | clojurebot | "([k x] [k x y] [k x y & more]); Returns the x for which (k x), a number, is greatest." |
| 08:08 | quizdr | clgv i think he wants the entire map the key came from |
| 08:08 | Profpatsch | clgv: I knew there was a convenience function for that. I bet it uses a reduce internally. |
| 08:08 | clgv | quizdr: yes and he gets it |
| 08:09 | quizdr | clgv well i'll be a jolly darn sweet pie-eating squirrel of a rabbit hunter, then! |
| 08:09 | AeroNotix | How crazy is it to assoc fields into the request value in Compojure middleware? |
| 08:09 | AeroNotix | In other frameworks this is considered normal, in others BAT SHIT INSANE |
| 08:09 | AeroNotix | so.. lemme know the ballpark idiocy here |
| 08:09 | Profpatsch | clgv: Yep, it does. |
| 08:10 | Profpatsch | clgv: With a little recursion. |
| 08:10 | clgv | Profpatsch: standard building block when you do lots of data analysis ;) |
| 08:10 | clgv | Profpatsch: you could also use (reduce (partial max-key :foo) coll) |
| 08: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. |
| 08:11 | clgv | Profpatsch: max-key is awesome because `key` can be any function not neccesarily a keyword |
| 08:11 | alew | AeroNotix: That works, until you have a text reminders system |
| 08:12 | Profpatsch | clgv: Neat |
| 08:13 | AeroNotix | alew: ? |
| 08:13 | alew | AeroNotix: Need the backend to send reminders at specific times |
| 08:14 | alew | AeroNotix: but I don't want to send a reminder at 5 am when people are sleeping :P |
| 08:14 | AeroNotix | alew: I'm associng in parsed cookies |
| 08:15 | AeroNotix | alew: so I'll add :parsed-cookies (parsecookies rawcookies) or w/e |
| 08:15 | alew | AeroNotix: I was talking about your Unix comment |
| 08:15 | alew | AeroNotix: as for associng in values, that's pretty standard |
| 08:16 | AeroNotix | ohhhh ! ok |
| 08:16 | alew | AeroNotix: https://github.com/ring-clojure/ring-json/blob/master/src/ring/middleware/json.clj |
| 08:16 | AeroNotix | alew: usually you have a user profile, if you store the user's preferred TZ, then it's coo' |
| 08:17 | AeroNotix | alew: sweet, assocs away |
| 08:17 | alew | AeroNotix: preferred TZ's are so old fashion |
| 08:17 | AeroNotix | then what? |
| 08: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! |
| 08:18 | AeroNotix | lol |
| 08:37 | ambrosebs | anyone following the definline conversation on the ML? |
| 08:38 | llasram | Seems pretty gross to me |
| 08:38 | ambrosebs | at a glance it seems ridiculous not to accept a patch. |
| 08:39 | mdrogalis | Relevant: https://twitter.com/MichaelDrogalis/status/425354886897618944 |
| 08: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 |
| 08:40 | llasram | s,BFDL,BDFL, |
| 08: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. |
| 08:41 | mdrogalis | I'd opt for more D, but need to hear more out of Rich on some of these tickets in that case |
| 08:42 | ambrosebs | I also don't see the point of definline if it can't be used higher-order. |
| 08:42 | llasram | ambrosebs: Is it `definline` itself you dislike, or compiler support for inlining via explicit :inline functions in metadata? |
| 08: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. |
| 08:43 | llasram | Gotcha |
| 08:44 | ambrosebs | llasram: It seems like Rich is saying he's not touching any definlines until it dies. |
| 08:44 | ambrosebs | so kill it .. |
| 08:44 | ambrosebs | I could be misinterpreting though, Rich hasn't actually said anything explicitly. |
| 08: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. |
| 08:45 | ambrosebs | mdrogalis: I would think the proximity to 1.6 release is a factor |
| 08:45 | llasram | mdrogalis: I think 1.2 -> 1.3 broke more than intended, and has created a bit of a "never again" attitude |
| 08:46 | llasram | Or at least "not until 2.0" |
| 08:46 | ambrosebs | llasram: yea |
| 08:46 | ambrosebs | soo, anyone listening please stop using definline in your code :) |
| 08:47 | llasram | Fiiiiine. Explicit :inline metadata it is |
| 08:47 | mdrogalis | 2.0 better be patch now or forever hold your peace lol |
| 08:47 | tbaldridge | definline was just the mark of a crappy compiler, imo |
| 08:48 | tbaldridge | no language should require the user to manually mark code for inlining |
| 08:48 | mdrogalis | tbaldridge: Yeah, I suppose that's an argument. |
| 08:48 | tbaldridge | Even C++ ignores the inline keyword these days |
| 08: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 |
| 08: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. |
| 08:49 | tbaldridge | stuartsierra: ... and the fact that the compiler can't figure that out on its own. |
| 08:50 | mdrogalis | Honestly though, either patch it or excise it. Don't leave it an open wound. :/ |
| 08:55 | ambrosebs | just so I'm understanding, is there a difference between the normal (defn ^{:inline ..}) and (definline), aside from reducing duplication? |
| 08:56 | Profpatsch | Is it just me or is using loop a code smell? Pointing at a too iterative style? |
| 08:56 | ambrosebs | Profpatsch: depends what you're doing |
| 08:59 | Profpatsch | ambrosebs: You mean high speed vs high level? |
| 09:00 | ambrosebs | Profpatsch: well you might be porting iterative code ;) |
| 09:00 | ambrosebs | Profpatsch: but seriously, I've ported a lot of Racket which sometimes has local mutation. loop has been useful for that. |
| 09:01 | stuartsierra | Some operations can only be written with loop/recur. Usually map/filter/reduce suffice. |
| 09:01 | Profpatsch | ambrosebs: Yeah, I’m implementing an algorithm that is described in an iterative way. |
| 09:02 | ambrosebs | Profpatsch: :D |
| 09:02 | Profpatsch | Temporal Difference Lerning with Sarsa: http://i.imgur.com/19EGHxH.jpg |
| 09:05 | ambrosebs | Profpatsch: looks like you want local mutation and c.c/while ? |
| 09:08 | Profpatsch | ambrosebs: Nah, I’m going to check the high-level perf first. |
| 09:09 | alandipert | new day, new hoplon demo. please enjoy! http://alandipert.github.io/hoplon-demos/tictactoe/ |
| 09:22 | zerokarmaleft | alandipert: heh, rand-nth for AI :D |
| 09:23 | alandipert | zerokarmaleft: minimax is... an exercise for the reader :-) |
| 09:28 | redinger | alandipert: It's quite an effort to get this AI to win a game. :) |
| 09:28 | alandipert | redinger: simple ain't easy! |
| 09:33 | alandipert | redinger: i'm putting together a multiplayer minesweeper we can hack on for an upcoming triclojure |
| 09:35 | zerokarmaleft | MMO minesweeper, with auto-generation when players approach a boundary...for ultimate madness and loafing |
| 09:36 | alandipert | zerokarmaleft: basically, yup! |
| 09:37 | clgv | ambrosebs: I only found a thread with 3 posts on definline - did you mean that one |
| 09:38 | ambrosebs | clgv: yes with Tassilo |
| 09:38 | clgv | pk |
| 09:38 | clgv | ok |
| 09:40 | redinger | alandipert: Sounds fun! |
| 09:49 | katox | oh, I just found out that projectil work fine unlike (probably deprecated) C-c C-t in emacs with cljx |
| 09:49 | katox | another tooling hurdle gone |
| 09:53 | gozala | anyone knows what’s idiomatic way to report errors in core.async ? |
| 09:54 | tbaldridge | gozala: the idiomatic way is to do what works best for your project :-) |
| 09:55 | tbaldridge | So use dedicated error channels, or return them from gos, whatever works best. Core.async is very agnostic in this area |
| 09:55 | gozala | tbaldridge: I mean am I supposed to just put errors on channel |
| 09:55 | gozala | or have an error channel |
| 09:56 | gozala | tbaldridge: I have being returning records of input and error channels in most of my APIs now |
| 09:57 | gozala | but feel like there should be a better way |
| 09:57 | gozala | 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 | mmitchell | 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 | ddellacosta | 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 | gfredericks | 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 | gfredericks | something about hygiene I think? |
| 10:09 | gfredericks | 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 | gfredericks | I think what I wanted was something that was syntactically function-like, but could still be inlined |
| 10:11 | gfredericks | 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 | ambrosebs | 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 | gfredericks | 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 | ambrosebs | 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 | gfredericks | 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 | gfredericks | 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 | ambrosebs | gfredericks: slight overstatement |
| 10:21 | ambrosebs | 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 | ambrosebs | 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 | ambrosebs | 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 | silasdavis | 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 | ambrosebs | :) |
| 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 | Wild_Cat | 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 | silasdavis | resource-paths |
| 10:38 | silasdavis | 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 | llasram | gfredericks: jinx! |
| 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 | llasram | There's been some clojure-users mailing list discussion, but not recently enough that I could find it easily |
| 10:40 | llasram | 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 | silasdavis | looking at lein profiles |
| 10:41 | silasdavis | 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 | gfredericks | 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 | dnolen | RickInAtlanta: but yes falls out CLJS |
| 10:47 | dnolen | 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 | nDuff | 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 | gfredericks | ,(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 | AeroNotix | 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 | AeroNotix | 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 | silasdavis | java -classpath <resource-dir> -jar uberjar.jar? |
| 11:07 | katox | silasdavis: no, they are ignored |
| 11:09 | katox | silasdavis: you can combine it with cp alone though |
| 11:09 | katox | 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 | stuartsierra | 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 | ambrosebs | 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 | mdrogalis | 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 | ambrosebs | 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 | Mandar | 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 | Mandar | 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 | jcromartie | ,(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 | jcromartie | ,(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 | ambrosebs | 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 | ambrosebs | ;) |
| 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 | technomancy | the two exceptions to 1) being nil safety and not accepting metadata |
| 12:24 | technomancy | 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 | gtrak | 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 | gfredericks | 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 | dnolen | 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 | dnolen | gtrak: you need to put information symbols for later phases |
| 12:31 | dnolen | information on |
| 12:31 | gtrak | ah, you don't want to have to wrap and unwrap everything. |
| 12:32 | gtrak | 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 | gfredericks | 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 | gfredericks | 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 | technomancy | 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 | technomancy | 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 | dnolen | 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 | katox | dnolen: and if you replace those with your own, weird things happen |
| 12:56 | dnolen | katox: vary-meta is your friend :) |
| 12:56 | dnolen | and namespaced keywords |
| 12:57 | dnolen | 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 | katox | dnolen: still, it is a bit wierd to have the ide changing the code path your program takes without a warning |
| 13:01 | katox | dnolen: I guess there is no easy way out for top level forms |
| 13:02 | katox | 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 | egghead | I bet that stuartsierra has used simulant before |
| 13:39 | egghead | :) |
| 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 | egghead | 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 | gfredericks | 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 | rurumate1 | it's because I have some clojure-defending work to do at my day job |
| 13:59 | rurumate1 | the first attack was, it doesn't perform because reflection |
| 14:00 | rurumate1 | 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 | rurumate1 | it's the latter |
| 14:01 | rurumate1 | 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 | jcromartie | 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 | rurumate1 | 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 | 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 | rurumate1 | tbaldridge: your company happens to be looking for new staff? |
| 14:09 | rurumate1 | 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:10 | gfredericks | bbloom: is this where I called you a dendrologist? |
| 14:10 | gfredericks | ~bbloom |
| 14:10 | clojurebot | bbloom is a dendrologist |
| 14:10 | bbloom | gfredericks: haha indeed |
| 14:10 | bbloom | gfredericks: <3 |
| 14:10 | bbloom | ~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 | gfredericks | a lot of clojure code leaves reflection in places that can easily tolerate it |
| 14:12 | gfredericks | 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 | gfredericks | 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 | gfredericks | 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 | gfredericks | Kant's ex is king |
| 14:19 | jcromartie | whoever wrote hiccup.form obviously never used it in an app |
| 14:19 | jcromartie | GIT BLAME TIME |
| 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 | llasram | 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 | jcromartie | 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 | djcoin | clojurescript, it would be great :)= |
| 14:57 | jocrau | add-watch to an atom |
| 14:58 | jocrau | (add-watch |
| 14:58 | jocrau | state ::state-change |
| 14:58 | jocrau | (fn [key reference old-state new-state] |
| 14:58 | jocrau | (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 | djcoin | 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 | djcoin | 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 | jcromartie | 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 | jcromartie | :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 | justin_smith | so you have different effective ordering on each side, but want all changes to be present |
| 15:07 | justin_smith | 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 | justin_smith | 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 | teslanick | 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 | teslanick | 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 | llasram | 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 | mmitchell | 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 | danneu | 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 | technomancy | 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 | technomancy | 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 | bbloom | technomancy: by that i mean whatever it is, lein, bundle/gem/rake, make, grunt, whatever |
| 16:13 | bbloom | people want everything to work via THE TOOL |
| 16:13 | bbloom | 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 | technomancy | 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 | bbloom | 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 | bbloom | 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 | technomancy | </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 | technomancy | 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 | technomancy | 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 | technomancy | 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 | mookerji | overlap in terms of metrics aggregation, specifically. |
| 17:04 | ztellman | mookerji: interval-metrics requires an external driver for the aggregating and emitting |
| 17:05 | ztellman | 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 | mookerji | 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 | ztellman | 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 | mookerji | by machinery, you're talking about interval-metrics being slightly slower |
| 17:10 | mookerji | 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 | ztellman | I'm not sure by how much, though |
| 17:36 | ztellman | probably not a lot |
| 17:36 | mookerji | ah, ok. |
| 17:37 | mookerji | 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 | technomancy | 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 | rasmusto | (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 | justin_smith | 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 | justin_smith | ((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 | TimMc | You can do some really obscure stuff that way. |
| 18:02 | TimMc | 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 | bbloom | 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 | alandipert | 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 | bbloom | 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 | tomjack` | oh, I can google |
| 18:07 | rasmusto | tomjack`: http://en.wikipedia.org/wiki/Fexpr |
| 18:07 | rasmusto | 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 | bbloom | 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 | bbloom | 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 | aperiodic | 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 | gfredericks | (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 | 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 | AeroNotix | 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 | hyPiRion | And then I end up using it at work, and since noone apart from me knows OCaml, I can work in peace. |
| 18:57 | hyPiRion | 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 | AeroNotix | Anderkent: same! |
| 18:58 | AeroNotix | hyPiRion: his Erlang looks ridiculous |
| 18:58 | AeroNotix | 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 | AeroNotix | Yeah generally older Erlang codebases are terrible |
| 18:59 | AeroNotix | even the OTP source is a rat's nest |
| 19:05 | sdegutis | Hey guys. |
| 19:05 | sdegutis | I came up with a riddle the other day that I told my wife and kids. |
| 19:05 | sdegutis | 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 | sdegutis | O, I C.. U R A B! |
| 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 | akurilin | 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 | akurilin | 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 | ztellman | 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 | ztellman | 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 | ztellman | 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 | ztellman | but otherwise, it's fine |
| 19:45 | ztellman | 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 | akurilin | 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 | alew | 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 | ztellman | 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 | turbofail | 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 | ztellman | (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 | ztellman | right now it's just evaluating (or x y) and return x |
| 19:59 | ztellman | 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 | ztellman | 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 | noonian | (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 | noonian | 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 | turbofail | 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 | akurilin | I already got what I was looking for from apply or |
| 20:05 | akurilin | 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 | noonian | 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 | Anderkent | lein try korma -> repl with korma. You just need to know the group/artifact name :p |
| 20:14 | Anderkent | I use it *all the time* |
| 20:17 | noonian | here it is compared to with apply: https://www.refheap.com/26625 |
| 20:17 | noonian | 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 | Anderkent | ,(eval (apply #'or [nil nil 1 2 3])) |
| 20:26 | clojurebot | 1 |
| 20:26 | turbofail | huh. |
| 20:26 | noonian | thats sweet |
| 20:27 | noonian | 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 | jcromartie | 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 | Anderkent | they're the &form and &env |
| 20:31 | Anderkent | :P |
| 20:31 | Anderkent | ,(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 | Anderkent | or rather the exception, not an exception |
| 20:35 | Anderkent | 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 | Bronsa | j |
| 20:37 | Bronsa | 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 | noonian | quizdr: it's an error if you actually try to pass a macro as a value |
| 20:38 | noonian | ,(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 | Bronsa | (some identity [nil nil false 1 2]) |
| 20:42 | Bronsa | ,(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 | Bronsa | 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 | t3soro | ,(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 | Bronsa | that's how or is defined |
| 20:49 | Bronsa | it's nil when called with no arg |
| 20:49 | Bronsa | 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 | Anderkent | ,(macroexpand '(or (+ 1 2))) |
| 20:51 | clojurebot | (+ 1 2) |
| 20:51 | rhg135 | code==values, just it's valid |
| 20:52 | rhg135 | 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 | rhg135 | think thats why debuggers exist |
| 20:54 | rhg135 | fix bad values |
| 20:54 | noonian | thanks guys, that was fun |
| 20:55 | noonian | 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 | sdegutis | (I'm using a MBP with OS X.) |
| 21:07 | rhg135 | ah |
| 21:07 | rhg135 | 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 | rhg135 | 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 | sdegutis | 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 | technomancy | 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 | quizdr | 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 | rhg135 | 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 | rhg135 | 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 | rhg135 | i ran a bsd vm |
| 21:16 | rhg135 | 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 | rhg135 | i don't think we'll see any major fixes |
| 22:20 | rhg135 | 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 | noprompt | dnolen: ie. wrapping reify in let with helper fn's. |
| 22:51 | noprompt | dnolen: because we do that until we're able to extract a component and it's subcomponents in to an ns. |
| 22:51 | noprompt | 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 | kanja | shoot, wrong channel :( |
| 23:03 | noprompt | dnolen: patched some grammar/spelling on the wiki ;) |
| 23:03 | noprompt | 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 | bbloom | 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 | ambrosebs | 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 | bbloom | 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 | bbloom | 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 | 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 | ambrosebs | 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 | ambrosebs | 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 | sm0ke | ,(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 | akurilin | 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 | akurilin | 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 | sm0ke | ,(doc rpartial) |
| 23:44 | clojurebot | Pardon? |
| 23:46 | akurilin | Actually that err->> macro might take a vecf |
| 23:46 | akurilin | *vec |
| 23:48 | technomancy | oh, rpartial and funcall don't actually exist in clojure |
| 23:48 | technomancy | I wish rpartial did though |
| 23:48 | technomancy | funcall, not so much |
| 23:49 | sm0ke | ->> would take apply i guess |
| 23:50 | sm0ke | ,(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 | ddellacosta | 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 | tutysara | ddellacosta: I got the multiple provider working |
| 23:57 | ddellacosta | tutysara: oh, nice--using sritchie's thing, or using friend? |
| 23:57 | ddellacosta | 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 | ddellacosta | 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 | tutysara | ddellacosta: yes sure I am interested in putting together an example |