#clojure logs

2014-02-16

00:02munderwohi all, so I have (map inc [1 2 3 4]) that I get a sequence out of (?), and I want to let each member of a sequence to a local var. How would I go about this?
00:04uvtcmunderwo, if you know how many elements in the seq you're starting off with, you can use destructuring like so: `(let [[a b c d] (map inc [1 2 3 4])] (println a b c d))`
00:04munderwouvtc: ahh! thats exactly what I want. I do know how many there will be.
00:14bob2if you don't, it doesn't make sense for them to be locals, anyway :)
00:18TravisDI've been reading through SICP and one of the exercises is to design an efficient procedure for counting the number of ways to make change for $1.00 with coins valued at $0.01, $0.05, $0.10, $0.25, and $0.50. I have come up with the following memoizing function that takes O(N*M) time, where N is the amount your calculating change for, and M is the number of denominations: http://cljbin.com/paste/530047a6e4b0e267ba6e2ab2. Please critique
00:20uvtc(Aside: didn't know there was another Clojure-based paste-bin!)
00:20TravisDuvtc: I'm just getting into clojure :) I found this one by googling "Clojure Pastebin" :P
00:21TravisDIn the running time bound I gave, N should really be M/c, where c is the smallest denomination
00:21TravisDer, M should be N/c. sorry, lol
00:23echosawhy is assoc-in sometimes fine with having the last argument be a string, and other times I get a String can't be can't to Character error?
00:23amalloyTravisD: the scheme idiom of putting defines inside defines is no good in clojure - you either want multiple top-level defs, or a let
00:23ambrosebsechosa: example?
00:23TravisDamalloy: Ah, good to know. What's bad about it in clojure?
00:24amalloydef and defn always create a top-level var
00:24TravisDah
00:24amalloyif you do that while running some other function, lots of things go bad, eg race conditions if count-change is called from two threads at once
00:24TravisDyeah, that is pretty dangerous. Do you know the rationalle for not lexically scoping them?
00:25echosaambrosebs: hang on.. might have figured something out...
00:25amalloywell like...we already have let for lexical scope. it's more clear if let is always lexical, and def is always global
00:26amalloyi'm sure there are other reasons, but that's the one that seems most obvious to me
00:26TravisDyeah, that makes sense
00:27TravisDso if you want to have helper procedures, is it idiomatic to have (let [helper (fn [...] ...)])?
00:27amalloyyes, or (letfn [(helper [...] ...)] ...)
00:28echosaassoc-in will give a String can't be cast to Character if you give it a generated vector like this: (assoc-in (vec (for [y (range 3)] (conj (vector-of :int) 1 2 3 4 5))) (list 1 1) "@")
00:28echosayet this is fine: (assoc-in [[1 2 3][4 5 6]] '(1 1) "@")
00:29rhg135anyone have any timps on how to write a network-using gui app?
00:29amalloyuhh...you're trying to put a string into a vector-of :it, echosa?
00:29amalloyof course that won't work
00:29rhg135normally i'd use web js, but cross-domain
00:29echosawhy does it work in my second example?
00:29amalloybecause [4 5 6] is a vector of Object
00:30amalloyreally (vector-of anything) is very very rarely used in clojure, and we use the boxed Object vectors all the time
00:30echosaಠ_ಠ I suppose that makes sense
00:30seancorfield,(vector-of :object)
00:30clojurebot#<NullPointerException java.lang.NullPointerException>
00:30seancorfieldhmm, wasn't sure that was possible :)
00:30seancorfield,(vector-of :int)
00:30clojurebot[]
00:31echosavector-of can only take :int :long :float :double :byte :short :char or :boolean
00:31echosahttp://clojuredocs.org/clojure_core/clojure.core/vector-of
00:31seancorfieldthanx. saves me looking it up :)
00:31echosaok, then I'm going to for the direct "give me the answer" route since I'm failing at figuring it out myself.
00:32seancorfield,(into (vector-of :int) "@")
00:32clojurebot[64]
00:32seancorfield,(into [] "@")
00:32clojurebot[\@]
00:33echosaI want to create a grid (vector of vectors) with a given height and width and have each "item" in the grid set to a random number between 1 and 9 (I have this part working), but THEN I need to be able to set a random element in the grid to "@" (this doesn't work because of the case, but *does* work if I use a number like zero instead of "@")
00:34echosaI pretty much have everything working, but it makes use of the vector-of, which screws me when I try to change an element to "@"
00:35seancorfieldWhy use vector-of at all? What's wrong with just [ [ ... ] [ ... ] [ ... ] ... ] ?
00:35echosaif the function gets passed a height of 5, then I'll need five inner vectors, if it gets passed 20 I'll need 20...
00:35echosathat's the only part I haven't figured out yet at all
00:35echosaso I've been working with a static height to get the rest working first
00:36seancorfield,(repeat 5 [])
00:36clojurebot([] [] [] [] [])
00:36TravisDamalloy: Is this better? http://cljbin.com/paste/53004d06e4b0e267ba6e2ab4 Also, it runs fine on my machine but gives an error on the pastebin - any idea why?
00:36echosahm.. I misspoke, its the width that I haven't gotten working (the number of things inside the inner vectors)
00:36echosabut maybe repeat will work
00:37echosa,(repeat 5 (rand-int))
00:37clojurebot#<ArityException clojure.lang.ArityException: Wrong number of args (0) passed to: core/rand-int>
00:37echosa,(repeat 5 (rand-int 9))
00:37clojurebot(0 0 0 0 0)
00:37amalloylooks pretty good, TravisD. i don't really like the cache'' name, is my main complaint
00:37TravisDechosa: That says "give me a random int, and then give me a list with 5 copies of it"
00:38echosaAh.
00:38seancorfield,(into [] (repeatedly 5 (fn [] (rand-int 9))))
00:38clojurebot[7 3 6 1 6]
00:38amalloyi'd just let [... (cache (-> cache (update-cache k1) (update-cache k2)))]
00:38amalloyer... [..., cache (-> cache (update-cache k1) (update-cache k2)))]
00:38rhg135oh and i can run on nodejs with node-webkit, but i lose interactive development
00:38TravisDamalloy: Can you rebind names?
00:38TravisDah, yeah, I was looking at ->
00:38TravisDthat's a good use
00:38amalloyTravisD: yes
00:38seancorfield,(into [] (repeatedly 5 (fn [] (into [] (repeatedly 8 (fn [] (rand-int)))))))
00:38clojurebot#<ArityException clojure.lang.ArityException: Wrong number of args (0) passed to: core/rand-int>
00:39seancorfield,(into [] (repeatedly 5 (fn [] (into [] (repeatedly 8 (fn [] (rand-int 9)))))))
00:39clojurebot[[3 1 8 0 8 ...] [5 1 6 0 0 ...] [2 7 1 1 5 ...] [3 6 1 8 5 ...] [5 0 0 5 6 ...]]
00:39amalloy&(let [a 1, b #(+ a %), a 2] (b a))
00:39lazybot⇒ 3
00:39echosaI've been trying to figure that out for far too long
00:39amalloyif you understand why 3 comes out there, you've got the mechanics of name-rebinding down
00:39seancorfieldechosa: but if you're updating that array a lot, maybe immutable vectors aren't what you need... just a thouhgt
00:40amalloyoh, and if it hasn't come up yet, #(+ a %) is just shorthand for (fn [x] (+ a x))
00:40TravisDamalloy: that is directed at me?
00:41amalloyyeah
00:41amalloysince you asked about name rebinding
00:41bbloom,(let [a 3, f (fn [%] (+ a %))] (f 5))
00:41clojurebot8
00:41TravisDah, yeah
00:41bbloomwas just wondering if % was a valid symbol there, i assumed it was
00:41bbloomheh
00:42echosaseancorfield: perhaps. Though with this I'm pretty closed to a "finished" releasable version of my first clojure program. Once I have it "done", I'll put it on github for code review and tips. :)
00:45TravisDamalloy: hmm, are variables pointers?
00:45amalloywelllll, that's a question with multiple correct answers
00:45amalloywhat behavior in particular are you thinking of?
00:47TravisDamalloy: Well, I was wondering if the free variables in a lambda expression get coppied from the environment. If the variables were pointers, that would explain why b's copy of a continues to have the value of 1, even after a has been rebound in the (let ...). Or something. lol
00:47uvtcTravisD, the Clojure language per se doesn't have "pointers" (that I know of). Typically, symbols are names that refer to a var which refers to a value. But when you type a symbol into the repl, it's automatically evaluated down to the value.
00:48amalloyuvtc: symbols very frequently don't refer to a var at all
00:48amalloythey refer to a local quite often
00:48uvtcRight. Thank you. I'd actually asked about that very thing when I first began using Clojure.
00:50uvtcTravisD, so, if you do `(def a (something...))`, then `a` refers to a var, but if you do `(let [a (something...)] ...` then `a` just refers directly to a value (within the `let` body).
00:51TravisDhmm, I don't know enough to know the difference between a var and a local
00:52TravisDIs there an approachable language spec somewhere
00:52TravisD?
00:53uvtcTravisD, a "local" is just when you get a symbol bound to a value using a `let` binding (or similar).
00:54TravisDso the only difference is that a var is in the top level scope and a local is in the scope of the let that defines it?
00:54uvtcTravisD, a Var is something you get when using `def`, `defn`, or similar (where, again, the symbol you use for it is connected with the var, which is (usually) connected with a value).
00:54amalloyTravisD: well, a Var is actually an object that exists at runtime, which you can play around with
00:55amalloy&(var clojure.core/inc)
00:55lazybot⇒ #'clojure.core/inc
00:55amalloywhereas a local is just a compiler-bookkeeping mechanism to remember what means what
00:55TravisDah
00:56amalloyanyway, in my example with a and b, b doesn't actually copy the value of a ever. but lambdas remember the environment they were created in. the later redefinition of a creates a new environment, but doesn't impact the lambda
00:57amalloyif a's value were some mutable thing, like a java.util.ArrayList, we could mutate it and then b's behavior would change. but introducing a new thing named a is different
00:57TravisDah, okay. And in the compiled code, all occurences of a will be translated to their numeric values or something?
00:58TravisDlike, the names there are just for our convenience?
01:00echosaOk, folks. Before I sign off shortly, here's the fruit of my efforts for a few days. It's my first ever Clojure app, and this channel was instrumental in getting it done as quickly as I did. All comments and critiques are welcome. The idea is for me to become better at Clojure. https://github.com/echosa/clojure-greed
01:01amalloyTravisD: the names actually get compiled into the bytecode, i believe, but they get mangled somehow
01:02TravisDamalloy: Ah alright! Sorry for asking so many questions - I should probably read about it for myself
01:02amalloyno worries, these are great questions
01:03echosaupdated the read me to actually have the controls listed
01:05TravisDamalloy: Good to hear :) I wont feel sheepish when I have more!
01:05TravisDechosa: Looks pretty cool. Are you working up to a rogue clone or something?
01:05echosaNo, it's a Clojure rewrite of greed, just like the readme says. ;-)
01:06TravisDah, alright. I was just noticing some of the similarities :P @ representing your character and the controlls
01:07echosaYeah, a lot of the old CLI games used the vim keybindings and @ for the player. ^_^
01:07uvtcechosa, I'm not familiar with the game "greed". Maybe provide more description of it, or a link to a desc in the readme?
01:07echosaI thought the readme explained it pretty well. I'll see if I can find an external link.
01:07TravisDechosa: Ah - they come from vim... lol
01:10echosaThe best I can find are http://terasaur.org/item/show/greed-3-2/3049 and https://apps.ubuntu.com/cat/applications/natty/greed/
01:10echosaneither of which are helpful
01:21uvtcechosa, Ah, heh, I see. That's pretty neat. Would be nice if it (A) printed your score somewhere on the screen, and (B) told you "game over" at the end. :)
01:21danielcomptonHi all, is it bad form to put side effects into let bindings? I'm doing some dom manipulation with clojurescript and that seems like a good place to put it
01:22echosaIt does tell you "game over" at the end.
01:22echosaThe score is coming later.
01:23echosareadme updated with TODO list and a special thanks to #clojure ;-)
01:23uvtcechosa, Oh, right you are.
01:24echosaalso, thanks for the compliments :-)
01:25echosaand now for some celebratory sleep... thanks for all the help, everyone!
01:25danielcomptonWell done, that was neat!
01:25RaynesSLEEP. IT IS FOR THE WEAK.
01:25echosaThanks!
01:26echosaRaynes: Then call me weak. I won't care. Because I'll be fast asleep. :-)
01:26TravisDnext step, write a solver for the game :)
01:26uvtcRaynes, bah, it's still early for you west-coasters!
01:26RaynesThis is true.
01:26eggheadyou kidding? it's almost 10:30!
01:26RaynesThis is also true.
01:26echosaplus I'm meeting my boss at work in 7 1/2 hours to work on a side project.
01:27RaynesI'm actually staying up far later tonight than usual.
01:27RaynesI've been old manning it to bed at like 10:30pm most nights.
01:27insamniacechosa: clojure side project i hope
01:27echosaso yeah, sleep. :-) Gotta make up for staying up late last night watching curling live.
01:27echosainsamniac: unfortunately, no. It's planning/working on a website for our office band/music group/jam nights
01:28uvtcRaynes, good for you. (inc healthy-sleeping-schedule).
01:28insamniacechosa: clojurescript!
01:28insamniacheh
01:28Raynesuvtc: I need less sleep, more PARTY!
01:28echosaRaynes: my wife and I are usually in bed between 9 and 10. Old manning it, indeed.
01:28Raynes;P
01:29echosa*9 or 10
01:29echosasee.. the lack of sleep is already affecting me...
01:29echosa:-D
01:29RaynesClearly.
01:29uvtcechosa, give that mustache it's beauty sleep :)
01:30echosauvtc: heh... the Internet is a wonderful tool, isn't it?
01:30uvtcs/it's/its/ bah. Yeah. You're braver than me though. Haven't put up a gravatar myself yet. :)
01:30Raynesuvtc: Goodness m8, you gonna ask his a/s/l next
01:30echosaI wish more sites made use of it
01:31uvtchehehehe
01:31Raynesechosa: Hey, I like music and have fished before. We should be friends after you've slept.
01:31Raynes<3
01:32echosaWell, you know where to find me... apparently... </internet-stalked>
01:32Raynesechosa: One note before you go
01:32echosaand I must be tired... that wouldn't even validate :-P
01:32Raynesechosa: Docstrings go before argument lists. The only reason this works is because the body of defns are evaluated inside of (do ..), so it evaluates the string and then moves on. If you try to use (doc ..) on any of your functions, it won't work.
01:33RaynesNo worries though, pretty much everyone gets the order mixed up at first!
01:33echosaWhy is Clojure different for the sake of different? docstrings first... arguments are vectors instead of lists... :-P
01:33Raynes:P
01:34RaynesBecause it's Clojure, not Pyjure silly. (:
01:34echosaAfter 5 years of sbcl and elisp, I have habits formed, dammit.
01:34echosaAh well, learning new things is half the fun.
01:34uvtcWeird that, at clojars, searching for "clojure-lanterna" turns up nothing, but searching for "lanterna" turns up clojure-lanterna...
01:34echosaThanks for the notes.
01:34echosalol@search fail
01:35Raynesechosa: This is an impressive first Clojure project.
01:35Raynesechosa: Keep it up!
01:35RaynesNow sleep before you fall out of your chair, good sir.
01:36echosaThanks! Like I said, i'm not new to Lisp in general. I'm just new to Clojure, and, seriously, this room helped significantly. Thanks for that.
01:36echosaAlso, the benefit of coding is a recliner: you don't fall out, you just fall asleep still typing. :-)
01:36echosaBut seriously... BED TIME! Later, all.
01:36uvtcg'night, echosa
02:09quizdrwhen you return a syntax quoted list from a macro, and that list begins with defn, shouldn't it define the function auctomatically when the macro returns?
02:20benkayis it crazy to want to persist the state of my application between runs?
02:20ivanno
02:21benkaydidn't think so. what's a good approach?
02:23quizdrbenkay just print your atoms out to a text file (called edn when you do this), then read them back in later to return the state.
02:23quizdras simply as spit/slurp and pr/read
02:24benkaymakes sense.
02:24bbloom~spitslurp
02:24clojurebotHuh?
02:24bbloom~spit
02:24clojurebotI don't understand.
02:24bbloomclojurebot: spit is http://www.brandonbloom.name/blog/2013/06/26/slurp-and-spit/
02:24clojurebotIk begrijp
02:24bbloom~spit
02:24clojurebotspit is http://www.brandonbloom.name/blog/2013/06/26/slurp-and-spit/
02:25quizdrguys i have a macro that does a defn and it works when i give it a specific key. but when I map this macro (wrapped in a fn) over a list of keys, it does not create any fns. so I added an 'eval' inside the map's fn, which still didn't do it. what am I missing about macros and defn?
02:26bbloomquizdr: post your macro
02:26quizdrbbloom ok one sec
02:27quizdrbbloom https://www.refheap.com/39919
02:28quizdrthen I map it here: https://www.refheap.com/39920
02:30quizdrmake-fn works fine on its own. it's mapping it over a bunch of keys that doesn't make the individual functions out of them.
02:30bbloomquizdr: think about what happens when you "map" a macro
02:30bbloommacros see the syntax that was given to them, not the evaluated arguments
02:30quizdrwell, it will create a list of lists of code, right?
02:30bbloomyou're giving the symbol '% (or whatever clojure rewrites that to) to your macro
02:31quizdroh... i see.
02:31quizdrit is expanding the macro with the %, not with the actual variable the % represents.
02:32bbloomquizdr: you got the idea, just be careful with that word "variable"
02:32bbloomthe macro sees the syntax that's at the place where the macro is called. it doesn't resolve symbols or do any other evaluation at that point
02:32quizdrso i should make a separate named function with defn that calls the macro, and use this named function in my map?
02:33quizdri guess that wouldn't do it either.
02:34quizdrperhaps i don't need macros for this, and instead use regular functions that return syntax quoted lists, then eval those lists? I had always heard that if you use eval, you probably are doing something unidiomatic
02:34alewis there an idomatic way to do something similar to mapcat, except lazily?
02:35eggheadhuh? is mapcat not lazy?
02:35alewit's not
02:35egghead,(doc mapcat)
02:35clojurebot"([f & colls]); Returns the result of applying concat to the result of applying map to f and colls. Thus function f should return a collection."
02:35alewit uses apply, which is not lazy
02:36bbloomquizdr: step back a second. what are you even trying to do?
02:37bbloomalew: apply is lazy past the max number of arguments
02:37bbloomalew: which means that it essentialy does chunking
02:37alewbbloom: you're right
02:37quizdrbbloom trying to dynamically generate a bunch of functions, where the names and arg lists for those functions are stored in a map. the functions are all similar, hence using a macro. since the macro works when used indivudally, it would be great to use it for the entire collection
02:38bbloomquizdr: you can trivially create functions without a macro... i assume you mean you want to create *vars* with functions in them.... now let's step back another layer: why do you want to do that?
02:39alew(inc bbloom)
02:39lazybot⇒ 29
02:39quizdrbbloom: the functions if all individually defined as seperate vars gives me some conveniences with a DSL i'm writing
02:40quizdrit's also nice to have them as separate vars for autocompletion and arity hints in the minibuffer
02:40alewbbloom: so when the max number of arguments is reached, what occurs? it passes the rest as a list to the function or something?
02:40bbloomalew: yeah, a lazy seq
02:42bbloomalew: actually, if the number of required args is known, it's lazy up until that point
02:42bbloomalew: https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/RestFn.java
02:42bbloomquizdr: i'm skeptical you really want that. i'm sure you *think* you want that, but there's likely a better way
02:42uvtcbbloom, thanks for the blog post (re. slurp/spit)!
02:43bbloomuvtc: my pleasure. glad you enjoyed it!
02:43bbloomquizdr: what does your DSL do?
02:44alewbbloom: I really do hope they used code to generate that file
02:45quizdrbbloom ah so i have resolved the issue with two minor changes. The defmacro is now just defn, otherwise unchanged. the map function now evals the list returned from the defn, generating all the functions.
02:45krakinaclojure rules
02:46bbloomalew: knowing that rich's primary IDE is a hammock with Omnigraffle installed, I wouldn't be surprised if he created that file with copy paste or some one-off script that has long since been lost
02:46bbloomquizdr: yes, that works, but i was trying to save you from macrology hell :-)
02:48quizdrbbloom technically i suppose it is still a macro-like approach even though I am not actually using defmacro
02:50bbloom k well i'm way over due to go to bed
02:50bbloombut much excellent code was written, so totally worth it
02:52quizdrcheers
03:21logic_proganyone see http://www.twitch.tv/twitchplayspokemon/ ? I've never been so amused by such a silly idea in my life.
03:48krakinazdrast
05:36krakinaclojure cool
05:40certainty((constantly true))
05:54krakinasup clos'
06:16krakinasnatchalope
07:01quizdrwhat is the best way to go from keyword to symbol? I can do (symbol (name :key)) but that seems verbose.
07:04bob2hm, what for?
07:05quizdrfor getting a function name from a keyword
07:05quizdri have a map of keys that are function names and values that are arguments for those functions
07:06ddellacostaquizdr: not sure there is a better way, but you could use the threading operator to make it slightly more readable, I suppose.
07:06ddellacosta,(-> :key name symbol)
07:06clojurebotkey
07:06ddellacostaarguable how much of an improvement that is
07:07ddellacosta,(map #(-> % name symbol) [:key1 :key2])
07:07clojurebot(key1 key2)
07:07quizdrnice, thanks
07:07ddellacosta,(map #(comp symbol name) [:key1 :key2])
07:07clojurebot#<ArityException clojure.lang.ArityException: Wrong number of args (1) passed to: sandbox/eval76/fn--77>
07:07ddellacostawhoops
07:08ddellacosta,(map (comp symbol name) [:key1 :key2])
07:08clojurebot(key1 key2)
07:15quizdr,(apply (symbol (name :println)) [6])
07:15clojurebotnil
07:15quizdrshouldn't that show 6?
07:15quizdr,(apply println [6])
07:15clojurebot6\n
07:16quizdris it possible to send a symbol to apply and have it be interpreted as a fn?
07:17certaintysomething like symbol-function in CL?
07:18quizdrperhaps
07:18quizdri was thinking that a symbol, regardless of whether it is literal or the result of an expression, would be interpreted as a function. should be, i'd think
07:18certaintymaybe resolve
07:19quizdrahh good one. resolve makes it work.
07:19quizdr(inc certainty)
07:19lazybot⇒ 1
07:19quizdryeah man
07:19btcNeverSleeps`,(inc certainty)
07:19clojurebot#<CompilerException java.lang.RuntimeException: Unable to resolve symbol: certainty in this context, compiling:(NO_SOURCE_PATH:0:0)>
07:21btcNeverSleeps`hey all... I've got a question regarding a "timing" behavior I'm seeing. I do bignum computation from Clojure, using Java's BigInteger class. When I do ten multiplication of two random BigInteger, the timing goes always like this:
07:21btcNeverSleeps`From a REPL inside Emacs: 80 ms, 81 ms, 79 ms, 82 ms, 81 ms, 81 ms, 80 ms, 78 ms, 81 ms, 80 ms
07:22btcNeverSleeps`From the command line, running a .jar created using "lein uberjar": 340 ms, 44 ms, 42 ms, 43 ms, 41 ms, 42 ms, 41 ms, 41 ms, 42 ms
07:22btcNeverSleeps`I'm doing two computation in parallel, using a future, if that matters. What explains the timing difference?
07:23btcNeverSleeps`I understand the first 340 ms from the command line is probably the JIT which didn't kick in yet, but why is it twice as fast for the other computation when not run from inside Emacs' REPL?
07:25AimHereAre you using a timer function that has some output? the clojure 'time' function does print out something about Elapsed time
07:42btcNeverSleeps`AimHere: I'm wrapping my computation inside the (time (...)) function
07:43AimHereIt might be the difference in overhead between printing to stdio and printing to emacs then
07:44btcNeverSleeps`AimHere: but (time ... ()) surely doesn't take it's own time into account right?
07:44AimHereI don't know what time does.
07:44btcNeverSleeps`,(source time)
07:45clojurebotSource not found\n
07:45AimHereYou could try doing 100 bignum multiplications all wrapped inside one (time ...) function so that it's all computation not much overhead
07:45btcNeverSleeps`Apparently 'time' as no overhead besides the 'str' creation.
07:46btcNeverSleeps`not even the str creation I guess: I suppose the call to (. System (nanotime)) happens before calling str.
07:53hyPiRiontime is a macro, so doesn't take itself into account. But there will be overhead for timing no matter what
07:53hyPiRionuse criterium for something bit more sophisticated than pure time
07:53AimHereYeah, but the case is whether it will be different overhead for an emacs repl than for a jarfile
07:54hyPiRionwhy should it be?
07:54AimHereWell the one guess I could think of was the difference in printing stuff
07:55hyPiRionbtcNeverSleeps`: it's likely because `lein` sets optimisation flags which increases startup time, but removes some optimisations
07:56hyPiRiontry to set `:jvm-opts []` in your project.clj and restart the emacs repl, if you need speed for development
08:01btcNeverSleeps`hyPiRion: oh I see
08:02btcNeverSleeps`yup, I'm not into precise timing or anything, I'm just wondering what's the technical explanation behind the big difference in running time from inside the REPL and from the command line (curiosity killed the cat).
08:02hyPiRion/s/increases/improves/
08:02btcNeverSleeps`Say this:
08:02btcNeverSleeps`,(let [f (fn [] (apply str (take 50000 (repeatedly #(inc (rand-int 9))))))] (time (.multiply (BigInteger. (f)) (BigInteger. (f)))) 42)
08:03clojurebot"Elapsed time: 1394.718069 msecs"\n42
08:03btcNeverSleeps`takes consistently about 325 ms in my Emacs REPL and constantly only 230 ms from the command line
08:04hyPiRionbtcNeverSleeps`: yeah, it's likely due to the jvm flags
08:04btcNeverSleeps`(once again, besides the first call from the command line, which isn't JIT'ed yet)... But I take it hyPirion is right about the REPL trade-off between startup time / execution time
08:04hyPiRionyou could check it out
08:04btcNeverSleeps`that is very interesting : )
08:18btcNeverSleepsindeed, I added ":jvm-opts []" to my defproject in project.clj and now the timing are identical
09:32thesaskwatchMikalv: well, why the global dependency then?
09:32thesaskwatchShouldn't ./node_modules/.bin/gulp just work?
10:31btcNeverSleeps,(defn boo [x] {:pre [> x 3]} x)
10:31clojurebot#'sandbox/boo
10:31btcNeverSleeps,(boo 1)
10:31clojurebot1
10:32btcNeverSleeps,(boo 7)
10:32clojurebot7
10:32btcNeverSleeps,(true? *assert*)
10:32clojurebottrue
10:32btcNeverSleepsWhy is is no exception raised because of pre-condition failure? *assert* is true
10:35qbg,(defn boo [x] {:pre [(> x 3)]} x)
10:35clojurebot#'sandbox/boo
10:35qbg,(boo 1)
10:35clojurebot#<AssertionError java.lang.AssertionError: Assert failed: (> x 3)>
10:36qbgDoes that help btcNeverSleeps?
10:36btcNeverSleepsqbg: Lisp! Forgot parentheses! What problem cannot be solved with more (or less) parentheses ^ ^
10:37qbgusing brackets instead of parentheses :p
10:37btcNeverSleeps:)
10:45specklewow, this channel is bigger than ##java
10:45AimHere##java has registration demands to keep out the riff raff. Clojure actively welcomes riff-raff
10:47speckleAh, now it all makes sense
10:49btcNeverSleepsouch
10:49btcNeverSleeps,(defn ok [] {:pre [(true? false)]} 42)
10:49clojurebot#'sandbox/ok
10:49btcNeverSleeps,(ok) ; so far so good
10:49clojurebot#<AssertionError java.lang.AssertionError: Assert failed: (true? false)>
10:49btcNeverSleeps,(defn nok [] "" {:pre [(true? false)]} 42)
10:49clojurebot#'sandbox/nok
10:49btcNeverSleeps,(nok)
10:49clojurebot42
10:50btcNeverSleepsPutting the comment / doc using "" before the {:pre ...} makes the precondition silently being not executed !?
10:50qbg,(defn nok "" [] {:pre [(true? false)]} 42)
10:50clojurebot#'sandbox/nok
10:50qbg,(nok)
10:50clojurebot#<AssertionError java.lang.AssertionError: Assert failed: (true? false)>
10:50qbgdoc string always comes before the arguments vector
10:50btcNeverSleepsI kinda get it but... What did my "nok" do?
10:51qbgIt is a function with three body forms
10:51qbg"", {:pre [(true? false)]}, and 42
10:51btcNeverSleepsoh right, because a map is a fn
10:51btcNeverSleepsthat's a bit tricky :)
10:52qbgdoc strings always come before argument vectors because you can have a function with different arities
10:52btcNeverSleepsqbg: thx a lot for the help with my riff-raff'ing : )
10:52qbgand there is a shared doc string for all of them
10:52btcNeverSleepsqbg: I see
10:53qbg,(defn foo "Hello, world!" ([] 0) ([x] x))
10:53clojurebot#'sandbox/foo
10:53qbg,(foo)
10:53clojurebot0
10:53qbg,(foo 5)
10:53clojurebot5
10:55qbg,(doc foo)
10:55clojurebot"([] [x]); Hello, world!"
11:02gtraktpope: got jump-to-def working, still waiting on patches to piggieback/cljs itself, but you can try it.
11:02gtrakhttp://dev.clojure.org/jira/browse/CLJS-764
11:24nickik{:op :vector,
11:24nickik :env {:ns {:name cljs.user}, :locals {}},
11:24nickik :form [1],
11:24nickik :items
11:24nickik [{:tag number,
11:24nickik :op :constant,
11:24nickik :env {:context :expr, :ns {:name cljs.user}, :locals {}},
11:25nickik :form 1}],
11:25nickik :children
11:25nickik [{:tag number,
11:25nickik :op :constant,
11:25nickik :env {:context :expr, :ns {:name cljs.user}, :locals {}},
11:25nickik :form 1}],
11:25nickik :tag cljs.core/IVector}
11:25nickikWho does it have :items and :chidren is this not always the same?
11:31voldymannickik: protip: https://www.refheap.com
11:41mzdravkovHow can I get the first element from an infinite seq that satisfies some condition?
11:42eggheadmzdravkov: some
11:42egghead,(doc some)
11:42bbloomnickik: all AST nodes have :children even if they aren't collections that also have :items. look at the analyzer output of an 'if form for example
11:42clojurebot"([pred coll]); Returns the first logical true value of (pred x) for any x in coll, else nil. One common idiom is to use a set as pred, for example this will return :fred if :fred is in the sequence, otherwise nil: (some #{:fred} coll)"
11:43nickik@bbloom I see that. But why, is the question. If for example has all elements allready saved in other keys :test and so on.
11:44nickikMost seam to do that.
11:44qbgmzdravkov: If you need to be able to find false or nil, you can use a combination of first and filter
11:47mzdravkovthe problem is that some returns true or false (or the searched element if used with set), but I don't know what the searched element is. I want to take the first rand-int that is even for example.
11:47bbloomnickik: the goal, which i don't think we've succeeded in accomplishing, is to support generic traversals over unknown node types. ie future proofing analyzer output consumesr
11:47bbloomnickik: there's a far bit of discussion about it on the mailing list and here in irc between myself and dnolen among others, if you search the logs
11:47mzdravkovqbg: filter on infinite seq? am I missing something? :)
11:47qbgfilter returns a lazy seq
11:48eggheadmzdravkov: if you ask for the first that satisfied a condition you are asking to exhaust the list until that condition is met
11:48nickik@bbloom Ok, I see. This are on clojure-dev? I will have to look for them.
11:48mzdravkovok, first and filter did the wokr, thanks a lot :)
11:48qbg,(first (filter even? (repeatedly #(rand-int 10))))
11:48clojurebot6
11:48bbloomnickik: start here: http://dev.clojure.org/display/design/AST+children
11:49nickikI am plaing to compile the ast to a bytecode (witch I design) and I will then write a interpreter for that bytecode.
11:49nickikThank you
11:49bbloomnickik: cool. may i ask what your goal with the byte code is?
11:50nickik@bbloom the main goal is to learn how to write a tracing jit compiler
11:50bbloomnickik: sounds like a fun project :-) feel free to stop by here for help, there are a number of clj & cljs analyzer & codegenerator experts that hang out here
11:51borkdudewhat is riff-raff?
11:51nickikSo the first state of the project is designing a bytecode, second a ast to bytecode compiler, third writing a interpreter
11:51nickikthen trace compiler :)
11:51qbgborkdude: disreputable or undesirable people.
11:52bbloomnickik: won't be easy, but should be pretty straightforward. good luck!
11:52nickik@bbloom Maybe you can answer me this, is the tools.analyzer used in cljc?
11:52nickikor are those diffrent projects
11:53bbloomnickik: i don't know anything about cljc, but tools.analyzer is part of Bronsa's ongoing effort to write clojure-in-clojure
11:53nickikThis project (or a version of it) has been in the back of my head for 5 years and now I started.
11:53bbloomnickik: tools.emitter.jvm is also a good place to look
11:53bbloomnickik: it generates jvm bytecode
11:54bbloomhttps://github.com/clojure/tools.emitter.jvm
11:55nickikI am still at the stage of just getting tools.analyzer to work for me but I will defently talk a closer look at tools.analyzer.jsm and emitter.
11:55bbloomnickik: have you written a byte code interpreter before?
11:56nickik@bbloom No. Not really.
11:56bbloomnickik: then you may want to start smaller: you can create your own lisp with fewer special forms and tricky edge cases
11:57nickikMe and a friend worked on another bytecode interpreter for a short time but we did not finish the project for other reasons
11:57nickikbbloom: My goal is not to have full clojure. If something is to hard I will just cut it out.
11:58bbloomnickik: that's a good mentality for learning: forward progress at all costs :-)
11:58nickikAlso I work with a friend wo allready wrote compilers and is smarter then me.
11:58bbloomnickik: that always helps too
11:58nickikIf you have comments see: https://github.com/nickik/clojit/blob/master/Bytecode%20Spec.md
11:59qbgluckily interpreters aren't that hard unless you make them that way :)
11:59qbgAnd a trivial non-optimizing compiler isn't much harder than an interpreter
12:00nickikI prefer the model of LuaJit to V8. Interpreter first then one jit instead of 2 jits.
12:00nickikI will however not write the interpreter in assembly :)
12:01bbloomnickik: i haven't written a jit myself (yet) but i've written lots of interpreters and a few small compiler thinggies
12:01qbgWhat language are you doing to do the interpreter in?
12:01bbloomright1: but i agree, having an interpreter on hand is just a good idea in general
12:01bbloomwhoos tha twas for nickik ^^
12:01right1:(
12:01nickikWe wanted something low level enougth but not C. So we are currently thinking of using Rust
12:02nickikTo get some more safty and GC
12:02qbgGetting a GC for free is always nice
12:02qbgWhat are you going to JIT down to?
12:02qbgassembly?
12:03nickikIm just afraid of using C, because getting the general logic right will be hard enougth I dont want to also run into to many memory issues.
12:03nickikYes that is the plan.
12:03qbgAre you going to write your own gc too then?
12:03nickikMaybe LLVM but Im not sure how well this works. This is something we have to learn more aobut.
12:04nickikAt first everything will be rust GC pointers, I dont want to write a GC.
12:04nickikMaybe in the future.
12:04nickikThere are some GC one could use MPS or Boehm
12:05bbloomnickik: may i suggest simply writing your own "GC" where the GC basically allocates linearly and never collects?
12:05bbloomnickik: turns out you can do a surprising amount of real work with the null garbage collector :-P
12:05nickikInstead of using Rust GC pointers?
12:06bbloomyeah
12:06nickikI will keep it in mind.
12:06nickikWe are yet far away from that beeing a factor.
12:06bbloomyou might find that interop with another system is harder than just writing a naive GC yourself... and you write the ULTIMATE naive GC, whose collection strategy is exit(1)
12:07qbgJust write crash tolerant programs and crash when you run out of memory :)
12:09nickikqbg, maybe writing a collecting gc is easier then writing crash tolerant programs :)
12:10gkoHello, I'm "proxy"-ing some class, but when I call one of its (Java) methods, I have a "No matching method found: " exception...
12:11gkoThe methods should be available, right?
12:15qbgAre you calling the method from within the proxy?
12:15qbgor outside of it?
12:18gkoInside
12:19gkoHere is the class: http://i1.dk/JavaDiameter/doc/ -> NodeManager
12:19gkoI proxied NodeManager
12:19Bronsagko: can you nopaste the proxy?
12:20gkoand within a Clojure-defined handleRequest, I call answer with (.answer this msg connkey)...
12:20gkoBronsa too big
12:20gkoHere's the top:
12:20gko(defn new-node-manager [node_settings]
12:20gko (proxy [NodeManager] [node_settings]
12:20gko....
12:20gkonopaste url?
12:21Bronsagko: use https://www.refheap.com/
12:21gkoO
12:21gkoK
12:23gkohttps://www.refheap.com/40193
12:24gkoIs it because of "protected" ?
12:26wei__anyone have a more elegant way of writing this? (defn take-only [n coll] (let [c (take n coll)] (when (= (count c) n) c)))
12:27wei__basically take N only if the collection has enough elements, nil otherwise
12:27qbgNote that while method fns can
12:27qbgbe provided to override protected methods, they have no other access
12:27qbgto protected members, nor to super, as these capabilities cannot be
12:27qbgproxied.
12:27qbggko: there is your answer from the doc string of proxy
12:29AmnesiousFunesIs there a paredit command to move the cursor up to the top level? I can't seem to find one
12:33AmnesiousFunesAh, nevermind; found it.
12:35gkoqbg Thanks. It seems that if I override it (answer), it doesn't work too... So, I can't call it (Clojure's .answer) from Clojure.
12:36gkoFortunately, original "answer" is just node.sendMessage(msg, connkey) :)
13:06andyfPerhaps the new Clojure 1.6 vars should be named bikeshed? if-bikeshed when-bikeshed (this is just blowing off steam -- I do care about names, just not so much as the people talking about this)
13:08r0b1andyf: how many bikes can u fit in this shed
13:10andyfI was just re-reading the Wikipedia page on Parkinson's Law for entertainment
13:34srrubyAnyone have discount codes/tickets for ClojureWest ? (I'm paying out of my own pocket FYI).
13:56qbgOm question for anyone that can answer it
13:57qbgShouldn't (om/update! cursor v) be the same as (reset! app-state v) if the cursor points at app-state?
14:00mphi. is it ok to ask seesaw questions here?
14:03r0b1yeehaw
14:17ambrosebsfirst version of typed clojure mode for emacs https://github.com/typedclojure/typed-clojure-mode
14:21mdeboardambrosebs: Huh, nice
14:27DomKMDoes anyone here have experience using JRuby from Clojure? I'm working on Clojure library that wraps a JRuby-compatible gem and I'm looking for some guidance.
14:44unsymbolDomKM: only a super small amount of experience because it was incredibly easy. what you got in mind?
14:46borkdudeambrosebs what am I doing wrong? https://gist.github.com/borkdude/e97c0cfc8644529053ac
14:49DomKMunsymbol: I'm wrapping the ruby whois library (ruby-whois.org) since there don't seem to be any good whois libs for Java. It's a pure ruby lib, compatible with jruby, and has no dependencies. I'm wondering whether I should try to figure out how to precompile it to class files (and if so how?) or use it from zweikopf (https://github.com/ifesdjeen/zweikopf)?
14:49DomKMI don't actually know if those two approaches are mutually exclusive. Anyway, if the latter (which is what I'm currently doing), I can't figure out how to extend the Clojureize protocol to a custom ruby class since its java class is always org.jruby.RubyObject.
14:49DomKMsorry for the wall of text, everyone
14:54TravisDDoes anyone here have experience with the Incanter library for scientific computing?
14:55amalloy~anyone
14:55clojurebotJust a heads up, you're more likely to get some help if you ask the question you really want the answer to, instead of "does anyone ..."
14:57borkdudeTravisD There is a book that goes into depth with this
14:58borkdudeTravisD Clojure Data Analysis Cookbook
14:58TravisDAh, hehe, I guess that makes sense. I was going to ask if it is the best choice
14:59borkdudeTravisD it is Incanter-focussed as far as I can see. I think the only one?
14:59TravisDThere are some other libraries like clojure-numerics and HipHip
15:01borkdudeTravisD yes, but you asked for incanter specifically, so ;)
15:01TravisDHehe, yeah, I was wondering if it was the best choice for doing numerical computing in clojure. Sorry, I was pretty unclear
15:03amalloyi know nothing about the field, but i would pick incanter
15:03TravisDyeah, seems to be pretty well polished
15:04amalloycore.matrix is probably worth a glance at
15:08AeroNotixDoes clojure have any "easy-pickings" tickets I can get my feet wet with contributing?
15:10jro_why (doseq [i .. j .. large ranges] do side effecting stuff with i j) much decades slower than (loop [i.. (loop j.. -construct?
15:10jro_is there higher level constructs to manipulate arrays, that does not suffer performance hit.
15:11qbgjro_: Try (nested) dotimes
15:11jro_ok, thanks.
15:11AeroNotixqbg: congratulations on understanding that sentence
15:12qbgseq creation is not free, so doseq will have a perf hit
15:12AeroNotix"much decades slower"
15:12jro_sorry about the language
15:13jro_should be "is about ten-time slower".
15:13AeroNotixaha, google translate made that "decades" I assume
15:13jro_hrm. Just a mistake.
15:14AeroNotixOh, ok
15:18paulswilliamsesqambrosebs: hi - remember my question about java.awt.Frame yesterday - well, here's an update: http://stackoverflow.com/questions/21803419/clojure-let-frame-java-awt-frame-within-un-invoked-function-causes-awt-to
15:26pcnhey, is there a common practice to save performance metrics w/ clojure? I want to receive a lot of messages, then write them out, and then maintain counters for them that are periodically collected, and reported on.
15:26pcnThis'll be multi-threaded etc.
15:28AeroNotixpcn: graphite?
16:12seangroveI'm looking for a clean way to have a default catch-all for a defmulti without the defmulti knowing about what's implemented and what isn't
16:12seangroveI would like to be able to lazily implement specific behaviors and have them called if available, really
16:42AmnesiousFunesIs there any common case where a top form would be formatted to start at a non-zero column, i.e. already indented?
16:53amalloyno
17:56TravisDIs there better support for clojure in emacs than clojure-mode?
17:58llasramTravisD: cider?
17:59bob2TravisD, what do you want to be better?
17:59bob2cider works with clojure-mode
17:59TravisDmostly I was hoping for some code completion and automatic error checking
18:00bob2code completion you get with https://github.com/alexander-yakushev/ac-cider-compliment
18:00bob2what do you mean by 'automatic error checking'?
18:00bob2flymake?
18:00TravisDyeah
18:01bob2haven't been able to find a thing for that yet, but C-c C-l will underline errors
18:01TravisDah, alright, thanks :)
18:01TravisD(in cider that underlines errors?)
18:03bob2it's related to cider
18:32akurilinRandom question: do any of you guys have experience implementing caches in web applications? So say you're backed by a SQL store, but you have pretty large tables and now you want to speed it up. Do you just manually implement "paging" against redis, kind of like what your OS would do for disk?
18:34qbgI've implemented in memory caching of domain level queries before
18:39qbgCorrectness is the hardest part
18:41akurilinSo we're talking about: write and read as much as possible from cache, write-back to disk every x seconds, evict pages that are not as popular as the other ones?
18:41qbgw.r.t. the world changing behind your back that is
18:41akurilinOh yeah, what I said would assume that you only ever touch the cache, but yes, if you change what's in the store that's bad :(
18:41qbgThe data I was caching was query only
18:42qbgbut was in the store would change periodically
18:42qbgLuckily I was in control of the process that changed the data in the store too
18:42qbgSo I could make it obvious to the application that the data changed
18:43qbgand dump the caches appropriately
18:44qbgHow many instances of your app are you going to have running at once against the same store?
18:46akurilinRight now one, but that's probably not going to last for too long, might need to add a second / third ones soon as the load goes up.
18:46akurilinRight now I was doing some caching locally with atoms under the assumption there'd be one instance, but it sounds like once you have 2+ you need a shared redis instance or something like that
18:48akurilinTalking to redis over the network in EC2 should still be faster than having Postgres query against a large table.
18:48aphyr(protip: you can probably cache more in a multithreaded JVM heap than in a singlethreaded redis node on the other side of a flaky network connection)
18:48akurilinAlthough I could be 100% wrong without actual test numbers.
18:48qbgHave you made sure that your SQL design is good?
18:48akurilinqbg: No.
18:49qbgIf you can get that to be fast enough, then your job becomes easier
18:49aphyr(additional protip: avoid caching layers if users will later write cached data back to the DB)
18:49aphyr(begging for race conditions and data inconsistency)
18:50akurilinaphyr: makes sense, I'm just starting to dip my toes into this.
18:50akurilinqbg: my problem is that I know basic SQL to get away with small-sized projects, but I've definitely not had to work with SQL once its tables start to hit billions of rows
18:50akurilinSo I'm learning as I go.
18:50akurilinDamage controlling :)
18:51qbgHow frequent are writes?
18:52akurilinWell, during the schoolday our kids dump maybe 30 rows every 3 mins. We have 10k of these kids, soon 100k..
18:52akurilinThis is during the hot hours, it's pretty much a wasteland in the evening.
18:52qbg30 rows per kid, or total?
18:53akurilinAt the same time teachers/admins run a bunch of analytics math against the data set and want to get stats/visualizations.
18:53akurilin30/kid/3mins
18:53aphyrakurilin: use indexes; use real hardware; use foreign key constraints; avoid redundant indices; use secondary spares for offline analytics; hire a DBA or take a course.
18:54aphyrDefinitely easier to improve mysql or postgres performance than to try and reason about distributed cache safety.
18:54akurilinaphyr: it's like bitemyapp is whispering that in your ear :P
18:54akurilinWhat's offline analytics out of curiosity? Pre-computing results?
18:55aphyr"teachers/admins run a bunch of analytics"
18:55aphyrIf that's expensive, run it on a separate node with a copy of the data.
18:55aphyrUse async replication from the primary node if consistency isn't critical.
18:56akurilinaphyr: got it, makes sense. How far can I take this?
18:56aphyrmillions of ops/sec should be readily achievable, depending on transaction contention/complexity.
18:57akurilinI guess the big boys eventually start shelving the old data into separate storages, right?
18:57aphyrDepends on your workload.
18:57aphyrMost indices are tree-structured; costs go up logarithmically with data volume.
18:57aphyrBut there are some linear costs.
18:57aphyr(disclaimer: I am not a database expert)
18:58akurilinI think PG's btrees were log32, so it should go a long way.
18:59akurilinqbg: but yes what you were saying is probably my biggest concern: that my schema is deeply inefficient and I could be having a much easier time.
18:59qbgcorrect
18:59akurilinBack at my previous gig we got really screwed over by giant joins and it was a disaster until we brought over a real DB person.
19:00aphyrYep. Probably easier to learn a bit of DB theory and tuning than to write your own distributed caching system.
19:00qbgno need to reinvent the wheel
19:00qbgespecially when the current one is battle tested
19:00akurilinaphyr: well there's DB theory and there's "giant DB tables theory", which I can't seem to find anywhere
19:00akurilinI guess there's "use the index luke" which I really need to finish going through.
19:00akurilinbut it felt pretty entry-level.
19:01akurilinAlso I powered through High Performance Postgres 9 a few months ago, but that's mostly about tuning for your hardware, which I did
19:01akurilineven though ironically I'm on EC2, so it sucks balls anyways.
19:02akurilinaphyr: do you have a favorite bare metal provider? I hear good things about softlayer
19:02qbgdo you have any real hardware?
19:02akurilinqbg: no, sadface.
19:02akurilinqbg: we got 15 grand of AWS credits through our incubator/coworking space so we're burning through that for now.
19:02aphyrSoftlayter's good.
19:02aphyrYeah, get the heck off EC2.
19:03aphyrExpect a 10x speedup just for using real hardware.
19:03akurilinqbg: but I'm not actually hard-wiring myself against anything AWS-specific, everything's portable thanks to ansible.
19:03aphyrI've been benching various DBs on EC2 for the last few months; bottom line is they're all terrible until you start spending about 15 grand/mo, and even then they're not great.
19:04aphyrThe i2 instances are the only ones even beginning to approach what I'd call "acceptable" IO perf.
19:04akurilinaphyr: in your experience, is the fact that we're pretty much only at full capacity during the day and totally dead the rest of the time, deserving of an "auto-scaling" solution?
19:04aphyrI mean, you gotta do the math
19:05aphyrbut if you're running machines half the day, and you can get 2x perf/price somewhere else, it's equivalent.
19:05akurilinaphyr: I remember reading a Parse.com report where they mentioned having to move to the SSD instances with reserved throughput and the 2nd IO channel for EBS and getting the largest RAM machines.
19:05akurilinSo I can see them blowing through a TON of cash on AWS.
19:05aphyrEBS with provisioned IOPS: expensive, also terrible.
19:05aphyrPretty much the only decent IO I've gotten has been with insane raid0 setups across piops ebs, or with SSD instance storage.
19:05aphyrEither way you'll pay about 10x more than the HW itself on a 3-year cycle.
19:06akurilinWe like perf, we like money, and we like not having to overengineer to make it happen.
19:06aphyrYou can build a 128-GB 48-core 10TB SSD box for ~12K.
19:06aphyrOr you could rent those boxes for ~4k/mo
19:07aphyradds up quick, haha
19:07aphyralso the virtualization imposes some pretty gross hits on app performance
19:07aphyrHVM is definitely better than paravirt, but it's still noticeable.
19:08aphyrYeah, just set up a softlayer acct. They run specials; use 'em.
19:08aphyrYou can usually get double ram for free, at least.
19:08akurilinHmm what am I going to miss from AWS?
19:08aphyrA horrible web UI?
19:08akurilinI like their VPC
19:08aphyr(I jest)
19:08akurilin:P
19:09aphyrNaw, they're totally different beasts.
19:09aphyrBut IMO it's less work ordering HW through SL than trying to fight the AWS APIs.
19:09aphyrIf you get to larger scale, AWS automation becomes more efficient, but the costs become proportionately larger.
19:10akurilinaphyr: so this is pretty much 100% "you don't use CM to check-out boxes and deploy on them". As in: you have boxes pre-allocated for you that might take days to get set up and you just deploy to them.
19:10aphyrYeah, I mean, capacity planning is a thing
19:10aphyrmonitor your latencies, disks, etc.
19:10akurilinHeh.
19:10aphyrsame as you do on EC2.
19:10aphyrJust plan on 6 hours to 3 days of lead time.
19:11aphyrSince the boxes are so much less expensive, just buy better HW and let it sit idle.
19:11akurilinAnd you can't go "oops one instance died, I'll spin another one up in 15 mins"
19:11aphyrYeah, EC2 is definitely less reliable.
19:11aphyrSL boxes do go bad, but at a significantly reduced rate in my experience.
19:11aphyrI usually see ~30% of my EC2 nodes fuck up in some way.
19:12aphyrSL, I think we had to cycle maybe 4 boxes out of 50 over a couple years?
19:12aphyrYMMV; I use a lot more IO than most people.
19:13aphyrSeriously though, may be cheapest just to hire a DBA for a few days to look over your schema.
19:14aphyr1000x perf improvements are not unheard of, haha
19:14aphyr"Oh, this table has no primary key", that sort of thing.
19:14akurilinInteresting. Well I do enjoy me a good EXPLAIN ANALYZE so I can certain optimize based on that, and I have logging in place for when certain queries go over xms
19:15akurilinBut that's a great idea for once we actually have money to pay experts for advice :)
19:15akurilinSo that's a point well-taken.
19:16aphyrbooks are also available.
19:16aphyrthough mysql optimization is out of my depth so I can't give you much specific feedback there. :(
19:16akurilinIf you know of good ones I'm all ears.
19:16bob2are you using percona
19:17akurilinI've been looking for books on web app architecture for a while and I can't find anything good
19:17akurilineverything's based on folklore
19:17akurilinbob2: what's that?
19:17bob2a fork of mysql that's significantly less crap
19:18akurilinbob2: I've been pretty happy with PG so far, no complaints. I do hear that replication is hard though.
19:18gtraktechnomancy: is there a way to load a lein-plugin at command-line time?
19:19bob2oh, I thought aphyr said you were using mysql
19:20gtrakah, I see the 'lein plugin' command is dead. Would be convenient for cider :-)
19:23muhoobob2 btw, you wouldn't happen to be the bob2 from #debian?
19:24bob2long ago
19:24muhooaye
19:26pcnAeroNotix: sorry, I was afk for a bit.
19:28pcnSure, graphite is an answer for "how do I display the metrics" the e.g. using codahale/metrics in plain java lets me annotate functions and have the info about the # of invocations, time taken, etc. recorded and quantized etc. in the program
19:28pcnMuch more scalable
19:29pcnOK, it looks like there are a few wrappers for codahale/metrics
19:29bob2take that, disks
19:29aphyrpcn: https://github.com/aphyr/interval-metrics might be oof interest
19:37pcnaphyr: thanks, that may be more than what I was asking about, which is very cool. What led you to this set of features?
19:44aphyrhttp://riemann.io
19:48muhoobtw, timbre is awesome
20:01pcntimbre does look useful
20:01gtrakaphyr: I hope it's no big deal I'm slacking on merging the no.disassemble PR :-) been sidetracked.
20:03gtrakjust thought about it now b/c I've been working in cider, considering a 'disassemble' nrepl op :-).
20:04gtrakbecause why not
20:07aphyrcool!
20:33muhoohmm i'm trying to load some data in -main, running from lein with :injections, and i'm getting the most bizarre error: java.lang.IllegalArgumentException: Parameter declaration log/info should be a vector
20:34muhoolog/info is the first call inside -main
20:34muhooum, and it doesn't seem to matter what function, the first function in -main fails with "Parameter declaration foo should be a vector"
20:35TravisDIs there a good book that introduces clojure? I'm thinking of picking up a copy of "The Joy of Clojure", but I'd like to see if there's a better buy first
20:35bob2muhoo, did you forget an arg list for -main
20:35muhooTravisD: joy is good, also clojure programming (oreilly) if you're looking for more practical
20:35muhoobob2: DOH thanks
20:35bob2TravisD, joy of clojure is not an intro, aside from a very fast tutorial in chapt 2
20:36bob2"clojure programming" (the o'reilly one) is quite good
20:36TravisDbob2: Ah. I'm a bit familiar with scheme and FP in general. Do you think joy of clojure is not appropriate to read first?
20:36AmnesiousFunesTravisD: I agree with bob2. Clojure Programming is quite good.
20:36bob2don't know
20:37bob2I have both
20:44AmnesiousFunesTravisD: As a concise introduction, Programming Clojure is also good. I'd suggest to at least check out a free chapter; Clojure is a bit quirky as far as LISP goes, and there are a few things you might know from elsewhere (e.g. STM)
20:45AmnesiousFunes*not know from elsewhere
20:45TravisDAmnesiousFunes: Ah, thanks I'll take a look :)
20:49AmnesiousFunesTravisD: There's also a free book at http://www.braveclojure.com/, but I'm not familiar with it
20:50TravisDcool, thanks :)
20:50AmnesiousFunesand the Clojure Koans as a sequence of exercises: http://clojurekoans.com/
21:06gfredericksis it weird that clojure.core/not doesn't have an inline version?
21:06bob2inline?
21:11gfredericks,(source +)
21:11clojurebotSource not found\n
21:11gfredericks&(source +)
21:11lazybotjava.lang.RuntimeException: Unable to resolve symbol: source in this context
21:11gfredericks&(clojure.repl/source +)
21:11lazybot⇒ Source not found nil
21:18amalloy~def +
22:07Tolstoy(d/create-database "datomic:mem//my-db") => ClassCastException clojure.lang.PersistentArrayMap cannot be cast to datomic.db.IndexSet datomic.db.Db (db.clj:1733)
22:09TolstoyMaybe it's the 1.6 beta.
22:16TolstoyYep. Dataomic is broken for clojure 1.6.0-beta1.
22:16gtraksounds like an AOT compilation issue
22:17gtrakdid it work for the alphas?
22:17TolstoyNo idea. Just tried it.
22:17TolstoyI'm just using a repl: no AOT compilation that I know of.
22:17gtrakdatomic itself would be aot compiled
22:18TolstoyAh.
22:19TolstoyIs there a Jira (or something) for Datomic?
22:20gtrakthere's a mailing list
22:21TolstoyAlas, no one else seems to have had the problem.
22:47pcnI'm looking for a way to make input validation less painful. Has anyone used https://github.com/leonardoborges/bouncer for this sort of thing?
22:48pcnbuffer graphite
22:48pcnwhoops, switching fail
23:27xenskycan anyone advise me on using multimethods to dispatch over multiple values? i'm having trouble with it
23:29bob2you mean on functions taking different numbers of arguments?
23:30xenskyno, not arity specifically
23:30xenskyi have a multimethod that i want to dispatch over two values
23:30xenskyi tried to dispatch over an array [val1 val2] and that dispatches fine
23:31bob2so, on types?
23:31xenskybut i can't figure out how to dispatch over defaults, to fall back when a method only matches one of the vals
23:31xenskyin my case it won't be dispatched on the types of the values, they'll be constants like keywords or strings
23:46dsrxhuh, are java strings interned
23:46dsrx,(identical? "foo" "foo")
23:46clojurebottrue
23:46amalloydsrx: some of them
23:46amalloystring literals in java source code are guaranteed to be interned, and you can intern others if you want
23:47amalloyi don't know if clojure guarantees to intern literals
23:47dsrxah, guaranteeing it for literals makes sense
23:47amalloyprobably does, though, since i think they go into the constant pool
23:47Wild_Catthat's an implementation detail, really
23:47Wild_Catyou shouldn't rely on it
23:47dsrxI'm not planning to rely on this
23:48Wild_Catbut yeah, it makes sense to intern literals of immutable object types
23:52amalloyWild_Cat: i mean, clojure probably does guarantee it
23:53Wild_Catactually, is there a Clojure language spec?
23:58xenskyi found a work-around for my defaulting problem. revised question: can i dispatch a multimethod on variable arity?