#clojure logs

2013-05-29

00:48muhoolife is but a dream, shebang, shebang
00:56technomancyleiningen 2.2.0 is out; will do a proper announcement tomorrow
00:56Ember-cool man!
00:57supersymsweet
00:58sinistersnaretechnomancy: is there a changelog? sounds fun
00:59technomancysinistersnare: sure: https://github.com/technomancy/leiningen/blob/e4b66b2b/NEWS.md
00:59sinistersnaretechnomancy: thanks! cool stuff
01:04amalloytechnomancy: does the first bullet point there mean i can now disable the ten-page essay that gets printed when i do `lein repl`?
01:05technomancyamalloy: yeah! :repl-options {:welcome (prn)} or something
01:05amalloythat's going straight into ~/.lein/profiles.clj
01:06technomancyit's only 5 lines now at least =)
01:06technomancywill be even shorter once https://github.com/trptcolin/reply/issues/114 is fixed
01:06amalloybecause of the last bullet point?
01:06technomancyayup
01:06technomancywhich also means apache httpclient won't be screwing up your dependency trees any more
01:06tomjack:repl-options {:welcome (print-essay! (find-printer :amalloy) {:pages 10})}
01:07tomjacklucky for you I only run `lein repl` like once a day
01:07technomancytomjack: next version we'll have lazybot integration so you can $mail amalloy every time your repl starts
01:07amalloyi think i'll finally be making the move from slime/swank to nrepl soon
01:07technomancysomeone's working on the inspector, which warms my heart of stone
01:08amalloyi worked on four ritz/nrepl issues today, hoping to get rid of the behaviors that, compared to swank, are awful
01:08amalloydon't much care about the inspector, personally
01:09technomancythe refusal to honor the namespace declared in the buffer until you force an explicit compile was really horrible
01:09technomancythankfully it appears to begone
01:10amalloytechnomancy: 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:11technomancyhm; haven't seen that myself
01:11holohi
01:11nkhodyunyaWill 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:11amalloyconceivably could be a ritz issue, rather than nrepl itself
01:12amalloynkhodyunya: those are the two books i'd recommend. if you've already read them, you should be in excellent shape
01:12amalloymore reading is never bad, but it's hardly critical
01:13holonkhodyunya hey, i'm going to read SICP too when i have the time
01:15holoare let forms still idiomatic if used in middle of a defn, e.g.?
01:16amalloyabsolutely, holo
01:17amalloythe only place they're not very common is inside of some other operation, like (+ 10 (let [x 2] (* x x)))
01:17amalloyeven there they're not *wrong*, you just need to make sure it's more readable than the alternative
01:20holo(inc amalloy) ; thanks!
01:20lazybot⇒ 57
01:20tomjackhuh, clojure-complete eh
01:43sinistersnare(inc amalloy)
01:43lazybot⇒ 58
01:43sinistersnarewhat?
01:43clojurebotWhat is 2d6
01:43sinistersnare(help)
01:44sinistersnare(println `swag)
01:44sinistersnare(println "swag")
01:44sinistersnare")
01:44sinistersnare:(
01:45holo,(println "swag")
01:45clojurebotswag\n
01:46sinistersnarewat
01:47sinistersnare,(println "wat")
01:47clojurebotwat\n
01:47sinistersnarewhats up with the ','
01:47metellus(because sometimes people want to say parentheticals)
01:47sinistersnaremetellus: so how do you use the lazybot?
01:47sinistersnarei can do
01:48sinistersnare(inc amalloy)
01:48lazybot⇒ 59
01:48sinistersnareand that works
01:48sinistersnarebut when i want to print something i need a ','?
01:48n_b&(prn "Like this") I think
01:48lazybot⇒ "Like this" nil
01:48metellusor inline ##(print "like this")
01:48lazybot⇒ like thisnil
01:48sinistersnareare those clojure symbols? or something specific to lazybot?
01:48metellusinc is a special case
01:49metellusthey're all specific to the bot
01:49metellusjust triggers to tell the bots "somebody wants you to evaluate some code here"
01:49n_bwell, #(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:49lazybotjava.lang.ClassCastException: java.lang.Long cannot be cast to clojure.lang.IFn
01:51metellustoo many parens? ##(#(inc %) 1)
01:51lazybot⇒ 2
01:51n_byup
01:52n_bparedit has forever spoiled me in matching parens
01:55sinistersnare:\
01:56amalloyn_b: you just have to use paredit+erc
01:56n_bI'm one of the dirty vim users amalloy
01:56amalloynot something i actually do, but i think technomancy swears by it
01:57sinistersnarei use sublime text...
01:57n_bI 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:58metellusn_b: paredit works well in vim?
01:58amalloyn_b: w3m, you mean? i think he actually uses knokeror. but either way, yes, technomancy is a bit of a fanatic
02:00n_bmetellus: 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:01n_bamalloy: 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:02metellusthat's great, I'll have to look into using it
02:02n_bmetellus: 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:03akurilinI'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:03sinistersnarerandom question: hows clojure in clojure going?
02:28technomancyamalloy: I don't actually use paredit in ERC; I only joke about it
02:28technomancyshow-paren-mode on the other hand, is invaluable
02:29technomancyalso: conkeror is different from konqueror
02:32callentechnomancy: Raynes told me about you using Conkeror yesterday. Why not vimium? You'll get to use a real browser then.
02:33technomancychromium's extension mechanism has offended my intelligence on a repeated basis
02:33callentechnomancy: fair. I take it Conkeror is more holistic with the keyboard integration?
02:34callentechnomancy: I forget, do you use XMonad too?
02:34technomancycallen: instead of being purely additive, conkeror replaces all the existing UI
02:34technomancyit's just another javascript application that uses gecko as a rendering engine
02:35technomancyyeah, I use xmonad
02:35callentechnomancy: LA is neat, great weather. I think the sunlight is making my mood noticeably cheerier.
02:36technomancyit's true; there are pockets of livability in LA
02:36callenthat's a good way of putting it.
02:36technomancyunfortunately they didn't overlap with regions of reasonably-priced housing last I checked
02:37technomancy(which was a while ago)
02:37callentechnomancy: prices seem slightly lower than the bay area, which is not flattering.
02:38technomancywhen I was in LA I hated sunny weather
02:38callenthe benefit seems to be being able to get a place within walking distance of the beach that is reasonably affordable.
02:38technomancyI was further inland though, so the coastal breezes didn't moderate the temperature
02:38callentechnomancy: yeah the breezes make allllll the difference. I don't normally like hot weather either.
02:38callenI'm in west hollywood and have been hanging out along the coast.
02:39callenthe valley would be Hell itself for me.
02:40technomancygotta head off; catch you fine folks later
04:09dbushenkohi all!
04:10dbushenkohow do you localize a clojurescript web application?
04:19supersymdbusenko..I use stringtemplate atm
04:22supersymthere are 2 clojure wrappers but they are outdated though
04:27dbushenkoyeah, but is there any more or less standard technology to store localized strings?
04:37supersymstandard? no
04:37supersymthat is the best next to perfect you'll get though, context free
04:38supersymyou can use json for the strings
04:38supersymor .property files
04:41dbushenkoor pure clojure :-)
04:47Morgawrhello 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:50dbushenkoMorgawr: I don't think so since design patterns are usually just wrappers arond language weaknesses
04:51dbushenkobut in Clojure with code-as-data and macros you can avoid typical code
04:51dbushenkobut still you can learn some good coding practicies from classical lisp books such as "On lisp" and others
04:51Morgawryes, 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:52MorgawrI'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:52dbushenkosure I understand :-)
04:53dbushenkoI don't think that you'll find any good books on best clojure practicies since its a young technology
04:53dbushenkoand really rapidly developing
04:53dbushenkobut you can read classical lisp books: LoL, PAIP, On Lisp and others -- they are good
04:53dbushenkoSICP especially
04:54Morgawrdbushenko: I'll give them a go, thanks
04:54dbushenkoalso I'd recommend you to read some clojure code from open source projects
04:54dbushenkousually it worth time
04:56Morgawryeah,that's how I learned how to develop a small game with ClojureScript, it was fun
04:59dbushenkois it deployed anywhere? can I see it?
04:59clgvMorgawr: there are indeed design patterns in functional languages as well. borrowing terminology from Peter Norvig, most of them are invisible or formal
05:01Morgawrdbushenko: 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:01Morgawrclgv: any resource for that?
05:01clgvMorgawr: 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:02clgvMorgawr: http://norvig.com/design-patterns/
05:02Morgawrclgv: thanks! I appreciate it!
05:02dbushenkoMorgawr, that took you just 48 hours???
05:02lazybotdbushenko: Oh, absolutely.
05:02dbushenkoNICE!
05:02clgvMorgawr: I use it for a lecture last semester
05:02Morgawrdbushenko: yeah, lots of lack of sleep
05:09ddellacostahow 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:09clgvddellacosta: use (.equals ob1 obj2)
05:10ddellacostaclgv: okay, thanks!
05:15dbushenkoclgv: do you teach clojure at the university?
05:16clgvdbushenko: we had a lisp course using sbcl - the choice of my boss. maybe it'll be clojure in the next course
05:16dbushenkowow!
07:11Morgawris 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:12MorgawrI mean, like performance-related advantages or some special functions to keep the handling of records cleaner than a bunch of (assoc ..) calls?
07:12dbushenkoyes
07:12dbushenkoits the performance benefit
07:12dbushenkosince defrecord creates a class, access to its members is faster than to the hash-map
07:12Morgawrdoes this also work for ClojureScript?
07:13dbushenkodon't know, cljs is still in development
07:13dbushenkothey add features and optimizations often
07:13dbushenkoso you'd really look into the source code and figure that out
07:13Morgawralright, thanks
07:14dbushenkobtw, the source code of the cljs is rather clear so give it a chance
07:14Morgawrso the only real difference (at least in pure Clojure) is the underlying memory representation?
07:14dbushenkoyes
07:14Morgawrok
07:14IamDrowsyrecords also give you type so you can use protocols with
07:26noncomweavejester: hi! so, about the state in a game-engine, did you make your choice?
07:27weavejesternoncom: Yep, I'm having success with an FRP implementation I cooked up (http://github.com/weavejester/reagi)
07:28Morgawrweavejester: you're making a game engine?
07:29weavejesterMorgawr: Yep, for a game. I'll probably open source the game engine part of it eventually, but it'll be a while.
07:30Morgawrah nice, I'm working on something like that as well, what type of game?
07:30weavejesterSandbox/bloxel type thing
07:30MorgawrI'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:31Morgawrstill 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:32weavejesterMorgawr: Me too. I've only done maybe 1 month of work
07:35Morgawris it possible, in Clojure, to change the value of a symbol bound with a (let ) ?
07:36weavejesterMorgawr: You can rebind it with an inner let
07:36weavejesterBut you can't mutate the value in place
07:36noncomMorgawr: I would say this is a design flaw if you want do like this.
07:37MorgawrI was just thinking about manipulating the state of a closure
07:37weavejesterMorgawr: You can't change a value sent to a closure
07:37weavejesterYou could use an atom
07:37noncomMorgawr: hmmm, refer outside
07:37weavejesterBut there's likely a better way of doing it
07:39Morgawrnoncom: 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:40noncomMorgawr: yeah,weavejester said it better. I think that Clojure is far more into immutability than CL.
07:41Morgawrit'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:41MorgawrI 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:42noncomMorgawr: 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:42weavejesterMorgawr: Using atoms when necessary is probably okay
07:42weavejesterMorgawr: But there are usually alternatives
07:43weavejesterLike having a function that takes a state and returns a new state
07:43Morgawrweavejester: 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:44weavejesterMorgawr: What do you need the atom for, out of interest?
07:44MorgawrI 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:44Morgawr^ pretty much that hehe
07:45weavejesterLoading files asynchronously sounds like something more like a promise
07:45Morgawras 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:45Morgawrpromises aren't implemented in ClojureScript afaik because javascript is single threaded
07:46MorgawrI use an onload function which has a closure on the actual resource to be loaded
07:46noncomMorgawr: strange you say about single-threaded. Afaik being insanely multithreaded is even an obstacle in writing for NodeJS
07:46Morgawrhttps://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:47Morgawrnoncom: I'm talking about javascript on browsers, they are single threaded but rely heavily on async calls
07:47weavejesterI think an atom's probably the right tool, but it could be wrapped up in something akin to a memoize
07:47noncomsince every other func you write runs on it's own!
07:47noncomMorgawr: oh, ok i have no much exp w/ it
07:47Morgawrso 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:48Morgawrthere are some theoretical race conditions with async calls as far as I know but an atom is all you need to solve them
07:48weavejesterIt looks like you're essentially implementing a future, in that you're waiting for the image to load before you can use it.
07:49Morgawryes, but that's all thanks to Javascript and how it's implemented
07:49Morgawryou either load everything statically in the page (cumbersome) or you load them dynamically at runtime (like what normal people would do in games)
07:49Morgawrthe problem is that as soon as you assign the "src" field of an image (or audio file, or whatever) it starts loading it
07:49Morgawrand then calls an onload() function you have provided once it's done
07:50Morgawrso you need to provide that function yourself (a lambda with a closure over the image identifier, in my case)
07:50weavejesterIs there something equivalent to clojure.lang.IDeref in ClojureScript?
07:50Morgawryou mean a dereferencing operator? like '@'?
07:51weavejesterMorgawr: Right
07:51Morgawrthat'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:51Morgawrmost of my practices are unorthodox
07:54weavejesterIt feels like promises are needed in ClojureScript to deal with cases like this
07:56Morgawryes 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:56Morgawrat least that's how I understand it
08:01broquaintMorgawr: WRT managing state in clojurescript - http://www.chris-granger.com/2012/12/11/anatomy-of-a-knockout/
08:02Morgawrbroquaint: nice, thanks! I'll read it all
08:20broquaintnp :)
08:25manutterweavejester: I think I understand FRP better after reading your reagi code than any of the other explanations I've seen.
08:26noncomweavejester: so you basically wrap all state so it looks like access to an immutable state.
08:26weavejestermanutter: That's assuming I've understood it correctly ;) - there are still some parts like switching I don't think I completely understand.
08:28weavejesternoncom: Well, it's more like… the results of an event stream can always be calculated from its inputs
08:28weavejesterSo it's functional; the output only depends on the inputs.
08:33noncomweavejester: 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:33lazybotnoncom: Yes, 100% for sure.
08:34MorgawrI think it's more about side-effects, though
08:34noncomMorgawr: that's the same thing, just from the opposite POV
08:35weavejesternoncom: To be more precise then, the output of an event stream is only affected by the values pushed into it.
08:35weavejesterIn the same way that the return value of a pure function is only affected by its arguments.
08:36weavejesterDone right, there shouldn't be any side-channels. It's a more constrained way of reacting to events.
08:40noncomweavejester: 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:41noncomsorry if i am stupid, i just try to understand
08:41weavejesterNo, no. You're right; the examples don't really show off what it can do very well.
08:42dnolenMorgawr: weavejester: that's the point of core.async - you can't really have proper promises in CLJS
08:42Morgawryup
08:43supersymreading Hackers and Painters by Paul Graham, I assume more here have :D ... truly inspiring, so much pieces fall into place
08:44dnolenMorgawr: re: defrecord, it has performance benefits in CLJS
08:45weavejesternoncom: Something like this is a slightly more useful example: https://gist.github.com/weavejester/dccd00f8be0cf7c4dfe9
08:45Morgawrdnolen: alright, great to know! thanks
08:46Morgawrlooks like I have a lot of research to do, all these options... amazing
08:47dnolenMorgawr: you might want to pick austinh's brain when he's around - he's been developing his next game in CLJS
08:48dnolenMorgawr: http://pettomato.com/
08:49Morgawrdnolen: 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:57mefestoGood morning all.
09:09mefestoI'm playing around with ClojureScript for NodeJS and I'm getting an error regarding this line: (set! *main-cli-fn* -main)
09:09mefestosays unable to resolve symbol: *main-cli-fn*
09:09mefestois this an old tutorial and this is now called something else by chance?
09:12dnolenmefesto: I see *main-cli-fn* in core.cljs, what tutorial are you following?
09:12mefestodnolen: http://dannysu.com/2013/01/14/clojurescript-for-nodejs/
09:12mefestoI'm using the latest lein-cljsbuild
09:13mefestoand here is my source code: https://www.refheap.com/15129
09:15dnolenmefesto: do you have the right extension on your file? .cljs and *not* .clj
09:15mefestodnolen: ugh i bet that's it ...
09:16mefestodnolen: yeah that was it :)
09:16mefestodnolen: thanks.
09:16dnolenmefesto: cool
09:18dnolenmefesto: no worries, I've been bit by that before. The error about *main-cli-fn* not being defined was the clue.
09:24mullrHas 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:27gdevI'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:28gdevit's only one of them so it's only a few lines of code
09:34ro_stso, i know i can give sort-by a key fn and a comparator
09:35ro_stbut 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:35xeqigdev: it seems like a direct translation. I bet you could come up with something simpler/more-clojure-ish with drop and (reduce + ...)
09:35ro_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:36ro_stmy guess is that this is not something sort-by can do for me
09:36ro_stand 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:38noncomweavejester: still i do not understand what's different from doing same stuff w/o wrapping it into behaviors
09:38gdevxeqi: yeah that's what I was afraid of. =o drop and reduce you say? I'll give it another go
09:38weavejesternoncom: Well, (a) it's more difficult, and (b) this way you can be sure there's no side channels.
09:39xeqigdev: well, I missread the description originally, but the manual recursion still feels weird
09:39noncomweavejester: i guess i'll be waiting for something you write with it and maybe i look and see :)
09:39weavejesterOnce you start putting together more complex transformations of event streams, doing the equivalent with atoms is significantly harder.
09:39dnolenmullr: 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:40noncomweavejester: possible i do not have enough experience to extrapolate this on real complex usecases
09:40mullrdnolen: 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:41gdevxeqi: yeah I searched for examples of backtracking strategy in clojure but it was getting late and just did a translation
09:41noncomthank you for the explanation though, it'll get me going
09:42gdevshould 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:43weavejesternoncom: 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:43dnolenmullr: heh sure, though core.logic isn't as fancy as it seems :)
09:44weavejesterNot only do map/filter/reduce make things easier, but you can also string them together
09:44gdevdnolen: are the core logic koans being maintained? was having an issue with them earlier.
09:46dnolengdev: I don't know, I contributed a bit but haven't followed along in a long while
09:47gdevdnolen: yeah I just now noticed the last commit was a year ago =]
09:47dnolengdev: 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:48gdevdnolen: life's an adventure, I'll check it out =D
09:48xeqigdev: 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:50xeqibut that does ignore the code level requirements in the kata, which are kinda weird to have
09:52tomjackweavejester: still going to claim reagi is not functional, though the behavior stuff does look cool
09:54gdevxeqi: 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:55gdevhowever, since this is just for my own benefit, following the constraints of the kata is at my own discretion
09:56weavejestertomjack: Why isn't it functional?
09:57weavejesterI mean, it uses state behind the scenes
09:57tomjackwell 'functional' is a vague word. but I claim it's not FRP. 'FRP' is ambiguous though :(
09:58weavejesterBut the output of an event stream depends only on its input.
09:58tomjack(def sum-e (r/reduce + e))
09:59tomjackthe value of @sum-e depends on when I ask, right?
10:00tomjackor rather, it depends on when I run (r/reduce + e) I guess?
10:02weavejestertomjack: On the contents of the event stream e
10:02weavejesterSematically event streams are similar to a lazy seq, except that they don't block.
10:03tomjackI think that should be the case, it doesn't appear to be
10:04weavejesterDerefing an event stream (i.e. getting the latest value) isn't pure, but while you're inside the stream it is.
10:05tomjackhttps://www.refheap.com/c6e52472564b32ca0e3fe2ad4
10:06weavejestertomjack: Well, that's true. There are some parts that are less pure for efficiency.
10:07tomjackI guess you can be careful to do things in such a way that that doesn't screw you up?
10:07weavejestertomjack: I assume that the event streams are all setup before pushing
10:07weavejesterOtherwise I'd have to cache all of an event stream in memory
10:08tomjackyeah :(
10:08weavejesterHaskell etc. don't have that problem because it's all precompiled
10:09tomjackwell Reactive's Reactive is a true monad
10:09weavejesterSame problem with defs in clojure I guess. In theory they don't change. In practise you can redef.
10:09weavejesterI guess I'm not aiming for complete purity :)
10:09tomjack(but Reactive caches it all in memory like a lazy seq)
10:10weavejestertomjack: Don't the Haskell frameworks warn about time leaks? That would imply they don't "hold onto the head"
10:11tomjacka time leak happens because you can hold onto the head
10:11tomjack(like we get space leaks with lazy seqs)
10:12tomjackanyway, 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:14weavejestertomjack: Yeah, but Reactive would need to know when *not* to hold onto the head, right?
10:15weavejestertomjack: Whereas in Clojure, because of how it evaluates things in series, that would be harder to achieve.
10:15weavejestertomjack: I take your point that Reagi isn't pure FRP, though :)
10:16weavejestertomjack: 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:30tomjackweavejester: I think that is close to the tricky part
10:30noncomweavejester: yeah.. interesting :)
10:30tomjackideally you wouldn't have to know when not to hold on
10:30tomjackthe GC will just collect the head when you stop holding it
10:31tomjackbut I think it is tricky..
10:31weavejestertomjack: Yeah… not sure how one would do that, though...
10:31tomjackthinking about it, I agree this deserves to be called "FRP" and I'd call what I want "first-class FRP"
10:31tomjacki.e. FRP with first-class events/behaviors
10:31tomjackelm comes to mind, where they bake in your assumption that everything's wired up beforehand as part of the compile to js
10:32tomjackand I think a few haskell 'FRP' attempts have had second-class events
10:32weavejesterYeah, I get what you mean
10:33weavejesterThere might be a better solution than Reagi, but at least it's in the right ballpack :)
11:32silasdavisis ther a standard way to send a json object as 'get data' in the URL of a GET request?
11:33silasdavisis it a weird thing to do; there seems to be much more use of form-encoded strings?
11:34justin_smiththe idiomatic thing is if you need to send a data structure what you are doing is probably a better match for POST
11:34justin_smithis there a reason it has to be GET?
11:34llasramThe CouchDB API uses query-strings with (usually tiny) JSON objects. You just JSON-encode then URL-encode. Nothing magical
11:35llasramBut as justin_smith is suggesting, it isn't very common
11:38justin_smithmaybe 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:38silasdavisjustin_smith, it's not destructive, it doesn't change anything
11:38justin_smithso the json object is a nested query object?
11:38silasdavisyeah that's sort of why I don't want to POST
11:38gfredericksGET allows a body actually
11:39gfredericksit's probably a weird thing to do though
11:39justin_smithgfredericks: how many web servers respect that?
11:39gfredericksseven
11:39justin_smithlol
11:39gfredericksI think security people might even flag such things
11:40gfredericksnot sure why exactly
11:40justin_smithobscure feature ... abused feature
11:40justin_smithhappens pretty frequently
11:40gfredericksin clojure too; since 2012 defstruct is only used by convicted felons
11:42llasram*snort*
11:43TimMcjustin_smith: Don't forget PATCH!
11:44justin_smithwow, never heard of it, it is like swap! for web services
11:44gfrederickswhich is a much saner way of doing updates
11:45justin_smithdefinitely
11:45gfredericksI definitely faked it in couch by hand a few times
11:45TimMcswap! assoc
11:45TimMcI guess you could encode other functions
11:45justin_smitha web server could even implement it as an atom
11:45gfredericksTimMc: speaking of which let's work on an embedded edn-processing subset of clojure
11:45gfredericksI'm looking for a better name than "clem"
11:46TimMcgfredericks: Explain?
11:46gfredericksall 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:48gfredericksedn : clojure-forms :: clem : clojure-code
11:48TimMcThis would be an extraction of Clojure persistent data structures + manipulations?
11:48gfredericksexactly
11:48gfredericksno host stuff, no vars, no generic I/O
11:49gfredericksso as an embedded language you can run things relatively safely without having to sandbox
11:49gfrederickscould be implemented on various platforms with the same semantics
11:49gfredericksI keep waffling back and forth on whether I think it would be genuinely useful or only in theory
11:50TimMcNo lambdas?
11:50gfredericksyes lambdas
11:51ToxicFroglambdas \o/
11:51TimMcLazy seqs?
11:51TimMcOh, I guess nothing infinite.
11:51gfrederickseh you could
11:51TimMcEDN wouldn't stand for it.
11:51justin_smithfor a command line tool, I think jvm is pretty much out of the question
11:51gfredericksit wouldn't?
11:51justin_smithsadly
11:51TimMc(except for... streamign EDN!)
11:52gfredericksyou could have them in memory at least
11:52gfredericksbut it'd be more of an implementation detail than it is in clojure
11:52solussddoes anybody know why nrepl inserts a bunch of whitespace immediately after evaluating an expression in emacs? (using nrepl-jack-in)
11:52gfredericksjustin_smith: this is why I think it'd be cool to implement clem in C or haskell :)
11:52solussd*and before printing the result
11:52justin_smithgfredericks: awesome idea
11:52justin_smitha haskell clojure backend would be sweet
11:53justin_smithand I imagine, relatively easy to implement
11:53thorwilsolussd: well, it doesn't do that, here
11:53justin_smithI looked at that c backend, it looked very rudimentary. I was looking for something I could use in signal processing code
11:53thorwilam 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:54TimMcgfredericks: I'd want to do some reworking of the coll and seq semantics.
11:54gfredericksTimMc: yeah that seems fine
11:54justin_smiththorwil: I think :only only affects the :as clause? not sure though
11:54gfredericksconj on a map should not take a map as a second arg :)
11:55justin_smiththorwil: 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:56gfredericksTimMc: what do you think about loop? and lazy-seq? do we need them?
11:56gfrederickscan we do proper tail recursion?
11:56thorwilusually i either require an ns with :as, or use :refer. but now i realize i'm clueless regarding pretty much all other options
11:57justin_smiththorwil: 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:58justin_smithnot that doing so in actual code is a good idea, but when lazy in a repl it works
11:58thorwili 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:59justin_smith(:require [tlog.interface.validate :as valid]) gives you valid/string
12:00thorwilof course, though i would have liked to express that i'm only interested in that one thing from that ns
12:00justin_smith(:require [tlog.interface.validate :rename {string valid-string}]) gives you valid-string (according to docs, I have never used the feature)
12:01justin_smithoh wait, the above was for :use not :require
12:01thorwilthanks, bbiab
12:02justin_smith(require '[clojure.set :refer :all :rename {union grand-union}]) <- that works in my shell
12:03justin_smithwhich makes me realize how much easier updating our old libs that used clojure.data.json could have been
12:03gfredericksoh man I don't even know about :rename
12:04justin_smithyeah, I wish I had known about :rename
12:05justin_smithas god is my witness, I will never have to suffer from a lib writer's shitty naming decisions again
12:05gfrederickshm
12:05gfredericksdoes it only work with :refer?
12:05justin_smithdunno? I will try
12:05gfrederickslooks like it
12:06justin_smiththat is much less useful
12:06justin_smithtoo bad
12:08justin_smiththough 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:25TimMcgfredericks: I guess it all depends on what not-clem's intended usage is.
12:28gfredericksTimMc: i.e., performance constraints?
12:29gfredericksI wonder if the no-vars purity thing would allow smarter compiler things
12:34justin_smithone bonus if the project took off: it could be used for smarter clojure parsing / high level manipulation of clojure code in editors
12:35gfrederickseh?
12:35gfrederickshow so?
12:35gfredericksoh I wonder if there are any major downsides to defining the syntax to be pure edn as well?
12:35gfrederickswould mean no regexes
12:35justin_smithsome basic transforms could be used to aid editor syntax awareness (as a helper task)
12:35gfredericksno metadata would probably be a big limitation too
12:36justin_smitheven emacs current clojure mode awareness has flaws and corner cases
12:36gfredericksjustin_smith: you mean by embedding clem in an editor that is not itself written in clojure?
12:36gfrederickshaha clem in elisp would be fun
12:37justin_smithor letting the editor use it, the way vim uses clang to parse c
12:37gfrederickshmm
12:37justin_smithactually clem in elisp would be a double win for us emacs users, yeah
12:38justin_smithnext step after that, re-implement emacs using an FRP arcitecture (how many "redo emacs in a better language" projects are there again?)
12:53ohpauleezreiddraper: 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:53reiddraperohpauleez: yes and yes
12:53ohpauleezreiddraper: Cool, keep me posted
12:54reiddraperohpauleez: will do. simple-check is still in it's infancy, mostly just a promising sketch at this point
12:55ohpauleezCool, for sure. I've been digging through the code - nice stuff for sure. All ideas start somewhere
12:55reiddraperty
13:18TimMcreiddraper: 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:18reiddraperTimMc: that's reassuring ;)
13:23TimMcThe guide is outdated as far as UI goes, but still relevant I think.
13:23TimMchttp://www.gnupg.org/gph/en/manual.html <- 14 years old
14:07tieTYT2I i develop in clojure and clojurescript for one app, should they have separate project.clj's?
14:08ohpauleezI don't think there's a hard rule - I typically leave them together.
14:08tieTYT2k, didn't even know that was possible
14:08ohpauleezI've broken them apart when they were really two separate applications that happen to work together nicely
14:15bhenrycan i make a library's resources be accessible on the referring web-app's classpath?
14:16tieTYT2what's a referring web app?
14:16bhenrytieTYT2: a webapp that uses the library
14:17tieTYT2yeah they're automatically accessible
14:17tieTYT2if the library can use them, you can access the resources, assuming the resources are in the library's jar
14:18bhenryso 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:19tieTYT2oh that's a different thing from what I thought you were asking
14:19tieTYT2let me think
14:19tieTYT2this sounds like a maven overlay, but not exactly
14:20bhenryi've been thinking about it for awhile
14:20hiredmanreally?
14:20hiredmanjust use wrap-resource or whatever the ring middleware is called
14:20tieTYT2http://stackoverflow.com/questions/4732965/exposing-resources-from-jar-files-in-web-applications-tomcat7
14:21tieTYT2yeah be aware I only know java, not too good with clojure
14:21tieTYT2i'd listen to hiredman
14:21bhenryhiredman: thanks. i'll look into it
14:22weavejesterbhenry: This is how I do it: https://github.com/weavejester/hiccup-bootstrap/blob/master/src/hiccup/bootstrap/middleware.clj
14:22bhenryweavejester: that's great thanks.
14:34gfrederickshow do I set an http proxy for a leiningen repository?
14:35gfredericksthe sample project.clj doesn't seem to have any attributes that look relevant
14:36kephaleccw 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:37cemerickkephale: you could check for the existence of ccw's tooling namespaces (all start with ccw.* IIRC)
14:39gfredericksunless there is only https://github.com/technomancy/leiningen/wiki/HTTP-Proxies and you can't do it in the project.clj at all
14:40abp##*clojure-version*
14:40gfredericks&*clojure-version*
14:40lazybot⇒ {:major 1, :minor 4, :incremental 0, :qualifier nil}
14:41kephalecemerick: works like a charm, thank you
14:41abpoh ok. now i'm sad.
14:42amalloyabp: why?
14:45abpamalloy: No clojure 1.5.1 for the bot. as-> etc
14:46amalloy.*clojure-mode*
14:46amalloy,*clojure-mode*
14:46clojurebot#<CompilerException java.lang.RuntimeException: Unable to resolve symbol: *clojure-mode* in this context, compiling:(NO_SOURCE_PATH:0:0)>
14:46amalloygod
14:46abp:D
14:46amalloy,*clojure-version*
14:46clojurebot{:interim true, :major 1, :minor 6, :incremental 0, :qualifier "master"}
14:47abpall right, thanks.
14:49mefestoim 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:10edtsechAs 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:11tieTYT2edtsech: cool, thanks
15:12tieTYT2i 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:15justin_smithtieTYT2: would you use field1 from one map and field2 from another?
15:15hyPiRionohooh
15:16hyPiRion,(group-by (some-fn :foo :bar identity) [{:foo "foo" :bar "bar"} {:bar "bar" :hurm 1} {:something :else}])
15:16clojurebot{"foo" [{:foo "foo", :bar "bar"}], "bar" [{:bar "bar", :hurm 1}], {:something :else} [{:something :else}]}
15:19tolitiusis 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:19antares_tolitius: for native dependencies, no, besides bundling them in for all platforms
15:21tolitiusantares_: 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:21justin_smithtolitius: have an assertion that looks for the dep, and gives the URL to get it if it is absent?
15:21justin_smithat the top of your init or -main if such a thing exists I guess
15:21antares_tolitius: it's not "clean" and usually very painful but that's what some projects do
15:22justin_smithship with a vm of linux configured to run said service :P
15:23technomancyyeah, the only way that works consistently is to depend on a jar with .so files and such in it
15:23technomancythere are no language-specific tools that do this well as far as I know
15:24tolitiustechnomancy: interesting, and then they would be resolved by reusing a classpath that points to that jar.. ?
15:24tolitius*they = ".so"s
15:25tolitiusjustin_smith: and if it is a cluster, ship a cluster? :)
15:25technomancytolitius: 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:25technomancy(in order to still work with uberjars)
15:25technomancyI think everyone rolls their own systems for runtime unpacking =\
15:25justin_smithyou could publish build rules for a port file / .deb / arch aur / whathaveyou and tell people to install the package to get the deps
15:25tolitiusantares_: I know Storm is trying to get away form zeromq for this and other reason, so yea, it is a problem
15:26technomancydebs are crappy for this since you need root and can only install one version at a time
15:26antares_tolitius; have you tried JeroMQ?
15:26antares_tolitius: it's a pure Java impl endorsed by the ZeroMQ lead dev
15:26nightflyVague question, but how many messages per second can a message queue route?
15:26tolitiusantares_: yea.. slow..ish
15:26tieTYT2justin_smith: nope
15:26hiredmansomeone just released a netty transport for zeromq
15:27mabesantares_: do you have personal experience with jeromq?
15:27technomancynightfly: depends on what kind of delivery guarantees you need
15:27antares_mabes: nope but it seems to be fairly actively developed and used. I doubt ZeroMQ guys would support it otherwise.
15:27tieTYT2hyPiRion: how does that work, is some-fn part of core?
15:27antares_hiredman: link?
15:27hyPiRiontieTYT2: yeah
15:27hyPiRion(doc some-fn)
15:27clojurebot"([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:27technomancyalso it depends on how many erlangs you have: http://bitfission.com/images/erlangs.png
15:28hiredmanhttps://github.com/spotify/netty-zmtp
15:28tieTYT2ah thanks
15:28justin_smithtieTYT2: 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:28hiredman"This is a ZeroMQ codec for Netty that aims to implement ZMTP/1.0, the ZeroMQ Message Transport Protocol."
15:28mabesantares_: 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:29tolitiusantares_: 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:29tieTYT2justin_smith: then what, should I use or like I was?
15:30antares_tolitius: are you trying to reach roflscale?
15:30justin_smithI think there is a way to do it with condp
15:31antares_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:32tolitiusantares_: right, I agree. I had a couple of customers that needed a several mil a second
15:32tieTYT2justin_smith: what's the problem with my attempt?
15:32tolitiusbut still staying in JVM
15:32antares_tolitius: fair enough :)
15:32tolitius0mq is really great for that
15:32tolitius+ some design thinking of course
15:35solussdanyone 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:37enquorasolussd: I archived a bookmark on a blog post, let me see if I can find it
15:40justin_smithtieTYT2: so is field1 a var that may be nil?
15:40tieTYT2yes
15:40justin_smith*a binding
15:40justin_smithahh, yeah, so that is what you want
15:40tieTYT2the or?
15:40justin_smithyeah
15:40tieTYT2cool, thanks
15:40justin_smithI misunderstood the question
15:41justin_smithand the somefn would give an npe when it gets to the one that is nil
15:41tieTYT2it's not actually a var, it's more like this (fn-to-get-field1 %)
15:41justin_smithyeah
15:41justin_smiththat is why I tried to correct myself to a more general term
15:42tieTYT2ok thanks for the help
15:43justin_smithI 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:44piranhasolussd: 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:44justin_smithif 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:45justin_smithI 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:45justin_smithor is allowing nodes in frp to mutate the set of connections just doing it wrong?
15:46tieTYT2if nobody can help you, maybe you can get help in #haskell
15:46justin_smithheh, I have been chatting with a haskell using friend about this on jabber
15:47tieTYT2i also find it hard to figure out what it is
15:48tieTYT2everyone tells you you're doing it wrong, nobody shows how to do it right
15:48justin_smithwell 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:49solussdpiranha: i had not, thanks.
15:50justin_smithmaybe 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:50justin_smithbut still I feel like there should be something cleaner here
15:53meliponehello! What's the best way to save a map containing other objects (such as functions) to a file?
15:53tieTYT2justin_smith: maybe this will help: http://www.youtube.com/watch?v=nket0K1RXU4
15:53tieTYT2but it's a time investment
15:54justin_smithtieTYT2: thanks! I'll watch it while eating lunch
15:54tieTYT2i'm not sure if it will help, but it's a clear explanation
15:54tieTYT2with sample code
15:54justin_smithhaskell?
15:54clojurebot"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:54tieTYT2no, clojurescript
15:54tieTYT2here's where I posted that: http://stackoverflow.com/a/16618078/61624
15:54justin_smithoh, awesome
15:55tieTYT2the SO link has a link to the source code
15:55tieTYT2perhaps skip directly to the source code
15:59amalloymelipone: you can't serialize functions in a readable way
16:03enquorasolussd: 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:05meliponeamalloy: I just want to save and load them back
16:05amalloythat's an accurate description of what i just said you can't do
16:06amalloyyou can write/read forms/expressions, but not functions
16:06meliponeamalloy: oh, okay
16:08loliveirahow 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:08loliveira :profiles {:prod {:server "server.prod"}
16:08loliveira :dev {:server "server.qa"}}
16:15tieTYT2justin_smith: also just found this: http://engineering.prezi.com/blog/2013/05/21/elm-at-prezi/
16:19llasramloliveira: Is this in a lein task, or in your application proper?
16:20loliveirait is both a repl task and ring uberwar task
16:20seangrovetieTYT2: Was a great video, thanks
16:22weavejesterloliveira: I wrote a library called environ where configuration can be specified via the project.clj file
16:22llasramloliveira: 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:22weavejesterloliveira: However, it won't translate over to an uberwar. For that you'll need to use system properties or environment variables.
16:22llasramIf 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:23tieTYT2seangrove: np
16:23technomancyamalloy: you tease
16:23tieTYT2that video is a little over my head actually
16:24amalloytechnomancy: hush! no one can know of our secret lovechild serializable-fn!
16:24amalloy*gasp* i've said too much
16:26konris there any lib cooler than swiss-arrows? https://github.com/rplevy/swiss-arrows
16:26loliveirallasram: 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:27loliveiraweavejester: what will happen if I generate my war with the rolling command: 'lein with-profile dev ring uberwar'?
16:28ohpauleezkonr: some-> as-> cond-> or https://github.com/LonoCloud/synthread
16:28weavejesterloliveira: 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:28weavejesterIn general hardwired configuration is a bad idea.
16:29loliveiraweavejester: how do you suggest I should resolve this?
16:32weavejesterloliveira: Which server are you deploying the war to?
16:32loliveirajetty
16:33loliveirajetty-distribution-9.0.3.v20130506
16:34weavejesterloliveira: Is it a requirement to deploy as a war?
16:38loliveiraweavejester: yes. And I can not change this. =(
16:38weavejesterloliveira: That's okay. I just wanted to check, because the alternatives are a lot easier :)
16:39loliveiraweavejester: =)
16:40konrohpauleez: awesome!
16:41weavejesterloliveira: 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:43loliveiraweavejester: it might work, but i loved the idea that I could concentrate all config in one place (project.clj) =(
16:44weavejesterloliveira: It makes sense not to do that when deploying to a (dare I say) more sane environment. :)
16:44technomancyproject.clj is not designed for runtime application configuration
16:44technomancythere are ways to make it work, but that's not what it's meant for
16:45loliveiraweavejester: you convinced me. I'll look for alternatives. thank you. =)
16:45weavejesterloliveira: I guess you could add a resource file that would only be included in your uberwar in production.
16:46weavejesterloliveira: You could add an extra directory to :resource-paths in a :prod profile, and then add a configuration file in the resource path.
16:47loliveiraweavejester: sounds nice. How do I select the right file to send to war?
16:47loliveiratechnomancy: agreed.
16:48weavejesterloliveira: Well, you could have something like: :profiles {:prod {:resource-paths ["resources" "config/prod"]}}
16:48technomancyweavejester: did you see the new :uberjar profile in lein 2.2?
16:48technomancymight want to support something similar for uberwars
16:48weavejestertechnomancy: Nope. What's that?
16:48weavejestertechnomancy: Oh, a profile just for uberjars, I guess?
16:48loliveiraweavejester: it just what I wanted. ty.
16:49technomancyyeah, gets applied implicitly
16:49weavejesterThat's a good idea
16:49clojurebotOne idea I had was to parameterise Keyword with the key it looks up. :a is of (Keyword :a). But that has other issues.
16:49technomancyweavejester: lets you add :main what.ever without contaminating regular dev time with AOT
16:49weavejestertechnomancy: Yeah. I like that idea.
18:11akurilinIn 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:14justin_smithakurilin: postmark has a drop in test version of its emailer
18:14mpenet,(doc with-redefs)
18:14clojurebot"([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:14mpenetthat could do it
18:14justin_smithyou can just make a version of the email function that verifies the types / content of the args and gripes if they are weird
18:15akurilinjustin_smith, how would I "inject" that version of the function?
18:16justin_smithpersonally 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:16nightflydynamic vars ftw
18:16justin_smithso instead of (defn send-mail [from to body subject] ...) I write a function (defn send-email [from to body subject emailer] ...)
18:16hiredmannightfly: no
18:17hiredmannightfly: no
18:17mpenetimho with-redefs really seems like the sane solutions here
18:17weavejesterI'd be inclined to choose an implementation via a configuration.
18:18hiredmanthe best solution is to base behaviour on passed in information, but if you can't do that then with-redefs
18:18weavejesterIn the same way that a database URL can point to a local (maybe embedded) database during developmnent, and a remote one in production.
18:18akurilinmpenet, 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:20akurilinhiredman, 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:20akurilinI feel like there must be something better than an if statement.
18:20mpenetnot 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:20nightflywith-redefs is pretty much dynamic scoping
18:20hiredmanuse carica, it comes with a config override deal exactly for tests
18:21mpenetnightfly: not really , the change is visible to *all* threads
18:21hiredmanhttps://github.com/sonian/carica#testing
18:21mpenetnightfly: but other than that yes, very similar
18:22weavejesterakurilin: It sounds like what you want is polymorphism over configurations
18:22weavejesterSo either multimethods or protocols
18:23weavejesterWhat you want is a "send-email" function that changes implementation based on a configuration, I'd guess.
18:23mpenetakurilin: For different setups via config, Environ is very handy
18:24mpenetbut weavejester can tell you more about it than me probably :)
18:24technomancyif it's just changing for test then with-redefs is better than a multimethod
18:24technomancywith-redefs works great with clojure.test fixtures
18:26akurilinSo, if I'm understanding that correctly, the idea would be to basically replace the email sending logic with clojure.test (is) calls?
18:27technomancyno, 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:28technomancy(let [delivered (atom [])] (with-redefs [send-email #(swap! delivered conj %&)] (do-stuff) (is (= [...] @delivered))))
18:28technomancyakurilin: ^
18:30akurilintechnomancy, 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:30akurilinyes?
18:30clojurebotyes isn't is
18:31technomancythanks clojurebot
18:31akurilinI love that guy :)
18:31technomancybut yeah, what you described is basically on-target
18:31akurilintechnomancy, great, thank you.
18:32technomancyoften people ask how they can mock functions out and get pointed to midje when all they really need is with-redefs =\
18:32akurilinI'm actually considering moving off of clojure.test, it's annoying that it doesn't print out the test case names by default
18:32akurilinI don't know if there's some out-of-the-box way of having that happen.
18:33technomancylein test will print the deftest names when there's a failure
18:33hiredmanakurilin: you mean when they pass?
18:33hiredmanseems useless
18:33hiredman(they definitely get printed out when they fail)
18:33akurilinI 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:33justin_smithtechnomancy: not to mention also any (testing "foo" ...) forms
18:34technomancyakurilin: (is (< (- (System/currentTimeMillis) start-time) 5000))
18:35akurilintechnomancy, that's definitely the most straightforward way. I went the long route and wrapped every test in a profiler call.
18:35akurilinWhich worked out ok, I discovered each test case takes 30ms, yuck.
18:36akurilinjustin_smith, (testing "foo") doesn't actually print anything either until it fails, right?
18:36justin_smithyeah, but it is helpful for extra context when you have more than one is clause in a deftest
18:37akurilinSince 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:37justin_smithif you want something printed every time, why not println?
18:37technomancyakurilin: with carica it's just based on the classpath
18:38akurilinjustin_smith, sure, that's quite doable.
18:38hiredmancarica doesn't have environments or profiles
18:38technomancyit's outside the scope of carica to manage the classpath
18:38justin_smithyou could even write a macro wrapping deftest that prints the name of the defined test
18:38hiredmangenerally you have a set of default configs that get backed in to your jar/uberjar
18:38technomancypresumably something is launching either `java -cp ...` or `lein run ...`; it's that tool's responsibility
18:39hiredmanand 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:39akurilinSo what you'se saying is that the best bet is to let project.clj choose the right config file depending on profile?
18:39akurilinin the lein case.
18:40technomancyakurilin: based on the classpath, which is a function of the :resource-paths of the currently-active profiles (if you want to get pedantic)
18:40decafnrepl client in emacs has great completion support. can I bring this to .clj file editing?
18:40technomancydecaf: M-TAB should work in clojure-mode if you're connected to nrepl
18:41justin_smithwith many wms that has to be escape-tab, sadly
18:41justin_smithunless you are like me and pick wm based on which one can be made not to steal meta
18:44akurilintechnomancy, 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:45technomancyakurilin: exactly
18:45technomancyakurilin: uberjar will strip out the default profiles for you actually
18:46akurilinAm I making this too Railsy or is that reasonable?
18:47akurilinI can never tell the difference between them just doing things right and me not knowing a better way :)
18:47technomancyif you need multiple environments, "check a file on the classpath" is a tried-and-true JVM-friendly way to do it
18:47technomancymost people don't need anything beyond resources/ and dev-resources/ directories
18:47akurilintechnomancy, ok that's great to know.
18:48akurilinI gotta mail this log to myself, you guys have shared so many pearls here with me today.
18:49technomancybetter than sharing perls
18:50hiredman~#95
18:50clojurebot95. Don't have good ideas if you aren't willing to be responsible for them. -- Alan J. Perlis
18:51akurilinFor 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:51technomancyakurilin: repeatable deployments and faster boot time
18:51technomancyusing git on production is sloppy
18:52flu-+1
18:53akurilinIt certainly does take a while to boot on a micro instance.
18:54hiredmanmicros suck
18:54Raynestechnomancy: What do you mean?
18:54Raynes'using git on production'
18:54decafif anyone else is looking for tab completion: https://raw.github.com/genehack/smart-tab/master/smart-tab.el
18:56technomancyRaynes: well, resolving dependencies on production nodes is sloppy
18:56technomancydependency resolution isn't completely deterministic
18:56abpakurilin: 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:56Raynestechnomancy: Don't understand the correlation between dependency resolution and git on production here.
18:56hiredmanI 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:57akurilinabp, do you have a repo for reference? That'd be really cool.
18:57technomancyRaynes: 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:58technomancyif you've got one way of getting jars to production and another way of getting source to production, that sounds unnecessarily complicated
18:58abpakurilin: Could whip up a sample, don't have anything public by now.
18:59technomancyif 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:59technomancyunfortunately existence is suffery
18:59technomancysuffering
18:59papachani just have installed leiningen 2.2
19:00akurilinabp, 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:00akurilinabp, your description above is good enough for me though :)
19:00papachanhow i can start with this feature:Isolate target paths by profiles?
19:01technomancypapachan: you don't have to do anything
19:01technomancyit just works that way by default
19:01papachantechnomancy: ok let me try :)
19:03abpakurilin: I'm at it.
19:04akurilinabp, kudos! Even better, you can turn that into a neat blog post.
19:04abpakurilin: I don't have a blog. :x
19:04akurilinabp, Ah! Well, one step at a time then! :)
19:42Sintendohow can i split up my code across files?
19:42abpSintendo: Create files and write code. :)
19:43abpSintendo: http://clojure-doc.org/articles/language/namespaces.html
19:44amalloyi'm amazed that a document that long doesn't mention the -/_ conversion
19:45abpamalloy: They don't?
19:45amalloyhaving just read it, i can tell you that it is not mentioned
19:45abpamalloy: I got caught by it when doing my first experiments two years ago and saw multiple people stumble since.
19:46amalloyeveryone trips on it sometime
19:46Sintendowhat do i do with those? filename conatins a - in my case
19:47hyPiRionuse _ instead
19:48abpamalloy: http://clojure-doc.org/articles/language/namespaces.html#namespaces_and_class_generation there it is. ;)
19:48hyPiRion,(munge "a.namespace.foo-bar")
19:48clojurebot"a.namespace.foo_bar"
19:49Sintendoso i must rename the file?
19:49amalloyeach _ in the filename must correspond to a - in the namespace, and vice versa
19:50abpSintendo: Yes, underscores in filenames, dashes in namespaces.
19:50SintendoCould not locate lru_cache__init.class or lru_cache.clj on classpath
19:51Sintendooh wait, i figured it out
19:51Sintendothanks everyone
19:52SintendoIs there a way to import private functions anyway?
19:53hyPiRionprivate functions from java or clojure?
19:53Sintendoclojure
19:53hiredmanwell java doesn't have functions, it has methods
19:53SintendoI guess not?
19:54hyPiRionSintendo: Well, you could refer to the var
19:55hyPiRion,(#'clojure.core/>1? 1)
19:55clojurebotfalse
19:55hyPiRion,(#'clojure.core/>1? 2)
19:55clojurebottrue
19:55Sintendowell, i guess it's easier to just make them public
19:56hyPiRionyeah
19:56Sintendothanks
19:56abphiding my functions, so I can call on vars
19:57benkaydatomic 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:57abpSintendo: Not making fun of you, just thought it's a funny phrase. :)
19:58benkaybueller?
19:59SintendoNo problem dude, thanks for the help!
20:06technomancyit'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:08hiredmanbenkay: my guess is you are defining a new entity and a new balance everytime you think you are "updating" the balanace
20:10hiredmanbenkay: like you are trying to upsert, but inserting instead
20:11benkayhiredman that's totally possible. i'm definitely *trying* to upsert but i haven't quite wrapped my head around the syntax yet.
20:11hiredmanyou may need a :db/unique :db.unique/identity on whatever attribute you intend as a "primary key"
20:11abptechnomancy: 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:12benkayhiredman i *just* saw that in the halloway upserting gist that's floating around :)
20:13hiredmanotherwise the only primary key is the entity id, which is often not known and basically treated as a gensym in transactions
20:18technomancyabp: yeah, that one is just outstanding in how easy it would be to offer helpful advice
20:21benkaythanks hiredman.
20:27abphiredman: When will carica with middleware support be released?
20:27hiredmanleathekd: ?
20:28hiredmanI don't know
20:29leathekdabp: I'll see what I can do. I don't believe there is anything else pending for 1.0.3
20:31abpleathekd: Cool, thanks. I've just written some middleware.
20:32leathekdNice. What did you make?
20:33technomancymiddleware?
20:33hiredmanhttps://github.com/sonian/carica#middleware
20:34technomancynice
20:40abpleathekd: I'm generalizing some environment-based config merging I wrote a while ago.
20:40abpWrote about it earlier in here.
20:40abpUsing middleware it's basically no code.
20:52dnolenbbloom: you look at React?
20:57leathekdabp: Cool, glad Carica is working out for you.
21:03justin_smithslightly 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:28bbloomdnolen: the new thing from facebook/instragram? not yet really
21:28bbloomdnolen: did you? thoughts?
21:29dnolenbbloom: 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:29bbloomdnolen: yeah, the DOM is just slow: period.
21:31bbloomwe 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:31bbloom:-P
21:32bbloomalso, i was instantly turned off by the XML preprocessor thing
22:04amalloybbloom: n^3? what algorithm are you thinking of?
22:05bbloomamalloy: layout when js code is constantly updating positions & styles
22:06bbloomi'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:16ohpauleezIs David Pollak in here?
22:18pandeirowould 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:19brehautpandeiro: i recall that they both consume :body, so yes they would
22:19brehautpandeiro: ring is *mostly* functional; :body is the exception, and can only be consumed once.
22:19pandeirobrehaut: makes sense
22:20brehautpandeiro: however, it should respect your content type header?
22:20pandeirohuh, right, it should
22:20pandeirobut let me step back one step
22:20pandeiroeven if the json-params are only being applied to some routes, that middleware would consume the body for any route?
22:21pandeirothat doesn't make sense actually because the multipart POST route comes before the json api routes
22:21brehautif those routes are called, and content tpye matches, yes
22:21pandeirobut route specific handlers as setup by defroutes short circuit, right?
22:21pandeiroi noticed the source of routes or routing uses 'some'
22:22brehautyeah
22:23pandeirok i'm still at a loss then... must be something else i am doing
22:31dnolenwow as-> cond-> really allow you remove some serious grossness
22:36pandeiroha
22:37pandeiroring-multipart-params won't handle the input[type=file] if there is no name attribute
22:48bbloomdnolen: 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:49dnolenbbloom: link doesn't work?
22:49bbloomdnolen: lol try again
22:50bbloomdnolen: apparently making it public took a second...
22:52phyrephoxso i'm building a webapp using clojure and clojurescript
22:52phyrephoxand i'm wondering if i can have some crossover code
22:53phyrephoxthat's the same code in clojure/clojurescript, but it does something different in clojure than in clojurescript
22:53phyrephoxi.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:53phyrephoxis this possible?
22:55phyrephoxhmm, maybe i can use cljsbuild conditional comments?
22:55hiredmanhttp://dev.clojure.org/display/design/Feature+Expressions
22:57phyrephoxso this is a patch and/or an experimental feature? doesn't seem too useful
22:57phyrephoxseems like a nicer solution than the cljs build comments though, that's for sure
22:58dnolenphyrephox: known pain point, maybe core.async will push it along, unclear
22:58phyrephoxcool thanks. i actually think i can accomplish what i want to using the ;*CLJSBUILD-REMOVE*; thing
22:59phyrephoxnot an ideal solution, but once a better solution comes along i don't think it'll be too hard to refactor
22:59dnolenso much craziness in my projects to remove w/ as-> cond->
23:04bbloomdnolen: what about as-> and cond-> ?
23:04dnolenbbloom: remove repeated bindings to the same name in a let
23:05dnolenwhich actually bit me a couple of times because it's not very functional
23:05bbloomheh, 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:05bbloomusually better to come up with clearer names or split up the function
23:22TimMcgfredericks: Are you sure that what you want for clem isn't Erlang? :-)
23:28bbloomi <3 clojure's data types so much
23:28bbloomwhere 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:46tomjack"Declarative" then the second example is "A Stateful Component" hmm
23:47dnolenbbloom: that feature of Clojure cannot be understated
23:48bbloomdnolen: it's totally mind altering. i don't even know how i used to write software like a year ago :-P
23:50dnolentomjack: yeah overall not interesting. But I think the virtual DOM + requestAnimationFrame could be promising for CLJS
23:50dnolenor for some CLJS lib
23:50dnolenI mean
23:51tomjackI really don't understand "virtual dom"
23:52dnolentomjack: touching the DOM is expensive so you manipulate a virtual representation instead
23:53dnolenyou accumulate changes, then you do a bulk update
23:53alisdairall problems in computer science can be solved with another layer of indirection
23:54tomjackdnolen: so that's pretty much just "use data" right
23:55dnolentomjack: yes
23:57xeqiwonder how that helps with Phil Karlton's problems
23:58bbloomdnolen: 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:58dnolenbbloom: yeah that's I mentioned it to you earlier
23:58dnolenthat's why