2013-04-22
| 00:19 | amalloy | xeqi: (for [[k v] m1 :when (< v (m2 k))] k) |
| 01:12 | mthvedt | is there a fn that does what ` does for symbols, and doesn't fail on undefined symbols? |
| 01:13 | Raynes | That's impossible without it either being a macro or your symbols being quoted before passed in. |
| 01:19 | mthvedt | raynes: why is it impossible? |
| 01:20 | Raynes | Because you'd be passing the symbols as an argument to the function and they'd get resolved before being passed and throw an exception. The function has no control over that. |
| 01:21 | mthvedt | ? using symbols as values isn't particularly exotic |
| 01:22 | mthvedt | most ns related fns take symbol values |
| 01:23 | Raynes | Yes, quoted symbol values. |
| 01:23 | Raynes | I'm just telling you that you can't pass undefined symbols to a function unless they're quoted. |
| 01:23 | Raynes | I assumed that when you said "and doesn't fail on undefined symbols" that you were trying to figure out how (a-fn foo bar baz) was failing. |
| 01:24 | mthvedt | i'm wondering if there's an easy way to have an f such that |
| 01:24 | mthvedt | (= (f 'foo *ns*) `foo) |
| 01:48 | yusup | any books / resources on clojure algorithms ? |
| 01:53 | yusup | anyone? |
| 01:53 | clojurebot | Just a heads up, you're more likely to get some help if you ask the question you really want the answer to, instead of "does anyone ..." |
| 01:54 | yusup | thanks |
| 02:09 | guns | Are lazy-seqs guaranteed to be thread-safe? I came across what appeared to be unsafe mutation of a native object in one of my deftypes |
| 02:10 | guns | but to my surprise there were no concurrency errors because the constrcutor fn was wrapped in lazy seq |
| 03:26 | qaaaaaaa | hi there |
| 06:32 | navgeet | Is it possible to override static methods using gen-class? |
| 06:33 | clgv | navgeet: there is no possibility to override static methods in java |
| 06:33 | clgv | navgeet: you can define a method with the same name though |
| 07:36 | stian_ | Xeqi; THanks! |
| 08:02 | silasdavis | I've created a web app with luminus: 'lein new luminus myapp +site +h2 +cljs' |
| 08:03 | silasdavis | This gives some authentication stuff built on lib-noir |
| 08:03 | silasdavis | I've also looked at friend |
| 08:03 | silasdavis | wondering what the relative merits my be of using friend or what I've been given in luminus for authentication |
| 08:04 | silasdavis | and if you are around yogthos any plans to add a +friend component to luminus? |
| 08:40 | yogthos | silasdavis: I haven't played much with friend myself, but I'd take a pull request :) |
| 08:41 | silasdavis | ok I'll see how I get on |
| 08:44 | yogthos | silasdavis: cool thanks :) |
| 08:50 | invis_ | guys, can some one help me write very simple txt parser on clojure ? I am new and want to have some experiense |
| 09:06 | jjl` | hi all. what are the options for a straightforward webapp in clojure? i'll be expecting to access a database, render templates and communicate with redis and a HTTP webservice |
| 09:07 | jjl` | i've used compojure, but it seems a bit DIY |
| 09:08 | weavejester | jjl`: You might want to take a look at http://www.luminusweb.net/ |
| 09:08 | ro_st | jjl`: http://www.luminusweb.net/ is a good starting point |
| 09:08 | ro_st | doh |
| 09:09 | jjl` | any recommendations on libraries for redis, json and http? i need http basic auth and SSL support on the http client |
| 09:10 | mduerksen | jjl: have a look at http://www.clojure-toolbox.com/ |
| 09:10 | jjl` | thanks :) |
| 09:16 | ro_st | jjl`: redis - https://github.com/ptaoussanis/carmine. json: https://github.com/clojure/data.json or https://github.com/dakrone/cheshire. http basic you can do with https://github.com/cemerick/friend and ssl i highly recommend you use nginx or apache for |
| 09:18 | jjl` | hrm, what are my alternative templating options? clabango doesn't appear to allow me to customise tag syntax and i'm using angular.js so need to change {{ }} |
| 09:18 | TimMc | ro_st: data.json is terrible -- cheshire is far better |
| 09:19 | stuartsierra | TimMc: Anything in particular? |
| 09:19 | TimMc | (You mentioned both, so I wanted to draw a distinction.) |
| 09:19 | jjl` | ro_st: i need to support SSL by client. i'm terminating it on nginx to handle SSL |
| 09:20 | TimMc | stuartsierra: I don't remember any details at this point, so perhaps I'm working off of old info, but I recall teh speed was not great and there were API/versioning issues. |
| 09:21 | stuartsierra | TimMc: I fixed the version issue. |
| 09:21 | stuartsierra | Cheshire, which has a pure-Java backend, is slightly faster. |
| 09:22 | ro_st | TimMc: nice. i use data.json, but only because i want to spit {"ok" :cool} back |
| 09:22 | ro_st | i use edn for *actual* data over http |
| 09:22 | ro_st | -grin- |
| 09:23 | ro_st | jjl`: lots of templating options. to the google! |
| 09:23 | TimMc | I'd like to see data.json become the gold standard, but it seems really immature at this point. |
| 09:23 | stuartsierra | TimMc: How so? |
| 09:23 | ro_st | templating is a very personal decision, like choosing pillow cases |
| 09:25 | jjl` | i *like* django's templating system so clabango would be acceptable if i could change the tags |
| 09:25 | TimMc | stuartsierra: Lack of a changelog, no indication of a versioning strategy (cheshire appears to use semver), still in 0.x (so it's not ready for production, right?) |
| 09:25 | jjl` | i'm going through the list on clojure toolbox but something makes each one unacceptable |
| 09:25 | stuartsierra | TimMc: The README has a change log. The versioning strategy (no 1.0.0) is dictated by Rich Hickey's contrib rules. |
| 09:26 | jjl` | comb would be great if template/fn returned a function that took the arg |
| 09:26 | TimMc | Oh, missed the changelog -- sorry about that. |
| 09:27 | stuartsierra | I admit I made a mistake with the 0.2.0 release breaking too many APIs, but I fixed that in 0.2.1. |
| 09:27 | TimMc | stuartsierra: Eh, the 0.2.0 thing doesn't bother me -- that happens, you fixed it. |
| 09:28 | ro_st | looks like TimMc's original contention to prefer cheshire has been mitigated? |
| 09:28 | TimMc | Yeah, my info is probably just old. Sorry about that. |
| 09:28 | ro_st | cool :-) |
| 09:28 | stuartsierra | Cheshire is still undeniably faster, but the difference is minor. The data.json code is about as fast as I can make it in pure Clojure. |
| 09:29 | ro_st | stuartsierra: you mentioned you'd recorded another 'cast with with Craig Andera. any idea when that's coming out? |
| 09:29 | stuartsierra | ro_st: no, should be some time in the next month. |
| 09:29 | ro_st | super :-) |
| 09:29 | ro_st | i've been loving the dev/user.clj file. so simple, but so handy. esp on our production machines. |
| 09:30 | stuartsierra | ro_st: Glad to hear it! |
| 09:30 | stuartsierra | I actually wouldn't mind giving over maintenance of data.json to someone else. I don't depend on JSON day-to-day now, so it's not a high priority for me. Mostly I was curious to see how fast I could make it in pure Clojure. |
| 09:30 | ro_st | also, the 'constructor' tip for the webserver works nicely. we already had all our config in the env, but the tip is nice when working on middleware |
| 09:33 | jjl` | ro_st: i've now gone through all of the templating languages on clojure-toolbox. are there any more? |
| 09:36 | ro_st | jjl`: i use hiccup |
| 09:37 | ro_st | also, you could look at enlive |
| 09:37 | stuartsierra | jjl`: If you don't mind a Java API, and you want arbitrary-text templating, StringTemplate may be worth a look. |
| 09:37 | ro_st | i never got on the mustache bandwagon |
| 09:38 | jjl` | well, ideally i was looking for something HTML-based that supported django-style template inheritance but allowed customisation of the tag delimiters |
| 09:38 | jjl` | however, at this stage i'm not sure whether to just do it in hiccup or just use another language to do it so i can have something working |
| 09:38 | ro_st | cool. hope you find something. i went for functional composition, since we're doing that for everything else already |
| 09:39 | ro_st | we've taught two greenhorn designers how to write hiccup, and they're coping, for the most part |
| 09:39 | ro_st | #works-for-me |
| 09:39 | jjl` | well right now we don't have any frontend people, but in the future i'm not sure i'd want to teach them hiccup |
| 09:40 | ro_st | sure |
| 09:41 | jjl` | what does luminus use for database connection pooling? |
| 09:43 | hlprmnky | jjl`: unrelated to connection pooling, but: Isn't luminus using clabango already? That is precisely what you asked about (Django templating in clojure) |
| 09:43 | jjl` | hlprmnky: yes, that's the default. also, i think it would be quite a lot of work to make it support alternative tag delimiters |
| 09:44 | jjl` | and that's assuming the author was willing to take the patch |
| 09:46 | hlprmnky | reading comprehension failure on my part, sorry |
| 09:46 | hlprmnky | more coffee required, apparently |
| 09:46 | jjl` | i know that feeling. i'd better go fill the pot up |
| 09:47 | tagrudev | pass the pot |
| 09:54 | jweiss | i must have done something very wrong with zippers. zip/down keeps returning a node even though i should be past the bottom of my tree. zip/children returns empty list. how is that possible? zip/down says it should return nil if i'm at the bottom. |
| 09:56 | houshuang | Another newbie question, trying to get my head around atoms and swap with maps. Why doesn't this: https://gist.github.com/5435306 work? (I just want to update the contents of a with the contents of b) |
| 09:57 | ToBeReplaced | houshuang because your swap does (conj {} (atom {:hi 1})) |
| 09:58 | jweiss | wow, i think i figured it out. the zipper funtion that returns children. If it has no children, it can't return an empty list, it has to return nil. is that right? |
| 09:59 | houshuang | @ToBeReplaced: so I need to deref b with @? |
| 10:00 | ToBeReplaced | houshuang: yes, or not wrap it in an atom |
| 10:00 | ro_st | (let [some-atom (atom {})] (swap! some-atom conj :hi 1) @some-atom ; {:hi 1} ) |
| 10:01 | houshuang | ToBeReplaced: Is it basically useless to use an atom inside a let? (Still wrapping my head around this) |
| 10:01 | ToBeReplaced | yes |
| 10:01 | ro_st | not useless. just not common |
| 10:02 | ro_st | stuartsierra spoke on using atoms within bindings as a way to make otherwise global state more 'closer' to the task at hand |
| 10:02 | ro_st | .. at CW this year |
| 10:03 | stuartsierra | ro_st: Not binding. |
| 10:03 | TimMc | houshuang: I've used atoms inside lets a number of times. |
| 10:03 | ro_st | sorry, badly worded. within let bindings. not (binding) bindings |
| 10:04 | ToBeReplaced | what's an example use case for that? |
| 10:04 | stuartsierra | I just recommended grouping related mutable state (atoms, refs, agents) inside otherwise immutable data structures and passing that as a parameter. |
| 10:04 | ToBeReplaced | the only time i've done it is interfacing with an api that requires it |
| 10:04 | houshuang | OK, so I was probably overcomplicating things (easy to follow along when reading Cloj books, harder when doing it yourself). This seems to work: https://gist.github.com/5435353 |
| 10:05 | ro_st | so (fn do-it [input] (let [state (atom nil)] (work-on state input))) |
| 10:06 | ro_st | houshuang: so that'll return a map {:hi 1}, but leave both a and b unaffected, and then a and b will be GCd |
| 10:06 | ToBeReplaced | houshuang: you can also have multiple bindings inside of the same let clause -> (let [a {} b {:hi 1}] (println a) (println a b)) etc.. |
| 10:08 | houshuang | OK, so this was actually a minimal example of trying to do make something that runs a fn whenever a file updates (inspired by ns-watch or what it was called, but I wanted to watch data files, not clj code, and try to implement it myself). I might be going about this the the wrong way. https://gist.github.com/5435378 |
| 10:08 | ro_st | ToBeReplaced: we use some business logic both in our stateful cljs frontend and our clj server. all but one namespace are pure, the last is the statebag. on the client, the cljs just bangs on the atoms in the statebag. on the server, all those atoms are wrapped in a (binding) call and then used within the context of a given task |
| 10:09 | ro_st | houshuang: current doesn't need to be an atom |
| 10:10 | ro_st | let [current (map-current files)] … (reset! old current) |
| 10:10 | ro_st | this is because you don't need to alter the contents of current |
| 10:11 | ToBeReplaced | ro_st: right that makes sense... i'm still missing when i would introduce an atom inside of a let; is that just to write the code after imperatively? like instead of a reduce, a doseq, or something? |
| 10:12 | ro_st | yeah. i've never done the local atom thing. just the binding thing |
| 10:12 | rbxbx``` | ToBeReplaced: in my experience an atom is typically a top level concept (ie: you'd likely def it off in your ns) |
| 10:12 | ToBeReplaced | houshuang: you are looking for loop recur: http://clojuredocs.org/clojure_core/clojure.core/loop |
| 10:13 | ro_st | unless stuartsierra is watching -grin- |
| 10:13 | ToBeReplaced | rxbx```: those were the only times i was using it; i'll have to watch stuartsierra's talk when it comes online to learn more |
| 10:14 | rbxbx``` | ah okay, I missed the beginning of the conversation. Apologies :) |
| 10:17 | ToBeReplaced | what naming convention(s) do people like for functions that return (anonymous) functions? |
| 10:19 | ToBeReplaced | i've got a function that returns a function that when called, will modify state; if the function was on its own, i would call it modify!; what is the name of the function that creates modify!? |
| 10:23 | cmajor7 | since lein does not support managing multi module projects, what would be the way to have a separate "module" to keep "*.proto", so "lein protobuf" would only compile and build _just the proto portion_ of the project (to be shared externally by the consumers of "proto" messages)? |
| 10:31 | zamaterian | cmajor7, see lein-sub and example here https://github.com/pedestal/pedestal/blob/master/project.clj |
| 10:34 | cmajor7 | zamaterian: great. looks good. thank you. |
| 10:40 | TimMc | ToBeReplaced: "modifier"? |
| 10:41 | ToBeReplaced | TimMc: i've been fighting between "modifier" and something like "modify!-fn", which mirrors things like :key-fn found in a number of libs |
| 10:48 | terom | "make-modifier" would be quite clear but if a shorter one is needed, then "modifier" is perhaps better imo |
| 10:59 | invis_ | guys, what is the best way to parse file like this https://www.refheap.com/paste/13864 ?? |
| 10:59 | lazybot | invis_: What are you, crazy? Of course not! |
| 11:01 | invis_ | want to create a map like :item , : price , :date from it |
| 11:04 | joegallo | invis_: if it's going to get more complicated than that, you might consider a real parser with a defined grammar |
| 11:05 | joegallo | but if that's the whole syntax of the file, you could honestly get away with line-seq'ing the contents of the files and mapping a little line handler function over the lines |
| 11:05 | joegallo | if the line is a date line, emit a date, if it's a price/item line then split on the : and return a vector of the price and item |
| 11:06 | joegallo | probably 10 lines of code |
| 11:06 | joegallo | you get back a seq of dates and price-tuples |
| 11:09 | beffbernard | Hey guys.. I'm having some macro woes... This is what I'm trying to do.. |
| 11:10 | mynomoto | Is there a code analyser that detects repetition in your code? |
| 11:10 | beffbernard | , (eval '(let [f# (fn [^String a#] (pr-str (meta a#)))] (f# "morecowbell"))) |
| 11:10 | clojurebot | #<Exception java.lang.Exception: SANBOX DENIED> |
| 11:11 | beffbernard | Basically I'm trying to type hint one of my arguments |
| 11:11 | beffbernard | but I can't get with-meta to play nice |
| 11:12 | invis_ | joegallo: I am new in clojure and dont know how to "tell" clojure that all price-items after date line belongs to that date |
| 11:12 | beffbernard | I've been trying something like this |
| 11:12 | beffbernard | (eval '(let [f# (fn [~(with-meta a# {:tag "String"})] (pr-str (meta a#)))] (f# "morecowbell"))) |
| 11:14 | joegallo | invis_: it's just more code. in my example, you'd have a seq of dates and price-tuples, you could then (partition-by type ...) that seq, and get the dates pulled out separately. then you could join the resulting seqs back together so you'd have a seq of tuples, the first item in each tuple is the date, and the second item in the tuple is a seq of all the price/item tuples for that date |
| 11:15 | joegallo | alternatively, you could do your parsing differently, so that such a datastructure was what you emitted in the first place, you could probably accomplish that in a single pass using reduce with an appropriately clever function over the line-seq of the file's data |
| 11:24 | asteve | is mapv a newer function? I'm trying to run a lein1 repl with source that has mapv |
| 11:24 | asteve | and I'm getting: Unable to resolve symbol: mapv in this context |
| 11:25 | nDuff | asteve: mapv was introduced in Clojure 1.4 |
| 11:25 | asteve | nDuff: ah, makes sense; thanks |
| 11:30 | jjttjj | if i have a list of 1s and 2s and want to remove all 1s that are directly followed by a two, is this a decent implementation, or is there a better way to do this: |
| 11:30 | jjttjj | https://www.refheap.com/paste/13866 |
| 11:30 | jjttjj | (also open to style suggestions here :) |
| 11:32 | ToBeReplaced | jjttjj: i think i would do something like (keep (fn [a b] (when-not (and (= a 1) (= b 2)) a)) coll (rest coll)) |
| 11:33 | jjttjj | ToBeReplaced: cool, thanks! |
| 11:33 | ToBeReplaced | that might not be totally right at the edge; you might drop the last value or something... but that's the approach i would take |
| 11:35 | ToBeReplaced | jjttjj: you'd need (map seq coll (rest coll)) and (fn [[a b]] ...) b/c keep only works with one coll |
| 11:35 | jjttjj | ToBeReplaced: k playing around with that |
| 11:35 | dnolen | also (map first (remove #(= % [1 2]) (partition 2 1 coll))) |
| 11:36 | ToBeReplaced | dnolen: that looks much better |
| 11:37 | jjttjj | dnolen: nice, thanks! |
| 11:37 | mpenet | np on s'occupe de ca demain |
| 11:37 | mpenet | oups |
| 11:52 | iamdrw | does anybody know how to load a huge json(> 1GB) in clojure? 300 mb works okay when I do (with-open [rdr (clojure.java.io/reader log-file)] |
| 11:52 | iamdrw | (let [sqls (json/read rdr)] |
| 11:52 | iamdrw | …), but for > 1 gb — I've got memory error. |
| 11:52 | iamdrw | I've the following set jvm opts :jvm-opts ["-Xms5000m", "-Xmx10000m", |
| 11:52 | iamdrw | "-XX:-UseGCOverheadLimit", "-XX:+UseConcMarkSweepGC", "-XX:+CMSIncrementalMode", |
| 11:52 | iamdrw | "-XX:+DoEscapeAnalysis", "-XX:+UseBiasedLocking", |
| 11:52 | iamdrw | "-XX:PermSize=64M", "-XX:MaxPermSize=256M"] |
| 11:53 | iamdrw | but still no luck :( |
| 11:56 | dnolen | iamdrw: might want to try using something like Jackson directly, I'm assuming you're using data.json? |
| 11:56 | iamdrw | yep |
| 11:56 | iamdrw | data.json |
| 11:57 | stuartsierra | If you've got >1GB in a single file, you probably want to look into streaming JSON parsers so you don't have to load the whole thing in memory at once. |
| 11:59 | dnolen | iamdrw: cheshire streams and uses jackson under the hood |
| 12:00 | dnolen | http://github.com/dakrone/cheshire |
| 12:00 | iamdrw | :dnolen thanx, I'll give it a try |
| 12:01 | iamdrw | also I'm wondering if I use used edn instead of json, would things be better? |
| 12:01 | technomancy | jackson is a lot more efficient than any existing edn parsers |
| 12:01 | technomancy | but don't take my word for it =) |
| 12:02 | stuartsierra | iamdrw: I expect the problem is the size of the resulting Clojure data structures. So whether the source is JSON or EDN, it's going to need a huge amount of memory if you want to read it all into persistent data structures. |
| 12:03 | stuartsierra | That's why I suggest using a pure-Java streaming parser that doesn't try to realize the whole document in memory. |
| 12:04 | iamdrw | and does clojure have something like reducers, but for files? |
| 12:04 | dakrone | depending on what the JSON looks like, you could parse it into a lazy seq and process it in smaller chunks in memory |
| 12:04 | iamdrw | my json is actually a big array of maps of pretty defined structure |
| 12:05 | stuartsierra | Can you break it up into smaller pieces then? |
| 12:05 | iamdrw | only by hands |
| 12:05 | iamdrw | but I'm working on how to automate that |
| 12:05 | dakrone | so right now I know of no lazy-tree parsers, you'll need something like '{"foo":"bar"}{"baz":"quux"}...' so each thing can be a separate object |
| 12:06 | dakrone | in order to take advantage of lazily parsing it |
| 12:07 | mynomoto | Is there a code analyser that detects repetition in your code? |
| 12:08 | technomancy | mynomoto: I don't think so. sounds like a fun project. =) |
| 12:08 | iamdrw | I guess I should also try https://github.com/michalmarczyk/clj-lazy-json |
| 12:09 | iamdrw | maybe it will work for my case |
| 12:10 | iamdrw | and does anybody knows a way how to split json into chunks? |
| 12:11 | iamdrw | without loading it :) |
| 12:11 | dakrone | iamdrw: sed/awk? ;) |
| 12:12 | nDuff | dakrone: As a member of #bash, I'm suddenly deeply, deeply disturbed that we'll have someone asking how to do just that. |
| 12:12 | mynomoto | technomancy: Yes. But, I was hopping that someone already did it. :) |
| 12:13 | dakrone | nDuff: heh. All text-processing problems can be expressed in terms of sed and awk if one is insane enough :) |
| 12:14 | nDuff | dakrone: If you're dealing with something that isn't a regular language, and you're specifying constraints around memory usage... I'd actually go so far as to call you wrong on that. |
| 12:14 | iamdrw | darktrone: on linux head -c .. and tail -c .. will do, but not for os x :( |
| 12:15 | iamdrw | and some ( echo "[" ; ..) magic :) |
| 12:15 | dakrone | nDuff: true, if you add the memory usage criteria |
| 12:15 | dakrone | huh, "darktrone", that's a new one |
| 12:15 | iamdrw | ahaha, sorry |
| 12:16 | dakrone | iamdrw: possible to tell your source of JSON to change their layout? |
| 12:16 | iamdrw | yes |
| 12:16 | dakrone | hey, that might work then |
| 12:24 | iamdrw | cheshire definitely does better job |
| 12:24 | iamdrw | 2 seconds vs 30 second on 300 mb file |
| 12:35 | gfredericks | does anybody know why a var's dynamic bindings are implemented as a literal stack? Why not just a threadLocalSet method or something like that? |
| 12:35 | gfredericks | just curious |
| 12:54 | silasdavis | Looking at: https://github.com/cemerick/friend it states "Note that Friend itself requires some core Ring middlewares: params, keyword-params and nested-params." |
| 12:54 | silasdavis | my app was not working because I hadn't used them |
| 12:54 | silasdavis | however I can't see where https://github.com/cemerick/friend-demo introduces them |
| 12:54 | silasdavis | (with form-interactive login) |
| 12:55 | silasdavis | yet it still works, could anyone shed any light on that |
| 12:57 | xeqi | silasdavis: https://github.com/cemerick/friend-demo/blob/master/src/clj/cemerick/friend_demo/http_basic.clj#L29 is one spot |
| 12:57 | weavejester | silasdavis: The compoure.handler/site function is applied to the routes |
| 12:57 | xeqi | compojure.handler/site includes them |
| 12:57 | weavejester | silasdavis: That's a convenience function that adds a bunch of middleware in the right order |
| 12:57 | weavejester | e.g. cookies before session, etc. |
| 12:58 | NeedMoreDesu | I wonder if clojure have inheritance. I don't see it in defprotocol, definterface, defrecord or deftype. Is it exists here at all? |
| 12:59 | silasdavis | ah great, thanks - that wasn't office. The friend demo app is nice in terms of showing the functionality but a bit hard to see the wood from the trees for a neophyte |
| 12:59 | silasdavis | um s/office/obvious |
| 12:59 | technomancy | NeedMoreDesu: not really |
| 12:59 | SegFaultAX | NeedMoreDesu: a) yes it does b) protocols are better c) what are you trying to do? |
| 12:59 | jjttjj | is there a common reason my files aren't being auto-reloaded in lein-ring in dev mode? I've ran into this problem before and it always seemed to get fixed by just updating to the latest lein-ring version, but that's not working this time |
| 12:59 | technomancy | technically there are ways, but it's better to pretend there aren't |
| 13:00 | weavejester | NeedMoreDesu: You can setup an inheritance tree of keywords, but in practise they're rarely used |
| 13:00 | weavejester | The only example I can think of is Friend, which uses them to define roles. |
| 13:00 | rasmusto | tpope: I took a stab at vim-fireplace + vim-fugitive buffers. Do you think I'm going in the right direction? https://github.com/rasmusto/vim-fireplace/compare/fugitive-integration It doesn't seem to work on windows, but I'm not sure if that's another issue poking through |
| 13:00 | NeedMoreDesu | SegFaultAX: I'm trying to learn a tool. Yet I've seen how to make protocol and define several records with same methods, yet it doesn't look like inheritance. |
| 13:00 | weavejester | jjttjj: Which version are you using? |
| 13:01 | jjttjj | weavejester: 0.8.5 |
| 13:01 | weavejester | jjttjj: Which Ring version, may I ask? |
| 13:01 | SegFaultAX | NeedMoreDesu: It's pretty heavily discouraged (save perhaps for certain special circumstances). Can you be more specific about what you're trying to accomplish? |
| 13:03 | jjttjj | weavejester: compojure 1.1.5, so 1.1.7 it seems? |
| 13:03 | weavejester | NeedMoreDesu: Protocols just provide polymorphism. OOP kinda confuses matters by jamming together a whole bunch of things together. |
| 13:04 | NeedMoreDesu | SegFaultAX: well, i'm not intend to use it, but it would be interesting to know, how can I inherit one class from another. Say, I have big fat class, and I want to create new class, adding several methods. |
| 13:05 | weavejester | jjttjj: Try adding in an explicit dependency to ring/ring-devel 1.1.8… although, lein-ring should in theory inject that dependency anyway. |
| 13:05 | NeedMoreDesu | weavejester: yep, I understand that I can forge my own OOP system with maps. Is it the only way? |
| 13:05 | weavejester | jjttjj: You might have run into a bug |
| 13:06 | NeedMoreDesu | SegFaultAX: and yep, several methods means I don't wand to re-write everything. |
| 13:06 | jjttjj | weavejester: yup adding the explicit dependency worked, thanks! |
| 13:06 | weavejester | NeedMoreDesu: You probably don't want to forge your own OOP system. OOP is essentially "Let jam together a whole bunch of unrelated concepts like polymorphism, inheritance and encapsulation". Clojure tends to emphasize the opposite. |
| 13:07 | SegFaultAX | NeedMoreDesu: If you're simply looking to extend an existing class with new methods, protocols are worth further investigation. |
| 13:07 | NeedMoreDesu | But I can't inherit one protocol with other. |
| 13:07 | SegFaultAX | NeedMoreDesu: Also, maps alone won't really help you here as maps don't introduce new types. |
| 13:07 | weavejester | NeedMoreDesu: So if you need polymorphism, use protocols. If you need inheritance, use functions like "derive" to link together keywords. |
| 13:08 | technomancy | you probably don't actually need polymorphism though |
| 13:08 | NeedMoreDesu | That means, if I have long trail of inheritance, I will need to have long trail of protocols. |
| 13:08 | weavejester | You probably don't need a long trail of inheritance. |
| 13:08 | SegFaultAX | NeedMoreDesu: Do you know what a Clojure protocol is? |
| 13:08 | technomancy | most people assume they do because they've never tried not using it |
| 13:09 | NeedMoreDesu | weavejester: I should have a look at derive. |
| 13:09 | weavejester | NeedMoreDesu: Could you describe the problem you're trying to solve? |
| 13:09 | weavejester | Inheritance is a very specialized tool |
| 13:10 | weavejester | In, what, 5 years of Clojure I don't think I've ever used it. |
| 13:10 | weavejester | And I've only seen one library that uses it for a very small part of its functionality. |
| 13:11 | SegFaultAX | Not to mention the whole concept of subtyping makes things a /lot/ harder to reason about. |
| 13:11 | NeedMoreDesu | weavejester: how could I write something like that? https://ideone.com/U4oBpY |
| 13:12 | silasdavis | can you create an inheritance chain longer than 2 with a single statement? |
| 13:12 | silasdavis | without defining anything new I mean |
| 13:12 | weavejester | NeedMoreDesu: Well, that looks like an example that specifically uses inheritance for the sake of it. Are you looking into inheritance just to see how Clojure does it? Not for any practical reason? |
| 13:13 | NeedMoreDesu | weavejester: yes, It just eats me that I don't know how can it be done. |
| 13:16 | SegFaultAX | NeedMoreDesu: Simply, inheritance isn't the Clojure way. There is probably a more idiomatic approach to solving whatever problem you have in Clojure that likely does *not* involve inheritance. |
| 13:16 | weavejester | NeedMoreDesu: Well, the specific example you give is one that demonstrates inheritance over classes. Clojure doesn't have that. |
| 13:17 | weavejester | NeedMoreDesu: However, what you can do is set up relationships between namespaced keywords |
| 13:17 | weavejester | ,(do (derive ::square ::shape) (isa? ::square ::shape)) |
| 13:17 | clojurebot | true |
| 13:18 | NeedMoreDesu | weavejester: so what do I achieve doing that? |
| 13:18 | technomancy | I love how there's only like two or three examples people use to discuss inheritance |
| 13:18 | technomancy | it's either animal > mammal > cat or shapes =) |
| 13:19 | SegFaultAX | technomancy: Or car parts! |
| 13:19 | rasmusto | technomancy: those are the killer apps for inheritance, like family trees are for logic programming |
| 13:19 | weavejester | NeedMoreDesu: You achieve inheritance in its purest form. You can test to see if a keyword inherits from another. |
| 13:19 | weavejester | technomancy: I just cribbed it from the multimethod docs ;) |
| 13:19 | technomancy | rasmusto: fibonacci with inheritance |
| 13:20 | rasmusto | technomancy: hmm |
| 13:20 | weavejester | All inheritance does is describe a particular form of relationship between things. |
| 13:20 | weavejester | OOP complicates things by mixing it with ideas about polymorphism. |
| 13:20 | weavejester | And encapsulation |
| 13:21 | rasmusto | chrome_bumper.speak() |
| 13:24 | NeedMoreDesu | Ok, thanks for answers. :3 |
| 13:32 | asteve | I want to remove all dependencies and previous built targets; will `lein clean` do this? |
| 13:32 | asteve | Leiningen 2.0.0 on Java 1.6.0_41 Java HotSpot(TM) 64-Bit Server VM |
| 13:32 | technomancy | asteve: dependencies will still be cached in ~/.m2 |
| 13:32 | asteve | can I *safely* blow the directory away? |
| 13:32 | asteve | I'd like to rebuild all deps |
| 13:32 | technomancy | what do you mean by rebuild? |
| 13:32 | asteve | well, pull them down again |
| 13:33 | technomancy | it's safe to blow it away, it will just be really slow next time you do anything |
| 13:33 | technomancy | and you will lose anything you installed manually |
| 13:33 | asteve | I'm upgrading from lein 1.7 to 2.0 and I believe lein2 is trying to load a dependency installed with 1.7 which is no logner valid |
| 13:34 | technomancy | not sure what that means, but you can certainly try it |
| 13:34 | technomancy | or you could just move it out of the way |
| 13:34 | technomancy | so you don't have to re-fetch everything for other projects if it turns out not to help |
| 13:35 | gfredericks | mv ~/.m2 ~/.m3 |
| 13:35 | technomancy | ironic since Leiningen doesn't use anything from maven 2 anymore |
| 13:59 | deg | I'm trying to pass a large set of keyword args between several functions, without listing them all. |
| 13:59 | deg | I thought I could use :as and then apply, like this: |
| 13:59 | deg | ,(defn f1 [& {:keys [a b] :as all}] (println "all: " all) (apply f2 all)) |
| 13:59 | clojurebot | #<Exception java.lang.Exception: SANBOX DENIED> |
| 13:59 | deg | oops |
| 13:59 | deg | (defn f1 [& {:keys [a b] :as all}] (println "all: " all) (apply f2 all)) |
| 13:59 | deg | (defn f2 [& {:keys [a b] :as got}] (println "got: " got) (list a b) |
| 13:59 | deg | (f1 :a 1 :b 2) |
| 14:00 | deg | all: {:a 1, :b 2} |
| 14:00 | deg | got: {[:a 1] [:b 2]} |
| 14:00 | deg | (nil nil) |
| 14:00 | deg | It looks like apply is implicitly converting the map to a vector. |
| 14:00 | deg | What is the idiomatic working way to do this? |
| 14:01 | joegallo | you could write something like apply-kv or apply-opts |
| 14:01 | joegallo | which iirc has been rejected for clojure.core |
| 14:01 | joegallo | but there's like a million copies floating around in different projects |
| 14:02 | deg | Ok, googling for them now. So, no built-in way to do this? |
| 14:02 | amalloy | deg: easy way is just don't use keyword args |
| 14:02 | joegallo | well, i mean, not as one function no |
| 14:02 | amalloy | pass a real, actual map around |
| 14:03 | joegallo | (apply my-function my args here (apply concat (seq awww-shoot-this-is-a-map-son))) |
| 14:03 | joegallo | which isn't sooo much typing... |
| 14:03 | deg | amalloy: Yup, but then I need to destructure in a let inside the function. Certainly not terrible, but one extra line. |
| 14:03 | amalloy | joegallo: and the (seq ) characters are pointless, os there's more savings |
| 14:03 | Raynes | No you don't. |
| 14:03 | joegallo | true dat |
| 14:04 | NeedMoreDesu | Do you want this? ,(apply concat {:a 1 :b 2}) |
| 14:04 | Raynes | &((fn [{:keys [a b]}] [a b]) 1 2) |
| 14:04 | lazybot | clojure.lang.ArityException: Wrong number of args (2) passed to: sandbox36074$eval55306$fn |
| 14:04 | Raynes | &((fn [{:keys [a b]}] [a b]) {:a 1 :b 2}) |
| 14:04 | lazybot | ⇒ [1 2] |
| 14:05 | deg | Raynes: I think I do. I need to refer to the arguments independently. Or, am I misunderstanding you? |
| 14:06 | Raynes | deg: What do you mean by refer to arguments independently? Isn't that what my example just did? |
| 14:06 | deg | Raynes: Our msgs crossed. My response to your example is that I have two functions (f1 and f2) that need to do this. |
| 14:07 | deg | But, one sec while I grok what you coded. |
| 14:08 | NeedMoreDesu | deg: http://ideone.com/Gv2W29 |
| 14:08 | Jambato | from how many variables defined in a let form can you consider there are too many of them? |
| 14:08 | Raynes | The IDEONE, it burns! |
| 14:09 | Raynes | Jambato: If you're asking that question, you've probably got too many. |
| 14:09 | Jambato | :p indeed |
| 14:09 | deg | Raynes: Oh, right, I'm caught up now. The problem is that I need to call f2 from other places too, so I "need" to have the args at top level. I would have to wrap them in a map in each caller. Not terrible, but not ideal. |
| 14:09 | Raynes | But there isn't a specific number. If it looks terrible then it's too many. |
| 14:10 | Raynes | If you want to show a specific piece of code, I'm sure we could give some tips to clean it up. |
| 14:10 | amalloy | deg: a map literal costs you literally two characters. any other solution will cost many characters *and* cognitive load of understanding what's going on |
| 14:10 | deg | amalloy: good point. |
| 14:11 | Raynes | But Alan, think of the curly brackets! |
| 14:11 | amalloy | (plus, you get those two characters back by avoiding "& " |
| 14:11 | amalloy | ) |
| 14:11 | deg | And you also avoid the :as foo |
| 14:11 | Jambato | Raynes: http://pastebin.com/72gDSnZu |
| 14:12 | amalloy | ~nduff |
| 14:12 | clojurebot | Please don't use pastebin.com: there are lots of annoying animated ads. Instead, try http://refheap.com, an ad-free pastebin written in Clojure. |
| 14:12 | deg | NeedMoreDesu: Your concat answer (in link above) is neat. |
| 14:12 | TimMc | amalloy: nice |
| 14:12 | amalloy | i'm complaining on my own behalf this time, actually, because pastebin isn't even loading |
| 14:12 | deg | But, I think I'm coming around to the consensus that it's better just to pass the map. |
| 14:13 | amalloy | ~mapply |
| 14:13 | clojurebot | You could (defn mapply [f & args] (apply f (apply concat (butlast args) (last args)))) |
| 14:13 | amalloy | (now that i've convinced you you shouldn't do it, there's the easy way) |
| 14:14 | deg | I'm going to have to think about the real code and decide between concat and passing a map. |
| 14:15 | deg | The real code is a first attempt at writing a clojurescript/clojure/compojure app. |
| 14:15 | TimMc | People are less likely to yell at you if yo pass a map. |
| 14:15 | deg | I'm started with positional args coming in from the html, but there are now seven args, and it's getting silly |
| 14:15 | deg | so I refactored into keywords, and hit this. |
| 14:16 | rasmusto | TimMc: do people use maps for optional arguments too? |
| 14:17 | deg | In a different context, I've played with using one map arg that gets passed to everyone, basically as whiteboard (in the old AI sense) where everyone can scribble useful values for everyone else. (Don't worry, all in a nice functional style) |
| 14:18 | deg | I didn't get far enough with that project to decide if I liked the style, but it had a lot of positive behavior. |
| 14:20 | NeedMoreDesu | deg: I did concat in place, where I wanted keywords, but passing a map as one arg may be faster(no seq->concat->hashmap transformation). |
| 14:22 | deg | Agreed. I just converted the code to the single map and it is more readable, plus (as you said) probably marginally more efficient. |
| 14:23 | TimMc | rasmusto: Yep. It's very convenient. |
| 14:23 | TimMc | rasmusto: Often times you will see this: (defn foo [a b c & [{opts}] ...) which means that the options map can be left out entirely as well. |
| 14:25 | deg | FWIW, I just found a old discussion on this topic that sums up both sides nicely: https://groups.google.com/forum/?fromgroups=#!topic/clojure-dev/9ctJC-LXNps |
| 14:30 | deg | New question: In this app, I'm using the compojure stack and AWS SimpleDB for back-end storage. I've already found Rummage and the db interface is a complete pleasure. |
| 14:31 | deg | But, I have some state that basically never changes, so I'd like to cache on my server between client calls. |
| 14:31 | deg | What is the best place for local caching in the web server? |
| 14:33 | rasmusto | TimMc: I've done this quite a bit: ,((fn foo [{:keys [a b c]} & {:keys [opt1 opt2]}] [a b c opt1 opt2]) {:a 1 :b 2 :c 3} :opt1 4 :opt2 5) ; can you think of any downsides to this method? |
| 14:40 | TimMc | rasmusto: Yep. The result is that I can't call apply if I already have an option map handy. |
| 14:40 | TimMc | *optional |
| 14:42 | rasmusto | TimMc: ah, understood. I've noticed that I put certain arguments first when I define a function so I can easily do ((partial myfn bind-some-arg) other-args). I guess having options as a map removes some complexity from similar situations |
| 14:43 | rasmusto | those situations are slightly related |
| 14:47 | ToBeReplaced | i don't think i understand the usecase for apply-kw in that google-groups thread; can't you just (apply foo arg1 arg2 (mapcat seq options))? |
| 14:48 | gfredericks | ToBeReplaced: yes I think people consider that tedious for normal use |
| 14:49 | ToBeReplaced | gfredericks: yeah, it's a lot of noise... and i don't like that the apply and the mapcat are far apart from eachother when they are coupled in their purpose |
| 14:56 | gfredericks | ~mapply |
| 14:56 | clojurebot | You could (defn mapply [f & args] (apply f (apply concat (butlast args) (last args)))) |
| 15:19 | kmicu | , (((comp comp comp) count filter) (complement zero?) [0 1 0 1 0]) |
| 15:19 | clojurebot | 2 |
| 15:20 | Raynes | kmicu: comp comp comp. Sounds like chain chomps from Mario games. |
| 15:22 | kmicu | Cuz it's Mario's Chomps Driven Programming aka Haskell Brain Leakage Malarkey ;] |
| 15:22 | TimMc | ,((((comp comp) (comp comp)) ((comp comp) (comp comp)))) ;; Raynes |
| 15:22 | clojurebot | #<core$identity clojure.core$identity@126016a> |
| 15:23 | mpenet | deg: core.cache and core.memoize are good for that, if you really don't care about persistance and/or don't want to use something like redis |
| 15:24 | mpenet | deg: or just atoms for stuff that never changes (as you said) |
| 15:24 | mpenet | well, "rarely" not never, otherwise even using an atom is overkill :) |
| 15:30 | Foxboron | Was thinking of writing my IRCBot into a framework (i know there is atleast one out there), anyone else think it is a good idea? |
| 15:31 | Raynes | Foxboron: I'd of course prefer you just contribute to irclj. |
| 15:31 | Raynes | But you're certainly welcome to do something entirely different. |
| 15:32 | Foxboron | Raynes, i did take a look at irclj because i wanted to make my socket code simpler, so i *cough* borrowed 3 lines. |
| 15:33 | Foxboron | I feel it is kinda complicated and a framework could have been done more simple. |
| 15:33 | Foxboron | Raynes, and i don't really feel i know enough Clojure to poke around your lib :) |
| 15:34 | howdynihao | regarding this subject or related where you have to keep a stateful connection |
| 15:34 | Raynes | Foxboron: Could you give me some specifics on how it is complicated? |
| 15:34 | howdynihao | what happens when you need to update your code? you'd have to restart all the connections |
| 15:34 | howdynihao | any way around that? |
| 15:34 | Raynes | It's not very easy to build a framework simpler than this that is actually flexible enough to be used for more than IRC bots. |
| 15:35 | Foxboron | Raynes, that i what was running through my mind when i was thinking about the current structure of my bot. |
| 15:36 | Foxboron | Raynes, also i kinda miss documentation. Because i feel i might be misinterperating the code a few places. |
| 15:38 | Raynes | Foxboron: It is admittedly not well documented at the moment. It isn't entirely finished, though it is usable. |
| 15:38 | Raynes | Hence why I mentioned contributing. |
| 15:39 | Raynes | Also, Foxboron, are you looking at https://github.com/Raynes/irclj? |
| 15:39 | ppppaul | <3 map + juxt |
| 15:39 | Raynes | Because https://github.com/flatland/irclj is the one that matters. |
| 15:39 | Raynes | In fact, I should delete my old repos. |
| 15:39 | Foxboron | Raynes, looking at the flatland one. I am just thinking. |
| 15:40 | Foxboron | Don't got so much time at my hands atm because of exams. But i also thinking making a framework/lib or maybe contributing would be a good way to get better knowledge in Clojure |
| 15:41 | ppppaul | core.cache ??? mpenet |
| 15:42 | mpenet | https://github.com/clojure/core.cache |
| 15:43 | mpenet | it's the foundation for core.memoize, you probably don't need to go that low level if you use the later, but it can be useful on its own depending on what you do |
| 15:44 | ppppaul | i use memoize a lot |
| 15:44 | mpenet | same here |
| 15:45 | mpenet | well core.memoize, the memoize function that is in core not so much (confusing heh!) |
| 15:45 | mpenet | who said naming is hard again |
| 15:45 | ppppaul | :) |
| 15:45 | ppppaul | i use the one in core... |
| 15:46 | ppppaul | for some things it works great |
| 15:46 | mpenet | sure |
| 15:47 | deg | mpenet: (I'm back now; catching up). What is the execution model of a ring server? Is each page response in a new environment, or does information persist? |
| 15:47 | ppppaul | so. core.memoize is ontop of core.cache? |
| 15:47 | deg | (excuse my beginner question... zero experience with modern web servers) |
| 15:47 | ppppaul | deg, if you use atoms or something, then you can persist data |
| 15:48 | ppppaul | you can persist data in your DB as well |
| 15:48 | deg | pppaul: I'm using SimpleDB as my real DB, but it's probably too slow to hit it every time. |
| 15:49 | ppppaul | no it's not |
| 15:49 | deg | Wow, really? |
| 15:49 | ppppaul | unless you have profiled and discovered that it is too time expensive to do so, otherwise it isn't |
| 15:50 | deg | I've not profiled, but I did play with writing to it from a desktop toy app. But, I just realized, I was faked out, because it does not auto-refresh its dashboard. |
| 15:50 | deg | So, I had mis-grokked that the DB was slow. |
| 15:51 | deg | Is it considered fast enough that I can use it to populate a DOM at page init time? |
| 15:52 | ppppaul | huh? |
| 15:52 | ppppaul | it's fast enough, until you find that it's not |
| 15:52 | ppppaul | most likely, you will find other things that are slower first |
| 15:53 | deg | Great. I had not bothered testing; assumed that the net round-trips would be too slow. |
| 15:53 | deg | (Am I dating myself as a pre-ajax kind of programmer? :-) ) |
| 15:53 | ppppaul | you can log them, most likely you are looking at .1/s or so |
| 15:54 | deg | Sad. I had this same conversation in 1989 or so with someone who will remain nameless because he has well-deserved guru status. |
| 15:54 | ppppaul | it's really only too slow once you are doing thousands a second |
| 15:54 | deg | At the time, he couldn't believe that some image processing activity could be done in a user-facing app because "Each addition takes a microsecond" was deeply wired into him. |
| 15:54 | ppppaul | to be honest, you get much better speed increases via CDNs and varnish |
| 15:55 | deg | I remember him doing the same double-take that I did just now. |
| 15:55 | ppppaul | so, figure out how to prevent your server from being hit |
| 15:55 | ppppaul | if you can't, then you can do the same type of caching on your server to prevent the DB from being hit |
| 15:55 | ppppaul | but you don't need any of that stuff, until you do need it |
| 15:56 | deg | Right. My q was premature optimization, but I was asking exactly that... how to do caching on my server. |
| 15:56 | ppppaul | and you want to start caching away from your server first... |
| 15:57 | deg | yup. |
| 15:57 | liftdeadtrees | Have any of you used clj-logging-config to setup log4j before? |
| 15:57 | ppppaul | if you can't easily cache away from your server, then get into core.memoize, and if that's not good enough, well you are in for some pain |
| 15:58 | deg | yup, thx. |
| 15:58 | ppppaul | but deg, it's not worth dealing with until you have metrics on what you need to optimize |
| 16:00 | deg | Yup, that's my real take-away here. I'd come in assuming that it must be slow, before I coded. |
| 16:02 | ppppaul | if you want to explore caching in clojure then you can make some things slow. if you just want to launch your product, then i would worry more about how to get metrics |
| 16:02 | deg | The latter. |
| 16:03 | ppppaul | :) |
| 16:03 | ppppaul | timbre is something i've found very useful for getting quick metrics on my code https://github.com/ptaoussanis/timbre |
| 16:04 | ppppaul | however, i'm not too good with the programs to get metrics on the JVM itself |
| 16:06 | deg | Timbre looks good, thx. When I first started in Clojure, I had looked at some Java-based profiling tools, but none were yet reasonable enough. I'll try Timbre. |
| 16:08 | technomancy | JMX can get you runtime stats on the JVM |
| 16:09 | technomancy | there's a cool web-repl project thingy that exposes some of that |
| 16:09 | technomancy | https://github.com/zoka/ringMon |
| 16:11 | gfredericks | that's a jamaican library? |
| 16:11 | technomancy | get up, stand up. stand up for your middleware. |
| 16:14 | deg | g'nite all. Hitting bedtime over here. Thanks for all the tips. |
| 16:16 | Raynes | technomancy: Or abandon it like pedestal! |
| 16:17 | Glenjamin | seems odd to me that timbre provides logging and profiling |
| 16:17 | Glenjamin | on the surface they seem to be entirely orthogonal |
| 16:19 | stuartsierra | Raynes: A lot of work went into making Pedestal compatible with Ring middleware as far as that was possible. |
| 16:21 | wink | gfredericks++ |
| 16:21 | Morgawr | do you guys know of any game engine written in/for Clojure? Or even more specifically for ClojureScript? (I know Clojure can interface with Java and ClojureScript with JavaScript, I'm mostly thinking if "native" Clojure/Script engines exist) |
| 16:22 | dnolen | Morgawr: people have built games, I'm not aware of any engines. |
| 16:22 | Morgawr | I'm going to try make a ClojureScript point and click game for next weekend's Ludum Dare competition, if something good comes out of it, I might release an engine, who knows |
| 16:22 | Morgawr | I was mostly interested if something like this already existed so I could take a look at it |
| 16:24 | dnolen | Morgawr: people have done their Ludum Dare projects in ClojureScript |
| 16:25 | tyler_ | anyone know of something similar to threading macro in ruby? i have something that looks like method(other_method(data)) and would like to do something similar to (-> data other_method method) but in ruby |
| 16:25 | tyler_ | not sure if right place to ask but i figure theres a few ex-ruby people in here |
| 16:25 | Morgawr | dnolen: yeah, I've seen a couple of games which is where I took pieces of code to learn :) |
| 16:27 | wink | tyler_: might I ask why? :) |
| 16:30 | tyler_ | wink: because my methods are getting nested pretty quick |
| 16:30 | tyler_ | and it doesn't look very idomatic to have foo(bar(bin(baz(boo(quux)))) |
| 16:31 | wink | tyler_: just askign because I neevr saw somethinh like -> in another language befoe |
| 16:32 | tyler_ | anything that combines functions |
| 16:32 | asteve | ,(macroexpand ->) |
| 16:32 | clojurebot | #<CompilerException java.lang.RuntimeException: Can't take value of a macro: #'clojure.core/->, compiling:(NO_SOURCE_PATH:0:0)> |
| 16:32 | asteve | WAT |
| 16:32 | technomancy | macroexpand is not a macro |
| 16:33 | xeqi | ##-> ##(macroexpand '->) |
| 16:33 | lazybot | ⇒ -> |
| 16:33 | xeqi | booo lazybot |
| 16:33 | asteve | ,(macroexpand '->) |
| 16:33 | clojurebot | -> |
| 16:33 | asteve | hah |
| 16:34 | lazybot | Nice try, xeqi. |
| 16:38 | stuartsierra | macroexpand operates on whole expressions, not symbols. |
| 16:40 | bruceadams | ,(source ->) |
| 16:40 | clojurebot | Source not found\n |
| 16:41 | stuartsierra | ,(macroexpand-1 '(-> x foo bar (baz 3 4))) |
| 16:41 | clojurebot | (clojure.core/-> (clojure.core/-> x foo) bar (baz 3 4)) |
| 16:41 | stuartsierra | ,(macroexpand '(-> x foo bar (baz 3 4))) |
| 16:41 | clojurebot | (baz (clojure.core/-> (clojure.core/-> x foo) bar) 3 4) |
| 16:45 | Xenon75 | Hi |
| 16:47 | TimMc | &(macroexpand '(->> a b (->> c d))) |
| 16:47 | lazybot | java.lang.StackOverflowError |
| 16:54 | Xenon75 | Hi, I am getting crazy with a Compojure application... Here it is a problem: I need to add some headers for making cross-origin work. Now if I add them using middleware everything works like a charm. If I add the by crafting a response "by hand" it doesn't. The browser seems to receive the same data, but for some reason in the second case it complains and stops. |
| 16:54 | Xenon75 | This is the working version: http://pastebin.com/Ud6bLYX6 and this is the not working one: http://pastebin.com/vMNxXJ46 |
| 16:54 | Xenon75 | any hint? |
| 16:57 | weavejester | Xenon75: Well, one adds the headers to both routes, the other just to one. You could also try evaluating post-routes with a request map in a REPL and see what happens both times. |
| 16:58 | Xenon75 | weavejester, now that you say that maybe I have completely misunderstood how cross-origin works |
| 16:59 | Xenon75 | weavejester, normally the browser does a preflight request using OPTIONS in order to understand the site is OK for receiving cross-origin XMLHttpRequest |
| 17:00 | Xenon75 | weavejester, then I try to do a POST to the same URI, but indeed, in the second case the response doesn't have the headers |
| 17:00 | Xenon75 | weavejester, but I don't see why this could compromise the correct functioning |
| 17:00 | nDuff | Xenon75: As an aside -- pastebin.com is full of animated ads for anyone not using adblock. Please consider using a pastebin without them. |
| 17:01 | Raynes | nDuff: I feel like I should start paying you or something. |
| 17:01 | weavejester | Xenon75: Try adding the headers to the other route and see what happens. |
| 17:01 | Xenon75 | nDuff, any suggesting? |
| 17:01 | Xenon75 | weavejester, indeed... good suggestion :) Trying.. |
| 17:01 | weavejester | Is there anything wrong with github gists? |
| 17:01 | nDuff | Xenon75: ...well, there's refheap.com (which Raynes wrote/runs). Also gist.github.com, sprunge.us, and several others. |
| 17:01 | Xenon75 | nDuff, thanks! |
| 17:02 | nDuff | weavejester: nope. For a while they had really awful javascript making it unnecessarily hard to copy/paste, but that's been fixed. |
| 17:02 | Raynes | weavejester: Well, it really depends on how much you like gist.github.com vs how much you like me. |
| 17:02 | Raynes | I personally like me lots, so I use refheap. |
| 17:02 | weavejester | Raynes: Haha |
| 17:02 | weavejester | I didn't know refheap was yours :) |
| 17:02 | arkh | Xenon75, it's not possible to do a POST via cross-origin XMLHttpRequest, is it? I'm thinking "jsonp" |
| 17:03 | Raynes | All mine, baby. |
| 17:03 | TimMc | I generally post to github, then paste the link into refheap. |
| 17:03 | TimMc | Because I like to pretend to like Raynes. |
| 17:04 | Xenon75 | arkh: it's possible if correct Access-Control-Allow-Origin headers are there |
| 17:04 | Xenon75 | weavejester, and you're right. it works |
| 17:05 | Xenon75 | weavejester, so I just misunderstood how cross-origin worked. :| |
| 17:06 | Xenon75 | weavejester, thanks and sorry for the noise :) |
| 17:07 | weavejester | Xenon75: It's not noise if you have an problem. Sometimes it helps just to get another pair of eyes on a problem :) |
| 17:13 | SegFaultAX | Ugh. The new AWS management console layout is horrible. |
| 17:13 | SegFaultAX | Not that the old one (or the one before that) were particularly good. But this one is /really/ bad. |
| 17:15 | liftdeadtrees | ppppaul I don't know if you were talking to me when I asked about clj-logging-config, but I'm liking timbre much better. Thanks! |
| 17:23 | nz | arkh: it is possible to use any http method, see header Access-Control-Allow-Methods |
| 17:24 | nz | arkh: for example: Access-Control-Allow-Methods: GET, POST, PUT, DELETE |
| 17:27 | arkh | nz: is Access-Control-Allow-Methods a more modern version of doing cross-site stuff by including <script> from another host as in jsonp? |
| 17:28 | arkh | nz: er, not meaning to imply it includes <script>..</script> tags |
| 17:32 | arkh | nz: nevermind - teh interwebz are teaching me all about it - thanks : ) |
| 17:34 | Raynes | stuartsierra: Oh, I was unaware that it supported ring middleware. |
| 17:34 | Raynes | stuartsierra: What are the limitations? |
| 17:35 | stuartsierra | Raynes: Pedestal requires a middleware fn to be split into 2 halves: one on the "incoming request" side, one on the "outgoing response" side. |
| 17:35 | Raynes | stuartsierra: So it isn't actually compatible with middleware without changes? |
| 17:35 | nz | arkh: that's correct |
| 17:35 | stuartsierra | Raynes: correct. But we submitted patches to Ring for all the standard middleware. |
| 17:36 | Raynes | Then I'm still pretty sad. :( |
| 17:36 | Raynes | But it's nice that you're putting effort forth to make them work. |
| 17:36 | stuartsierra | Raynes: If you don't care about Pedestal extensions like async responses and Server-Sent Events, then you can just use Ring middlewares as-is. |
| 17:36 | nz | arkh: and you need to use also other CORS headers, of course |
| 17:37 | Raynes | Makes sense. |
| 17:37 | Raynes | I think I'd like pedestal more if your hair was still blue, stuartsierra. |
| 17:38 | gfredericks | what would be good design for something like slingshot's try+ but is only meant to work with ex-info's? |
| 17:38 | stuartsierra | Raynes: I didn't even have that much to do with it. I wrote some of the low-level infrastructure of interceptors and routing, that's it. |
| 17:38 | Raynes | It effects the atmosphere, man. |
| 17:38 | Raynes | Ripple effects and what not. |
| 17:39 | stuartsierra | I was always a corporate stooge. The blue hair was just misdirection. :P |
| 17:39 | gfredericks | by which I don't mean it can't work with normal exceptions, just that the only feature is more semantic handling of ex-info |
| 17:39 | stuartsierra | gfredericks: What's wrong with try/catch? |
| 17:39 | gfredericks | stuartsierra: I want to catch conditionally based on the contents of the ex-info |
| 17:39 | gfredericks | e.g., if it has a particular key |
| 17:39 | technomancy | try/catch is based on classes, which is silly |
| 17:39 | stuartsierra | try/catch/cond/throw |
| 17:40 | gfredericks | stuartsierra: yes, that is the boilerplate I'm trying to get around |
| 17:40 | technomancy | the whole point of ex-info is to not think about exception classes |
| 17:41 | stuartsierra | I don't see it exactly that way. I think the point of ex-info is to attach arbitrary data to an exception without having to define a new class. |
| 17:42 | gfredericks | (try ... (catch-data {foo :bar} ...)) |
| 17:42 | technomancy | well, classes of exceptions aren't going to go away, but they're pretty clearly gunk which you should only have to think about when interacting with legacy code |
| 17:42 | alandipert | gfredericks: i'm with you on this ability |
| 17:42 | gfredericks | I don't think you could support arbitrary destructuring there though |
| 17:43 | gfredericks | not if you want it to be a conditional as well |
| 17:43 | TimMc | gfredericks: I thought slingshot already provided for this. |
| 17:43 | gfredericks | TimMc: it doesn't work fluently with ex-info though |
| 17:43 | gfredericks | I'd rather just use ex-info than all the tasty slingshot features I don't need |
| 17:44 | hiredman | gfredericks: well look at how slingshot does it, the thing that determines if you catch and the destructuring are separate |
| 17:44 | gfredericks | hiredman: yeah that's the other option |
| 17:44 | gfredericks | mildly repetitive but probably better overall |
| 17:44 | hiredman | the other option is to pull in core.match |
| 17:44 | gfredericks | (try ... (catch-data :bar {foo :bar} ...)) |
| 17:45 | technomancy | pattern matching on ex-info makes a lot of sense |
| 17:45 | gfredericks | hiredman: oh that could be nice |
| 17:45 | hiredman | yeah, but is core.match still buggy? |
| 17:45 | technomancy | buggy and/or quirky by design |
| 17:45 | hiredman | "their are many known issues" |
| 17:45 | hiredman | there |
| 17:47 | gfredericks | so is it better to extend slingshot with this or make a separate lib? |
| 17:47 | technomancy | gfredericks: if you just want to get stuff done, use slingshot |
| 17:47 | technomancy | if you want to push something in clojure, you'd need to start from scratch |
| 17:48 | gfredericks | technomancy: "push something in clojure" meaning suggest it for core? |
| 17:48 | technomancy | right; when I asked rich about it two conjes ago he was of the opinion that slingshot does way too much |
| 17:48 | technomancy | (which I agree with) |
| 17:49 | gfredericks | are you imagining a contrib lib, a macro in core, or some modification to the try special form? |
| 17:50 | hiredman | it would be nice to be able to extend catch sites without changing code |
| 17:50 | gfredericks | hiredman: like being able to write catch macros without rewriting try? |
| 17:50 | hiredman | sort like if you did something like (try … (catch Thorable t (some-multi-method t))) |
| 17:50 | gfredericks | oh |
| 17:51 | technomancy | gfredericks: I don't know; I guess I'm just rambling and thought I'd mention that I had run the idea by rich |
| 17:52 | gfredericks | technomancy: I guess a lib with minimal features is pretty easy |
| 17:52 | gfredericks | of the (catch pred binding & body) form |
| 17:52 | gfredericks | oh maybe catch-data instead of catch |
| 17:52 | technomancy | right; could be a good place to noodle on pred semantics |
| 17:53 | technomancy | I felt like some of the rules slingshot used to distinguish between different catch styles were too subtle |
| 17:53 | gfredericks | that way you can mix catch with catch-data and don't have to worry about mixing class-based and data-based syntax |
| 17:53 | technomancy | yeah, that would be helpful |
| 17:53 | gfredericks | okay now I just need a name. ##(format "lib-%04d" (rand-int 10000)) |
| 17:53 | lazybot | ⇒ "lib-7358" |
| 17:54 | gfredericks | any better suggestions? |
| 17:54 | gfredericks | oh dear |
| 17:55 | hiredman | I've had https://gist.github.com/hiredman/5438880 sitting in my scratch.clj |
| 17:56 | gfredericks | hiredman: this is for extensible catch-sites? |
| 17:57 | hiredman | yes |
| 17:57 | hiredman | it inlines as a cond and uses that unless the site is extended later, if I recall |
| 17:58 | hiredman | the inlining may just be ridiculous |
| 17:59 | naeg | someone having experience with lacij? the graph visualization library |
| 17:59 | amalloy | ~anyone |
| 17:59 | clojurebot | Just a heads up, you're more likely to get some help if you ask the question you really want the answer to, instead of "does anyone ..." |
| 18:00 | tyler_ | does anyone? |
| 18:01 | tyler_ | its turtles all the way down man |
| 18:01 | SegFaultAX | Has anyone really been far even as decided to use even go want to do look more like? |
| 18:01 | tyler_ | thanx markov |
| 18:05 | gfredericks | uh oh I might make it anaphoric |
| 18:06 | gfredericks | gotta figure out some way to get the exception object itself if you want it |
| 18:06 | gfredericks | e.g., to re-throw it, or print the stack trace or something |
| 18:07 | gfredericks | options A) add a second binding slot (ew), B) add it to the map under :com.gfredericks.catch-data/exception (ew?), C) make it anaphoric with &e or something |
| 18:09 | technomancy | you could add an arity to throw and pst which operate on the implicit caught ex when given no args |
| 18:09 | technomancy | not that I think it's a great idea |
| 18:11 | gfredericks | well there's other reasons to want the object |
| 18:11 | gfredericks | e.g., passing it to a log function |
| 18:11 | technomancy | yep |
| 18:12 | amalloy | gfredericks: i don't like &e |
| 18:12 | gfredericks | option D) is have two clauses, catch-data and catch-data-e |
| 18:12 | naeg | can someone help with the layout of graphs drawn by lacij? |
| 18:12 | gfredericks | amalloy: you don't like the anaphorism or the name choice? |
| 18:12 | amalloy | gfredericks: the anaphorism |
| 18:12 | naeg | here's my code: http://pastebin.com/cjYc7VLN and the result: http://i.imgur.com/zb8rjwf.png |
| 18:13 | gfredericks | amalloy: do you have a favorite of the other 3 options? :) |
| 18:13 | amalloy | it ruins composability, like if you (try (...) (catch {...} (try (...) (catch {...} (... &e ...)))) |
| 18:13 | technomancy | gfredericks: you could have the binding slot treat vectors as destructuring and lists as "bind both these things" |
| 18:13 | technomancy | amalloy: that's gross |
| 18:14 | technomancy | if you're going to do something like that it's not much work to let-bind &e on the outer one anyway |
| 18:14 | technomancy | but two try blocks in one defn is suuuuper sketchy |
| 18:15 | gfredericks | technomancy: for ex-info you'll only ever destructer as a map |
| 18:15 | gfredericks | so the vector form could be used for what you're suggesting |
| 18:15 | technomancy | gfredericks: oh duh |
| 18:15 | gfredericks | that is a very promising option E |
| 18:15 | technomancy | still a bit wacky but probably better than an anaphora? |
| 18:16 | technomancy | wait |
| 18:16 | technomancy | why not something like :as |
| 18:16 | gfredericks | oh hey |
| 18:16 | gfredericks | that's brilly |
| 18:16 | technomancy | we already have precedent for specially-named keywords |
| 18:16 | gfredericks | cause it doesn't trample on anything |
| 18:16 | gfredericks | what do we call it? |
| 18:16 | technomancy | :ex maybe |
| 18:16 | gfredericks | option F wins |
| 18:16 | gfredericks | (inc technomancy) |
| 18:16 | lazybot | ⇒ 49 |
| 18:19 | hyPiRion | oh |
| 18:19 | hyPiRion | half a century |
| 18:19 | hyPiRion | (inc technomancy) |
| 18:19 | lazybot | ⇒ 50 |
| 18:22 | hyPiRion | and why I wrote century is beyond my knowledge. If anyone knows where I can get English lessons, please tell me. |
| 18:23 | technomancy | it's a bit archaic, but not wrong |
| 18:25 | gfredericks | huh. so multiple catch-data clauses will have to be merged into a single (catch ExceptionInfo e ...) clause, obviously |
| 18:25 | gfredericks | but what if the catch-data clauses are interleaved with catch clauses? Will have to pick a spot for it. |
| 18:25 | gfredericks | could forbid that |
| 18:26 | technomancy | what happens now if you specify a class twice? |
| 18:26 | technomancy | but yeah, precedence is tricky because you want to treat it as an implementation detail |
| 18:27 | gfredericks | if you re-throw do the other clauses get tried? |
| 18:27 | amalloy | no |
| 18:27 | gfredericks | ,(try (throw (ex-info "hey" {})) (catch Exception e (throw e)) (catch Exception e :caught)) |
| 18:27 | clojurebot | gfredericks: Cool story bro. |
| 18:27 | gfredericks | &(try (throw (ex-info "hey" {})) (catch Exception e (throw e)) (catch Exception e :caught)) |
| 18:27 | lazybot | java.lang.SecurityException: You tripped the alarm! catch is bad! |
| 18:27 | gfredericks | garble |
| 18:28 | gfredericks | technomancy: in any case it compiles but ignores the later clauses |
| 18:28 | technomancy | right; so the question is whether users should have to think about whether catch-data is implemented in terms of catching ExceptionInfo |
| 18:29 | technomancy | I'd just ban catching ExceptionInfo for starters and come back to it if I were you |
| 18:29 | gfredericks | oh I was just thinking of multiples catch-data clauses with regular catches of anything in between |
| 18:29 | gfredericks | not of catching ExceptionInfo explicitely |
| 18:29 | chessguy | hi all |
| 18:29 | technomancy | gfredericks: tricky |
| 18:30 | chessguy | excited to go see a talk on pedestal tomorrow night |
| 18:30 | technomancy | gfredericks: safest thing is to ban mixing and revisit later =) |
| 18:30 | gfredericks | technomancy: yep :) |
| 18:31 | callen | chessguy: why? |
| 18:31 | chessguy | callen: why am i excited? |
| 18:31 | callen | chessguy: about Pedestal |
| 18:31 | chessguy | callen: because it looks like a cool concept |
| 18:31 | chessguy | or, rather, several cool concepts |
| 18:31 | callen | chessguy: have you done any web development in Clojure? |
| 18:31 | blr | it just looks baffling to me |
| 18:31 | callen | chessguy: or frontend with ClojureScript? |
| 18:32 | chessguy | callen: no |
| 18:32 | callen | I'm going to run out of blackboard soon. |
| 18:33 | blr | I looked at the Pedestal docs and came away thinking, I must not be smart enough for this framework, oh well. |
| 18:33 | chessguy | callen: is that column people who haven't done web development in clojure? or people who haven't done web development in clojure and are also excited about pedestal |
| 18:33 | chessguy | ? |
| 18:33 | jimkcar | anyone else having trouble accessing http://clojure.org ? |
| 18:33 | technomancy | the transformers stuff looks solid from what I saw at the talk |
| 18:33 | callen | jimkcar: not coming up for me (CA) |
| 18:33 | technomancy | it's just baffling why it's bundled with a bunch of orthogonal concepts |
| 18:33 | technomancy | err--interceptors |
| 18:34 | jimkcar | callen: ya something's up. I'm in MD |
| 18:34 | chessguy | blr: i felt the same way, that's why i'm excited to see someone actually explain it |
| 18:34 | callen | jimkcar: maybe...the server is down. |
| 18:34 | chessguy | jimkcar: having trouble with it too |
| 18:34 | callen | chessguy: it's seriously not that novel or useful. |
| 18:34 | blr | on the subject of web development, has anyone tried writing an angular app in clojurescript or is that ill advised? |
| 18:34 | callen | blr: I've done vanilla JS and Angular apps in CLJS, the latter only once. |
| 18:35 | blr | does it work okay callen? |
| 18:35 | gfredericks | okay here is https://github.com/fredericksgary/catch-data |
| 18:35 | gfredericks | but I have to go home first |
| 18:35 | callen | blr: uhhhh...lets go with "no" |
| 18:35 | SegFaultAX | jimkcar: http://www.downforeveryoneorjustme.com/clojure.org |
| 18:35 | gfredericks | planning on having it working tonight |
| 18:35 | blr | ah, thought as much :/ |
| 18:35 | callen | blr: given enough crowbar you can make anything work, but it's not a good idea. CLJS is extremely problematic unless you're doing the whole shebang yourself top to bottom. |
| 18:35 | hiredman | technomancy: my guess is they started with the client side event stuff and the interceptors were what is required to enable it |
| 18:36 | blr | I like the notion of having a clojure full stack - just haven't found the impetus to end my javascript dependancy :P |
| 18:36 | technomancy | hiredman: yeah, and it was a rush to release it before the conference I guess |
| 18:36 | technomancy | no time to split it out properly? |
| 18:36 | jimkcar | SegFaultAX: that's one of those useful sites that I'll never remember. |
| 18:37 | rasmusto | jimkcar: isup.me |
| 18:37 | callen | chessguy: the infatuation with pedestal is unmerited and generally only among people that haven't deployed anything. |
| 18:37 | SegFaultAX | jimkcar: I just start typing "downforme" into Chrome and it completes for me (even if I've never visited on that machine) |
| 18:37 | SegFaultAX | Very handy. |
| 18:37 | chessguy | hiredman: that's consistent with what i've heard |
| 18:37 | chessguy | callen: infatuation? |
| 18:37 | chessguy | seriously? |
| 18:37 | hiredman | technomancy: again, guessing, but I wonder if splitting it out even was on their radar, from their presepective it is likely to be just a piece of supporting tech for the client side |
| 18:37 | SegFaultAX | Who's infatuated with pedestal? |
| 18:37 | chessguy | because i'm excited to go hear about it? |
| 18:38 | chessguy | SegFaultAX: nobody i know |
| 18:38 | jimkcar | SeqFaultAX: I was also wondering if someone here could do something about it ;) Perhaps too passive aggressive |
| 18:38 | callen | blr: you know Prismatic? |
| 18:38 | blr | nope sorry, what's that? |
| 18:38 | callen | blr: hokay so, for one thing, take a look at their web app |
| 18:39 | callen | blr: for another, look at their tech blog. They have good stuff on using CLJS + CLJ web apps. |
| 18:39 | chessguy | prismatic is awesome |
| 18:39 | callen | blr: they've released some nice tooling. |
| 18:39 | SegFaultAX | blr: One of the more famous companies using a complete Clojure stack. |
| 18:39 | blr | ok cool, thanks for the suggestion |
| 18:39 | callen | blr: I don't actually recommend their approach on the frontend, but it's still educational. |
| 18:39 | callen | theirs is more viable than trying to make cljs play ball with angular though. |
| 18:39 | technomancy | have they re-released everything they unreleased yet? |
| 18:39 | SegFaultAX | technomancy: I don't think so. |
| 18:40 | technomancy | =\ |
| 18:40 | SegFaultAX | Only their graph stuff. |
| 18:40 | SegFaultAX | And dommy, which is meh. |
| 18:40 | callen | technomancy: nope. |
| 18:40 | blr | yeah I've been enjoying using angular, but I figured it wasn't going to play nicely with cljs |
| 18:40 | callen | technomancy: I don't really know what's going on there. |
| 18:40 | callen | blr: the attitude I take is, "when in Rome". Which in this case means, "keep the browser stuff native" |
| 18:41 | callen | blr: generally speaking, I don't need "fancy" in my frontend code (such as CLJS might make easier), I just need it to work. Using vanilla JS, jQuery, or angular makes more sense with those priorities. |
| 18:41 | blr | yeah, there's probably something to be said for that - I don't mind javascript particularly.. at least I don't hate it bitterly like so many devs seem to |
| 18:41 | callen | blr: that said, I use Ring/Clojure on the backend with gusto. |
| 18:41 | callen | I don't hate JS because I don't let myself get caught up in the much. |
| 18:41 | callen | muck* |
| 18:41 | callen | JS is simply more merciless at culling those with too much hubris. |
| 18:41 | SegFaultAX | I think JS on the server-side is really silly. |
| 18:41 | technomancy | easier to just find someone to pay to deal with the yucky bits? |
| 18:42 | callen | technomancy: I have no problems doing frontend code, it's half of what I get paid for as a consultant. |
| 18:42 | callen | oh speaking of, I'm a free agent now. |
| 18:42 | technomancy | half by the hour or half by the dollar? =) |
| 18:42 | callen | technomancy: getting a car soon and re-evaluating where to go after California after my current contract. |
| 18:43 | callen | technomancy: uhm, in terms of value proposition. |
| 18:43 | callen | technomancy: a lot of my value comes in being able to flit around like a hummingbird to whatever needs tending. |
| 18:43 | callen | I haven't found any work yet that would involve my deeper experience. |
| 18:43 | technomancy | escape from the bay |
| 18:44 | hiredman | technomancy: I recall that strangeloop keynote by the guy joyously proclaiming js everywhere, and how depressing it was |
| 18:44 | callen | technomancy: I most assuredly want to. |
| 18:44 | technomancy | hiredman: srsly |
| 18:44 | blr | hiredman: the one about prototypal inheritance? |
| 18:44 | callen | guys, I don't like server-side JS myself either (especially not Node.js), but there are real advantages to empowering frontend people to learn to serve their own needs. |
| 18:45 | tcrayford | Like being able to count ;) |
| 18:45 | callen | oh I'm sorry, did I break the circlejerk? let me see myself to the door. |
| 18:45 | SegFaultAX | callen: I don't disagree, but why can't "frontend" people just learn a new language like the rest of the development community? Why does there have to be a one-size-fits-all language? |
| 18:45 | hiredman | no this was the 2011 strangeloop I think |
| 18:46 | hiredman | https://thestrangeloop.com/sessions/post-pc-computing-is-not-a-vision |
| 18:46 | callen | SegFaultAX: I honestly really don't know. I've taught a lot of frontend people C# and Python. |
| 18:46 | SegFaultAX | callen: Note: I equally thing that "backend" people (like myself) should learn Javascript. |
| 18:46 | SegFaultAX | s/thing/think/ |
| 18:46 | callen | all I know is that node.js caused a really huge burst of activity and it's done a lot for open source. |
| 18:47 | callen | I don't believe in writing CPS code myself because I'm not a fucking coal miner, but I'm not going to look down on people that want to use what they know. |
| 18:47 | ieure | It caused a burst of activity because they had to reinvent the wheel, asynchronously. |
| 18:50 | SegFaultAX | callen: "Use what they know" is the statement I take issue with. As a poor analogy, that's like if I only ever learned to use a hammer, and then someone started a hammer-attachment project where I could attach screwdrivers and saws to my hammer to do other things than just, well, hammer. |
| 18:50 | SegFaultAX | Instead of, you know, just learning how to use a screwdriver and a saw. |
| 18:50 | aphyr | Anyone know how to use difftest with variables instead of literal values? |
| 18:50 | SegFaultAX | Hammers are a perfectly reasonable tool for some tasks, and completely inappropriate for others. Languages are sometimes the same way, I think. |
| 18:51 | aphyr | Or rather, in the context of macros? Definitely have a weird evaluation order problem here |
| 19:17 | aphyr | Aha, difftest relies on the *unqualified* symbol '= |
| 19:17 | aphyr | but if you use a macro to generate a test, it might emit clojure.core/= |
| 19:17 | aphyr | then the match fails |
| 19:22 | callen | aphyr: are you the one that did Riemann? |
| 19:22 | SegFaultAX | callen: Yup |
| 19:23 | callen | awesssssome. I need to find an excuse to use that :) |
| 19:23 | aphyr | Ya |
| 19:28 | TimMc | technomancy, gfredericks: Anaphora get tricky when they get hidden in macros, e.g. doseq causing problems for loop/recur. |
| 19:30 | amalloy | TimMc: how does doseq cause problems with loop/recur? it's clear that the body of a doseq is not in tail position, so the fact that recur doesn't work isn't related to recur being anaphoric as far as i can see |
| 19:32 | TimMc | Eh, bad example. |
| 19:33 | technomancy | I've just come to re-evaluate my knee-jerk reaction against anaphoric macros after reading some elisp that did it really nicely because it's able to guarantee it'll never be used in a place where you'd want nesting. |
| 19:37 | amalloy | i still <3 my lazy-loop anaphor: (lazy-loop [xs (range 10)] (when-let [xs (seq xs)] (cons (f (first xs)) (lazy-recur (rest xs))))) |
| 19:39 | TimMc | Does it have to be an anaphor? |
| 19:40 | amalloy | TimMc: no, but if it isn't then it's just lazy-seq (if i understand what you're asking) |
| 19:41 | amalloy | like, that's equivalent to ((fn step [xs] (lazy-seq (when-let [xs (seq xs)] (cons (f (first xs)) (step (rest xs)))))) (range 10)) |
| 19:41 | amalloy | if you have to pass a made-up name for step, it's just lazy-seq and a lambda |
| 20:20 | mthvedt | is there anything like partial that allows you to plug args into any position |
| 20:20 | amalloy | fn |
| 20:21 | mthvedt | the position(s) aren't known ahead of time |
| 20:22 | aphyr | apply? |
| 20:22 | technomancy | every 2-3 months I wish for rpartial |
| 20:22 | aphyr | technomancy: yeah me too |
| 20:22 | aphyr | then I remember partial is like 7 characters longer than # |
| 20:23 | aphyr | (modulo varargs) |
| 20:23 | technomancy | but less swearjury |
| 20:23 | technomancy | no offense to the heroic swearjure hackers |
| 20:23 | aphyr | :D |
| 20:30 | arohner | what is the best way to serialize clojure datastructures into memcached? |
| 20:30 | SegFaultAX | arohner: edn is a thing. |
| 20:31 | Raynes | arohner: (pr-str data-structures) |
| 20:31 | Raynes | If you're concerned about space, use a byte format or somethin'. |
| 20:31 | hiredman | arohner: also fressian |
| 20:32 | hiredman | https://github.com/Datomic/fressian |
| 20:32 | Raynes | Sure, like that. |
| 20:33 | arohner | Raynes: hiredman: thanks |
| 20:33 | aphyr | ooh |
| 20:33 | aphyr | fressian looks neat, may have to use that for somethiing |
| 20:34 | Raynes | aphyr: Hi. |
| 20:34 | Raynes | You're a good person. Just sayin'. |
| 20:36 | aphyr | Thanks! :D |
| 20:36 | aphyr | (also: you clearly don't know me ;-) |
| 20:37 | SegFaultAX | Speaking of Riemann... I hate that when I type in "Riemann" to Chrome, it /always/ autocomplete to Riemann Sum. fffuuu |
| 20:37 | Raynes | aphyr: You made lazybot better. That made him happy. If he is happy, I'm happy. |
| 20:37 | aphyr | SegFaultAX: UGH I know what you mean. I have a, like, 500 character twitter search for riemann stuff |
| 20:37 | aphyr | always trying to filter out the math |
| 20:38 | aphyr | Also it's given me a bizarre degree of insight into some random teenager's life |
| 20:38 | technomancy | the leiningen searches area always fun because you get 8th graders who are soooo mad about the fact that they have homework |
| 20:38 | SegFaultAX | aphyr: Haha |
| 20:38 | Raynes | aphyr: I can give you such insights. |
| 20:38 | aphyr | technomancy: hahaha, OTOH, I never have to worry about finding unrelated results when I search for 'lein something' |
| 20:38 | Raynes | I'm a 19 year old. AMA |
| 20:38 | technomancy | aphyr: https://mobile.twitter.com/leiningenhaters |
| 20:39 | aphyr | lmao is that you? |
| 20:39 | technomancy | it is |
| 20:39 | aphyr | ahaha |
| 20:39 | aphyr | get eaten by ants already |
| 20:39 | aphyr | ahahaha |
| 20:39 | technomancy | they've stopped tweeting about it so it must just be assigned around the beginning of the semester |
| 20:40 | technomancy | there's also a Carl Leiningen who plays college baseball for Sacred Heart University |
| 20:41 | jblomo | I'm having trouble setting *use-context-classloader* with lein's :global-vars option: IllegalStateException Can't change/establish root binding of: *use-context-classloader* with set clojure.lang.Var.set |
| 20:41 | jblomo | using clojure 1.5.1. How should I be setting these compiler options? |
| 20:41 | xeqi | http://www.linkedin.com/pub/lein-jenkins/43/3aa/3a2 is a fun name |
| 20:41 | SegFaultAX | xeqi: Haha |
| 20:42 | technomancy | someone plz endorse him in leiningen and jenkins |
| 20:42 | technomancy | good skills |
| 20:43 | TimMc | Today I did my first endorsement. |
| 20:43 | TimMc | It was for "turboencabulator". |
| 20:43 | technomancy | jblomo: :global-vars only works on things that Clojure establishes an implicit binding for |
| 20:43 | SegFaultAX | TimMc: Oh man, awesome. |
| 20:43 | Morgawr | guys, is there a way to actually compile Clojure in such a way where it does't require the JVM (aka native code)? |
| 20:43 | SegFaultAX | TimMc: I'm a fan of the retroencabulator myself. |
| 20:43 | TimMc | Hipster. |
| 20:43 | Morgawr | https://github.com/takeoutweight/clojure-scheme I've seen this which compiles Clojure to Scheme to native code and it's interesting, but any other attempts? |
| 20:44 | jblomo | technomancy: parsing... |
| 20:44 | SegFaultAX | TimMc: The panametric fam and dingle arms are much better. |
| 20:45 | SegFaultAX | I like to include subtle movie references in my code. I've had more than one project with a "white rabbit object" |
| 20:48 | jblomo | technomancy: OK, so it sounds like this option is built into clojure core itself, not something I could change for a library? |
| 20:48 | TimMc | SegFaultAX: Would that be... a matrix? |
| 20:49 | SegFaultAX | TimMc: Jurassic Park. |
| 20:49 | TimMc | Too subtle for me. |
| 20:49 | SegFaultAX | "Whatever it did, it did it all." |
| 20:49 | scottj | Morgawr: another attempt is https://github.com/schani/clojurec |
| 20:50 | amalloy | Morgawr: there's clojure-c too, but they're all basically useless. clojure is at its core a hosted language |
| 20:50 | TimMc | SegFaultAX: Is that the name of the malware the annoying guy installs? |
| 20:51 | SegFaultAX | TimMc: Yes :) |
| 20:53 | Morgawr | scottj and amalloy, thanks... the problem is that I love Clojure as a language but I don't like the JVM that much :( |
| 20:53 | Morgawr | at the moment I'm using ClojureScript and I love it a lot and I'd love to have that outside of the browser (or a javascript environment) without having to rely on the JVM (or the clr) |
| 20:53 | talios | node.js? |
| 20:54 | Morgawr | yes but that adds a whole lot of other problems :) |
| 20:54 | amalloy | clojurebot: cljs on node.js is a disaster |
| 20:54 | clojurebot | Ack. Ack. |
| 20:54 | talios | hah |
| 20:54 | SegFaultAX | clojurebot: Have you been watching Mars Attacks again? |
| 20:54 | clojurebot | It's greek to me. |
| 20:54 | hiredman | I think you mean "node.js is a ..." |
| 20:55 | talios | I've following a lot of the scala folk using Avian as an alternative, thats a lightweight JVM that compiles down to LLVM "statically", which would mean you'd need to AOT all your clojure tho |
| 20:55 | talios | http://oss.readytalk.com/avian/index.html |
| 20:55 | amalloy | hiredman: cljs adds all kinds of exciting new problems to the node ecosystem. they're both useful statements to make |
| 20:56 | talios | mmm actually its not LLVM as I thought, just pure c++ |
| 20:59 | mthvedt | i think this is the generalized partial i wanted earlier: https://gist.github.com/mthvedt/5439964 |
| 21:10 | technomancy | jblomo: you would have to wrap everything in a binding for it to work without changes to clojure |
| 21:11 | jblomo | technomancy: ok, thanks. I can't easily change the wrapping code (writing a class for Hadoop) so will explore other options |
| 21:12 | technomancy | or I guess alter-var-root |
| 21:13 | technomancy | not sure if that would work |
| 21:13 | technomancy | doesn't really belong in leiningen though |
| 21:13 | technomancy | |
| 21:31 | gfredericks | Okay guys I made https://github.com/fredericksgary/catch-data |
| 21:31 | gfredericks | tell me how it is terrible |
| 21:31 | gfredericks | and then I will put it on clojars |
| 21:38 | hiredman | gfredericks: you could use your own special key &ex for the exception object |
| 21:39 | hiredman | so destructuring wold be {&env the-exception}, and you can bind &env to some gensym |
| 21:41 | gfredericks | hiredman: this is instead of the :ex tactic? |
| 21:46 | tomoj | gfredericks: thanks! slingshot bothers me and tiny is good |
| 22:04 | uvtc | If I want mutation in a function, is there anything wrong with doing: `(defn foo [x] (let [n (atom 0)] ... #_(mutate n) @n))`? |
| 22:05 | uvtc | It seems to work fine... |
| 22:05 | uvtc | I guess I'd only previously made atoms at the top-level, as in: `(def foo (atom 0))`... |
| 22:07 | xeqi | uvtc: that sounds like you want a transient to me |
| 22:10 | uvtc | xeqi: Hm. I'd mostly ignored transients the first time I'd read about them ... (taking a peek again at what they are) |
| 22:22 | bttf | if I have vector [4 5] and another [6 7] how can i make them into [4 5 6 7] |
| 22:22 | bttf | i only have luck in making [4 5 [6 7]] |
| 22:22 | brehaut | ,(into [4 5] [6 7]) |
| 22:22 | clojurebot | [4 5 6 7] |
| 22:23 | bttf | ah into, ok ill check that out thanks |
| 22:23 | metellus | ,(concat [4 5] [6 7]) |
| 22:23 | clojurebot | (4 5 6 7) |
| 22:23 | brehaut | which is basically just ##(reduce conj [4 5] [6 7]) |
| 22:23 | lazybot | ⇒ [4 5 6 7] |
| 22:23 | bttf | reduce .. ok |
| 22:23 | brehaut | metadaddy__: but concat produces a lazy-seq rather than a vector |
| 22:23 | bttf | and concat too |
| 22:23 | bttf | oh |
| 22:24 | brehaut | bttf: into is just a reduce with conj because conj is polymorphic over collection type |
| 22:25 | bttf | interesting i didnt see at first that reduce takes a fn as its first param |
| 22:25 | bttf | anyways thank you |
| 22:25 | brehaut | that is the magic of it |
| 22:27 | brehaut | (if you look at (source into) you'll see that what i said is slightly a lie; it uses a transient collection if it supports it for performance reasons, so its probably a better choice than the raw reduce in most cases) |
| 22:46 | uvtc | xeqi: thanks. I think transients are just what I was looking for. Though, it is interesting to me that you can also assign an atom to a local and use that for mutation as well. |
| 22:46 | amalloy | $findfn [4 5] [6 7] [4 5 6 7] |
| 22:46 | lazybot | [clojure.set/union clojure.core/lazy-cat clojure.core/concat clojure.core/into] |
| 22:46 | amalloy | uvtc: it seems pretty unlikely that transients and atoms will fulfill the same need for you |
| 22:47 | amalloy | transients act like standard immutable structures, except that they are allowed to use mutation internally for performance. you can never count on them changing, the way you would an atom |
| 22:48 | uvtc | amalloy: I'm composing a gist to show what I was trying to do. Just a minute or two... |
| 22:48 | trptcolin | how does one perform a for-in (javascript) loop in clojurescript? |
| 22:49 | trptcolin | i've tried some (js* "for(var i in [...] stuff but no dice yet |
| 22:49 | gfredericks | $latest com.gfredericks/catch-data |
| 22:49 | lazybot | [com.gfredericks/catch-data "0.1.0"] -- https://clojars.org/com.gfredericks/catch-data |
| 22:51 | uvtc | amalloy: I was fiddling around finding integers that are palindromes. |
| 22:51 | uvtc | https://gist.github.com/uvtc/5440450 |
| 22:51 | uvtc | In try1.clj I used an atom for that local mutable state. |
| 22:52 | amalloy | yeah, transients are not applicable at all here |
| 22:53 | uvtc | amalloy: interestingly, try2 is slightly *faster* than try1. |
| 22:53 | amalloy | atoms are, although the version with no mutation is much better imo |
| 22:54 | amalloy | uvtc: i imagine that's just variance. they should be about the same, though i expect try1 is marginally faster in the long run |
| 22:55 | amalloy | try using criterium if you want to get benchmarking results that are useful, if not conclusive |
| 22:55 | uvtc | amalloy: I've been using `time lein exec try1.clj`. :) |
| 23:11 | trptcolin | best so far (ugh) (js* "eval('var results = []; for(var i in {\"foo\": \"bar\"}){ results.push(i) }; results')") |
| 23:29 | goza | hi, is there a way to use min-key with duplicate minimums? |
| 23:47 | trptcolin | goza: what do you want to have happen? |
| 23:51 | trptcolin | you could use sort-by and take-while, but min-key returns exactly one result from the inputs |
| 23:51 | goza | trptcolin: I was doing 4clojure 108, but I solved it already. I was just wondering |
| 23:52 | goza | yea sort/take seem like a good way to do it |