2013-05-29
| 00:48 | muhoo | life is but a dream, shebang, shebang |
| 00:56 | technomancy | leiningen 2.2.0 is out; will do a proper announcement tomorrow |
| 00:56 | Ember- | cool man! |
| 00:57 | supersym | sweet |
| 00:58 | sinistersnare | technomancy: is there a changelog? sounds fun |
| 00:59 | technomancy | sinistersnare: sure: https://github.com/technomancy/leiningen/blob/e4b66b2b/NEWS.md |
| 00:59 | sinistersnare | technomancy: thanks! cool stuff |
| 01:04 | amalloy | technomancy: does the first bullet point there mean i can now disable the ten-page essay that gets printed when i do `lein repl`? |
| 01:05 | technomancy | amalloy: yeah! :repl-options {:welcome (prn)} or something |
| 01:05 | amalloy | that's going straight into ~/.lein/profiles.clj |
| 01:06 | technomancy | it's only 5 lines now at least =) |
| 01:06 | technomancy | will be even shorter once https://github.com/trptcolin/reply/issues/114 is fixed |
| 01:06 | amalloy | because of the last bullet point? |
| 01:06 | technomancy | ayup |
| 01:06 | technomancy | which also means apache httpclient won't be screwing up your dependency trees any more |
| 01:06 | tomjack | :repl-options {:welcome (print-essay! (find-printer :amalloy) {:pages 10})} |
| 01:07 | tomjack | lucky for you I only run `lein repl` like once a day |
| 01:07 | technomancy | tomjack: next version we'll have lazybot integration so you can $mail amalloy every time your repl starts |
| 01:07 | amalloy | i think i'll finally be making the move from slime/swank to nrepl soon |
| 01:07 | technomancy | someone's working on the inspector, which warms my heart of stone |
| 01:08 | amalloy | i worked on four ritz/nrepl issues today, hoping to get rid of the behaviors that, compared to swank, are awful |
| 01:08 | amalloy | don't much care about the inspector, personally |
| 01:09 | technomancy | the refusal to honor the namespace declared in the buffer until you force an explicit compile was really horrible |
| 01:09 | technomancy | thankfully it appears to begone |
| 01:10 | amalloy | technomancy: i don't know what that is. what i've noticed is kinda the opposite: i can't C-c C-k a file until i've used C-c M-n to switch into its namespace |
| 01:11 | technomancy | hm; haven't seen that myself |
| 01:11 | holo | hi |
| 01:11 | nkhodyunya | Will it be good time investment to read metaobject protocols and let over lambda or any other kind of lisp book in order to make myself better clojure user? It's a question couse i'm very slow on technical reading, e.g. learning clojure with clojure programming book took me around 6 month (after working through SICP for 1 year) and i have long "read later"" list. |
| 01:11 | amalloy | conceivably could be a ritz issue, rather than nrepl itself |
| 01:12 | amalloy | nkhodyunya: those are the two books i'd recommend. if you've already read them, you should be in excellent shape |
| 01:12 | amalloy | more reading is never bad, but it's hardly critical |
| 01:13 | holo | nkhodyunya hey, i'm going to read SICP too when i have the time |
| 01:15 | holo | are let forms still idiomatic if used in middle of a defn, e.g.? |
| 01:16 | amalloy | absolutely, holo |
| 01:17 | amalloy | the only place they're not very common is inside of some other operation, like (+ 10 (let [x 2] (* x x))) |
| 01:17 | amalloy | even there they're not *wrong*, you just need to make sure it's more readable than the alternative |
| 01:20 | holo | (inc amalloy) ; thanks! |
| 01:20 | lazybot | ⇒ 57 |
| 01:20 | tomjack | huh, clojure-complete eh |
| 01:43 | sinistersnare | (inc amalloy) |
| 01:43 | lazybot | ⇒ 58 |
| 01:43 | sinistersnare | what? |
| 01:43 | clojurebot | What is 2d6 |
| 01:43 | sinistersnare | (help) |
| 01:44 | sinistersnare | (println `swag) |
| 01:44 | sinistersnare | (println "swag") |
| 01:44 | sinistersnare | ") |
| 01:44 | sinistersnare | :( |
| 01:45 | holo | ,(println "swag") |
| 01:45 | clojurebot | swag\n |
| 01:46 | sinistersnare | wat |
| 01:47 | sinistersnare | ,(println "wat") |
| 01:47 | clojurebot | wat\n |
| 01:47 | sinistersnare | whats up with the ',' |
| 01:47 | metellus | (because sometimes people want to say parentheticals) |
| 01:47 | sinistersnare | metellus: so how do you use the lazybot? |
| 01:47 | sinistersnare | i can do |
| 01:48 | sinistersnare | (inc amalloy) |
| 01:48 | lazybot | ⇒ 59 |
| 01:48 | sinistersnare | and that works |
| 01:48 | sinistersnare | but when i want to print something i need a ','? |
| 01:48 | n_b | &(prn "Like this") I think |
| 01:48 | lazybot | ⇒ "Like this" nil |
| 01:48 | metellus | or inline ##(print "like this") |
| 01:48 | lazybot | ⇒ like thisnil |
| 01:48 | sinistersnare | are those clojure symbols? or something specific to lazybot? |
| 01:48 | metellus | inc is a special case |
| 01:49 | metellus | they're all specific to the bot |
| 01:49 | metellus | just triggers to tell the bots "somebody wants you to evaluate some code here" |
| 01:49 | n_b | well, #(stuff) is an anonymous function, I had thought lazybot's trigger was #, but I'm not sure if it actually works if you do e.g. ##((#(inc %) 1)) |
| 01:49 | lazybot | java.lang.ClassCastException: java.lang.Long cannot be cast to clojure.lang.IFn |
| 01:51 | metellus | too many parens? ##(#(inc %) 1) |
| 01:51 | lazybot | ⇒ 2 |
| 01:51 | n_b | yup |
| 01:52 | n_b | paredit has forever spoiled me in matching parens |
| 01:55 | sinistersnare | :\ |
| 01:56 | amalloy | n_b: you just have to use paredit+erc |
| 01:56 | n_b | I'm one of the dirty vim users amalloy |
| 01:56 | amalloy | not something i actually do, but i think technomancy swears by it |
| 01:57 | sinistersnare | i use sublime text... |
| 01:57 | n_b | I think he also swears by w3c, no? Once in a while I like to take a break from my text editor (though I'd likely be more productive if I didn't) |
| 01:58 | metellus | n_b: paredit works well in vim? |
| 01:58 | amalloy | n_b: w3m, you mean? i think he actually uses knokeror. but either way, yes, technomancy is a bit of a fanatic |
| 02:00 | n_b | metellus: Now that I'm on trunk and not some super outdated version, yes. Has full support for all the popular vim+clojure plugins, slurps and barfs with the best of them |
| 02:01 | n_b | amalloy: A quick Google says that seems right. And I could deal with being branded a fanatic to be half as talented as he is ;) |
| 02:02 | metellus | that's great, I'll have to look into using it |
| 02:02 | n_b | metellus: the biggest issues with current vim/clojure solutions are really support for proper REPL buffers, and dealing with long-running operations without blocking the main thread |
| 02:03 | akurilin | I'm playing around with clojure.tools.trace and I'm trying to understand what exactly "tracing" is doing in this case. What does it mean to "trace a value"? For example, I can see it println whenever my ring request is "modified" (in th mvcc way, I guess). |
| 02:03 | sinistersnare | random question: hows clojure in clojure going? |
| 02:28 | technomancy | amalloy: I don't actually use paredit in ERC; I only joke about it |
| 02:28 | technomancy | show-paren-mode on the other hand, is invaluable |
| 02:29 | technomancy | also: conkeror is different from konqueror |
| 02:32 | callen | technomancy: Raynes told me about you using Conkeror yesterday. Why not vimium? You'll get to use a real browser then. |
| 02:33 | technomancy | chromium's extension mechanism has offended my intelligence on a repeated basis |
| 02:33 | callen | technomancy: fair. I take it Conkeror is more holistic with the keyboard integration? |
| 02:34 | callen | technomancy: I forget, do you use XMonad too? |
| 02:34 | technomancy | callen: instead of being purely additive, conkeror replaces all the existing UI |
| 02:34 | technomancy | it's just another javascript application that uses gecko as a rendering engine |
| 02:35 | technomancy | yeah, I use xmonad |
| 02:35 | callen | technomancy: LA is neat, great weather. I think the sunlight is making my mood noticeably cheerier. |
| 02:36 | technomancy | it's true; there are pockets of livability in LA |
| 02:36 | callen | that's a good way of putting it. |
| 02:36 | technomancy | unfortunately they didn't overlap with regions of reasonably-priced housing last I checked |
| 02:37 | technomancy | (which was a while ago) |
| 02:37 | callen | technomancy: prices seem slightly lower than the bay area, which is not flattering. |
| 02:38 | technomancy | when I was in LA I hated sunny weather |
| 02:38 | callen | the benefit seems to be being able to get a place within walking distance of the beach that is reasonably affordable. |
| 02:38 | technomancy | I was further inland though, so the coastal breezes didn't moderate the temperature |
| 02:38 | callen | technomancy: yeah the breezes make allllll the difference. I don't normally like hot weather either. |
| 02:38 | callen | I'm in west hollywood and have been hanging out along the coast. |
| 02:39 | callen | the valley would be Hell itself for me. |
| 02:40 | technomancy | gotta head off; catch you fine folks later |
| 04:09 | dbushenko | hi all! |
| 04:10 | dbushenko | how do you localize a clojurescript web application? |
| 04:19 | supersym | dbusenko..I use stringtemplate atm |
| 04:22 | supersym | there are 2 clojure wrappers but they are outdated though |
| 04:27 | dbushenko | yeah, but is there any more or less standard technology to store localized strings? |
| 04:37 | supersym | standard? no |
| 04:37 | supersym | that is the best next to perfect you'll get though, context free |
| 04:38 | supersym | you can use json for the strings |
| 04:38 | supersym | or .property files |
| 04:41 | dbushenko | or pure clojure :-) |
| 04:47 | Morgawr | hello everyone... I was wondering, are there resources for common design patterns/good application architecture pratices for Clojure or other lisp-like languages? Because I'm building a game engine (somewhat) with ClojureScript and while not unfamiliar with game development, I find it a bit hard to keep it clean and easily re-usable with Clojure as I lack this basic knowledge |
| 04:50 | dbushenko | Morgawr: I don't think so since design patterns are usually just wrappers arond language weaknesses |
| 04:51 | dbushenko | but in Clojure with code-as-data and macros you can avoid typical code |
| 04:51 | dbushenko | but still you can learn some good coding practicies from classical lisp books such as "On lisp" and others |
| 04:51 | Morgawr | yes, I understand, probably "design patterns" is a too well established definition. I'm more looking for common programming/development practice for large re-usable algorithms/solutions |
| 04:52 | Morgawr | I've read a few books and stuff and mostly they are all theoretical with small examples that fit well for solving one problem but don't "click" well together in a large application, not sure if you understand what I mean |
| 04:52 | dbushenko | sure I understand :-) |
| 04:53 | dbushenko | I don't think that you'll find any good books on best clojure practicies since its a young technology |
| 04:53 | dbushenko | and really rapidly developing |
| 04:53 | dbushenko | but you can read classical lisp books: LoL, PAIP, On Lisp and others -- they are good |
| 04:53 | dbushenko | SICP especially |
| 04:54 | Morgawr | dbushenko: I'll give them a go, thanks |
| 04:54 | dbushenko | also I'd recommend you to read some clojure code from open source projects |
| 04:54 | dbushenko | usually it worth time |
| 04:56 | Morgawr | yeah,that's how I learned how to develop a small game with ClojureScript, it was fun |
| 04:59 | dbushenko | is it deployed anywhere? can I see it? |
| 04:59 | clgv | Morgawr: there are indeed design patterns in functional languages as well. borrowing terminology from Peter Norvig, most of them are invisible or formal |
| 05:01 | Morgawr | dbushenko: https://github.com/Morgawr/ld26 here's the source code and http://www.morgawr.eu/ld26/index.html here is the game, keep in mind it was developed in only 48 hours (And I had never really written anything this big in Clojure) |
| 05:01 | Morgawr | clgv: any resource for that? |
| 05:01 | clgv | Morgawr: one example for a formal pattern is "memoization" (implement once, use everywhere). another example for an invisible pattern is the "strategy pattern" which consists of using first class functions in clojure |
| 05:02 | clgv | Morgawr: http://norvig.com/design-patterns/ |
| 05:02 | Morgawr | clgv: thanks! I appreciate it! |
| 05:02 | dbushenko | Morgawr, that took you just 48 hours??? |
| 05:02 | lazybot | dbushenko: Oh, absolutely. |
| 05:02 | dbushenko | NICE! |
| 05:02 | clgv | Morgawr: I use it for a lecture last semester |
| 05:02 | Morgawr | dbushenko: yeah, lots of lack of sleep |
| 05:09 | ddellacosta | how do I compare a Java object with another in Clojure? This is for a test, I don't care about exact identity, just that it has the same type and state. |
| 05:09 | clgv | ddellacosta: use (.equals ob1 obj2) |
| 05:10 | ddellacosta | clgv: okay, thanks! |
| 05:15 | dbushenko | clgv: do you teach clojure at the university? |
| 05:16 | clgv | dbushenko: we had a lisp course using sbcl - the choice of my boss. maybe it'll be clojure in the next course |
| 05:16 | dbushenko | wow! |
| 07:11 | Morgawr | is there really an advantage with using defrecord instead of just a normal hashmap? I mean, in the end it just plays out like any hashmap (with assoc for keys, keys aren't even fixed and can be added/removed, etc etc) |
| 07:12 | Morgawr | I mean, like performance-related advantages or some special functions to keep the handling of records cleaner than a bunch of (assoc ..) calls? |
| 07:12 | dbushenko | yes |
| 07:12 | dbushenko | its the performance benefit |
| 07:12 | dbushenko | since defrecord creates a class, access to its members is faster than to the hash-map |
| 07:12 | Morgawr | does this also work for ClojureScript? |
| 07:13 | dbushenko | don't know, cljs is still in development |
| 07:13 | dbushenko | they add features and optimizations often |
| 07:13 | dbushenko | so you'd really look into the source code and figure that out |
| 07:13 | Morgawr | alright, thanks |
| 07:14 | dbushenko | btw, the source code of the cljs is rather clear so give it a chance |
| 07:14 | Morgawr | so the only real difference (at least in pure Clojure) is the underlying memory representation? |
| 07:14 | dbushenko | yes |
| 07:14 | Morgawr | ok |
| 07:14 | IamDrowsy | records also give you type so you can use protocols with |
| 07:26 | noncom | weavejester: hi! so, about the state in a game-engine, did you make your choice? |
| 07:27 | weavejester | noncom: Yep, I'm having success with an FRP implementation I cooked up (http://github.com/weavejester/reagi) |
| 07:28 | Morgawr | weavejester: you're making a game engine? |
| 07:29 | weavejester | Morgawr: Yep, for a game. I'll probably open source the game engine part of it eventually, but it'll be a while. |
| 07:30 | Morgawr | ah nice, I'm working on something like that as well, what type of game? |
| 07:30 | weavejester | Sandbox/bloxel type thing |
| 07:30 | Morgawr | I'm tackling a point-and-click game project with ClojureScript and developing a library on the side (pretty much collecting useful features and abstractions) |
| 07:31 | Morgawr | still at the very early stages though, mostly planning. I'm trying to see if I can recycle good practices from my previous game (from Ludum Dare, it's not the best coding ever in 48 hours.. hehe) or if I should approach it differently |
| 07:32 | weavejester | Morgawr: Me too. I've only done maybe 1 month of work |
| 07:35 | Morgawr | is it possible, in Clojure, to change the value of a symbol bound with a (let ) ? |
| 07:36 | weavejester | Morgawr: You can rebind it with an inner let |
| 07:36 | weavejester | But you can't mutate the value in place |
| 07:36 | noncom | Morgawr: I would say this is a design flaw if you want do like this. |
| 07:37 | Morgawr | I was just thinking about manipulating the state of a closure |
| 07:37 | weavejester | Morgawr: You can't change a value sent to a closure |
| 07:37 | weavejester | You could use an atom |
| 07:37 | noncom | Morgawr: hmmm, refer outside |
| 07:37 | weavejester | But there's likely a better way of doing it |
| 07:39 | Morgawr | noncom: what do you men with "refer outside"? As weavejester said, I've always used an atom for such things and wanted to know if there's a better option. I'm reading this lisp book referencing common lisp and they talk about closures and changing their values to pass state around |
| 07:40 | noncom | Morgawr: yeah,weavejester said it better. I think that Clojure is far more into immutability than CL. |
| 07:41 | Morgawr | it's just that sometimes you need to have some permanent state passed around (without polluting the global state), so my best bet is to just go with an atom? |
| 07:41 | Morgawr | I try not to do this often, usually I just try to flow from function to function keeping the parameters immutable within each step, but sometimes you can't really avoid it |
| 07:42 | noncom | Morgawr: afaik LISP initially has no special attitude for immutability and what is true for other lisps is not always true for Clojure.. but that's no surprise:) |
| 07:42 | weavejester | Morgawr: Using atoms when necessary is probably okay |
| 07:42 | weavejester | Morgawr: But there are usually alternatives |
| 07:43 | weavejester | Like having a function that takes a state and returns a new state |
| 07:43 | Morgawr | weavejester: yes, that's what I mean with "flowing from function to function", I usually try to have most of my state-defining code with (-> state (func1) (func2) (func3)) etc etc |
| 07:44 | weavejester | Morgawr: What do you need the atom for, out of interest? |
| 07:44 | Morgawr | I try to use atoms only for global resource identifiers (like in my case, images and audio files to be loaded asyncronously thanks to shitty javascript hehe) and game data found in files (like settings or scripts which will be themselves also instances of ClojureScript language) |
| 07:44 | Morgawr | ^ pretty much that hehe |
| 07:45 | weavejester | Loading files asynchronously sounds like something more like a promise |
| 07:45 | Morgawr | as I am approaching it now, I have a bank of resources and identifiers, I pass the identifiers around but load the actual resources into this global bank (which is an atom) and then retrieve them when I need to render them on screen |
| 07:45 | Morgawr | promises aren't implemented in ClojureScript afaik because javascript is single threaded |
| 07:46 | Morgawr | I use an onload function which has a closure on the actual resource to be loaded |
| 07:46 | noncom | Morgawr: strange you say about single-threaded. Afaik being insanely multithreaded is even an obstacle in writing for NodeJS |
| 07:46 | Morgawr | https://github.com/Morgawr/ld26/blob/master/src/cljs/ld26/image.cljs#L24 this is an example of what I mean, taken from my Ludum Dare game |
| 07:47 | Morgawr | noncom: I'm talking about javascript on browsers, they are single threaded but rely heavily on async calls |
| 07:47 | weavejester | I think an atom's probably the right tool, but it could be wrapped up in something akin to a memoize |
| 07:47 | noncom | since every other func you write runs on it's own! |
| 07:47 | noncom | Morgawr: oh, ok i have no much exp w/ it |
| 07:47 | Morgawr | so technically on a browser with ClojureScript, if you were to implement a promise and wait for it to be fulfilled, you would block forever |
| 07:48 | Morgawr | there are some theoretical race conditions with async calls as far as I know but an atom is all you need to solve them |
| 07:48 | weavejester | It looks like you're essentially implementing a future, in that you're waiting for the image to load before you can use it. |
| 07:49 | Morgawr | yes, but that's all thanks to Javascript and how it's implemented |
| 07:49 | Morgawr | you either load everything statically in the page (cumbersome) or you load them dynamically at runtime (like what normal people would do in games) |
| 07:49 | Morgawr | the problem is that as soon as you assign the "src" field of an image (or audio file, or whatever) it starts loading it |
| 07:49 | Morgawr | and then calls an onload() function you have provided once it's done |
| 07:50 | Morgawr | so you need to provide that function yourself (a lambda with a closure over the image identifier, in my case) |
| 07:50 | weavejester | Is there something equivalent to clojure.lang.IDeref in ClojureScript? |
| 07:50 | Morgawr | you mean a dereferencing operator? like '@'? |
| 07:51 | weavejester | Morgawr: Right |
| 07:51 | Morgawr | that's what I use to dereference atoms, I'm not really an expert with Clojure (yet) , that's why I'm studying a lot on how to apply all this stuff properly |
| 07:51 | Morgawr | most of my practices are unorthodox |
| 07:54 | weavejester | It feels like promises are needed in ClojureScript to deal with cases like this |
| 07:56 | Morgawr | yes but promises in ClojureScript would block infinitely because you'd be waiting for another thread to fulfill such promise but that will never happen because it's single-threaded |
| 07:56 | Morgawr | at least that's how I understand it |
| 08:01 | broquaint | Morgawr: WRT managing state in clojurescript - http://www.chris-granger.com/2012/12/11/anatomy-of-a-knockout/ |
| 08:02 | Morgawr | broquaint: nice, thanks! I'll read it all |
| 08:20 | broquaint | np :) |
| 08:25 | manutter | weavejester: I think I understand FRP better after reading your reagi code than any of the other explanations I've seen. |
| 08:26 | noncom | weavejester: so you basically wrap all state so it looks like access to an immutable state. |
| 08:26 | weavejester | manutter: That's assuming I've understood it correctly ;) - there are still some parts like switching I don't think I completely understand. |
| 08:28 | weavejester | noncom: Well, it's more like… the results of an event stream can always be calculated from its inputs |
| 08:28 | weavejester | So it's functional; the output only depends on the inputs. |
| 08:33 | noncom | weavejester: that's rather vague. since boolean logic that underlies computers is deterministic, output always depends on inputs no matter what. when they say opposite, they usually mean that there is some "hidden" input which is not listed explicitly as a function's param??? |
| 08:33 | lazybot | noncom: Yes, 100% for sure. |
| 08:34 | Morgawr | I think it's more about side-effects, though |
| 08:34 | noncom | Morgawr: that's the same thing, just from the opposite POV |
| 08:35 | weavejester | noncom: To be more precise then, the output of an event stream is only affected by the values pushed into it. |
| 08:35 | weavejester | In the same way that the return value of a pure function is only affected by its arguments. |
| 08:36 | weavejester | Done right, there shouldn't be any side-channels. It's a more constrained way of reacting to events. |
| 08:40 | noncom | weavejester: i think that the first two examples from the reagi readme should be coupled then to show how this works.. because still it all looks more like a convention (to me). currently the third example looks more like a fancy way to write perform "inc".. |
| 08:41 | noncom | sorry if i am stupid, i just try to understand |
| 08:41 | weavejester | No, no. You're right; the examples don't really show off what it can do very well. |
| 08:42 | dnolen | Morgawr: weavejester: that's the point of core.async - you can't really have proper promises in CLJS |
| 08:42 | Morgawr | yup |
| 08:43 | supersym | reading Hackers and Painters by Paul Graham, I assume more here have :D ... truly inspiring, so much pieces fall into place |
| 08:44 | dnolen | Morgawr: re: defrecord, it has performance benefits in CLJS |
| 08:45 | weavejester | noncom: Something like this is a slightly more useful example: https://gist.github.com/weavejester/dccd00f8be0cf7c4dfe9 |
| 08:45 | Morgawr | dnolen: alright, great to know! thanks |
| 08:46 | Morgawr | looks like I have a lot of research to do, all these options... amazing |
| 08:47 | dnolen | Morgawr: you might want to pick austinh's brain when he's around - he's been developing his next game in CLJS |
| 08:48 | dnolen | Morgawr: http://pettomato.com/ |
| 08:49 | Morgawr | dnolen: great, thanks. I've see a lot of different small games deveoped in cljs and everybody always follows a slightly different approach (same goes for normal game development) |
| 08:57 | mefesto | Good morning all. |
| 09:09 | mefesto | I'm playing around with ClojureScript for NodeJS and I'm getting an error regarding this line: (set! *main-cli-fn* -main) |
| 09:09 | mefesto | says unable to resolve symbol: *main-cli-fn* |
| 09:09 | mefesto | is this an old tutorial and this is now called something else by chance? |
| 09:12 | dnolen | mefesto: I see *main-cli-fn* in core.cljs, what tutorial are you following? |
| 09:12 | mefesto | dnolen: http://dannysu.com/2013/01/14/clojurescript-for-nodejs/ |
| 09:12 | mefesto | I'm using the latest lein-cljsbuild |
| 09:13 | mefesto | and here is my source code: https://www.refheap.com/15129 |
| 09:15 | dnolen | mefesto: do you have the right extension on your file? .cljs and *not* .clj |
| 09:15 | mefesto | dnolen: ugh i bet that's it ... |
| 09:16 | mefesto | dnolen: yeah that was it :) |
| 09:16 | mefesto | dnolen: thanks. |
| 09:16 | dnolen | mefesto: cool |
| 09:18 | dnolen | mefesto: no worries, I've been bit by that before. The error about *main-cli-fn* not being defined was the clue. |
| 09:24 | mullr | Has anybody given any thought to linear systems by way of core.logic? CLP(R), I guess. I've seen the finite domain package, but I'd like to have floats. |
| 09:27 | gdev | I'm rewriting some of my java kata in clojure, so I guess this would be a code kata review: https://gist.github.com/gdeer81/5667796 any feedback appreciated. |
| 09:28 | gdev | it's only one of them so it's only a few lines of code |
| 09:34 | ro_st | so, i know i can give sort-by a key fn and a comparator |
| 09:35 | ro_st | but what if i want to sort by a juxt of several key-fns, and use a different comparator for just one of the key-fns? |
| 09:35 | xeqi | gdev: it seems like a direct translation. I bet you could come up with something simpler/more-clojure-ish with drop and (reduce + ...) |
| 09:35 | ro_st | (sort-by (juxt :name :title :date) (comp - compare) coll) ; i only want the comparator for :date - name and title ascending, but date descending |
| 09:36 | ro_st | my guess is that this is not something sort-by can do for me |
| 09:36 | ro_st | and that i'll have to use sort-by for the first two, do some sort of group-by, and then sort again with the descending comparator |
| 09:38 | noncom | weavejester: still i do not understand what's different from doing same stuff w/o wrapping it into behaviors |
| 09:38 | gdev | xeqi: yeah that's what I was afraid of. =o drop and reduce you say? I'll give it another go |
| 09:38 | weavejester | noncom: Well, (a) it's more difficult, and (b) this way you can be sure there's no side channels. |
| 09:39 | xeqi | gdev: well, I missread the description originally, but the manual recursion still feels weird |
| 09:39 | noncom | weavejester: i guess i'll be waiting for something you write with it and maybe i look and see :) |
| 09:39 | weavejester | Once you start putting together more complex transformations of event streams, doing the equivalent with atoms is significantly harder. |
| 09:39 | dnolen | mullr: I would like a CLP(R) implementation, but I don't intend to embark on that myself. Would be happy to help along any contribution towards that goal. |
| 09:40 | noncom | weavejester: possible i do not have enough experience to extrapolate this on real complex usecases |
| 09:40 | mullr | dnolen: ok, thanks for the reply. Perhaps one day, far in the future, when I'm better at core.logic I'll have a go. |
| 09:41 | gdev | xeqi: yeah I searched for examples of backtracking strategy in clojure but it was getting late and just did a translation |
| 09:41 | noncom | thank you for the explanation though, it'll get me going |
| 09:42 | gdev | should I try using core logic to get all the possible combinations of numbers I'd need and then compare that to the given array? |
| 09:43 | weavejester | noncom: I guess, to use an analogy, it's the same reason you'd want to use map/filter/reduce instead of manually writing loops with loop/recur. |
| 09:43 | dnolen | mullr: heh sure, though core.logic isn't as fancy as it seems :) |
| 09:44 | weavejester | Not only do map/filter/reduce make things easier, but you can also string them together |
| 09:44 | gdev | dnolen: are the core logic koans being maintained? was having an issue with them earlier. |
| 09:46 | dnolen | gdev: I don't know, I contributed a bit but haven't followed along in a long while |
| 09:47 | gdev | dnolen: yeah I just now noticed the last commit was a year ago =] |
| 09:47 | dnolen | gdev: you could probably get fancier since core.logic has CLP(FD), but if you haven't done much core.logic it's a massive distraction |
| 09:48 | gdev | dnolen: life's an adventure, I'll check it out =D |
| 09:48 | xeqi | gdev: this problem speaks to me as "are there any sublists of this list starting at this index that sum to target". something like (any? #(= (sum %) target) (sublists (drop start lst))). If sublists can be generated lazily then I don't think you'll need backtracking |
| 09:50 | xeqi | but that does ignore the code level requirements in the kata, which are kinda weird to have |
| 09:52 | tomjack | weavejester: still going to claim reagi is not functional, though the behavior stuff does look cool |
| 09:54 | gdev | xeqi: yeah it was just supposed to be an example of using recursion and not using loops. in java it's hard make an example that isn't overly complicated but still uses recursion. Since clojure is, for lack of a better term, good, a lot of this kata is going to feel odd |
| 09:55 | gdev | however, since this is just for my own benefit, following the constraints of the kata is at my own discretion |
| 09:56 | weavejester | tomjack: Why isn't it functional? |
| 09:57 | weavejester | I mean, it uses state behind the scenes |
| 09:57 | tomjack | well 'functional' is a vague word. but I claim it's not FRP. 'FRP' is ambiguous though :( |
| 09:58 | weavejester | But the output of an event stream depends only on its input. |
| 09:58 | tomjack | (def sum-e (r/reduce + e)) |
| 09:59 | tomjack | the value of @sum-e depends on when I ask, right? |
| 10:00 | tomjack | or rather, it depends on when I run (r/reduce + e) I guess? |
| 10:02 | weavejester | tomjack: On the contents of the event stream e |
| 10:02 | weavejester | Sematically event streams are similar to a lazy seq, except that they don't block. |
| 10:03 | tomjack | I think that should be the case, it doesn't appear to be |
| 10:04 | weavejester | Derefing an event stream (i.e. getting the latest value) isn't pure, but while you're inside the stream it is. |
| 10:05 | tomjack | https://www.refheap.com/c6e52472564b32ca0e3fe2ad4 |
| 10:06 | weavejester | tomjack: Well, that's true. There are some parts that are less pure for efficiency. |
| 10:07 | tomjack | I guess you can be careful to do things in such a way that that doesn't screw you up? |
| 10:07 | weavejester | tomjack: I assume that the event streams are all setup before pushing |
| 10:07 | weavejester | Otherwise I'd have to cache all of an event stream in memory |
| 10:08 | tomjack | yeah :( |
| 10:08 | weavejester | Haskell etc. don't have that problem because it's all precompiled |
| 10:09 | tomjack | well Reactive's Reactive is a true monad |
| 10:09 | weavejester | Same problem with defs in clojure I guess. In theory they don't change. In practise you can redef. |
| 10:09 | weavejester | I guess I'm not aiming for complete purity :) |
| 10:09 | tomjack | (but Reactive caches it all in memory like a lazy seq) |
| 10:10 | weavejester | tomjack: Don't the Haskell frameworks warn about time leaks? That would imply they don't "hold onto the head" |
| 10:11 | tomjack | a time leak happens because you can hold onto the head |
| 10:11 | tomjack | (like we get space leaks with lazy seqs) |
| 10:12 | tomjack | anyway, I think you understand what I mean now when I say 'not FRP', so I'll stop saying it from now on :). also regardless, reagi looks pretty cool, and beautifully short |
| 10:14 | weavejester | tomjack: Yeah, but Reactive would need to know when *not* to hold onto the head, right? |
| 10:15 | weavejester | tomjack: Whereas in Clojure, because of how it evaluates things in series, that would be harder to achieve. |
| 10:15 | weavejester | tomjack: I take your point that Reagi isn't pure FRP, though :) |
| 10:16 | weavejester | tomjack: But I'd probably still use the term "FRP" because we tend to refer to Clojure as "FP", even though it isn't pure. |
| 10:30 | tomjack | weavejester: I think that is close to the tricky part |
| 10:30 | noncom | weavejester: yeah.. interesting :) |
| 10:30 | tomjack | ideally you wouldn't have to know when not to hold on |
| 10:30 | tomjack | the GC will just collect the head when you stop holding it |
| 10:31 | tomjack | but I think it is tricky.. |
| 10:31 | weavejester | tomjack: Yeah… not sure how one would do that, though... |
| 10:31 | tomjack | thinking about it, I agree this deserves to be called "FRP" and I'd call what I want "first-class FRP" |
| 10:31 | tomjack | i.e. FRP with first-class events/behaviors |
| 10:31 | tomjack | elm comes to mind, where they bake in your assumption that everything's wired up beforehand as part of the compile to js |
| 10:32 | tomjack | and I think a few haskell 'FRP' attempts have had second-class events |
| 10:32 | weavejester | Yeah, I get what you mean |
| 10:33 | weavejester | There might be a better solution than Reagi, but at least it's in the right ballpack :) |
| 11:32 | silasdavis | is ther a standard way to send a json object as 'get data' in the URL of a GET request? |
| 11:33 | silasdavis | is it a weird thing to do; there seems to be much more use of form-encoded strings? |
| 11:34 | justin_smith | the idiomatic thing is if you need to send a data structure what you are doing is probably a better match for POST |
| 11:34 | justin_smith | is there a reason it has to be GET? |
| 11:34 | llasram | The CouchDB API uses query-strings with (usually tiny) JSON objects. You just JSON-encode then URL-encode. Nothing magical |
| 11:35 | llasram | But as justin_smith is suggesting, it isn't very common |
| 11:38 | justin_smith | maybe it is foolish, but I like to respect the failed dream of the semantic web, including each of GET / POST / PUT / DELETE having its own specific function |
| 11:38 | silasdavis | justin_smith, it's not destructive, it doesn't change anything |
| 11:38 | justin_smith | so the json object is a nested query object? |
| 11:38 | silasdavis | yeah that's sort of why I don't want to POST |
| 11:38 | gfredericks | GET allows a body actually |
| 11:39 | gfredericks | it's probably a weird thing to do though |
| 11:39 | justin_smith | gfredericks: how many web servers respect that? |
| 11:39 | gfredericks | seven |
| 11:39 | justin_smith | lol |
| 11:39 | gfredericks | I think security people might even flag such things |
| 11:40 | gfredericks | not sure why exactly |
| 11:40 | justin_smith | obscure feature ... abused feature |
| 11:40 | justin_smith | happens pretty frequently |
| 11:40 | gfredericks | in clojure too; since 2012 defstruct is only used by convicted felons |
| 11:42 | llasram | *snort* |
| 11:43 | TimMc | justin_smith: Don't forget PATCH! |
| 11:44 | justin_smith | wow, never heard of it, it is like swap! for web services |
| 11:44 | gfredericks | which is a much saner way of doing updates |
| 11:45 | justin_smith | definitely |
| 11:45 | gfredericks | I definitely faked it in couch by hand a few times |
| 11:45 | TimMc | swap! assoc |
| 11:45 | TimMc | I guess you could encode other functions |
| 11:45 | justin_smith | a web server could even implement it as an atom |
| 11:45 | gfredericks | TimMc: speaking of which let's work on an embedded edn-processing subset of clojure |
| 11:45 | gfredericks | I'm looking for a better name than "clem" |
| 11:46 | TimMc | gfredericks: Explain? |
| 11:46 | gfredericks | all the pure functions on data in clojure.core -- so you could do things like have a remote service that takes update code, or a command line utility that transforms edn |
| 11:48 | gfredericks | edn : clojure-forms :: clem : clojure-code |
| 11:48 | TimMc | This would be an extraction of Clojure persistent data structures + manipulations? |
| 11:48 | gfredericks | exactly |
| 11:48 | gfredericks | no host stuff, no vars, no generic I/O |
| 11:49 | gfredericks | so as an embedded language you can run things relatively safely without having to sandbox |
| 11:49 | gfredericks | could be implemented on various platforms with the same semantics |
| 11:49 | gfredericks | I keep waffling back and forth on whether I think it would be genuinely useful or only in theory |
| 11:50 | TimMc | No lambdas? |
| 11:50 | gfredericks | yes lambdas |
| 11:51 | ToxicFrog | lambdas \o/ |
| 11:51 | TimMc | Lazy seqs? |
| 11:51 | TimMc | Oh, I guess nothing infinite. |
| 11:51 | gfredericks | eh you could |
| 11:51 | TimMc | EDN wouldn't stand for it. |
| 11:51 | justin_smith | for a command line tool, I think jvm is pretty much out of the question |
| 11:51 | gfredericks | it wouldn't? |
| 11:51 | justin_smith | sadly |
| 11:51 | TimMc | (except for... streamign EDN!) |
| 11:52 | gfredericks | you could have them in memory at least |
| 11:52 | gfredericks | but it'd be more of an implementation detail than it is in clojure |
| 11:52 | solussd | does anybody know why nrepl inserts a bunch of whitespace immediately after evaluating an expression in emacs? (using nrepl-jack-in) |
| 11:52 | gfredericks | justin_smith: this is why I think it'd be cool to implement clem in C or haskell :) |
| 11:52 | solussd | *and before printing the result |
| 11:52 | justin_smith | gfredericks: awesome idea |
| 11:52 | justin_smith | a haskell clojure backend would be sweet |
| 11:53 | justin_smith | and I imagine, relatively easy to implement |
| 11:53 | thorwil | solussd: well, it doesn't do that, here |
| 11:53 | justin_smith | I looked at that c backend, it looked very rudimentary. I was looking for something I could use in signal processing code |
| 11:53 | thorwil | am i suffering from previous definitions, or does a :require in ns with :only still make everything else from the required ns available, if called with the full path? |
| 11:54 | TimMc | gfredericks: I'd want to do some reworking of the coll and seq semantics. |
| 11:54 | gfredericks | TimMc: yeah that seems fine |
| 11:54 | justin_smith | thorwil: I think :only only affects the :as clause? not sure though |
| 11:54 | gfredericks | conj on a map should not take a map as a second arg :) |
| 11:55 | justin_smith | thorwil: I know I have used libs in a repl that I never required, but code I required had required, by spelling out the full namespace |
| 11:56 | gfredericks | TimMc: what do you think about loop? and lazy-seq? do we need them? |
| 11:56 | gfredericks | can we do proper tail recursion? |
| 11:56 | thorwil | usually i either require an ns with :as, or use :refer. but now i realize i'm clueless regarding pretty much all other options |
| 11:57 | justin_smith | thorwil: yeah, I just reproduced it - you can use any code clojure has loaded by spelling out the full ns, even if you have not directly required it in the current ns |
| 11:58 | justin_smith | not that doing so in actual code is a good idea, but when lazy in a repl it works |
| 11:58 | thorwil | i have a function "string" in "tlog.interface.validate". what can i do so i can call it as either valid/string or valid-string? |
| 11:59 | justin_smith | (:require [tlog.interface.validate :as valid]) gives you valid/string |
| 12:00 | thorwil | of course, though i would have liked to express that i'm only interested in that one thing from that ns |
| 12:00 | justin_smith | (:require [tlog.interface.validate :rename {string valid-string}]) gives you valid-string (according to docs, I have never used the feature) |
| 12:01 | justin_smith | oh wait, the above was for :use not :require |
| 12:01 | thorwil | thanks, bbiab |
| 12:02 | justin_smith | (require '[clojure.set :refer :all :rename {union grand-union}]) <- that works in my shell |
| 12:03 | justin_smith | which makes me realize how much easier updating our old libs that used clojure.data.json could have been |
| 12:03 | gfredericks | oh man I don't even know about :rename |
| 12:04 | justin_smith | yeah, I wish I had known about :rename |
| 12:05 | justin_smith | as god is my witness, I will never have to suffer from a lib writer's shitty naming decisions again |
| 12:05 | gfredericks | hm |
| 12:05 | gfredericks | does it only work with :refer? |
| 12:05 | justin_smith | dunno? I will try |
| 12:05 | gfredericks | looks like it |
| 12:06 | justin_smith | that is much less useful |
| 12:06 | justin_smith | too bad |
| 12:08 | justin_smith | though you can always do (:require [foo.bar.baz :as baz :refer [quux] :rename {:quux baz-q}]) or something like that - serves a similar function to requiring the namespace prefix, though not is elegant |
| 12:25 | TimMc | gfredericks: I guess it all depends on what not-clem's intended usage is. |
| 12:28 | gfredericks | TimMc: i.e., performance constraints? |
| 12:29 | gfredericks | I wonder if the no-vars purity thing would allow smarter compiler things |
| 12:34 | justin_smith | one bonus if the project took off: it could be used for smarter clojure parsing / high level manipulation of clojure code in editors |
| 12:35 | gfredericks | eh? |
| 12:35 | gfredericks | how so? |
| 12:35 | gfredericks | oh I wonder if there are any major downsides to defining the syntax to be pure edn as well? |
| 12:35 | gfredericks | would mean no regexes |
| 12:35 | justin_smith | some basic transforms could be used to aid editor syntax awareness (as a helper task) |
| 12:35 | gfredericks | no metadata would probably be a big limitation too |
| 12:36 | justin_smith | even emacs current clojure mode awareness has flaws and corner cases |
| 12:36 | gfredericks | justin_smith: you mean by embedding clem in an editor that is not itself written in clojure? |
| 12:36 | gfredericks | haha clem in elisp would be fun |
| 12:37 | justin_smith | or letting the editor use it, the way vim uses clang to parse c |
| 12:37 | gfredericks | hmm |
| 12:37 | justin_smith | actually clem in elisp would be a double win for us emacs users, yeah |
| 12:38 | justin_smith | next step after that, re-implement emacs using an FRP arcitecture (how many "redo emacs in a better language" projects are there again?) |
| 12:53 | ohpauleez | reiddraper: Have you signed an Clojure CA? (I'm curious if you're interested in migrating some of the ideas in simple-check to test.generative and data.generators) |
| 12:53 | reiddraper | ohpauleez: yes and yes |
| 12:53 | ohpauleez | reiddraper: Cool, keep me posted |
| 12:54 | reiddraper | ohpauleez: will do. simple-check is still in it's infancy, mostly just a promising sketch at this point |
| 12:55 | ohpauleez | Cool, for sure. I've been digging through the code - nice stuff for sure. All ideas start somewhere |
| 12:55 | reiddraper | ty |
| 13:18 | TimMc | reiddraper: I've been reading through the GNU Privacy Handbook, and I think I'll probably need another month before I'd feel comfortable telling people how to make and manage their own keys. |
| 13:18 | reiddraper | TimMc: that's reassuring ;) |
| 13:23 | TimMc | The guide is outdated as far as UI goes, but still relevant I think. |
| 13:23 | TimMc | http://www.gnupg.org/gph/en/manual.html <- 14 years old |
| 14:07 | tieTYT2 | I i develop in clojure and clojurescript for one app, should they have separate project.clj's? |
| 14:08 | ohpauleez | I don't think there's a hard rule - I typically leave them together. |
| 14:08 | tieTYT2 | k, didn't even know that was possible |
| 14:08 | ohpauleez | I've broken them apart when they were really two separate applications that happen to work together nicely |
| 14:15 | bhenry | can i make a library's resources be accessible on the referring web-app's classpath? |
| 14:16 | tieTYT2 | what's a referring web app? |
| 14:16 | bhenry | tieTYT2: a webapp that uses the library |
| 14:17 | tieTYT2 | yeah they're automatically accessible |
| 14:17 | tieTYT2 | if the library can use them, you can access the resources, assuming the resources are in the library's jar |
| 14:18 | bhenry | so my library has /resources/public/library/js/blarg.js and what needs to be done for the app using my library to be able to serve up localhost:3000/library/js/blarg.js ? |
| 14:19 | tieTYT2 | oh that's a different thing from what I thought you were asking |
| 14:19 | tieTYT2 | let me think |
| 14:19 | tieTYT2 | this sounds like a maven overlay, but not exactly |
| 14:20 | bhenry | i've been thinking about it for awhile |
| 14:20 | hiredman | really? |
| 14:20 | hiredman | just use wrap-resource or whatever the ring middleware is called |
| 14:20 | tieTYT2 | http://stackoverflow.com/questions/4732965/exposing-resources-from-jar-files-in-web-applications-tomcat7 |
| 14:21 | tieTYT2 | yeah be aware I only know java, not too good with clojure |
| 14:21 | tieTYT2 | i'd listen to hiredman |
| 14:21 | bhenry | hiredman: thanks. i'll look into it |
| 14:22 | weavejester | bhenry: This is how I do it: https://github.com/weavejester/hiccup-bootstrap/blob/master/src/hiccup/bootstrap/middleware.clj |
| 14:22 | bhenry | weavejester: that's great thanks. |
| 14:34 | gfredericks | how do I set an http proxy for a leiningen repository? |
| 14:35 | gfredericks | the sample project.clj doesn't seem to have any attributes that look relevant |
| 14:36 | kephale | ccw folks (cemerick?): is there a variable/way of detecting if a source file is being run from CCW? the intention is to run -main if the file was evaluated with CCW's "load file in REPL" |
| 14:37 | cemerick | kephale: you could check for the existence of ccw's tooling namespaces (all start with ccw.* IIRC) |
| 14:39 | gfredericks | unless there is only https://github.com/technomancy/leiningen/wiki/HTTP-Proxies and you can't do it in the project.clj at all |
| 14:40 | abp | ##*clojure-version* |
| 14:40 | gfredericks | &*clojure-version* |
| 14:40 | lazybot | ⇒ {:major 1, :minor 4, :incremental 0, :qualifier nil} |
| 14:41 | kephale | cemerick: works like a charm, thank you |
| 14:41 | abp | oh ok. now i'm sad. |
| 14:42 | amalloy | abp: why? |
| 14:45 | abp | amalloy: No clojure 1.5.1 for the bot. as-> etc |
| 14:46 | amalloy | .*clojure-mode* |
| 14:46 | amalloy | ,*clojure-mode* |
| 14:46 | clojurebot | #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: *clojure-mode* in this context, compiling:(NO_SOURCE_PATH:0:0)> |
| 14:46 | amalloy | god |
| 14:46 | abp | :D |
| 14:46 | amalloy | ,*clojure-version* |
| 14:46 | clojurebot | {:interim true, :major 1, :minor 6, :incremental 0, :qualifier "master"} |
| 14:47 | abp | all right, thanks. |
| 14:49 | mefesto | im playing around with cljs + nodejs + socket.io and have a basic websocket thing going. am i able to use socket.io for a commandline *client* as well or does the client part require a browser to work? |
| 15:10 | edtsech | As an Emacs beginner I've created simple Clojure Emacs setup for other beginners https://github.com/edtsech/clojure-emacs-setup if you would like to try emacs for clojure development check this out. Feedback is welcome. |
| 15:11 | tieTYT2 | edtsech: cool, thanks |
| 15:12 | tieTYT2 | i want to group by field1 if it exists, *otherwise* group by field2 and if neither exist, put it in its own group. How do you go about doing that? Is that a group-by #(or field1 field2 (identity %)) data) |
| 15:15 | justin_smith | tieTYT2: would you use field1 from one map and field2 from another? |
| 15:15 | hyPiRion | ohooh |
| 15:16 | hyPiRion | ,(group-by (some-fn :foo :bar identity) [{:foo "foo" :bar "bar"} {:bar "bar" :hurm 1} {:something :else}]) |
| 15:16 | clojurebot | {"foo" [{:foo "foo", :bar "bar"}], "bar" [{:bar "bar", :hurm 1}], {:something :else} [{:something :else}]} |
| 15:19 | tolitius | is there a good way (besides documentation) to specify dependencies of "the thing" deployed to clojars? I'd like to publish a jar of https://github.com/tolitius/highlander but it depends (might depend) on zeromq to be installed in order to run. |
| 15:19 | antares_ | tolitius: for native dependencies, no, besides bundling them in for all platforms |
| 15:21 | tolitius | antares_: hm.. that would not be too clean, especially given the fact that zeromq needs both: itself and java bindings.. built for a particular platform |
| 15:21 | justin_smith | tolitius: have an assertion that looks for the dep, and gives the URL to get it if it is absent? |
| 15:21 | justin_smith | at the top of your init or -main if such a thing exists I guess |
| 15:21 | antares_ | tolitius: it's not "clean" and usually very painful but that's what some projects do |
| 15:22 | justin_smith | ship with a vm of linux configured to run said service :P |
| 15:23 | technomancy | yeah, the only way that works consistently is to depend on a jar with .so files and such in it |
| 15:23 | technomancy | there are no language-specific tools that do this well as far as I know |
| 15:24 | tolitius | technomancy: interesting, and then they would be resolved by reusing a classpath that points to that jar.. ? |
| 15:24 | tolitius | *they = ".so"s |
| 15:25 | tolitius | justin_smith: and if it is a cluster, ship a cluster? :) |
| 15:25 | technomancy | tolitius: leiningen will unpack the .so files for the proper OS/arch if you run with it; otherwise you can do it at runtime, which I think is what overtone and penumbra do |
| 15:25 | technomancy | (in order to still work with uberjars) |
| 15:25 | technomancy | I think everyone rolls their own systems for runtime unpacking =\ |
| 15:25 | justin_smith | you could publish build rules for a port file / .deb / arch aur / whathaveyou and tell people to install the package to get the deps |
| 15:25 | tolitius | antares_: I know Storm is trying to get away form zeromq for this and other reason, so yea, it is a problem |
| 15:26 | technomancy | debs are crappy for this since you need root and can only install one version at a time |
| 15:26 | antares_ | tolitius; have you tried JeroMQ? |
| 15:26 | antares_ | tolitius: it's a pure Java impl endorsed by the ZeroMQ lead dev |
| 15:26 | nightfly | Vague question, but how many messages per second can a message queue route? |
| 15:26 | tolitius | antares_: yea.. slow..ish |
| 15:26 | tieTYT2 | justin_smith: nope |
| 15:26 | hiredman | someone just released a netty transport for zeromq |
| 15:27 | mabes | antares_: do you have personal experience with jeromq? |
| 15:27 | technomancy | nightfly: depends on what kind of delivery guarantees you need |
| 15:27 | antares_ | mabes: nope but it seems to be fairly actively developed and used. I doubt ZeroMQ guys would support it otherwise. |
| 15:27 | tieTYT2 | hyPiRion: how does that work, is some-fn part of core? |
| 15:27 | antares_ | hiredman: link? |
| 15:27 | hyPiRion | tieTYT2: yeah |
| 15:27 | hyPiRion | (doc some-fn) |
| 15:27 | clojurebot | "([p] [p1 p2] [p1 p2 p3] [p1 p2 p3 & ps]); Takes a set of predicates and returns a function f that returns the first logical true value returned by one of its composing predicates against any of its arguments, else it returns logical false. Note that f is short-circuiting in that it will stop execution on the first argument that triggers a logical true result against the original predicates." |
| 15:27 | technomancy | also it depends on how many erlangs you have: http://bitfission.com/images/erlangs.png |
| 15:28 | hiredman | https://github.com/spotify/netty-zmtp |
| 15:28 | tieTYT2 | ah thanks |
| 15:28 | justin_smith | tieTYT2: if you need to use the same selector on all args, some-fn is not what you want (if that was what your nope was about) |
| 15:28 | hiredman | "This is a ZeroMQ codec for Netty that aims to implement ZMTP/1.0, the ZeroMQ Message Transport Protocol." |
| 15:28 | mabes | antares_: well, my understanding is that while zmq is endorsing jeromq they aren't supporting it: http://stackoverflow.com/questions/14491000/is-jeromq-production-ready |
| 15:29 | tolitius | antares_: yea, JeroMQ it has a good idea: e.g. 0mq protocol compliant without a need to install 0mq ".so"s, but it is not as fast as native.. |
| 15:29 | tieTYT2 | justin_smith: then what, should I use or like I was? |
| 15:30 | antares_ | tolitius: are you trying to reach roflscale? |
| 15:30 | justin_smith | I think there is a way to do it with condp |
| 15:31 | antares_ | tolitius: many people would take tens of thousands of msg/s as a pretty good throughput, so convenience may be more important for them than reaching the performance of the native library |
| 15:32 | tolitius | antares_: right, I agree. I had a couple of customers that needed a several mil a second |
| 15:32 | tieTYT2 | justin_smith: what's the problem with my attempt? |
| 15:32 | tolitius | but still staying in JVM |
| 15:32 | antares_ | tolitius: fair enough :) |
| 15:32 | tolitius | 0mq is really great for that |
| 15:32 | tolitius | + some design thinking of course |
| 15:35 | solussd | anyone know of any pedestal tutorials aimed at current users of MVC app frameworks? Whie I understand, conceptually, how pedestal web apps work, I'm struggling with building anything in it. |
| 15:37 | enquora | solussd: I archived a bookmark on a blog post, let me see if I can find it |
| 15:40 | justin_smith | tieTYT2: so is field1 a var that may be nil? |
| 15:40 | tieTYT2 | yes |
| 15:40 | justin_smith | *a binding |
| 15:40 | justin_smith | ahh, yeah, so that is what you want |
| 15:40 | tieTYT2 | the or? |
| 15:40 | justin_smith | yeah |
| 15:40 | tieTYT2 | cool, thanks |
| 15:40 | justin_smith | I misunderstood the question |
| 15:41 | justin_smith | and the somefn would give an npe when it gets to the one that is nil |
| 15:41 | tieTYT2 | it's not actually a var, it's more like this (fn-to-get-field1 %) |
| 15:41 | justin_smith | yeah |
| 15:41 | justin_smith | that is why I tried to correct myself to a more general term |
| 15:42 | tieTYT2 | ok thanks for the help |
| 15:43 | justin_smith | I am playing around with frp, trying to build something from scratch in order to really grok it (though I may just use someone else's lib later once I get it) |
| 15:44 | piranha | solussd: are you talking about client-side of pedestal? If so, have you seen http://squirrel.pl/blog/2013/05/16/getting-started-with-pedestal-on-client-side/ ? |
| 15:44 | justin_smith | if I have inputs to the frp nodes from multiple threads (say a network socket driving one, a gui driving another, midi device driving a third), how to best synchronize when individual parts of the network want to mutate the network (change who listens to what for example) |
| 15:45 | justin_smith | I was just passing a big network data structure around, and using run as an arg to swap!, but then the same message may produce side effects twice - I want the messages to only propagate once |
| 15:45 | justin_smith | or is allowing nodes in frp to mutate the set of connections just doing it wrong? |
| 15:46 | tieTYT2 | if nobody can help you, maybe you can get help in #haskell |
| 15:46 | justin_smith | heh, I have been chatting with a haskell using friend about this on jabber |
| 15:47 | tieTYT2 | i also find it hard to figure out what it is |
| 15:48 | tieTYT2 | everyone tells you you're doing it wrong, nobody shows how to do it right |
| 15:48 | justin_smith | well I decided I was doing it wrong when I realized I had to worry about state and race conditions, that was kind of a red flag |
| 15:49 | solussd | piranha: i had not, thanks. |
| 15:50 | justin_smith | maybe what I think requires change of state ("have the mouse click do something different next time") are better done as a message queue for something that is consumed by the other thread |
| 15:50 | justin_smith | but still I feel like there should be something cleaner here |
| 15:53 | melipone | hello! What's the best way to save a map containing other objects (such as functions) to a file? |
| 15:53 | tieTYT2 | justin_smith: maybe this will help: http://www.youtube.com/watch?v=nket0K1RXU4 |
| 15:53 | tieTYT2 | but it's a time investment |
| 15:54 | justin_smith | tieTYT2: thanks! I'll watch it while eating lunch |
| 15:54 | tieTYT2 | i'm not sure if it will help, but it's a clear explanation |
| 15:54 | tieTYT2 | with sample code |
| 15:54 | justin_smith | haskell? |
| 15:54 | clojurebot | "you have to see features like that in the context of Haskell's community, which is something like Perl's community in the garden of Eden: detached from all shame or need to do any work." -- ayrnieu |
| 15:54 | tieTYT2 | no, clojurescript |
| 15:54 | tieTYT2 | here's where I posted that: http://stackoverflow.com/a/16618078/61624 |
| 15:54 | justin_smith | oh, awesome |
| 15:55 | tieTYT2 | the SO link has a link to the source code |
| 15:55 | tieTYT2 | perhaps skip directly to the source code |
| 15:59 | amalloy | melipone: you can't serialize functions in a readable way |
| 16:03 | enquora | solussd: dunno if this will help, but for what it's worth, despite extreme attraction to cljs, I've yet to see any guidance on structuring a non-trivial app so I'm using it just for libraries. http://squirrel.pl/blog/2013/05/16/getting-started-with-pedestal-on-client-side/ |
| 16:05 | melipone | amalloy: I just want to save and load them back |
| 16:05 | amalloy | that's an accurate description of what i just said you can't do |
| 16:06 | amalloy | you can write/read forms/expressions, but not functions |
| 16:06 | melipone | amalloy: oh, okay |
| 16:08 | loliveira | how do I access in my project a variable defined in project.clj? This is a fragment of my project.clj and I'd like que access the variable :server. |
| 16:08 | loliveira | :profiles {:prod {:server "server.prod"} |
| 16:08 | loliveira | :dev {:server "server.qa"}} |
| 16:15 | tieTYT2 | justin_smith: also just found this: http://engineering.prezi.com/blog/2013/05/21/elm-at-prezi/ |
| 16:19 | llasram | loliveira: Is this in a lein task, or in your application proper? |
| 16:20 | loliveira | it is both a repl task and ring uberwar task |
| 16:20 | seangrove | tieTYT2: Was a great video, thanks |
| 16:22 | weavejester | loliveira: I wrote a library called environ where configuration can be specified via the project.clj file |
| 16:22 | llasram | loliveira: Not completely following... So when you use `lein`, it launches one JVM which loads leiningen + plugins and reads the project map etc, then if you're running a task which has to actually load your code (like `repl` or `run`) it launches another JVM to actually load your code |
| 16:22 | weavejester | loliveira: However, it won't translate over to an uberwar. For that you'll need to use system properties or environment variables. |
| 16:22 | llasram | If you want to have stuff in your project.clj that you can access in the latter context, then weavejester's library is what I was going to point you at |
| 16:23 | tieTYT2 | seangrove: np |
| 16:23 | technomancy | amalloy: you tease |
| 16:23 | tieTYT2 | that video is a little over my head actually |
| 16:24 | amalloy | technomancy: hush! no one can know of our secret lovechild serializable-fn! |
| 16:24 | amalloy | *gasp* i've said too much |
| 16:26 | konr | is there any lib cooler than swiss-arrows? https://github.com/rplevy/swiss-arrows |
| 16:26 | loliveira | llasram: i'd like to be able to run 'lein with-profile dev repl' and generate an war that connect in the right server using 'lein with-profile dev ring uberwar' |
| 16:27 | loliveira | weavejester: what will happen if I generate my war with the rolling command: 'lein with-profile dev ring uberwar'? |
| 16:28 | ohpauleez | konr: some-> as-> cond-> or https://github.com/LonoCloud/synthread |
| 16:28 | weavejester | loliveira: It'll compile the uberwar with the dev profile, but the configuration won't be hardwired into the war, which is what I'm guessing you want. |
| 16:28 | weavejester | In general hardwired configuration is a bad idea. |
| 16:29 | loliveira | weavejester: how do you suggest I should resolve this? |
| 16:32 | weavejester | loliveira: Which server are you deploying the war to? |
| 16:32 | loliveira | jetty |
| 16:33 | loliveira | jetty-distribution-9.0.3.v20130506 |
| 16:34 | weavejester | loliveira: Is it a requirement to deploy as a war? |
| 16:38 | loliveira | weavejester: yes. And I can not change this. =( |
| 16:38 | weavejester | loliveira: That's okay. I just wanted to check, because the alternatives are a lot easier :) |
| 16:39 | loliveira | weavejester: =) |
| 16:40 | konr | ohpauleez: awesome! |
| 16:41 | weavejester | loliveira: Hm, it looks like there's a configuration file for wars that Jetty uses. I guess that would be the official way of conifguring the war. |
| 16:43 | loliveira | weavejester: it might work, but i loved the idea that I could concentrate all config in one place (project.clj) =( |
| 16:44 | weavejester | loliveira: It makes sense not to do that when deploying to a (dare I say) more sane environment. :) |
| 16:44 | technomancy | project.clj is not designed for runtime application configuration |
| 16:44 | technomancy | there are ways to make it work, but that's not what it's meant for |
| 16:45 | loliveira | weavejester: you convinced me. I'll look for alternatives. thank you. =) |
| 16:45 | weavejester | loliveira: I guess you could add a resource file that would only be included in your uberwar in production. |
| 16:46 | weavejester | loliveira: You could add an extra directory to :resource-paths in a :prod profile, and then add a configuration file in the resource path. |
| 16:47 | loliveira | weavejester: sounds nice. How do I select the right file to send to war? |
| 16:47 | loliveira | technomancy: agreed. |
| 16:48 | weavejester | loliveira: Well, you could have something like: :profiles {:prod {:resource-paths ["resources" "config/prod"]}} |
| 16:48 | technomancy | weavejester: did you see the new :uberjar profile in lein 2.2? |
| 16:48 | technomancy | might want to support something similar for uberwars |
| 16:48 | weavejester | technomancy: Nope. What's that? |
| 16:48 | weavejester | technomancy: Oh, a profile just for uberjars, I guess? |
| 16:48 | loliveira | weavejester: it just what I wanted. ty. |
| 16:49 | technomancy | yeah, gets applied implicitly |
| 16:49 | weavejester | That's a good idea |
| 16:49 | clojurebot | One idea I had was to parameterise Keyword with the key it looks up. :a is of (Keyword :a). But that has other issues. |
| 16:49 | technomancy | weavejester: lets you add :main what.ever without contaminating regular dev time with AOT |
| 16:49 | weavejester | technomancy: Yeah. I like that idea. |
| 18:11 | akurilin | In clj, what's a good way to swap method implementations for unit testing purposes? For example, I have a compojure route that ends in an email being sent through some AWS infrastructure. In development, I would probably want to replace that last part with something else more testable. |
| 18:14 | justin_smith | akurilin: postmark has a drop in test version of its emailer |
| 18:14 | mpenet | ,(doc with-redefs) |
| 18:14 | clojurebot | "([bindings & body]); binding => var-symbol temp-value-expr Temporarily redefines Vars while executing the body. The temp-value-exprs will be evaluated and each resulting value will replace in parallel the root value of its Var. After the body is executed, the root values of all the Vars will be set back to their old values. These temporary changes will be visible in all threads. Useful for mockin... |
| 18:14 | mpenet | that could do it |
| 18:14 | justin_smith | you can just make a version of the email function that verifies the types / content of the args and gripes if they are weird |
| 18:15 | akurilin | justin_smith, how would I "inject" that version of the function? |
| 18:16 | justin_smith | personally I prefer to rewrite my functions so anything I wouldn't want to happen at test time is a parameter and not baked in, but that probably isn't to everyone's stylistic preference |
| 18:16 | nightfly | dynamic vars ftw |
| 18:16 | justin_smith | so instead of (defn send-mail [from to body subject] ...) I write a function (defn send-email [from to body subject emailer] ...) |
| 18:16 | hiredman | nightfly: no |
| 18:17 | hiredman | nightfly: no |
| 18:17 | mpenet | imho with-redefs really seems like the sane solutions here |
| 18:17 | weavejester | I'd be inclined to choose an implementation via a configuration. |
| 18:18 | hiredman | the best solution is to base behaviour on passed in information, but if you can't do that then with-redefs |
| 18:18 | weavejester | In the same way that a database URL can point to a local (maybe embedded) database during developmnent, and a remote one in production. |
| 18:18 | akurilin | mpenet, for with-redefs, I include the function I want to override in the namespace where my tests are, and then everything contained with that with-redefs will basically use the new version? Am I understanding that correctly? |
| 18:20 | akurilin | hiredman, weavejester : what would you recommend as an elegant way to select between two implementations if I were to go the environ route and check for development/production/test etc? |
| 18:20 | akurilin | I feel like there must be something better than an if statement. |
| 18:20 | mpenet | not exactly: see examples here http://clojuredocs.org/clojure_core/clojure.core/with-redefs . It redefines vars for the body of the redef, and restores them once the body executed |
| 18:20 | nightfly | with-redefs is pretty much dynamic scoping |
| 18:20 | hiredman | use carica, it comes with a config override deal exactly for tests |
| 18:21 | mpenet | nightfly: not really , the change is visible to *all* threads |
| 18:21 | hiredman | https://github.com/sonian/carica#testing |
| 18:21 | mpenet | nightfly: but other than that yes, very similar |
| 18:22 | weavejester | akurilin: It sounds like what you want is polymorphism over configurations |
| 18:22 | weavejester | So either multimethods or protocols |
| 18:23 | weavejester | What you want is a "send-email" function that changes implementation based on a configuration, I'd guess. |
| 18:23 | mpenet | akurilin: For different setups via config, Environ is very handy |
| 18:24 | mpenet | but weavejester can tell you more about it than me probably :) |
| 18:24 | technomancy | if it's just changing for test then with-redefs is better than a multimethod |
| 18:24 | technomancy | with-redefs works great with clojure.test fixtures |
| 18:26 | akurilin | So, if I'm understanding that correctly, the idea would be to basically replace the email sending logic with clojure.test (is) calls? |
| 18:27 | technomancy | no, you would replace it with a function that saves the args off to an atom or something |
| 18:27 | _{^_^}__ | someone asked me what the crowning difference between observer pattern and frp was |
| 18:27 | _{^_^}__ | i couldn't answer |
| 18:27 | _{^_^}__ | now im curious |
| 18:28 | technomancy | (let [delivered (atom [])] (with-redefs [send-email #(swap! delivered conj %&)] (do-stuff) (is (= [...] @delivered)))) |
| 18:28 | technomancy | akurilin: ^ |
| 18:30 | akurilin | technomancy, basically the issue is that there's really no easy way of passing back the values that are at the bottom of that call stack that we want to test, because that whole call chain ends in a side-effect, so one's best bet is to basically "extract" them and test them. |
| 18:30 | akurilin | yes? |
| 18:30 | clojurebot | yes isn't is |
| 18:31 | technomancy | thanks clojurebot |
| 18:31 | akurilin | I love that guy :) |
| 18:31 | technomancy | but yeah, what you described is basically on-target |
| 18:31 | akurilin | technomancy, great, thank you. |
| 18:32 | technomancy | often people ask how they can mock functions out and get pointed to midje when all they really need is with-redefs =\ |
| 18:32 | akurilin | I'm actually considering moving off of clojure.test, it's annoying that it doesn't print out the test case names by default |
| 18:32 | akurilin | I don't know if there's some out-of-the-box way of having that happen. |
| 18:33 | technomancy | lein test will print the deftest names when there's a failure |
| 18:33 | hiredman | akurilin: you mean when they pass? |
| 18:33 | hiredman | seems useless |
| 18:33 | hiredman | (they definitely get printed out when they fail) |
| 18:33 | akurilin | I guess mine is a corner case, I had one test case take 20 seconds every 4-5 runs and I couldn't tell which one it was |
| 18:33 | justin_smith | technomancy: not to mention also any (testing "foo" ...) forms |
| 18:34 | technomancy | akurilin: (is (< (- (System/currentTimeMillis) start-time) 5000)) |
| 18:35 | akurilin | technomancy, that's definitely the most straightforward way. I went the long route and wrapped every test in a profiler call. |
| 18:35 | akurilin | Which worked out ok, I discovered each test case takes 30ms, yuck. |
| 18:36 | akurilin | justin_smith, (testing "foo") doesn't actually print anything either until it fails, right? |
| 18:36 | justin_smith | yeah, but it is helpful for extra context when you have more than one is clause in a deftest |
| 18:37 | akurilin | Since we were on the carica/environ topic, I'm a bit puzzled that neither documentations really shows you how to switch between different environments that one creates configs for. Basically I get how to make that config file, but how do I switch between multiple? Is that purely lein profile based? |
| 18:37 | justin_smith | if you want something printed every time, why not println? |
| 18:37 | technomancy | akurilin: with carica it's just based on the classpath |
| 18:38 | akurilin | justin_smith, sure, that's quite doable. |
| 18:38 | hiredman | carica doesn't have environments or profiles |
| 18:38 | technomancy | it's outside the scope of carica to manage the classpath |
| 18:38 | justin_smith | you could even write a macro wrapping deftest that prints the name of the defined test |
| 18:38 | hiredman | generally you have a set of default configs that get backed in to your jar/uberjar |
| 18:38 | technomancy | presumably something is launching either `java -cp ...` or `lein run ...`; it's that tool's responsibility |
| 18:39 | hiredman | and then you might have some other tool (chef, puppet, etc) write out overrides somewhere and put those overrides on the right place on the classpath for your app |
| 18:39 | akurilin | So what you'se saying is that the best bet is to let project.clj choose the right config file depending on profile? |
| 18:39 | akurilin | in the lein case. |
| 18:40 | technomancy | akurilin: based on the classpath, which is a function of the :resource-paths of the currently-active profiles (if you want to get pedantic) |
| 18:40 | decaf | nrepl client in emacs has great completion support. can I bring this to .clj file editing? |
| 18:40 | technomancy | decaf: M-TAB should work in clojure-mode if you're connected to nrepl |
| 18:41 | justin_smith | with many wms that has to be escape-tab, sadly |
| 18:41 | justin_smith | unless you are like me and pick wm based on which one can be made not to steal meta |
| 18:44 | akurilin | technomancy, So if I wanted to have a couple of separate config files based on environment, would you recommend that I just add their respective folders in the :resource-paths of each profile I'm interested in? And then, as hiredman suggested, make sure I build the uberjar with the production environment. |
| 18:45 | technomancy | akurilin: exactly |
| 18:45 | technomancy | akurilin: uberjar will strip out the default profiles for you actually |
| 18:46 | akurilin | Am I making this too Railsy or is that reasonable? |
| 18:47 | akurilin | I can never tell the difference between them just doing things right and me not knowing a better way :) |
| 18:47 | technomancy | if you need multiple environments, "check a file on the classpath" is a tried-and-true JVM-friendly way to do it |
| 18:47 | technomancy | most people don't need anything beyond resources/ and dev-resources/ directories |
| 18:47 | akurilin | technomancy, ok that's great to know. |
| 18:48 | akurilin | I gotta mail this log to myself, you guys have shared so many pearls here with me today. |
| 18:49 | technomancy | better than sharing perls |
| 18:50 | hiredman | ~#95 |
| 18:50 | clojurebot | 95. Don't have good ideas if you aren't willing to be responsible for them. -- Alan J. Perlis |
| 18:51 | akurilin | For a one VM scenario, is there actually a significant benefit to uberjarring my project for production? My use case is really basic, and I've been able to get away with just fetching the repo with git and running the web app straight from source. |
| 18:51 | technomancy | akurilin: repeatable deployments and faster boot time |
| 18:51 | technomancy | using git on production is sloppy |
| 18:52 | flu- | +1 |
| 18:53 | akurilin | It certainly does take a while to boot on a micro instance. |
| 18:54 | hiredman | micros suck |
| 18:54 | Raynes | technomancy: What do you mean? |
| 18:54 | Raynes | 'using git on production' |
| 18:54 | decaf | if anyone else is looking for tab completion: https://raw.github.com/genehack/smart-tab/master/smart-tab.el |
| 18:56 | technomancy | Raynes: well, resolving dependencies on production nodes is sloppy |
| 18:56 | technomancy | dependency resolution isn't completely deterministic |
| 18:56 | abp | akurilin: Recently I used weavejester's environ to get a profile.clj setting or environment variable. So on dev machines I add :env {:my-project-env :dev} to lein profile.clj, on servers set MY_PROJECT_ENV=live etc. Then in /resources I have a base config.clj and one dev_config.clj, live_config.clj etc. that overwrite parts of config.clj, according :to my-project-env, when loaded via carica. |
| 18:56 | Raynes | technomancy: Don't understand the correlation between dependency resolution and git on production here. |
| 18:56 | hiredman | I had clojurebot (3-4 jvm services) running on a t1.micro, I have it half moved over to a cheaper node on non-aws virtualized hosting and the node is way more responsive with even more jvms running on it |
| 18:57 | akurilin | abp, do you have a repo for reference? That'd be really cool. |
| 18:57 | technomancy | Raynes: it's an implied correlation. if you're freezing jars in a build environment, you've got some way to ship files out... why not use that for application source as well as jars? |
| 18:58 | technomancy | if you've got one way of getting jars to production and another way of getting source to production, that sounds unnecessarily complicated |
| 18:58 | abp | akurilin: Could whip up a sample, don't have anything public by now. |
| 18:59 | technomancy | if there were no such thing as version ranges, snapshots, or unreliable maven repositories, then dependency resolution could be strictly deterministic and everything would be peachy |
| 18:59 | technomancy | unfortunately existence is suffery |
| 18:59 | technomancy | suffering |
| 18:59 | papachan | i just have installed leiningen 2.2 |
| 19:00 | akurilin | abp, I think it'd be valuable to more than just me, since it's not something I've seen much in public repos at this point and it's very much relevant to almost every web app out there. |
| 19:00 | akurilin | abp, your description above is good enough for me though :) |
| 19:00 | papachan | how i can start with this feature:Isolate target paths by profiles? |
| 19:01 | technomancy | papachan: you don't have to do anything |
| 19:01 | technomancy | it just works that way by default |
| 19:01 | papachan | technomancy: ok let me try :) |
| 19:03 | abp | akurilin: I'm at it. |
| 19:04 | akurilin | abp, kudos! Even better, you can turn that into a neat blog post. |
| 19:04 | abp | akurilin: I don't have a blog. :x |
| 19:04 | akurilin | abp, Ah! Well, one step at a time then! :) |
| 19:42 | Sintendo | how can i split up my code across files? |
| 19:42 | abp | Sintendo: Create files and write code. :) |
| 19:43 | abp | Sintendo: http://clojure-doc.org/articles/language/namespaces.html |
| 19:44 | amalloy | i'm amazed that a document that long doesn't mention the -/_ conversion |
| 19:45 | abp | amalloy: They don't? |
| 19:45 | amalloy | having just read it, i can tell you that it is not mentioned |
| 19:45 | abp | amalloy: I got caught by it when doing my first experiments two years ago and saw multiple people stumble since. |
| 19:46 | amalloy | everyone trips on it sometime |
| 19:46 | Sintendo | what do i do with those? filename conatins a - in my case |
| 19:47 | hyPiRion | use _ instead |
| 19:48 | abp | amalloy: http://clojure-doc.org/articles/language/namespaces.html#namespaces_and_class_generation there it is. ;) |
| 19:48 | hyPiRion | ,(munge "a.namespace.foo-bar") |
| 19:48 | clojurebot | "a.namespace.foo_bar" |
| 19:49 | Sintendo | so i must rename the file? |
| 19:49 | amalloy | each _ in the filename must correspond to a - in the namespace, and vice versa |
| 19:50 | abp | Sintendo: Yes, underscores in filenames, dashes in namespaces. |
| 19:50 | Sintendo | Could not locate lru_cache__init.class or lru_cache.clj on classpath |
| 19:51 | Sintendo | oh wait, i figured it out |
| 19:51 | Sintendo | thanks everyone |
| 19:52 | Sintendo | Is there a way to import private functions anyway? |
| 19:53 | hyPiRion | private functions from java or clojure? |
| 19:53 | Sintendo | clojure |
| 19:53 | hiredman | well java doesn't have functions, it has methods |
| 19:53 | Sintendo | I guess not? |
| 19:54 | hyPiRion | Sintendo: Well, you could refer to the var |
| 19:55 | hyPiRion | ,(#'clojure.core/>1? 1) |
| 19:55 | clojurebot | false |
| 19:55 | hyPiRion | ,(#'clojure.core/>1? 2) |
| 19:55 | clojurebot | true |
| 19:55 | Sintendo | well, i guess it's easier to just make them public |
| 19:56 | hyPiRion | yeah |
| 19:56 | Sintendo | thanks |
| 19:56 | abp | hiding my functions, so I can call on vars |
| 19:57 | benkay | datomic chan x-post: I have a "balance" i update in place in datomic, but when I query for that balance, I keep getting a list of the past balances. what's the idiomatic query format to request just the most recent datom? |
| 19:57 | abp | Sintendo: Not making fun of you, just thought it's a funny phrase. :) |
| 19:58 | benkay | bueller? |
| 19:59 | Sintendo | No problem dude, thanks for the help! |
| 20:06 | technomancy | it's basically a slap in the face that clojure's "could not find foo_bar.clj" message doesn't check for foo-bar.clj and advise you to rename it |
| 20:08 | hiredman | benkay: my guess is you are defining a new entity and a new balance everytime you think you are "updating" the balanace |
| 20:10 | hiredman | benkay: like you are trying to upsert, but inserting instead |
| 20:11 | benkay | hiredman that's totally possible. i'm definitely *trying* to upsert but i haven't quite wrapped my head around the syntax yet. |
| 20:11 | hiredman | you may need a :db/unique :db.unique/identity on whatever attribute you intend as a "primary key" |
| 20:11 | abp | technomancy: That's true for many of clojures exceptions until you know'em or at least how to diagnose. Also it's not easy to ignore unhelpful stacktraces and just find your mistake when still learning. |
| 20:12 | benkay | hiredman i *just* saw that in the halloway upserting gist that's floating around :) |
| 20:13 | hiredman | otherwise the only primary key is the entity id, which is often not known and basically treated as a gensym in transactions |
| 20:18 | technomancy | abp: yeah, that one is just outstanding in how easy it would be to offer helpful advice |
| 20:21 | benkay | thanks hiredman. |
| 20:27 | abp | hiredman: When will carica with middleware support be released? |
| 20:27 | hiredman | leathekd: ? |
| 20:28 | hiredman | I don't know |
| 20:29 | leathekd | abp: I'll see what I can do. I don't believe there is anything else pending for 1.0.3 |
| 20:31 | abp | leathekd: Cool, thanks. I've just written some middleware. |
| 20:32 | leathekd | Nice. What did you make? |
| 20:33 | technomancy | middleware? |
| 20:33 | hiredman | https://github.com/sonian/carica#middleware |
| 20:34 | technomancy | nice |
| 20:40 | abp | leathekd: I'm generalizing some environment-based config merging I wrote a while ago. |
| 20:40 | abp | Wrote about it earlier in here. |
| 20:40 | abp | Using middleware it's basically no code. |
| 20:52 | dnolen | bbloom: you look at React? |
| 20:57 | leathekd | abp: Cool, glad Carica is working out for you. |
| 21:03 | justin_smith | slightly OT: I am deploying a ring app to tomcat, and I am seeing messages about the app shutting down, but nothing in catalina.log indicating how or why it stopped - short of putting debug printouts all through my app is there something I can do to see what exactly is happening in tomcat when it autodeploys my war? |
| 21:28 | bbloom | dnolen: the new thing from facebook/instragram? not yet really |
| 21:28 | bbloom | dnolen: did you? thoughts? |
| 21:29 | dnolen | bbloom: I didn't think it was very interesting until I read they operate on a virtual DOM model to minimize touching the real DOM for perf reasons. |
| 21:29 | bbloom | dnolen: yeah, the DOM is just slow: period. |
| 21:31 | bbloom | we got lucky that the founders of the WWW escaped the brain dead OOP wave of the 90s, but that doesn't change the fact that the DOM is effectively a big mutable bag of callbacks (even internally) with naively O(N^3) algorithms that are arguably NP hard to optimize in the general case facing interactive mutation |
| 21:31 | bbloom | :-P |
| 21:32 | bbloom | also, i was instantly turned off by the XML preprocessor thing |
| 22:04 | amalloy | bbloom: n^3? what algorithm are you thinking of? |
| 22:05 | bbloom | amalloy: layout when js code is constantly updating positions & styles |
| 22:06 | bbloom | i'm playing fast and loose with the formalities of that…. my point is that it's hard & made much harder by the fact that things are changing, animating, etc |
| 22:16 | ohpauleez | Is David Pollak in here? |
| 22:18 | pandeiro | would ring.middleware.json-params interfere with ring.middleware.multipart-params? i'm wrapping my entire app handler in compojure's site middleware, along with wrap-json-params on some API routes, and my multipart form POST requests are never getting added to :params/:multipart-params. can't figure out why not... |
| 22:19 | brehaut | pandeiro: i recall that they both consume :body, so yes they would |
| 22:19 | brehaut | pandeiro: ring is *mostly* functional; :body is the exception, and can only be consumed once. |
| 22:19 | pandeiro | brehaut: makes sense |
| 22:20 | brehaut | pandeiro: however, it should respect your content type header? |
| 22:20 | pandeiro | huh, right, it should |
| 22:20 | pandeiro | but let me step back one step |
| 22:20 | pandeiro | even if the json-params are only being applied to some routes, that middleware would consume the body for any route? |
| 22:21 | pandeiro | that doesn't make sense actually because the multipart POST route comes before the json api routes |
| 22:21 | brehaut | if those routes are called, and content tpye matches, yes |
| 22:21 | pandeiro | but route specific handlers as setup by defroutes short circuit, right? |
| 22:21 | pandeiro | i noticed the source of routes or routing uses 'some' |
| 22:22 | brehaut | yeah |
| 22:23 | pandeiro | k i'm still at a loss then... must be something else i am doing |
| 22:31 | dnolen | wow as-> cond-> really allow you remove some serious grossness |
| 22:36 | pandeiro | ha |
| 22:37 | pandeiro | ring-multipart-params won't handle the input[type=file] if there is no name attribute |
| 22:48 | bbloom | dnolen: https://github.com/brandonbloom/ascribe <- a very early version of the attribute grammar thing i was showing you. I linked some of the literature in the readme if you're interested at all. lots more work locally in branches that i'm putzing with |
| 22:49 | dnolen | bbloom: link doesn't work? |
| 22:49 | bbloom | dnolen: lol try again |
| 22:50 | bbloom | dnolen: apparently making it public took a second... |
| 22:52 | phyrephox | so i'm building a webapp using clojure and clojurescript |
| 22:52 | phyrephox | and i'm wondering if i can have some crossover code |
| 22:53 | phyrephox | that's the same code in clojure/clojurescript, but it does something different in clojure than in clojurescript |
| 22:53 | phyrephox | i.e. there's a macro in the crossover code, and it generates one set of code in CLJ and another set of code in CLJS |
| 22:53 | phyrephox | is this possible? |
| 22:55 | phyrephox | hmm, maybe i can use cljsbuild conditional comments? |
| 22:55 | hiredman | http://dev.clojure.org/display/design/Feature+Expressions |
| 22:57 | phyrephox | so this is a patch and/or an experimental feature? doesn't seem too useful |
| 22:57 | phyrephox | seems like a nicer solution than the cljs build comments though, that's for sure |
| 22:58 | dnolen | phyrephox: known pain point, maybe core.async will push it along, unclear |
| 22:58 | phyrephox | cool thanks. i actually think i can accomplish what i want to using the ;*CLJSBUILD-REMOVE*; thing |
| 22:59 | phyrephox | not an ideal solution, but once a better solution comes along i don't think it'll be too hard to refactor |
| 22:59 | dnolen | so much craziness in my projects to remove w/ as-> cond-> |
| 23:04 | bbloom | dnolen: what about as-> and cond-> ? |
| 23:04 | dnolen | bbloom: remove repeated bindings to the same name in a let |
| 23:05 | dnolen | which actually bit me a couple of times because it's not very functional |
| 23:05 | bbloom | heh, yeah, i find when you just stick a * or a ' on the end it can be confusing… especially around version*** three or so :-P |
| 23:05 | bbloom | usually better to come up with clearer names or split up the function |
| 23:22 | TimMc | gfredericks: Are you sure that what you want for clem isn't Erlang? :-) |
| 23:28 | bbloom | i <3 clojure's data types so much |
| 23:28 | bbloom | where other people painstakingly create these data models & hand code all these behaviors in to them, i just grab some maps and vectors & everything just frickin works |
| 23:46 | tomjack | "Declarative" then the second example is "A Stateful Component" hmm |
| 23:47 | dnolen | bbloom: that feature of Clojure cannot be understated |
| 23:48 | bbloom | dnolen: it's totally mind altering. i don't even know how i used to write software like a year ago :-P |
| 23:50 | dnolen | tomjack: yeah overall not interesting. But I think the virtual DOM + requestAnimationFrame could be promising for CLJS |
| 23:50 | dnolen | or for some CLJS lib |
| 23:50 | dnolen | I mean |
| 23:51 | tomjack | I really don't understand "virtual dom" |
| 23:52 | dnolen | tomjack: touching the DOM is expensive so you manipulate a virtual representation instead |
| 23:53 | dnolen | you accumulate changes, then you do a bulk update |
| 23:53 | alisdair | all problems in computer science can be solved with another layer of indirection |
| 23:54 | tomjack | dnolen: so that's pretty much just "use data" right |
| 23:55 | dnolen | tomjack: yes |
| 23:57 | xeqi | wonder how that helps with Phil Karlton's problems |
| 23:58 | bbloom | dnolen: as you know, i've been experimenting with that bulk update model. so far it seems pretty nice, but i've only made small prototypes |
| 23:58 | dnolen | bbloom: yeah that's I mentioned it to you earlier |
| 23:58 | dnolen | that's why |