2012-10-27
| 01:16 | muhoo | wasn't the nyc the first ever clojure group? |
| 01:16 | muhoo | i.e. didn't rhickey launch clojure to the nyc lisp group? |
| 01:16 | muhoo | i thought he lived in nyc |
| 01:23 | amalloy | he's presented at the nyc meetup a number of times |
| 01:25 | amalloy | eg cljs was announced there, and i think he gave a reducers talk not long after releasing them |
| 01:27 | ambrosebs | Now accepting contributions to Typed Clojure (Clojure CA only). Lots of small easy jobs I can give. https://github.com/frenchy64/typed-clojure |
| 01:44 | Sgeo | ambrosebs, I assume you use some macro-expander. I trust it's not clojure.walk/macroexpand-all? |
| 01:45 | ambrosebs | Sgeo: https://github.com/frenchy64/typed-clojure |
| 01:45 | ambrosebs | whoops! |
| 01:46 | ambrosebs | https://github.com/frenchy64/analyze rather |
| 01:46 | ambrosebs | It's an AST :) |
| 01:48 | tomoj | wow |
| 01:48 | tomoj | nice work |
| 01:49 | ambrosebs | next best thing to Clojure-in-Clojure! |
| 01:49 | ambrosebs | clojure 1.5.0-beta1 only atm. |
| 01:49 | Sgeo | ,(do (require '[clojure.walk :as walk]) (walk/macroexpand-all '(quote (let [a 1] a)))) |
| 01:49 | clojurebot | (quote (let* [a 1] a)) |
| 01:50 | Sgeo | Just a demo of how utterly bad clojure.walk/macroexpand-all is |
| 01:50 | ambrosebs | Sgeo: good thing the clojure compiler knows how. ;) |
| 01:51 | ambrosebs | g2g! |
| 01:51 | Sgeo | Bye |
| 01:52 | Sgeo | I should learn how to praise and not just criticise |
| 01:52 | clojurebot | Cool story bro. |
| 01:52 | Sgeo | (Not that I have criticism about ambrosebs's work, because I don't) |
| 01:57 | andyfingerhut | Does anyone know how to modify a Clojure modular contrib module's pom.xml file (e.g. for data.xml) so that I can pass additional command line args to the java commands invoked to compile the code? Or is there a way to do it from the mvn command line? |
| 02:46 | brainproxy | trying to switch over to ritz-swank from swank-clojure but having some problems... |
| 02:47 | brainproxy | i've got a clean lein 2 project, and with the lein-ritz in my profile, I can fire up `lein ritz 4005` for example |
| 02:47 | brainproxy | and then I can use slime-connect to connect to it |
| 02:47 | brainproxy | from w/in emacs that is |
| 02:47 | brainproxy | but... I get a warning about slime and swank having different versions, *and* after choosing to continue past the warning, I never actually get a repl |
| 02:48 | brainproxy | i just get a notice the connection was made |
| 03:37 | muhoo | new i7 in the hizzy. now i can clojure it up with impunity. |
| 03:59 | S11001001 | andyfingerhut: for scalar datatypes, there's usually a direct mapping between the XML options for each plugin and -D options you can give to maven |
| 04:01 | S11001001 | andyfingerhut: I assume the javac options are in string settings, so those should suit |
| 04:25 | scottj | brainproxy: well ritz does use a different version of slime than swank-clojure |
| 04:43 | brainproxy | scottj: yes, but I had swank-clojure uninstalled and was installed the version of slime rec'd by the ritz-swank readme |
| 04:43 | brainproxy | anyway, for now just using nREPL and nrepl.el |
| 05:12 | wingy | im making a SDK for an HTTP API .. i have some options for how to deal with the HTTP API endpoint: 1. pass the url to the functions 2. hardcode it in the functions 3. have it in the SDK's config.clj file |
| 05:15 | wingy | option 3 seems to be a flexible one .. what is the best practice for this? |
| 05:27 | andrewmcveigh | wingy: you can throw out #2 - that's crazy, #1 might get tedious, passing a URL to every function call. |
| 05:27 | wingy | so 3? |
| 05:28 | andrewmcveigh | well, out of those 3 options, I'd pick #3. |
| 05:28 | wingy | andrewmcveigh: are there more optons? |
| 05:28 | wingy | options |
| 05:29 | wingy | andrewmcveigh: i just thought about FP .. shouldn't all data be passed as params? |
| 05:29 | andrewmcveigh | many java/.net sdks use a singleton to store the current "binding" - not suggesting that this is a good option. |
| 05:30 | andrewmcveigh | wingy: what do you do with other configurable options? |
| 05:30 | wingy | yeah |
| 05:30 | wingy | i guess i put them in config.clj |
| 05:30 | wingy | btw .. i think having a *service-url* is good |
| 05:31 | wingy | much better than a config.clj |
| 05:31 | andrewmcveigh | how do you set *service-url*? |
| 05:32 | wingy | andrewmcveigh: does this mean that i have to wrap them inside (binding [*service-url*] (make-request)) |
| 05:32 | wingy | you said binding and i thought about dynamic binding |
| 05:32 | andrewmcveigh | I quoted "binding", because it has nothing to do with clojure's binding... |
| 05:32 | wingy | but that is a good idea? |
| 05:33 | wingy | kinda like *out* |
| 05:33 | andrewmcveigh | Personally, I don't think singletons are a good idea in clojure, but I'm no expert. |
| 05:35 | andrewmcveigh | wingy: I think if you're doing something like (binding [*service-url* (:service-url (read-config))] (make-request)) - that's alright. |
| 05:36 | wingy | andrewmcveigh: is there a way to set *service-url* once so all SDK fns dont have to be wrapped? |
| 05:37 | andrewmcveigh | ,(doc alter-var-root) |
| 05:37 | andrewmcveigh | &(doc alter-var-root) |
| 05:37 | lazybot | java.lang.SecurityException: You tripped the alarm! alter-var-root is bad! |
| 05:38 | Bronsa | ,alter-var-root |
| 05:38 | Bronsa | &alter-var-root |
| 05:38 | lazybot | java.lang.SecurityException: You tripped the alarm! alter-var-root is bad! |
| 05:38 | Bronsa | woah :( |
| 05:38 | andrewmcveigh | wingy: or you could use an atom/ref to hold it. |
| 05:39 | andrewmcveigh | wingy: that's mutable territory though. |
| 05:40 | wingy | ,(def *service-url* (atom "http://service.com/api")) |
| 05:40 | wingy | i'll try with it |
| 05:41 | wingy | not mutable, but switchable right? |
| 05:41 | wingy | the current state changes .. but the values don't |
| 05:42 | andrewmcveigh | if state changes... is that not mutation? |
| 05:45 | wingy | is it? |
| 05:45 | wingy | ok mutation in the identifier |
| 05:46 | wingy | correct me if i am wrong |
| 05:47 | andrewmcveigh | from http://clojure.org/atoms "Atoms provide a way to manage shared, synchronous, independent state. " |
| 05:48 | andrewmcveigh | so if you (reset! atom1 5), you've changed it's state. |
| 05:49 | andrewmcveigh | it's just been managed by clojure. |
| 08:56 | wunki | I keep getting "method not found" for trying to call the static `of` method here: http://thumbnailator.googlecode.com/hg/javadoc/index.html |
| 08:56 | wunki | trying to call it with `(Thumbnails/of ...)` |
| 09:06 | keugaerg | ,(+ 2 3) |
| 09:07 | keugaerg | ret |
| 09:08 | jonasac | hi, kinda new to clojure trying to get the examples repo form programming clojure2nd edition to work |
| 09:08 | jonasac | did lein deps and it installed a bunch of stuff to .m2 folder |
| 09:08 | jonasac | but when i run lein repl i cant import the example code like the book says |
| 09:08 | jonasac | being told examples is not in the classpath |
| 09:09 | rod_ | what's the command you're using to import the example code into the repl jonasac? |
| 09:09 | jonasac | (require 'examples.introduction) |
| 09:10 | rodnaph | and the file is "src/examples/introduction.clj" |
| 09:10 | jonasac | yep |
| 09:10 | rodnaph | with (ns examples.introdution) as the namespace? |
| 09:10 | rodnaph | and u start the repl from the folder that contains "src" |
| 09:11 | jonasac | yes and yes |
| 09:11 | rodnaph | what's the exact error? can you paste an example session to refheap.com (from cd'ing to the folder, ls'ing the contents and starting the repl) |
| 09:12 | jonasac | lein self-install helped |
| 09:12 | jonasac | i installed clojure via homebrew |
| 09:12 | jonasac | but it works now |
| 09:13 | rodnaph | oh right (sorry if i got the wrong end of the stick, just joined channel) |
| 09:14 | jonasac | no, thanks for the help, just joined myself |
| 09:15 | jonasac | been mising lisp ever since SICP at uni |
| 09:16 | rodnaph | clojure is my first lisp, real eye opener though. |
| 12:06 | erwagasore | I am doing clojure koans and I am stuck, need help: (= 25(__ ((fn[n] (* n n)))) |
| 12:06 | erwagasore | what should I put in __ place? |
| 12:08 | antares_ | erwagasore: do you have a link to the example? |
| 12:10 | erwagasore | antares_ line 24 test https://github.com/functional-koans/clojure-koans/blob/master/src/koans/06_functions.clj |
| 12:11 | antares_ | erwagasore: ok, that example makes sense |
| 12:12 | erwagasore | antares_ maybe I need to understand what|how higher-order functions works after all. |
| 12:13 | antares_ | http://clojure-doc.org/articles/language/functions.html#higher_order_functions |
| 12:14 | antares_ | ,((fn [f] (f 5)) (fn [n] (* n n))) |
| 12:15 | antares_ | $ ((fn [f] (f 5)) (fn [n] (* n n))) |
| 12:15 | antares_ | ~((fn [f] (f 5)) (fn [n] (* n n))) |
| 12:15 | antares_ | lazybot: help |
| 12:15 | lazybot | You're going to need to tell me what you want help with. |
| 12:16 | antares_ | erwagasore: well, here is your answer: a function that takes another funtion (the squaring one) and calls it with an argument of 5 |
| 12:30 | erwagasore | antares_ amazing thanks now I understand |
| 12:39 | dnolen | bbloom: thx for the core.logic patch |
| 13:22 | tomoj | sitting here wondering whether I need to create a new datomic db or whether the changes I made to the schema are compatible with what's already there. I hadn't committed to git yet. I should have, but still, using git history for that would suck. a few lines of code lets me say "ok, pretend I committed this schema tx, then clojure.data/diff that with my current schema" :D |
| 13:30 | TimMc | lazybot: help me with my homework |
| 13:30 | lazybot | Topic: "me" doesn't exist! |
| 13:31 | TimMc | Oh good, it isn't self-aware yet. |
| 13:38 | hyPiRion | lazybot: What is the purpose of life? |
| 13:46 | hyPiRion | Well, it isn't even aware. |
| 13:46 | hyPiRion | At least not fully aware. |
| 13:46 | AdmiralBumbleBee | maybe it is aware, but it's too lazy to make it fully apparent |
| 13:47 | tomoj | it seems aware of some of what I type |
| 13:47 | AdmiralBumbleBee | it's aware of all of it, too lazy to respond to all of it |
| 13:48 | AdmiralBumbleBee | maybe someone needs to kick it with a doall |
| 13:58 | bbloom | dnolen: my pleasure. thanks for posting that OZ link on the mailing list the other day. i found it really helpful for understanding how core logic works |
| 14:00 | dnolen | bbloom: Oz is pretty neat, the Prolog-like bits of core.logic are quite different from Oz, but I basically want to steal the Oz FD feature set wholesale |
| 14:01 | bbloom | dnolen: yup, i'm most interested in optimization |
| 14:02 | bbloom | as in minimization, not perf |
| 14:02 | bbloom | although perf is also important :-) |
| 14:03 | bbloom | dnolen: are there any examples of solver systems that include both a finite domain solver and some other category of solver? for example a linear programming solver that operates on floating point values? |
| 14:03 | dnolen | bbloom: as am I. core.logic needs a distribute functionality - it's pretty easy add. |
| 14:04 | dnolen | bbloom: core.logic already has multiple solvers, CLP(Tree) & CLP(FD), it's also a goal for both to be present in the same program. |
| 14:05 | dnolen | bbloom: and I would like to see CLP(R), floating point ops |
| 14:05 | bbloom | dnolen: same program == same top-level "run" form? i.e. the same constraint system? |
| 14:06 | bbloom | dnolen: seems like this CLP(X) form turns up some results in the literature. is there a survey of this terminology and the various types of solvers? |
| 14:06 | dnolen | bbloom: different constraint solvers in the same run yes |
| 14:06 | bbloom | dnolen: i may be interested in contributing a Simplex solver for linear inequalities -- I want to use it for UI layout |
| 14:07 | dnolen | bbloom: I'm not aware of a survey, but lots of various papers of course |
| 14:07 | dnolen | bbloom: that would be sweet |
| 14:09 | bbloom | dnolen: meanwhile, i have my CLJS CPS transform in pretty good shape… there's one small patch to analyze fn methods that would help me get it to a released state :-) |
| 14:10 | dnolen | bbloom: cool, yes I saw that will take closer look soon. related, your patch did break top level lets, do you have any thoughts about fixing that? |
| 14:10 | bbloom | top level lets? hmmm |
| 14:10 | bbloom | let me look |
| 14:11 | dnolen | bbloom: http://dev.clojure.org/jira/browse/CLJS-401 |
| 14:11 | dnolen | bbloom: top level lets just drop JS vars at the top level, gensym protected overwriting, that's no longer the case |
| 14:11 | bbloom | dnolen: d'oh! makes sense |
| 14:11 | gtrak | errr... someone must know the answer to this. I've been trying to create a clojure.test fixture that looks for exceptions in an agent, and I can't find a proper way to report the error. Throwing exceptions kills the main test-runner thread, using clojure.test/do-report seems to die on 'lein test', though it works on swank: https://gist.github.com/27cac036ef633a2b5cdd |
| 14:11 | bbloom | ill see what i can come up with |
| 14:12 | dnolen | bbloom: thx much |
| 14:12 | dnolen | bbloom: I mention a possible fix, but I haven't had a chance to try it out. Might totally kill perf since if you have enough nested functions GClosure won't optimize. |
| 14:13 | gtrak | the current approach: https://gist.github.com/562db53028a9a9a0218c |
| 14:16 | bbloom | dnolen: i know GClosure can optimize away top level self invocations … those (function() { … })(); forms |
| 14:16 | bbloom | maybe we should do that for every top-level? |
| 14:18 | dnolen | bbloom: hmm, I'd prefer a patch that only did for top-level lets. |
| 14:19 | bbloom | dnolen: sure. it may be generally value to include "is top level" in the AST somehow |
| 14:19 | bbloom | although, i guess you can infer that.... |
| 14:20 | dnolen | bbloom: yeah I thinking you could tell this from env right, if so perhaps this is a simple fix. |
| 14:22 | bbloom | well env is statement, expression, return |
| 14:22 | bbloom | there isn't really top-level, since that is the same as statement |
| 14:23 | gtrak | I think it's because I'm not having proper bindings... grr..... |
| 14:25 | bbloom | dnolen: yeah, it's not sufficient to do only top level lets |
| 14:25 | bbloom | consider: |
| 14:25 | bbloom | (do 1 (let [y 2] (js/alert y)) 3) |
| 14:25 | bbloom | that exhibits the same issue |
| 14:28 | dnolen | bbloom: do doesn't introduce bindings so I'm not really concerned about that |
| 14:29 | bbloom | dnolen: no, the output of that is: |
| 14:29 | bbloom | var y = 2; alert(y); |
| 14:29 | dnolen | bbloom: oh right |
| 14:29 | bbloom | still happens |
| 14:29 | bbloom | :-/ |
| 14:29 | bbloom | dnolen: i think i can just change compile-file to wrap each top-level & it will be all good |
| 14:30 | dnolen | bbloom: sure give it a shot. |
| 14:36 | bbloom | dnolen: hmm interesting… compiler.clj and closure.clj both have a compile-file method… but it seems like the one in compiler.clj is unused |
| 14:37 | dnolen | bbloom: it used, closure.clj line 356 calls compile-file in compiler.clj |
| 14:37 | dnolen | bbloom: also line 398 |
| 14:37 | dnolen | comp/compile-file |
| 14:38 | bbloom | ah comp/compile-file yes.. but the later case is a reference to line 349 |
| 14:42 | bbloom | dnolen: ok, well this seems to work. let me cleanup & test a bunch of stuff & then i'll submit a patch |
| 14:46 | dnolen | bbloom: excellent |
| 14:47 | wingy | what is the equivalent of setTimeout in clojure? |
| 14:47 | bbloom | dnolen: eh, never mind. doesn't play nice with def & especially with advanced optimizations |
| 14:47 | wingy | (with-timeout) |
| 14:47 | wingy | or hmm |
| 14:48 | dnolen | bbloom: darn. in what way is problematic w/ def? |
| 14:49 | dnolen | wingy: ScheduledThreadExecutor I think |
| 14:49 | bbloom | well so you get globals by omitting the "var" keyword |
| 14:50 | wingy | dnolen: can i use Thread/sleep |
| 14:54 | dnolen | wingy: that's not really equivalent to setTimeout as that will block execution of your program unlike in JS |
| 14:54 | amalloy | of his current thread, anyway |
| 14:54 | bbloom | dnolen: ok, so the issue is that in advanced mode, top-levels of the form x.y.z = w will get intelligently converted to namespace export things, where x and x.y will be initialized to {} |
| 14:55 | bbloom | dnolen: but if you wrap the func around that, then it won't do it |
| 14:55 | dnolen | bbloom: right |
| 14:55 | bbloom | dnolen: not sure if there's a way around that |
| 14:57 | bbloom | goog.provide? |
| 14:57 | dnolen | bbloom: doubt it. I think we need to reify the notion of the top level in the AST, perhap a :scope field in env, it gets set to top |
| 14:57 | dnolen | bbloom: let will should modify the scope to be something other than :top |
| 14:57 | bbloom | dnolen: that won't help because you can have a def inside a let |
| 14:58 | bbloom | (let [x 1] (def y x)) |
| 14:58 | bbloom | if you wrap that in (function(){…})(); |
| 14:58 | bbloom | then def breaks |
| 15:00 | dnolen | bbloom: I think the approach on the ticket is ok minus the hacky dynamic var bit. just gensym top level lets in the compiler. |
| 15:00 | dnolen | bbloom: on the existing patch on the ticket. |
| 15:03 | dnolen | bbloom: there lots of annoying edge cases to consider here. "the top level is hopeless" to quote Felleisen |
| 15:04 | bbloom | dnolen: goog.provide is what we want :-P |
| 15:06 | dnolen | bbloom: ah so you're suggesting wrapping everything, and emitting a provide for each top level? :) |
| 15:06 | bbloom | yes |
| 15:06 | bbloom | trying that now |
| 15:06 | dnolen | bbloom: k |
| 15:07 | bbloom | dnolen: should also help with some dependency analysis stuff, since now goog closure will have publish export info for each def |
| 15:08 | wingy | is jetty creating a thread for each request? |
| 15:09 | dnolen | wingy: yes |
| 15:09 | bbloom | surely it has a thread pool… |
| 15:11 | dnolen | bbloom: right, wingy: using a thread per request |
| 15:13 | wingy | cool |
| 15:14 | wingy | soon you will see a good comparison between js/node.js/express and clojure/ring/compojure/hiccup |
| 15:15 | Sgeo | express? |
| 15:15 | tomoj | great |
| 15:16 | tomoj | I plan to argue that to my team shortly |
| 15:16 | Sgeo | :/ is that the thing my gf is raving about? |
| 15:16 | tomoj | except .. hiccup |
| 15:17 | bbloom | debugging advanced output is a pita. |
| 15:18 | dnolen | bbloom: yep |
| 15:27 | brainproxy | express is pretty nice, there's also restify and strata |
| 15:28 | tomoj | I haven't thought about it enough yet, but I expect the choice connect made about middleware causes trouble for express |
| 15:28 | brainproxy | they all work similarly but have different goals, if you will, and so offer different bells and whistles |
| 15:29 | tomoj | express 3.0 may have completely solved that trouble, but I doubt it |
| 15:29 | brainproxy | tomoj: can you elaborate? |
| 15:29 | brainproxy | in any case, I now vastly prefer ring/compojure/liberator |
| 15:30 | tomoj | a middleware in connect is like (fn [req res next]) |
| 15:30 | brainproxy | haven't had occasion yet to experiment w/ aleph |
| 15:30 | tomoj | where ring has (fn [next] (fn [req] res)) |
| 15:30 | tomoj | I suspect this causes composability issues |
| 15:31 | brainproxy | well, passing the res object along is pretty important given the async nature of things |
| 15:31 | tomoj | not to mention that you side-effect a response out instead of returning one |
| 15:31 | tomoj | that's just because they didn't solve the async problem |
| 15:32 | brainproxy | well given that js doesn't have threads, then unless you're going to introduce a control flow mechanism along with the router |
| 15:32 | brainproxy | then you're stuck w/ the "async problem" |
| 15:32 | brainproxy | although some folks don't see it as a "problem" per se |
| 15:32 | brainproxy | it's just the nature of the beast |
| 15:33 | tomoj | yeah, it could make sense to build something better over connect |
| 15:33 | brainproxy | i think the approach strata takes is to embrace the streams concept very deeply |
| 15:33 | tomoj | if you can return a response stream, great |
| 15:33 | brainproxy | so as you pass control through the handlers, you're working with streams |
| 15:34 | tomoj | or do you just write to the response stream they give you? |
| 15:35 | brainproxy | tomoj: not sure, haven't really gotten into it, just know some folks using it, heard them talk about it, have looked at the website from time to time |
| 15:35 | brainproxy | http://stratajs.org/manual |
| 15:38 | AntelopeSalad | what is the standard way to run jetty in production mode if any? |
| 15:38 | tomoj | looks nicer |
| 15:38 | tomoj | middleware has the right shape |
| 15:40 | tomoj | it looks weird because you create a Response out of nowhere and then response.send(callback), but that's pretty much sugar for passing the response to the callback, which is the low-level async equivalent of returning it |
| 15:43 | tomoj | http://news.ycombinator.com/item?id=3021564 "leaky abstraction" looks like a fully general counterargument |
| 15:43 | tomoj | ""leaky abstraction" looks like a fully general counterargument" looks like a fully general counterargument :( |
| 15:46 | brainproxy | it's been over a year since that HN piece, and the project is still actively dev'd |
| 15:47 | brainproxy | so I guess something's working out for the users of it |
| 15:51 | bbloom | dnolen: sorry, had to step out |
| 15:51 | bbloom | dnolen: unfortunately, i don't think my idea works either… b/c then you have conflicts between top level vars and namespace names. |
| 15:51 | bbloom | dnolen: consider namespace foo with symbol bar and namespace foo.bar with symbol baz |
| 15:53 | bbloom | this further solidifies my belief that, while cute, POJsO make poor namespaces |
| 15:56 | bbloom | hmm i guess the top-level vs namespace conflict already exists.... |
| 15:59 | dnolen | bbloom: yeah I don't see how that's a problem. |
| 16:04 | AntelopeSalad | is there a ring setting i need to enable so it handles etags properly? |
| 16:06 | tomoj | is there an entity binding syntax hidden in datomic already? something like :where [?p {:person/name ?name :person/age ?age}] |
| 16:06 | tomoj | I mean besides :where [?p :person/name ?name] [?p :person/age ?age] ofc |
| 16:08 | sritchie | does anyone here have experience with monadic parsing in clojure? |
| 16:08 | sritchie | I'm writing a parser using clojure.algo.monads and working off of the numerous recursive descent parser blog posts out there, |
| 16:09 | sritchie | but I haven't seen any project that pulls all of those combinators together into their own project |
| 16:10 | gensymv | hello, is there a particularly good way of defining pointfree functions in clojure? |
| 16:10 | gensymv | defining them with def seems a whole lot slower then explicitly naming the arguments |
| 16:14 | gensymv | see exhibit a https://www.refheap.com/paste/6185 |
| 16:15 | callen | gensymv: well you know what they say about points-free programming... |
| 16:15 | callen | gensymv: it's pointless. |
| 16:16 | gensymv | callen, that's really helpful. |
| 16:16 | callen | I was going for punny. |
| 16:16 | jasonjckn | sritchie: I don't, but have you tried asking for help within your near social network? |
| 16:16 | sritchie | jasonjckn: :) |
| 16:16 | dnolen | gensymv: there's very little support for that style in Clojure |
| 16:16 | sritchie | jasonjckn: I'll use your clarsec |
| 16:16 | jasonjckn | Sweet |
| 16:16 | sritchie | can we get it updated to use clojure.algo.monads? |
| 16:17 | bbloom | gensymv: that's function call overhead of less than 0.0003 msecs |
| 16:17 | jasonjckn | i wrote my own monad |
| 16:17 | bbloom | seems pretty reasonable to me |
| 16:17 | Sgeo | sritchie, clojure.algo.monads's maybe-m monad breaks the monad laws |
| 16:17 | callen | sritchie: you should write a parser for C++ |
| 16:17 | gensymv | bbloom, i see it as approx 30 times slower ^^ |
| 16:18 | sritchie | C++ to clojure, that'd be a nice weekend |
| 16:18 | callen | sritchie: my deeper point is that I'd be impressed if you simply wrote a passable C++ parser in using parser combinators. |
| 16:18 | callen | 'simply' |
| 16:18 | sritchie | jasonjckn: writing your own parser monad's cool, but defining it using clojure.algo.monads lets you use the existing domonad, m-lift, etc |
| 16:18 | sritchie | Sgeo: interesting |
| 16:19 | bbloom | gensymv: seems like premature optimization to me.... |
| 16:19 | dnolen | gensymv: you should look at the implementation of partial - it relies on rest args and apply, you're just not going to get super great perf out of partial. |
| 16:19 | jasonjckn | sritchie: I have those 2 ops |
| 16:19 | jasonjckn | sritchie: take it or leave it :) |
| 16:19 | jasonjckn | sritchie: an exercise to the reader is to port it yourself |
| 16:20 | gensymv | dnolen, so you essentially say that currying is not what clojure is built for. |
| 16:20 | bbloom | gensymv: no. you can do currying |
| 16:20 | sritchie | callen: I'm working on a far more junior-level project |
| 16:20 | bbloom | gensymv: what dnolen is saying is that partial supports variadic functions |
| 16:20 | sritchie | parsing the thrift IDL |
| 16:20 | gensymv | ah |
| 16:20 | callen | sritchie: parsing C++ is demi-junior. |
| 16:21 | bbloom | gensymv: which haskell doesn't…. which makes optimizing currying and partial application easier |
| 16:21 | gensymv | so the two functions aren't semantically equivalent |
| 16:21 | wingy | we have a guy here wanting to switch back to node.js because he says jetty can't cache correctly |
| 16:21 | bbloom | gensymv: right. you can implement curry without var args & you'll get better perf |
| 16:21 | wingy | is this correct? |
| 16:21 | callen | wingy: that doesn't make any sense at all. |
| 16:21 | callen | wingy: cache what? |
| 16:21 | gensymv | bbloom, thanks that is helpful. |
| 16:22 | jasonjckn | sritchie: one disadvantage algo.monad is you need to wrap everything in with-monad, makes it hard to C-xC-e your parsers with interactive development |
| 16:22 | sritchie | sure, that's true |
| 16:22 | callen | wingy: jetty is a web server. |
| 16:22 | Sgeo | sritchie, note protocol monads, a different implementation. Although it uses do as a macro name, which kind of sucks |
| 16:22 | dnolen | wingy: it's so sad that some of the thing they say about Node.js users is so true - http://www.youtube.com/watch?v=bzkRVzciAZg |
| 16:22 | jasonjckn | sritchie: also, because i'm using multi methods, you can derive monad's from other monads, although I haven't used that feature, limited value afaik. |
| 16:22 | marcellu` | how do I call extend-type for a type from a different namespace? |
| 16:22 | callen | dnolen: <3 |
| 16:23 | sritchie | Sgeo: interesting, thanks for the tip |
| 16:23 | Sgeo | yw |
| 16:23 | sritchie | https://github.com/jduey/protocol-monads |
| 16:23 | callen | sritchie: now go write a C++ parser |
| 16:23 | sritchie | will do, sensei |
| 16:23 | wingy | dnolen: im on your side |
| 16:29 | antares_ | marcellu`: the same way but you make it qualified, e.g. otherns/MyType and you may have to import it in some cases |
| 16:30 | tomoj | hmm, `:where [(fn-returning-integer ?x) [?int ...]]` gives "Don't know how to create ISeq from: java.lang.Integer" as expected, but `:where [(fn-returning-integer ?x) ?int]` gives "ArrayIndexOutOfBoundsException 2" |
| 16:30 | tomoj | oh |
| 16:30 | tomoj | whoops |
| 16:32 | antares_ | wingy: Jetty is an embeddable Web server. It almost certainly does not do caching automatically (not of its business) but you can set etags/last-modified in your app just like with anything else. |
| 16:32 | jasonjckn | sritchie: honestly, as cool as monadic parsers are, recursive decent parsers will never surpass LR/LL parsers afaik in performance |
| 16:32 | jasonjckn | sritchie: https://github.com/cgrand/parsley |
| 16:32 | sritchie | yeah, that lib is really cool |
| 16:32 | jasonjckn | sritchie: never used it, but that's probably the best clojure parser |
| 16:32 | wingy | AntelopeSalad: ^ |
| 16:32 | sritchie | for anything beyond thrift / learning experience, I'd go there |
| 16:32 | sritchie | maybe I'll do it in both |
| 16:35 | wingy | http://www.youtube.com/watch?v=bzkRVzciAZg good one :) |
| 16:39 | jasonjckn | sritchie: so you're trying to build a parser with algo.monads and you're not sure how? |
| 16:39 | sritchie | no, I'm doing fine |
| 16:40 | sritchie | it works, it's great, |
| 16:40 | sritchie | just wanted to know if someone else had built up these combinators in a lib I should use |
| 16:40 | jasonjckn | sritchie: never seen a lib that used algo.monads |
| 16:40 | jasonjckn | most people rolled their own |
| 16:40 | sritchie | midje |
| 16:40 | jasonjckn | for parsing? |
| 16:40 | sritchie | no |
| 16:41 | jasonjckn | ok I meant to add that qualifier |
| 16:41 | sritchie | I think you did parsing before algo.monads |
| 16:41 | sritchie | yeah |
| 16:41 | jasonjckn | yes |
| 16:41 | jasonjckn | exactly |
| 16:44 | mklappstuhl | I'm having trouble with namespaces here: https://github.com/mklappstuhl/computational-investing.clj |
| 16:44 | mklappstuhl | trying to load the core presents me this: |
| 16:44 | mklappstuhl | user=> (require 'mklappstuhl.stock-utils.core) |
| 16:44 | mklappstuhl | WARNING: extend already refers to: #'clojure.core/extend in namespace: mklappstuhl.stock-utils.util, being replaced by: #'clj-time.core/extend |
| 16:44 | mklappstuhl | CompilerException java.lang.IllegalArgumentException: Parameter declaration quote should be a vector, compiling:(mklappstuhl/stock_utils/metrics.clj:1) |
| 16:45 | jasonjckn | mklappstuhl: you don't nest defn's inside ns |
| 16:45 | jasonjckn | mklappstuhl: (ns foo) (defn …) etc |
| 16:47 | mklappstuhl | jasonjckn, I which file am I doing this? |
| 16:47 | jasonjckn | sritchie: some languages need to be tokenized in order to parse successfully. |
| 16:47 | antares_ | mklappstuhl: metrics.clj, see the exception? |
| 16:47 | jasonjckn | https://github.com/mklappstuhl/computational-investing.clj/blob/master/src/mklappstuhl/stock_utils/metrics.clj |
| 16:48 | mklappstuhl | jasonjckn, wtf o.O I have this file open in vim and it looks completely different ?! |
| 16:48 | jasonjckn | mklappstuhl: save it |
| 16:49 | mklappstuhl | jasonjckn, I just closed and reopened it and its still the correct version |
| 16:49 | jasonjckn | well push your changes to git |
| 16:49 | jasonjckn | master |
| 16:50 | mklappstuhl | jasonjckn, sure. I just did git add . and git commit 2 minutes ago...?! kind of confusing, haha |
| 16:51 | mklappstuhl | jasonjckn, pushed |
| 16:51 | jasonjckn | ok it's updated |
| 16:52 | jasonjckn | that file looks fine |
| 16:52 | jasonjckn | try recompiling |
| 16:52 | mklappstuhl | jasonjckn, seems to work now... |
| 16:53 | mklappstuhl | jasonjckn, sorry this probably made a wierd impression :D |
| 16:54 | jasonjckn | sounds like you had some old cached files, not sure |
| 16:56 | jasonjckn | sritchie: consider if ( true ) {}; if = 2; if your parser is (<|> assignment-statement-pfn if-statement) then you'll incorrectly accept 'if' as a variable name |
| 16:57 | jasonjckn | sritchie: unless your assignment-statement-pfn is defined to exclude the parsing of keywords. which if expressed through combinator parsers would be super slow |
| 16:58 | jasonjckn | the correct way to handle that is to tokenize first (with maximal munch) |
| 16:59 | jasonjckn | …so the assignment-statement-pfn will try to accept the token "symbol" and it'll encounter the token "if" |
| 16:59 | jasonjckn | and fail |
| 17:00 | Roxxi | Hey, if I want to make a new record that is sortable, is there a Protocol or interface I can have it implement so that (clojure.core/compare rec1 rec2) automatically works? |
| 17:00 | Roxxi | I suppose analgous to Comparable? |
| 17:01 | Roxxi | Or is it just java.lang.Comparable o.O |
| 17:04 | Roxxi | Looks like it is.. |
| 17:05 | bbloom | dnolen: see http://dev.clojure.org/jira/browse/CLJS-401?focusedCommentId=29830 |
| 17:06 | dnolen | bbloom: so we don't need goog.provide? |
| 17:07 | bbloom | dnolen: nope! the issue was that i needed to not wrap the top level ns form |
| 17:07 | dnolen | bbloom: excellent! this looks good! |
| 17:08 | dnolen | bbloom: thx much |
| 17:08 | bbloom | dnolen: my pleasure! but while you're thanking me, you can also merge the patch at http://dev.clojure.org/jira/browse/CLJS-408 :-) |
| 17:09 | Kneferilis | hello |
| 17:10 | dnolen | bbloom: will do will apply these in a little bit |
| 17:11 | bbloom | dnolen: one last one: a small cleanup i made while working on the top-levels patch: https://gist.github.com/3966254 |
| 17:11 | bbloom | dnolen: if you want that too :-) |
| 17:12 | dnolen | bbloom: sure ticket+patch I'll apply it as well. |
| 17:12 | bbloom | *sigh* so much overhead :-/ but ok |
| 17:13 | bbloom | can i sneak it in on the other ticket? heh |
| 17:13 | dnolen | bbloom: heh, nope |
| 17:15 | bbloom | http://dev.clojure.org/jira/browse/CLJS-409 |
| 17:15 | dnolen | bbloom: thx |
| 17:28 | mklappstuhl | I have this little project here and I'd like to run simulations on collections of stock symbols... I have a rough draft of how I could structure this in simulate.clj but I'm pretty sure there are other more clojure-esque ways to do this |
| 17:29 | mklappstuhl | so I'd love to have some input :) 'm just starting with clojure btw |
| 17:30 | gfredericks | is simulate.clj a library? or just a file of yours? |
| 17:30 | mklappstuhl | https://github.com/mklappstuhl/computational-investing.clj |
| 17:31 | mklappstuhl | gfredericks, forgot the link somehow ... ^ |
| 17:31 | gfredericks | righto |
| 17:32 | gfredericks | I'm more prone to comment on low-level things first |
| 17:32 | gfredericks | like your call to hash-map could be a map literal |
| 17:32 | gfredericks | e.g., (hash-map name trades) => {name trades} |
| 17:33 | gfredericks | hard to say much more about this without knowing how you're intending to use it |
| 17:33 | mklappstuhl | gfredericks, I know about the hash map thing... I just feel like its more readable |
| 17:34 | mklappstuhl | I'm happy about any input like this one too though |
| 17:34 | gfredericks | I almost never see clojure code like that; but it's a minor point, and even more minor if this code is just for yourself |
| 17:36 | mklappstuhl | gfredericks, I want to run simulations on historical data with fictional transactions at the beginning |
| 17:36 | mklappstuhl | kind of like: |
| 17:36 | mklappstuhl | 10MM of AAPL shares |
| 17:36 | mklappstuhl | 5MM of IBM shares |
| 17:37 | mklappstuhl | with a date when the stocks were bought and an end date for the simulation |
| 17:37 | mklappstuhl | gfredericks, good to know about the hash-map convention |
| 17:40 | gfredericks | so you're simulating the value of a fictional portfolio given actual historical prices? |
| 17:40 | mklappstuhl | gfredericks, yes |
| 18:00 | dnolen | bbloom: patches applied |
| 18:01 | bbloom | dnolen: cool, thx |
| 18:47 | Raynes | Hrm |
| 18:47 | thearthur_ | strange Incanter problem, |
| 18:47 | Raynes | I wonder how targeting nodejs and writing libraries in it works. |
| 18:47 | thearthur_ | yesterday incnater charts stopped displaying (i suspect they are displaying off screen) |
| 18:48 | gensymv | hello, in ubuntu 12.10 i installed the package clojure-contrib, but somehow cannot "use" it from clojure. i tried locating the libraries but had no lock with it. can anybody help me pls? |
| 18:48 | gensymv | *luck |
| 18:52 | bbloom | Raynes: you mean for cljs? it should work reasonably well, but won't really play super nice with the module system |
| 18:53 | Raynes | bbloom: I'm talking about how one would write a library in cljs they could distribute with npm and use in other nodejs-targeting cljs apps. |
| 18:53 | Raynes | The whole namespace system for regular clojurescript makes no sense to me at all though. |
| 18:53 | Raynes | So I don't really even understand how you'd do that there either. |
| 18:54 | bbloom | Raynes: well clojurescript piggybacks on Google Closure's module system. if you wanted to target node's module system, you could just refer to js/window.exports to bypass the symbol munging in both cljs and google closure |
| 18:54 | Raynes | That easy, eh? |
| 18:54 | Raynes | ;) |
| 18:55 | bbloom | Raynes: heh, yeah it is. just use bin/cljsc in the clojurescript source tree. when used with advanced compilations, it will compile your entire app to a single .js file |
| 18:56 | Raynes | How does that help with library distribution? |
| 18:56 | bbloom | Raynes: in that file, you can do something like (set! js/window.exports somesym somesym) to export functions to the node ecosystem |
| 18:56 | bbloom | just check in the .js output :-) |
| 18:56 | bbloom | i think package.json can run your build script pre-publish too |
| 18:57 | Raynes | That's kinda convoluted though, isn't it? And it also includes all of Clojure as well. |
| 18:57 | bbloom | in theory, it should only include the bits of clojure that you depend on |
| 18:57 | bbloom | but we've got still some shortcomings for dead code removal |
| 18:57 | bbloom | you just make sure the functions that you expose take plain javascript objects |
| 18:57 | dnolen | Raynes: someone could easily provide CLJS w/ simple optimizations + :static-fns as an npm module, and |
| 18:57 | bbloom | similar to how you'd stick a C interface on a C++ library |
| 18:58 | bbloom | js/window.exports -> js/module.exports |
| 18:58 | dnolen | Raynes: then CLJS compiler would need a option to compile w/o core so you can provide your own libs w/ core as a npm dep |
| 18:58 | bbloom | sorry, been a while since i did some node.js |
| 18:58 | dnolen | bbloom: dead code elimination matters a whole lot less for node.js |
| 18:59 | bbloom | dnolen: i know, but Raynes said "it also includes all of Clojure as well" :-) |
| 18:59 | dnolen | bbloom: non-issue in my mind. |
| 18:59 | bbloom | agreed |
| 18:59 | dnolen | 20,000 lines of JS is nothing to v8 |
| 19:00 | Raynes | But wouldn't there be issues with duplicated functions, or clashes, or something? |
| 19:00 | dnolen | given that tools like emscripten generation hundreds of thousands of lines of JS and the modern engines handle it well |
| 19:00 | dnolen | who cares on the server |
| 19:00 | Raynes | It wasn't size I was worried about. |
| 19:00 | bbloom | Raynes: node's module system should protect you there |
| 19:00 | dnolen | Raynes: I mentioned ^ that you would need a way to compile your own lib w/o core. |
| 19:01 | dnolen | Raynes: we could add that feature to the compiler. |
| 19:01 | Raynes | But didn't you just say that it didn't matter? :( |
| 19:01 | dnolen | Raynes: I said dead code elimination didn't matter. |
| 19:01 | dnolen | different thing altogether |
| 19:01 | dnolen | advanced compilation is not relevant for server side JS |
| 19:01 | bbloom | heh, i think it doesn't matter… doesn't node's module system prevent globals without explicit references to `global`? |
| 19:02 | bbloom | dnolen: i mention using advanced compilation so that you can get a single js output w/o needing to muck with the stitching logic of that top level output js file… but there may be some other easy way to get a build step to concatenate those |
| 19:02 | dnolen | bbloom: yeah but I'd still be concerned w/ confusing v8 and deoptimization if multiple versions of cljs.core are getting loaded. |
| 19:03 | bbloom | dnolen: ah, good point. i forget that we muck w/ prototypes |
| 19:06 | bbloom | dnolen: in general, there is some ugliness in the compiler around the module system |
| 19:06 | bbloom | it might be nice to provide something like a namespace compilation protocol, to support pluggable module systems |
| 19:06 | bbloom | would be nice to decouple us from the closure compiler, even tho it's super useful now |
| 19:07 | dnolen | bbloom: yes Node.js case in point |
| 19:08 | bbloom | dnolen: yup :-) also worth discussing at some point is the namespaces atom |
| 19:08 | dnolen | bbloom: though the Node.js module model simply sucks in a massive way. |
| 19:08 | dnolen | the whole wrapping all libs in function making everything opaque is total shit. |
| 19:08 | bbloom | dnolen: yeah, common.js is the simplest possible realization of the brain dead objects == maps == namespaces world view |
| 19:09 | bbloom | dnolen: it's particularly great for thwarting interactive development. you want to "use" some symbol, so you do `var foo = pkg.foo` and then you later want to redefine pkg.foo, but that doesn't impact `var foo`! |
| 19:10 | bbloom | argh. |
| 19:10 | bbloom | python suffers from a similar issue |
| 19:10 | dnolen | bbloom: so it makes adopting the Node.js model in the compiler less compelling, but it means sharing libs w/ Node.js and vice versa kinda lame as it is today. |
| 19:11 | bbloom | either way, protocol-izing the module system would help us better understand the requirements |
| 19:11 | dnolen | though to be honest I just don't see Node.js folks using CLJS libs, the style of programming is just incredibly different. |
| 19:12 | bbloom | tangentially related: i'd also like to purify that ana/namespaces atom ;) |
| 19:12 | dnolen | bbloom: sure what do you have in mind? |
| 19:12 | bbloom | oh heh, i already said that… |
| 19:12 | bbloom | didn't mean to repeat myself :-) |
| 19:13 | bbloom | some kind of "compilation unit" AST node |
| 19:13 | dnolen | bbloom: ? in ana/namespaces ? |
| 19:13 | bbloom | no, instead of that atom |
| 19:14 | dnolen | bbloom: what for? |
| 19:14 | bbloom | i haven't fully thought it out, but i ran into some minor annoyances while debugging my CPS transform b/c that atom was stateful |
| 19:15 | bbloom | or at least b/c it is bound at the top-level, rather than within the scope of a compilation unit |
| 19:15 | dnolen | bbloom: this will require considerable thought since the utility of having it around for reflection is quite significant |
| 19:16 | bbloom | dnolen: yeah, it's just a gut reaction to "ugh, that thing annoys me".. i wonder if it could be made unbound and :dynamic, and then there could be a with-world type macro |
| 19:17 | bbloom | dnolen: definitely needs more thought. I'm just gonna let the thought bake for a while |
| 19:17 | dnolen | bbloom: it's worth investigating, would allow lein-cljsbuild to get parallel builds back too. |
| 19:17 | bbloom | mmm parallel builds :-) |
| 19:18 | bbloom | oh, that brings up one other thought |
| 19:19 | bbloom | AST transformations seem to be inherently discrete. by that i mean you have to complete transform A before you can do transform B. if you wanted parallelize, you could only really do it by compilation unit |
| 19:19 | bbloom | i wonder if top-levels could be processed lazily… such that you could have A run on form 0, then while A is running on form 1, B is running on form 0 |
| 19:19 | bbloom | dnolen: does that make any sense? |
| 19:20 | bbloom | (assuming you have two cores) |
| 19:20 | bbloom | i think i answered my own question: yes :-P |
| 19:21 | bbloom | except that the top level ana/namespaces prevents it... |
| 19:21 | dnolen | bbloom: heh lein-cljsbuild parallel-build was just a way to build multiple version of the script at the same time |
| 19:21 | dnolen | bbloom: you're thinking about something more ambitious |
| 19:22 | dnolen | bbloom: having the compiler be able to compile different files in parallel would probably be the source of the most win w/o adding too much complexity. |
| 19:22 | frawr | Having some unexcpected behavior with lein run here. When I change something in the code and do lein run again, i get weird errors. I have to call lein clean first everytime. |
| 19:22 | bbloom | dnolen: yup |
| 19:23 | amalloy | frawr: aot compilation makes things complicated. don't do it unless you absolutely have to |
| 19:23 | frawr | So clear the aot list? |
| 19:23 | frawr | And when would I have to? |
| 19:24 | frozenlock | Is there a function like clojure.contrib.string/take available? |
| 19:24 | amalloy | mainly when you want to expose a named class to a java program, or if you need really complicated gen-class stuff |
| 19:24 | amalloy | &(doc subs) |
| 19:24 | lazybot | ⇒ "([s start] [s start end]); Returns the substring of s beginning at start inclusive, and ending at end (defaults to length of string), exclusive." |
| 19:24 | frozenlock | Excellent, thanks! |
| 19:25 | amalloy | frawr: yes, clear :aot, and adjust your main entry -- :main ^:skip-aot myapp.main |
| 19:27 | frawr | thnx |
| 19:28 | frawr | the errors are normal ones now, thnx. speeds up the proccess a whole lot. |
| 19:29 | biscarch | How do I access a Java property? Equiv code in Java would be Environment.SANDBOX |
| 19:30 | bbloom | Environment/SANDBOX |
| 19:30 | biscarch | ::facepalm:: thanks |
| 19:30 | hyPiRion | ,(Integer/MAX_VALUE) |
| 19:31 | hyPiRion | &(Integer/MAX_VALUE) |
| 19:31 | lazybot | ⇒ 2147483647 |
| 19:31 | hyPiRion | &Integer/MAX_VALUE |
| 19:31 | lazybot | ⇒ 2147483647 |
| 19:33 | bbloom | dnolen: so let me know how i can help with distributions stuff in core.logic. I'd really love to general purpose minimization technique for prototyping a bunch of ideas i have :-) |
| 19:34 | bbloom | dnolen: i may ultimately need special purpose solvers, but general minimization would go a long way during the design phase |
| 19:47 | dnolen | bbloom: there's a key fn called map sum which tries each value of vars domain |
| 19:48 | dnolen | bbloom: a bunch of strategies could be added there, including possibly a custom cost function which knows how vars are entailed and which order to try which values. |
| 19:49 | dnolen | bbloom: currently it completely naive and just tries them in order and doesn't consider relationships between vars |
| 19:49 | dnolen | gotta run |
| 19:49 | bbloom | k, i'll need to study it more. probably won't get to it for a while. |
| 19:49 | bbloom | cya |
| 20:05 | callen | I still say Clojure needs a mascot like go. |
| 20:05 | callen | Clojure...Clown Fish? |
| 20:06 | Iceland_jack | That sounds horrifying.. |
| 20:09 | hyPiRion | http://www.flickr.com/photos/lndr/2648570113/ |
| 20:09 | hyPiRion | It's not the blue/green colour scheme though |
| 20:15 | wingy | is it possible to use something like (str) but strip all whitespace? |
| 20:15 | wingy | since i am using (str) in my code and the test and they are not the same since they contain different indentation whitespaces |
| 20:16 | wingy | due to their positioning in the source file |
| 20:16 | callen | hyPiRion: I'm sure that with some food dye, anything can be arranged. |
| 20:16 | wingy | but if i strip all whitespaces then they will be equal |
| 20:19 | Somelauw | ,(clojure.string.replace "white spaced" #"\s+" "") |
| 20:19 | Somelauw | &(clojure.string.replace "white spaced" #"\s+" "") |
| 20:19 | lazybot | java.lang.ClassNotFoundException: clojure.string.replace |
| 20:19 | Somelauw | &(clojure.string/replace "white spaced" #"\s+" "") |
| 20:19 | lazybot | ⇒ "whitespaced" |
| 20:20 | wingy | &(clojure.string/replace "white spaced yes <input \>" #"\s+" "") |
| 20:20 | lazybot | java.lang.RuntimeException: Unsupported escape character: \> |
| 20:21 | wingy | &(clojure.string/replace "<input \><a>some link</a>" #"\s+" "") |
| 20:21 | lazybot | java.lang.RuntimeException: Unsupported escape character: \> |
| 20:22 | wingy | doesn't seem to be a good idea .. ill just stick with having the multi line string starting without indentation |
| 20:30 | wingy | i start to love xml :/ |
| 20:32 | callen | wingy: YOU TAKE THAT BACK RIGHT NOW |
| 20:34 | wingy | *swallowing* |
| 20:36 | hyPiRion | callen: colorizing the image is easier ;) |
| 20:45 | Somelauw | wingy: xml stands for everything that is wrong with this world :P |
| 20:45 | wingy | xml is more powerful than json! |
| 20:46 | Somelauw | More powerful? Both can represent the same datastructures? |
| 20:46 | wingy | and we are quite used to it through html |
| 20:46 | wingy | html as json would be messy |
| 20:48 | Somelauw | Maybe I should make a tool that can convert back and forth between s-expressions and html. |
| 20:49 | Somelauw | xml is the reason i hate maven and ant |
| 20:50 | Somelauw | I think cmake is much more readable than ant |
| 21:12 | akhudek | Tried eclipse for a day, and though I like CC, eclipse is just so slow compared to IntelliJ. |
| 21:21 | hyPiRion | Oh, sweet |
| 21:22 | hyPiRion | DST is off here in Norway, so I can hack for one more hour |
| 21:22 | hyPiRion | turned off, or what you call it. |
| 21:27 | akhudek | hyPiRion: isn't it mostly dark in Norway this time of year? |
| 21:30 | hyPiRion | akhudek: It's "okay" right now - the sun shines from 8 am to 5 pm. |
| 21:31 | akhudek | oh that's not too bad |
| 21:32 | hyPiRion | It's worse in December, then the sun rises 10 am, and it's pitch black around 2:30 pm |
| 21:33 | akhudek | wow! I visited Bergen once, but it was fortunately during the summer. Very nice then! |
| 21:34 | hyPiRion | heh :) Norway is a good place to live/be at summer, I think |
| 21:35 | hyPiRion | Though I suppose people living at hotter places may disagree |
| 21:36 | akhudek | I'm in Canada, but in the southern parts. In december it's dark by 5, but that's the worst that it gets |
| 21:39 | hyPiRion | It's not easy, livin' in these countries far north. |
| 21:46 | biscarch | has anyone used the java Braintree library? or can point me to a recent example for using third party java libs? |
| 21:49 | akhudek | biscarch: http://clojure-doc.org/articles/language/interop.html |
| 21:50 | biscarch | akhudek: haven't seen that yet. Thanks. |
| 21:50 | akhudek | biscarch: the only other trick is getting the library jars into the classpath |
| 21:51 | akhudek | if it's in maven, you can just get lein to pull them in like [groupid/artifactid "version"] |
| 21:52 | biscarch | akhudek: I set it up a :java-source-path in leiningen. I 'll check to see if the lib is in maven though |
| 21:57 | akhudek | biscarch: as long as the jars in get into the classpath you'll be fine. I just find setting things up via lein deps to be the most convenient |
| 22:06 | Sgeo | Someone should write a Leiningen installer for Windows |
| 22:07 | xeqi | Sgeo: do you mean something beyond the lein.bat ? |
| 22:08 | Sgeo | xeqi, putting wget or curl on the path, and putting lein.bat somewhere on the path |
| 22:10 | AntelopeSalad | would it be a good idea to use require instead of use 99% of the time? |
| 22:10 | xeqi | AntelopeSalad: yes |
| 22:10 | xeqi | Sgeo: ah, right. I forgot about that prereq |
| 22:10 | akhudek | AntelopeSalad: also, when using use, it's good practise to use :only |
| 22:11 | akhudek | helps to know what the specific dependencies are |
| 22:11 | AntelopeSalad | akhudek: yeah, that seemed to be a common trend in some examples i've seen |
| 22:11 | Sgeo | xeqi, also, I didn't use emacs-starter-kit much, but I think there's more to getting emacs set up for Clojure than it. Clojure-mode too, I think? |
| 22:12 | AntelopeSalad | i need to get used to searching for different terms |
| 22:12 | AntelopeSalad | every time i google for ring, it assumes i'm going to type ring worms |
| 22:13 | akhudek | prefixing with clojure always seems to work for me |
| 22:13 | xeqi | clojure-mode, clojure-test-mode, nrepl-mode, paredit-mode |
| 22:13 | AntelopeSalad | yeah or put github in there somewhere, i find myself looking at the api docs pretty often |
| 22:14 | AntelopeSalad | for some reason i can't get wrap-file-info working properly though |
| 22:15 | AntelopeSalad | it never reports back what the docs say |
| 22:17 | akhudek | AntelopeSalad: if you are using it in conjunction with wrap-file, make sure that wrap-file comes first |
| 22:18 | AntelopeSalad | yep, i am |
| 22:18 | AntelopeSalad | i followed this to a T https://github.com/ring-clojure/ring/wiki/Static-Resources |
| 22:19 | AntelopeSalad | the api docs say it should give me the content-type and last-modified but it doesn't seem to |
| 22:19 | akhudek | I take it you've restarted your jetty server since adding it? |
| 22:19 | AntelopeSalad | yep, it just omits reporting back those header fields every time |
| 22:20 | AntelopeSalad | i'm not sure of the idiomatic way to handle responses yet (this is basically day #1 of coding with clojure for me) |
| 22:20 | AntelopeSalad | i've been using ring responses with the default keynames, i figured the middleware would change the response as necessary |
| 22:23 | akhudek | I don't have any more guesses for you, but I've found it helpful to dump the actual responses or requests at various points to figure out what is going on. |
| 22:23 | akhudek | you can use something like this: https://www.refheap.com/paste/6188 |
| 22:23 | akhudek | oops, I had a bug |
| 22:24 | akhudek | it's fixed now |
| 22:24 | AntelopeSalad | i wouldn't have to manually setup the keyname for content-type and last-modified right? |
| 22:24 | akhudek | no |
| 22:24 | AntelopeSalad | example: https://github.com/ring-clojure/ring/wiki/Creating-responses |
| 22:25 | AntelopeSalad | i've been using the -output- directly as my response |
| 22:25 | AntelopeSalad | except i didn't include the headers |
| 22:25 | akhudek | if you look at the code https://github.com/mmcgrana/ring/blob/master/ring-core/src/ring/middleware/file_info.clj |
| 22:26 | AntelopeSalad | the only thing i really changed from the guide is i transformed those uses into requires |
| 22:26 | akhudek | the only way I can see that it wouldn't add the right keys is if the body is not a File object |
| 22:26 | AntelopeSalad | but i guess it would have crashed if i did something wrong |
| 22:26 | AntelopeSalad | all the other middleware works following the same require pattern |
| 22:26 | Sgeo | Is the Joy of Clojure not available on Nook? |
| 22:26 | AntelopeSalad | hmm, the body in all cases so far has been either a string or a function to a hiccup function |
| 22:27 | akhudek | are the strings path names or something? |
| 22:27 | AntelopeSalad | nope, just random output |
| 22:28 | AntelopeSalad | i built up some examples without using templating, and then added templating after |
| 22:28 | AntelopeSalad | :body "foo" , etc. stuff like that |
| 22:28 | akhudek | Oh. Then I'm confused why you are using file-info |
| 22:28 | akhudek | it's for augmenting file responses, not html responses |
| 22:28 | AntelopeSalad | that could do it haha |
| 22:29 | AntelopeSalad | so far i've only been passing around hiccup functions to the response body |
| 22:29 | AntelopeSalad | i wasn't sure how else to do it (could probably figure it out with google) |
| 22:29 | AntelopeSalad | i had a layout clj file setup with a namespace, and then imported into my main app file, etc. |
| 22:30 | AntelopeSalad | how would i let ring know to keep track of last-modified for non-file responses? |
| 22:31 | akhudek | what would the last-modified time of a generated file be? |
| 22:31 | akhudek | or do you mean the last modified time of the template? |
| 22:32 | AntelopeSalad | i'm honestly not sure, i only bring this up because another language puts an etag in the header for all responses |
| 22:32 | AntelopeSalad | and i was trying to get that to happen with ring too |
| 22:32 | AntelopeSalad | this way it can return 200 or 304, etc. |
| 22:33 | akhudek | well, in general, for all languages, you can only return a last modified time for static content |
| 22:33 | AntelopeSalad | this was an etag in specific, not last-modified |
| 22:33 | akhudek | or effectively static content like a compiled template |
| 22:33 | AntelopeSalad | not sure of the value, it looked like a negative unix time maybe |
| 22:33 | AntelopeSalad | i think it does compile templates for you |
| 22:34 | AntelopeSalad | is there a way to tell ring or hiccup to compile/cach templates automatically? |
| 22:34 | AntelopeSalad | *cache |
| 22:35 | akhudek | not that I know of |
| 22:35 | akhudek | though that doesn't mean such a thing doesn't exist |
| 22:35 | akhudek | I suppose you want some form have middleware that tracks if a response has changed since the last call |
| 22:36 | AntelopeSalad | so this would certainly lie on the shoulders of ring/ring's middleware not the template language? |
| 22:36 | Sgeo | "Purchase includes free PDF, ePub, and Kindle eBooks downloadable at manning.com." |
| 22:36 | Sgeo | How do I get those? |
| 22:37 | akhudek | AntelopeSalad: it could be handled by either, though probably doens't happen currently |
| 22:38 | akhudek | AntelopeSalad: a quick search turns up http://akoestler.blogspot.ca/2011/11/selective-browser-caching-with-etags-in.html\ |
| 22:38 | akhudek | then just change the etag every time you change your code |
| 22:38 | akhudek | if you are doing hiccup style outputs |
| 22:38 | AntelopeSalad | checking |
| 22:40 | AntelopeSalad | what's that crazy +global-etag+ syntax mean? |
| 22:40 | akhudek | nothing |
| 22:40 | AntelopeSalad | i know + is ok to have as a variable name, but does it have context? |
| 22:40 | akhudek | author just likes plus signs I think |
| 22:41 | Sgeo | In Common Lisp, it's stylistic to have constants named with + on each side, I think |
| 22:41 | akhudek | it's not idiomatic to signify globals that way though |
| 22:41 | AntelopeSalad | ah, he does mention his def is a constant (but should be changed later) |
| 22:42 | AntelopeSalad | thanks btw, this article seems pretty good -- i wonder why this isn't default functionality in ring, or at least a highly offically unofficial third party middleware |
| 22:43 | akhudek | probably a combination of nobody looking into it enough to write something, and also that the problem isn't actually trivial to solve in a very generic way |
| 22:43 | akhudek | I mean, that solution requires you manually version your app, and make sure you don't apply the tag to dynamic responses. |
| 22:45 | AntelopeSalad | it seems to be solved in other libs |
| 22:46 | AntelopeSalad | i couldn't say if the solution is ideal/perfect but i haven't seen anyone complain yet |
| 22:53 | akhudek | AntelopeSalad: give me a bit and I will give a shot at a middleware |
| 22:53 | AntelopeSalad | if you know javascript i can point you to a very good lib which handles auto-etags |
| 22:53 | AntelopeSalad | the code doesn't seem too hairy, might be able to get it even without js knowledge |
| 22:57 | AntelopeSalad | seems to be a 3 step problem: 1) a fn to generate the etag, 2) a value to store whether or not the request is fresh or not, 3) a fn to set fresh's value and the etag as well as trim out irrelevant headers when it's stale (content-type+length) |
| 22:58 | callen | hyPiRion: I prefer food dye. |
| 23:02 | hyPiRion | callen: Well, each to their own, I suppose. |
| 23:08 | Sgeo | What function does ` use to namespace a symbol? |
| 23:10 | Sgeo | ,(let [foo 'bar] ``~foo) |
| 23:10 | Sgeo | .. |
| 23:10 | Sgeo | &(let [foo 'bar] ``~foo) |
| 23:10 | lazybot | ⇒ clojure.core/foo |
| 23:10 | Sgeo | &(let [foo 'bar] `~foo) |
| 23:10 | lazybot | ⇒ bar |
| 23:13 | ambrosebs | Sgeo: hard to tell exactly where this is done. |
| 23:16 | ambrosebs | Sgeo: do you just want the semantics, or literally where the code is? |
| 23:17 | Sgeo | The semantics, although literally where the code is would be interesting |
| 23:17 | ambrosebs | Sgeo: clojure.lang.LispReader$SyntaxQuoteReader/syntaxQuote I think |
| 23:17 | ambrosebs | in clojure/lang/LispReader.java |
| 23:19 | Sgeo | Why is that else way out there on L802? |
| 23:19 | ambrosebs | I think syntax quote just tries to resolve the symbol, and if it doesn't resolve to a var, just qualify it in the current namespace. |
| 23:19 | Sgeo | &`~@[1 2] |
| 23:19 | lazybot | java.lang.IllegalStateException: splice not in list |
| 23:19 | ambrosebs | Sgeo: Rich works in mysterious ways in Java :) |
| 23:19 | ambrosebs | Sgeo: I assume it's Rich |
| 23:20 | ambrosebs | I've never seen Java quite like the Clojure compiler. |
| 23:20 | ambrosebs | But I don't read much Java. |
| 23:20 | arosequist | I'm trying to learn core.logic fds. (+fd x y 5) works for x + y = 5, but what if I want x - y = 5? Is there a way to negate a domain? |
| 23:21 | arosequist | (that might be a really dumb question...brand new to core.logic in general) |
| 23:21 | hyPiRion | arosequist: x - y = 5 <==> x = 5 + y, ain't it? |
| 23:21 | hyPiRion | I don't know if it works for +fd though. |
| 23:21 | hyPiRion | (Not used core.logic, shoot me for that :( ) |
| 23:22 | arosequist | hyPiRion: Ah, it works perfectly. Of course. Thanks. |
| 23:26 | akhudek | AntelopeSalad: you can try this https://www.refheap.com/paste/6189 |
| 23:27 | akhudek | there is probably a better way to implement it, but it seemed to do the right thing in light testing |
| 23:27 | AntelopeSalad | ok |
| 23:27 | AntelopeSalad | i will experiment with it tomorrow, using it should be straight forward right? |
| 23:27 | AntelopeSalad | just throw this into my app.clj file and then put it into the middleware stack? |
| 23:27 | akhudek | also expect a performance hit to the server, though I don't know how much. Computing hash values certainly takes time |
| 23:28 | akhudek | yep |
| 23:28 | AntelopeSalad | just so i'm 100% clear on this for later |
| 23:28 | AntelopeSalad | https://github.com/ring-clojure/ring/wiki/Static-Resources |
| 23:29 | AntelopeSalad | all i would have to do is replace: wrap-file-info with wrap-etag , right? |
| 23:29 | akhudek | right |
| 23:29 | akhudek | it computes the etag only on the body |
| 23:29 | akhudek | so as long as the body is set |
| 23:29 | akhudek | it should work |
| 23:29 | AntelopeSalad | i wonder how bad the performance hit would be |
| 23:29 | akhudek | no clue |
| 23:30 | AntelopeSalad | in the end it should save time i would think |
| 23:30 | akhudek | well, for the client, not for the servers cpu |
| 23:30 | xeqi | I would expect it to save bandwidth, not really cpu time |
| 23:30 | AntelopeSalad | if it doesn't have to recompile a template and serve it, that's a pretty big win |
| 23:31 | akhudek | responses will still be generated |
| 23:31 | akhudek | it only saves bandwidth |
| 23:31 | AntelopeSalad | yeah but as a slimmed down 304 right? |
| 23:31 | akhudek | nope, full responses are generated using this |
| 23:31 | akhudek | for static files you can do much better |
| 23:32 | AntelopeSalad | hmm |
| 23:32 | AntelopeSalad | why couldn't we set the body to empty on 304? |
| 23:32 | akhudek | so for performance, you'd want to use this only on non-static but rarely changing responses |
| 23:32 | AntelopeSalad | then send an empty body |
| 23:32 | akhudek | I think it does work that way |
| 23:32 | akhudek | so you do save bandwidth |
| 23:33 | akhudek | and your site will appear faster to clients |
| 23:33 | AntelopeSalad | so it is working in the way that is sends an empty body on 304s? |
| 23:34 | AntelopeSalad | or would that doing something to "res" and then just wiping the body before returning it? |
| 23:34 | AntelopeSalad | *require doing |
| 23:35 | akhudek | when I tried it with curl, curl didn't download the body when setting the if-none-match |
| 23:35 | akhudek | not sure if that is just curl doing that, or jetty doing it |
| 23:35 | AntelopeSalad | did you curl it with verbose mode? |
| 23:35 | akhudek | yup |
| 23:36 | AntelopeSalad | would it be a good idea to remove the content-type and length for 304s too? |
| 23:36 | akhudek | if you want, you can also modify the handler to additionally clear the :body |
| 23:36 | akhudek | not, sure, I didn't read the specs that closely |
| 23:36 | akhudek | also easy changes to make :) |
| 23:36 | AntelopeSalad | i ask because of this: https://github.com/visionmedia/express/blob/master/lib/response.js#L129 |
| 23:37 | AntelopeSalad | he strips out those 2 headers and clears the body on 204/304 |
| 23:39 | AntelopeSalad | we could probably use crc instead of hash too to eliminate some calculations? |
| 23:40 | akhudek | looks like ring does have etag support https://github.com/ring-clojure/ring/blob/master/ring-core/src/ring/middleware/not_modified.clj |
| 23:40 | akhudek | oops, should have checked first |
| 23:41 | akhudek | that still won't add etags to dynamic responses though |
| 23:41 | AntelopeSalad | but it had nothing to write the etag |
| 23:41 | AntelopeSalad | yeah |
| 23:42 | AntelopeSalad | your middleware handles both right? |
| 23:42 | AntelopeSalad | it clearly writes an etag and sends a 304 when it needs to |
| 23:43 | akhudek | yes, but it might be better to use this https://www.refheap.com/paste/6190 |
| 23:43 | akhudek | and then not-modified on top |
| 23:43 | AntelopeSalad | on top as in, 1 function before this one in the middleware stack? |
| 23:43 | akhudek | Ideally you'd only use wrap-etag on non-static routes, since static files will have last-modified times. |
| 23:44 | akhudek | not-modified must come after wrap-etag |
| 23:44 | AntelopeSalad | ok, might as well use that then for sure? |
| 23:45 | AntelopeSalad | the smaller wrap-etag + built in last-modified |
| 23:45 | akhudek | right, use this version as it fixes a capitalization issue: https://www.refheap.com/paste/6191 |
| 23:46 | AntelopeSalad | the built in one looks like it's doing so much more than your first version |
| 23:46 | akhudek | yeah, it checks last modified time too |
| 23:46 | AntelopeSalad | i guess that's necessary? |
| 23:47 | akhudek | no, but it's optimal for static resources |
| 23:47 | akhudek | you don't really want to be computing hash values on big files like images for example |
| 23:47 | AntelopeSalad | so we would want last-modified to run on all requests |
| 23:47 | AntelopeSalad | and wrap-etag on just non-static requests? |
| 23:48 | akhudek | right, you want file-info on static requests, and wrap-etag on other requests |
| 23:48 | AntelopeSalad | that will involve editing wrap-etag in some way to skip doing its thing? |
| 23:49 | akhudek | no, you can just group your dynamic routes and add wrap-etag only to that group |
| 23:49 | akhudek | check out compojure's defroutes |
| 23:49 | AntelopeSalad | i'm not really sure to "fork" 2 middlewares based on a condition |
| 23:49 | AntelopeSalad | *how to |
| 23:50 | AntelopeSalad | hmm that seems weird |
| 23:51 | AntelopeSalad | when i look at defroutes, i think it's to be used to associate a group of routes to a sub-route |
| 23:51 | AntelopeSalad | like /user/foo , /user/bar |
| 23:52 | akhudek | it can group any handlers |
| 23:52 | AntelopeSalad | what happens if you have a bunch of dynamic routes with no pattern |
| 23:52 | akhudek | e.g. https://www.refheap.com/paste/6192 |
| 23:53 | AntelopeSalad | like /foo and /bar might be dynamic but aren't related |
| 23:53 | akhudek | they are checked in order until the first non-nil response |
| 23:53 | AntelopeSalad | oh wow |
| 23:53 | akhudek | I think there are tutorials around for that too. I personally quite like compojure for url routing |
| 23:53 | AntelopeSalad | the way you have this is nothing like what the docs say |
| 23:54 | AntelopeSalad | this seems like arbitrary grouping (a very good thing) |
| 23:54 | AntelopeSalad | https://github.com/weavejester/compojure/wiki/Nesting-routes |
| 23:54 | AntelopeSalad | how the heck are we supposed to know what you just did when we read that lol? |
| 23:55 | akhudek | that page is talking about the context macro |
| 23:55 | akhudek | there are better docs and tutorials around for compojure though |
| 23:55 | akhudek | if you dig |
| 23:55 | AntelopeSalad | yeah, that'll be tomorrow's project -- thanks for pointing me in the right direction |
| 23:55 | AntelopeSalad | i think this is a very good start to have a reasonable solution |
| 23:56 | akhudek | your welcome, the clojure web libraries take a while to learn, but they are pretty great once you know them |
| 23:56 | AntelopeSalad | btw what's your opinion on using a crc lib instead of hashing to save some cpu time, or do you think it's not even relevant? |
| 23:56 | akhudek | crc is a form of hashing |
| 23:57 | AntelopeSalad | brief googling (stackoverflow) seems to say it's less cpu intensive |
| 23:57 | akhudek | there may be more performant hash routines than clojures built in function though |